Bir etkinliğin geçirdiği bir dizeyi nasıl değiştirebilirim?


10

Benim gözlemci işlevi, böyle bir olay tarafından geçen bir değişken olsun:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
}

Bir sthnesne ise, üzerinde yöntem çağırarak değiştirebilirim. Ama sthbasit bir dize ise nasıl değiştirebilirim ? Aşağıdakileri başarılı olmadan denedim:

public function observerFunc(Varien_Event_Observer $observer)
{
    $sth = $observer->getEvent()->getSth();
    $observer->getEvent()->setSth('test');
    $observer->setSth('test');
}

Sadece bazı olayların da dizenin değiştirilebileceği bir taşıma nesnesini geçtiğini öğrendim (teşekkürler Alex ), ancak olay page_block_html_topmenu_gethtml_aftergeçmiyor. Peki ne yapabilirim?

Söz konusu olay bu şekilde gönderilir ve $ html'yi değiştirmek istiyorum:

$html = $this->_getHtml($this->_menu, $childrenWrapClass);
Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
    'menu' => $this->_menu,
    'html' => $html
));

Yanıtlar:


12

Yapamazsın.

Taşıma nesnesi yaklaşımının çalışmasının nedeni PHP'nin nesnelerinin diğer adları / referansları olmasıdır . Bir nesneyi değiştirdiğinizde, Tek Gerçek Nesneyi değiştirirsiniz.

PHP'nin ilkel türleri (ints, dize, boolean, vb.) Nesne değildir ve PHP'nin argümanlar için değer kurallarına göre geçer . Bir Magento modülü geliştiricisi size bir olay gözlemcisinde ham bir dize geçirirse

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_after', array(
        'menu' => $this->_menu,
        'html' => $html
    ));

bu onların söylemesi

Bu değere bakabilirsiniz, ama değiştirmenizi istemiyorum.

Bunun kasıtlı bir tasarım kararı mı yoksa şeyleri okuyucu için bir alıştırma olarak düşünmeyen bir geliştirici mi bırakacağız.

Sorulmamış sorunuzla ilgili olarak, üst menüyü değiştirmek istiyorsanız, alacağım birkaç yaklaşım var. İçine çengel page_block_html_topmenu_gethtml_beforeolay ve değiştirme menunesne

    Mage::dispatchEvent('page_block_html_topmenu_gethtml_before', array(
        'menu' => $this->_menu
    ));

çalışmalı, çünkü _menubir nesne

/**
 * Top menu data tree
 *
 * @var Varien_Data_Tree_Node
 */
protected $_menu;

İkinci olarak, menü üreten sınıfı yeniden yazabilirsiniz

public function getHtml($outermostClass = '', $childrenWrapClass = '')
{
    $html = parent::getHtml($outermostClass, $childrenWrapClass);
    //monkey with $html here to add your menu items or custom markup
    return $html;
}

Üçüncü olarak, mevcut üst menü bloğunu kaldırmak ve oluşturduğunuz özel bir sınıfa yeni bir blok eklemek için düzen güncellemelerini kullanabilirsiniz. Özel sınıfınız, varolan üst menü sınıfını genişletir ve sonra yeniden tanımlar getHtml. Bu daha karmaşıktır, ancak yeniden yazma ile ilgili sorunları önler.


5

Bunun bir tasarım hatası olduğunu söyleyebilirim.

Nesneler referans olarak aktarılır, böylece manipüle edilebilirler. Dizeler her zaman kopyalanır. Yani bu durumda dize gözlemcinin içinde manipüle edilemez, page_block_html_topmenu_gethtml_afterolay bile bana sadece amacı gibi davranması için size bir şans vermektir $html.


3

İse gözlemleyerek taşınan dizesi yoluyla blok çıkışını değiştirmek mümkün core_block_abstract_to_html_afterolayı (bağlantı) . Bu durumda, oluşturulan içerik blok örneğinden gözlemci örneğine taşınır ve en önemlisi taşınan içerik, blok sınıfı tarafından döndürülen içeriktir. Aşağıdaki örnekte açıkladığım önemli bir önbellek değerlendirmesi olduğunu unutmayın.

Misal

Bu olay her blok oluşturma için tetiklendiğinden , gözlemciyi tek birton olarak yapılandırmalı ve blok türünün bir örneği olup olmadığını test etmelisiniz Mage_Page_Block_Html_Topmenu.

public function manipulateTopmenuOutput(Varien_Event_Observer $obs)
{
     if ($obs->getBlock() instanceof Mage_Page_Block_Html_Topmenu){
         $initialOutput = $obs->getTransport()->getHtml();
         //e.g. $modified output = $this->yourManipulationMethod($initialOutput);
         $obs->getTransport()->setHtml($modifiedOutput);
     }
}

Manipülasyon mantığınız gözlem yönteminde uygulanabilir veya gözlemcide başka bir yöntemde bulunabilir.

Sorunlar

Çıktı manipülasyonu içerdiğinden ve tüm blok render'ları için gözlemci çağrıldığından, bu yalnızca birincil endişe bir blok yeniden yazımından kaçındığında kullanılmalıdır. Ayrıca, bu gözlemcide oluşturulan içerik, block_htmlönbellek yazma işleminden sonra (blok örneğinin çağrılması yoluyla _saveCache()) değiştirilir, bu nedenle ya block_htmlgözlemcideki girişi yeniden önbelleğe almanız gerekir (yansıma kullandığınız için biraz yapışkan) veya her ikisinden mantığı çoğaltarak _saveCache()ve _getSidPlaceholder()ağaç düğüm verilerine ilişkin herhangi bir şey işlemek gerekiyorsa yöntemlerle, nihayet önbellek giriş yazmak. ve üzere, ağaç düğümü verilerin bir kopyasını üretmek gerekir. Bu teorik tarafından yapılabilirdi kapma Mage_Catalog_Model_Observertekil, çok yapışkan aslında ... ondan ağaç kapma.


1
Magento'nun TopMenu'yu uygulamamı ruhumun özünden nefret ediyorum. Navigasyon özelleştirmesi gerektiren herhangi bir uygulama sırasında rutin olarak başımı ona çarpıyorum. Bu HTML çıktısını göze batmayan bir şekilde değiştirmeyi çok zorlaştırdılar; Magento size her adımda savaşır.
wlvrn

Evet, menü uygunsuz bir şekilde esnek değil, ancak çalışan işlevselliği biraz elde edersiniz.
Benmarks
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.