मैं एक घटना द्वारा पारित स्ट्रिंग को कैसे बदल सकता हूं?


10

मेरे पर्यवेक्षक समारोह में, मुझे इस तरह घटना से गुज़रा एक चर मिलता है:

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

यदि sthकोई वस्तु है, तो मैं उस पर तरीकों को कॉल करके इसे बदल सकता हूं। लेकिन sthअगर यह एक साधारण स्ट्रिंग है तो मैं कैसे बदल सकता हूं ? मैंने सफलता के बिना निम्नलिखित की कोशिश की:

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

मैंने अभी सीखा कि कुछ ईवेंट एक ट्रांसपोर्ट ऑब्जेक्ट भी पास करते हैं जिसमें स्ट्रिंग को बदला जा सकता है (धन्यवाद एलेक्स ), लेकिन इवेंट page_block_html_topmenu_gethtml_afterनहीं होता है। तो मै क्या कर सकता हूँ?

सवाल में घटना इस तरह से भेजा जाता है और मैं $ html को बदलना चाहता हूं:

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

जवाबों:


12

आप नहीं कर सकते।

जिस कारण से ट्रांसपोर्ट ऑब्जेक्ट एप्रोच काम करता है, PHP की वस्तुएं उपनाम / संदर्भ हैं । जब आप किसी ऑब्जेक्ट को संशोधित करते हैं, तो आप One True Object को संशोधित कर रहे हैं।

PHP के आदिम प्रकार (ints, strings, booleans, आदि) ऑब्जेक्ट नहीं हैं, और तर्कों के लिए मूल्य नियमों द्वारा PHP के पास आते हैं । यदि कोई Magento मॉड्यूल डेवलपर आपको किसी घटना पर्यवेक्षक में एक कच्ची स्ट्रिंग देता है

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

उनके कहने का तरीका है

आप इस मूल्य को देख सकते हैं, लेकिन मैं नहीं चाहता कि आप इसे संशोधित करें।

हम छोड़ देंगे कि क्या यह एक जानबूझकर डिजाइन निर्णय है या एक डेवलपर पाठक के लिए एक अभ्यास के रूप में चीजों के बारे में नहीं सोच रहा है।

आपके अनकहे प्रश्न के अनुसार, यदि आप शीर्ष मेनू को संशोधित करना चाहते हैं, तो कुछ दृष्टिकोण हैं जिन्हें मैं ले जाऊंगा। page_block_html_topmenu_gethtml_beforeघटना में हुक करना और menuवस्तु को संशोधित करना

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

काम करना चाहिए, क्योंकि _menuएक वस्तु है

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

दूसरे, आप मेनू बनाने वाले वर्ग को फिर से लिख सकते हैं

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

तीसरा, आप मौजूदा शीर्ष मेनू ब्लॉक को हटाने के लिए लेआउट अपडेट का उपयोग कर सकते हैं, और आपके द्वारा बनाए गए कस्टम वर्ग के साथ एक नया ब्लॉक सम्मिलित कर सकते हैं। आप कस्टम क्लास मौजूदा टॉप मेनू क्लास और उसके बाद फिर से परिभाषित करेंगे getHtml। यह अधिक जटिल है, लेकिन पुनर्लेखन से जुड़ी समस्याओं से बचा जाता है।


5

मैं कहूंगा कि उस घटना में एक डिज़ाइन बग है।

ऑब्जेक्ट्स को संदर्भ द्वारा पास किया जाता है, इसलिए उन्हें हेरफेर किया जा सकता है। स्ट्रिंग्स हमेशा कॉपी हो जाती हैं। तो इस मामले में पर्यवेक्षक के अंदर स्ट्रिंग में हेरफेर नहीं किया जा सकता है, यहां तक ​​कि page_block_html_topmenu_gethtml_afterघटना सिर्फ मुझे दिखती है जैसे कि इसका उद्देश्य आपको हेरफेर करने का मौका देना है $html


3

यह है को देख कर ले जाया स्ट्रिंग के माध्यम से ब्लॉक उत्पादन को संशोधित करने के लिए संभव core_block_abstract_to_html_afterघटना (लिंक) । इस घटना में, प्रदान की गई सामग्री को ब्लॉक उदाहरण से पर्यवेक्षक के उदाहरण के लिए ले जाया जाता है, और - सबसे महत्वपूर्ण बात - परिवहन की गई सामग्री वह है जो ब्लॉक वर्ग द्वारा लौटा दी जाती है। ध्यान दें कि एक महत्वपूर्ण कैशिंग विचार है जिसे मैंने उदाहरण के नीचे समझाया है।

उदाहरण

क्योंकि यह घटना हर ब्लॉक रेंडर के लिए निकाल दी जाती है , आपको पर्यवेक्षक को एक सिंगलटन के रूप में कॉन्फ़िगर करना चाहिए और परीक्षण करना चाहिए कि ब्लॉक का एक उदाहरण है 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);
     }
}

आपके हेरफेर तर्क को अवलोकन विधि में लागू किया जा सकता है या पर्यवेक्षक में किसी अन्य विधि में रखा जा सकता है।

मुद्दे

क्योंकि इसमें आउटपुट हेरफेर शामिल है और पर्यवेक्षक को सभी ब्लॉक रेंडरर्स के लिए कहा जाता है, इसका उपयोग केवल तब किया जाना चाहिए जब प्राथमिक चिंता ब्लॉक रीराइट से बच रही हो। इसके अलावा, इस पर्यवेक्षक में उत्पन्न सामग्री को पोस्ट- block_htmlकैश लिखने (ब्लॉक इंस्टेंस कॉल के माध्यम से _saveCache()) में हेरफेर किया जाता है , इसलिए आपको या तो block_htmlऑब्जर्वर (थोड़ा चिपचिपा) में प्रविष्टि को फिर से कैश करना होगा, जैसा कि आप या तो प्रतिबिंब का उपयोग करेंगे। या दोनों से तर्क डुप्लिकेट _saveCache()और _getSidPlaceholder()तरीकों कैश प्रविष्टि लिखने के लिए। और अंत में, यदि आप पेड़ नोड डेटा से संबंधित कुछ भी हेरफेर करने के लिए की जरूरत है, तो आप पेड़ नोड डेटा की एक प्रतिलिपि उत्पन्न करने के लिए होगा। यह सैद्धांतिक रूप से से किया जा सकता है हथियाने Mage_Catalog_Model_Observerसिंगलटन और इसे से पेड़ हथियाने ... बहुत चिपचिपा वास्तव में।


1
मुझे अपनी आत्मा के बहुत सार के साथ टॉपमेनू के मैगेंटो के कार्यान्वयन से नफरत है। मैं नियमित रूप से किसी भी कार्यान्वयन के दौरान इसके खिलाफ अपना सिर टकराता हूं जिसमें नेविगेशन अनुकूलन की आवश्यकता होती है। उन्होंने उस HTML आउटपुट को विनीत तरीके से ट्विक करना सुपर कठिन बना दिया है; Magento के हर कदम पर आप लड़ते हैं।
wlvrn

ठीक है, हां, मेनू अनुचित रूप से अनम्य है, लेकिन आपको बहुत अधिक कार्यक्षमता मिलती है जो काम करती है।
बेंचमार्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.