जब कोई एक्सटेंशन विश्व स्तर पर एक वर्ग को अधिलेखित करता है और मैं मूल का उपयोग करना चाहता हूं तो मैं क्या करूं?


42

हम एक एक्सटेंशन का उपयोग कर रहे हैं, जो विश्व स्तर पर Mage_Catalog_Block_Product_List_Toolbar ब्लॉक को अधिलेखित करता है।

<global>
    <blocks>
        <catalog>
            <rewrite>
                <product_list_toolbar>Amasty_Shopby_Block_Catalog_Product_List_Toolbar</product_list_toolbar>
            </rewrite>
        </catalog>
    </blocks>
</global>

जबकि एक्सटेंशन एक स्तरित नेविगेशन श्रेणी के संदर्भ में काम करता है, फिर से लिखा हुआ वर्ग ठीक से काम नहीं करता है जब हम अपने स्वयं के इन-हाउस मॉड्यूल में एक अन्य (कस्टम) दृश्य में एक मनमाना उत्पाद सूची सम्मिलित करते हैं। यदि हम एक्सटेंशन को केवल परीक्षण के उद्देश्य के लिए अधिलेखित कर देते हैं, तो सब कुछ ठीक काम करता है।

एक्सटेंशन डेवलपर के समुदाय कोड को संपादित किए बिना हम केवल अपने स्वयं के नियंत्रक के लिए एक्सटेंशन के पुनर्लेखन को पूर्ववत कैसे कर सकते हैं?


2
यदि आप क्लास बदलते हैं तो आप शायद शॉपबाई एक्सटेंशन को तोड़ देंगे लेकिन ... कभी भी ऐसा करने की कोशिश नहीं की, लेकिन आप अपने एक्सटेंशन में उस क्लास को फिर से लिखना चाह सकते हैं Your_Extension_Block_Catalog_Product_List_Toolbar का विस्तार Amasty_hopby_Block_Catalog_Product_List_Toolbar
Sander

मैं जो बता सकता हूं, मैगेंटो केवल एक <rewrite>प्रति वर्ग की अनुमति देता है , इसलिए हालांकि मैं कोर क्लास का विस्तार करने के लिए अपनी खुद की कक्षा बना सकता हूं, मुझे यकीन नहीं है कि मैं इसे getBlock('catalog/product_list_toolbar')फैक्ट्री पद्धति के माध्यम से कैसे काम करूंगा ।
आरोन पोलक

यदि यह एक भुगतान किया गया एक्सटेंशन है, तो आपको एमस्टी सपोर्ट से संपर्क करना चाहिए, यह बग के रूप में दिखता है
फ्रा

क्या आपने इस मुद्दे को इंगित करने का प्रबंधन किया है? आप जिस समस्या का सामना कर रहे हैं उसका क्या कारण है (विस्तारित वर्ग में कौन सा कार्य)?
फ्लोरिनसेल यह

1
@AaronPollock शायद, लेकिन यह समस्या अभी भी एक विस्तार से उत्पन्न हो सकती है जो चीजों को मोटे तौर पर उतनी ही व्यापक रूप से लिखती है जितना इसे करने की आवश्यकता है। शायद हम वंशानुक्रम मॉडल को फिर से तैयार करना बेहतर होगा। शायद मिश्रण या लक्षण मदद करेंगे।
कोजिरो

जवाबों:


25

कैविट्स: सिस्टम में जो आप पूछ रहे हैं, उसे करने के लिए कोई डिज़ाइन तरीका नहीं है। निम्नलिखित को काम करना चाहिए, लेकिन मैंने इसे बड़े पैमाने पर उत्पादन प्रणाली पर आजमाया नहीं है, और ऐसी परिस्थितियां हो सकती हैं जहां यह अधिक परेशानी का कारण बन जाएगा जो इसके लायक है। केवल तभी आगे बढ़ें जब आप एक कार्य प्रणाली के पुनर्लेखन को बदलने से संबंधित आरामदायक डिबगिंग समस्याएँ हों।

चरण 1 पुनर्लेखन को पूर्ववत कर रहा है। Magento के कॉन्फ़िगरेशन ट्री को रनटाइम में बदला जा सकता है। तो, यदि आप निम्न कोड चलाते हैं

$config = Mage::getConfig();        
$config->setNode(
    'global/blocks/catalog/rewrite/product_list_toolbar',
    'Mage_Catalog_Block_Product_List_Toolbar'
);

तब Magento Mage_Catalog_Block_Product_List_Toolbarअनुरोध के शेष के लिए मूल ब्लॉक को तुरंत लिख देगा ।

चरण 2 यह तय कर रहा है कि इसे अपने मॉड्यूल में कहां कॉल करें। चूँकि यह सिर्फ आपके कंट्रोलर के लिए है और यह एक ऐसे ब्लॉक को फिर से लिख रहा है जो आपके कंट्रोलर के अंत तक तुरंत नहीं होगा, मैं आपके कंट्रोलर क्लास को कुछ इस तरह से एक तरीका जोड़ूँगा।

protected function _undoRewrites()
{
    $config = Mage::getConfig();        
    $config->setNode(
        'global/blocks/catalog/rewrite/product_list_toolbar',
        'Mage_Catalog_Block_Product_List_Toolbar'
    );    
}

और फिर अपने प्रत्येक कार्य के प्रारंभ में इस विधि को कॉल करें

public function indexAction()
{
    $this->_undoRewrites();
    $test = Mage::getSingleton('core/layout')->createBlock('catalog/product_list_toolbar');        
    var_dump($test);
}

यह थोड़ा क्लिंकी लग सकता है, लेकिन मुझे लगता है कि जब आप मैगेंटो के सिस्टम ऑब्जेक्ट्स के साथ चतुर हो रहे हैं, तो क्लंकी (यानी स्पष्ट) होना एक अच्छा विचार है। इसके लिए एक और स्थान controller_action_predispatchया controller_action_predispatch_front_controller_actionघटनाएँ और / या सशर्त रूप से लागू की जा सकती हैं।

जब तक इस विधि को नहीं कहा जाता है, बस फिर से लिखना पूर्ववत नहीं होगा। इसका मतलब है कि यदि आप कॉल करने से पहले किसी ब्लॉक को तुरंत _undoRewritesलिखने का प्रयास करते हैं , तो पुनर्लेखन वर्ग का उपयोग ऑब्जेक्ट को त्वरित करने के लिए किया जाएगा।


19

समाधान 1:
आप अपने नियंत्रक में सीधे वर्ग (php तरीका) को तुरंत करने की कोशिश कर सकते हैं

के बजाय

$this->getLayout()->createBlock('catalog/product_list_toolbar');

कुछ इस तरह:

$block = New Magento_Catalog_Product_List_Toolbar;
$this->getLayout()->addBlock(....);

समाधान 2:
एक और दृष्टिकोण आपके मॉड्यूल में एक नया वर्ग बनाएगा, जो मूल वर्ग का विस्तार करता है और उस एक का उपयोग करता है।

समाधान 3:
अन्यथा यदि एक्सटेंशन क्रिप्टेड नहीं है (हम सभी ओपन सोर्स से प्यार करते हैं :) आप यह जानने की कोशिश कर सकते हैं कि यह आपके सामान को क्यों तोड़ता है


समाधान 2 काम (व्यावहारिक समाधान) करता है, लेकिन यह महान नहीं है कि मैं rewriteउसी आधार वर्ग पर एक सेकंड नहीं कर सकता । इसलिए फ़ैक्टरी विधि काम नहीं करेगी (आप समझ गए हैं कि मुझे यह पहले से ही लगता है)। हो सकता है कि ऐसा करने का कोई मैगेंटो तरीका न हो, लेकिन यह देखने के लिए कि क्या कोई बेहतर तरीका है, इसे देखने के लिए थोड़ा ध्यान दें।
एरोन पोलक

समाधान 2 वह है जिसके साथ मैं जाऊंगा ... मैं सुझाव देने के लिए तैयार हो रहा था कि जब तक मैं फ्रांसेस्को का जवाब नहीं देख लेता। ;)
डेवडाइगर

1
भले ही मुझे समाधान 2 सबसे अच्छा लगता है, समाधान 1 का एक नोट: आप createBlock (जैसा कि $this->getLayout()->createBlock("Mage_Catalog_Block_Product_List_Toolbar")जब आपके ब्लॉक वर्ग के संदर्भ में होते हैं) को एक पूर्ण वर्ग नाम प्रदान कर सकते हैं । यदि /पैरामीटर में नहीं है तो Magento बस स्ट्रिंग का उपयोग करेगा जैसा कि कक्षा की खोज के लिए है।
मथायस ज़ीस

1
@ एरोन पोलक, आप उसी आधार वर्ग पर दूसरा पुनर्लेखन कर सकते हैं। बस मॉड्यूल नेमस्पेस को Z नाम दें (A के बाद कोई भी अक्षर) और Magento इसे Amasty one के बजाय इसका उपयोग करेगा।
22

5

यदि एक ही वर्ग के उपनाम के लिए कई पुनर्लेखनों का अस्तित्व है, तो अंतिम एक मैग्नेटो लोडर पार्स config.xml "जीत" से आता है। मैं इस समस्या पर हमला करूँगा:

  1. अपना खुद का एक नया एक्सटेंशन बनाएं।
  2. catalog/product_list_toolbarअपने विस्तार में फिर से लिखें
  3. अपने ब्लॉक Mage_Catalog_Block_Product_List_Toolbarको एंबेसी क्लास की बजाय बढ़ाएं।
  4. अपनी कक्षा को उदारतापूर्वक यह समझाते हुए टिप्पणी करें कि यह फिर से संघर्ष जानबूझकर किया गया है। आप एक अन्य डेवलपर नहीं चाहते हैं जो आपके द्वारा अभी बनाए गए पुन: लेखन संघर्ष को आज़माने और चलाने के लिए MageRun चलाता है।
  5. अपने एक्सटेंशन के ऐप / etc / मॉड्यूल / blah.xml फ़ाइल में एक निर्भरता जोड़ें ताकि यह सुनिश्चित हो सके कि आपका एक्सटेंशन एमस्टी वन के बाद लोड किया गया है।

1

फ्रांसेस्को ने ऊपर जो सुझाव दिया था, उसके समान, लेकिन मेरा मानना ​​है कि आप वास्तव में पूरी तरह से नाम पाने के लिए पास कर सकते हैं। इस तरह, आप कुछ हद तक एक ही काम कर रहे हैं, लेकिन इसे करने के लिए मुख्य तरीकों का उपयोग कर रहे हैं। मैं इस पद्धति के पेशेवरों / विपक्षों के बारे में पूरी तरह से निश्चित नहीं हूं, लेकिन मैंने सोचा कि मैं इसे एक विचार के रूप में बाहर फेंक दूंगा।

Mage::getModel('Mage_Catalog_Block_Product_List_Toolbar');

एक साइड नोट पर, मेरा मानना ​​है कि यह Magento2 में कक्षाओं को लोड करने का मानक तरीका होगा।


1

मुझे विस्तार कोड में थोड़ा बदलाव करने की जरूरत है, मुझे डर है। config.xmlअब अपने आप में कक्षा को फिर से न लिखें , बस Amasty_Shopby_Block_Catalog_Product_List_Toolbarअपनी कक्षा का विस्तार करने के लिए बदलें जो बदले में फैली हुई है Mage_Catalog_Block_Product_List_Toolbar


मुझे कोर कोड जैसा एक्सटेंशन कोड दिखाई देता है - किसी और का व्यवसाय (सफाई को उन्नत करने की क्षमता बनाए रखने के लिए)। एक ऐसा तरीका होना चाहिए जो इसे छूने से बचता है। इसके अलावा, समस्या यह है कि एमस्टी क्लास एक अनियंत्रित उत्पाद सूची के संदर्भ में मुख्य कार्यक्षमता को तोड़ता है। मैं अपनी कार्यक्षमता को इंजेक्ट नहीं करता; मुझे कोर कार्यक्षमता को पुनर्जीवित करने की आवश्यकता है। मेरा अपना वर्ग, अगर मैं आपके समाधान का पालन करने वाला हूं, तो खाली हो जाएगा और मेरे द्वारा वहां पर लगाए गए किसी भी प्रयास को उच्चतर पूर्ववर्ती राजवंश वर्ग द्वारा अधिलेखित कर दिया जाएगा।
एरोन पोलक

यह एक बुरी आदत है। बाहरी मॉड्यूल हमेशा अछूते होने चाहिए। यदि आपको अपने मॉड्यूल को अपडेट करने की आवश्यकता है, तो आपको नए संस्करण में अपने सभी परिवर्तनों को फिर से करना होगा। यह स्थिरता के मामले में एक बुरा सपना बन सकता है।
माइकल Türk

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