मैजेंटो 2: इंटरेक्शन से पहले / आसपास / उसके बाद प्लग इन करें


32

Magento 2 में, जब आप "चारों ओर" प्लगइन बनाते हैं

public function aroundRenderResult(
    \Magento\Framework\Controller\ResultInterface $subject,
    \Closure $proceed,
    ResponseHttp $response
) {
    //...
    $proceed($response);
    //...      
}    

आप पास के आस-पास अगले प्लगइन के लिए आगे बढ़ सकते हैं , कॉल कर सकते हैं, वास्तविक मूल विधि को कॉल कर सकते हैं , कॉल कर सकते हैं / पारित $proceedविधि को लागू कर सकते हैं । यह एक सामान्य डिजाइन पैटर्न है, जिसे अक्सर PHP फ्रेमवर्क मिडलवेयर कार्यान्वयन में देखा जाता है।

हालाँकि - यह कार्यान्वयन विवरणों के लिए कुछ भ्रम w / r / t प्रस्तुत करता है। विशेष रूप से

यदि, aroundPluginकिसी ऑब्जेक्ट के अलावा , किसी ऑब्जेक्ट / क्लास में एक beforeया afterप्लगइन परिभाषित है, तो वे चारों ओर प्लग की श्रृंखला के संबंध में कब आग लगाते हैं?

अर्थात सभी तरीकों से पहले आग लग जाएगी किसी भी चारों ओर प्लगइन तरीकों से आग? या प्लग इन से पहले इच्छा ही अंतिम, वास्तविक से पहले आग वास्तविक विधि आग?

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

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

क्या किसी को पता है, प्रत्यक्ष अवलोकन से, या सांस्कृतिक ज्ञान से, यह प्राथमिकता कैसे काम करने वाली है?


एलन, क्या आपके पास एक प्लग में \closure $proceedबनाम का उपयोग करने के लिए अंगूठे का एक नियम है \callable $proceed? आधिकारिक दस्तावेज़ केवल उल्लेख है \callableऔर पर कभी नहीं छू लेती है \closure
2

जवाबों:


38

प्लगइन्स को पहले क्रम से क्रमबद्ध किया जाता है, और फिर विधि उपसर्ग द्वारा।

उदाहरण: विधि के लिए 3 प्लगइन्स (PluginA, PluginB, PluginC) निम्न विधियों और सॉर्टऑर्डर के साथ:

  • प्लगइन (सॉर्टऑर्डर = 10)
    • beforeDispatch ()
    • afterDispatch ()
  • PluginB (सॉर्टऑर्डर = 20)
    • beforeDispatch ()
    • aroundDispatch ()
    • afterDispatch ()
  • PluginC (सॉर्टऑर्डर = 30):
    • beforeDispatch ()
    • aroundDispatch ()
    • afterDispatch ()

निष्पादन प्रवाह निम्न होना चाहिए:

  • PluginA :: beforeDispatch ()
  • PluginB :: beforeDispatch ()
  • PluginB :: aroundDispatch ()
    • PluginC :: beforeDispatch ()
    • PluginC :: aroundDispatch ()
      • कार्रवाई :: प्रेषण ()
    • PluginC :: afterDispatch ()
  • PluginB :: afterDispatch ()
  • PluginA :: afterDispatch ()

16

Magento 2 रसोई की किताब से:

यदि कई प्लगइन्स हैं जो समान मूल फ़ंक्शन का विस्तार करते हैं, तो उन्हें निम्नलिखित अनुक्रम में निष्पादित किया जाता है:

  • सबसे कम के साथ पहले प्लगइन sortOrder
  • सबसे कम के साथ चारों ओर प्लगइन sortOrder
  • अन्य प्लगइन्स से पहले (सबसे कम से उच्चतम sortOrder)
  • अन्य प्लगइन्स के आसपास (सबसे कम से उच्चतम तक sortOrder)
  • उच्चतम के साथ प्लगइन के बाद sortOrder
  • अन्य प्लगइन्स के बाद (उच्चतम से निम्नतम तक sortOrder)

1

मेरे लिए यह काम करना चाहिए:

  • यदि क्रम क्रम शून्य के समतुल्य परिभाषित नहीं किया गया है (और इसका मतलब यह है कि वास्तविक आदेश अपरिभाषित है)
  • प्लगइन्स क्रम से क्रमबद्ध होना चाहिए

यदि आप कोड की समीक्षा करते हैं, तो आप \Magento\Framework\Interception\Interceptor::___callPlugins()उस प्लग इन को $pluginInfoचर में संग्रहीत के क्रम में देख सकते हैं । इस जानकारी ने इंटरसेप्टर्स में ऑटो उत्पन्न विधि का निर्माण किया

public function {method}()
{
    $pluginInfo = $this->pluginList->getNext($this->subjectType, '{method}');
    if (!$pluginInfo) {
        return parent::{method}();
    } else {
        return $this->___callPlugins('{method}', func_get_args(), $pluginInfo);
    }
}

जैसा कि आप \Magento\Framework\Interception\PluginListInterfaceइंटरफ़ेस और \Magento\Framework\Interception\PluginList\PluginListडिफ़ॉल्ट कार्यान्वयन प्लगइन छँटाई के लिए जिम्मेदार देखते हैं । _InheritPlugins देखें : 152 विधि

/**
 * Sort items
 *
 * @param array $itemA
 * @param array $itemB
 * @return int
 */
protected function _sort($itemA, $itemB)
{
    if (isset($itemA['sortOrder'])) {
        if (isset($itemB['sortOrder'])) {
            return $itemA['sortOrder'] - $itemB['sortOrder'];
        }
        return $itemA['sortOrder'];
    } elseif (isset($itemB['sortOrder'])) {
        return $itemB['sortOrder'];
    } else {
        return 1;
    }
} 

मेरे लिए इस फ़ंक्शन में दो तार्किक त्रुटियाँ हैं:

  • return $itemB['sortOrder'];होना चाहिए return - $itemB['sortOrder'];
  • return 1; होना चाहिए return 0;

आशा है इससे आपकी मदद होगी।


लेकिन $ pluginInfo पूरी तरह से प्लगइन्स के साथ भरी हुई है? या वहाँ कुछ आलसी लोड हो रहा है कि व्यवहार को प्रभावित कर सकता है? कई प्लगइन्स के लिए सॉर्ट ऑर्डर का क्या मतलब है? यानी यह "प्लगइन 1 से पहले, प्लगइन 1 के आसपास, प्लगइन 1 के बाद, प्लगइन 2 से पहले, प्लगइन 2 के आसपास, प्लगइन 2 के बाद" या प्लगइन 1 से पहले ", प्लगइन 2 से पहले, प्लगइन 1 के आसपास, प्लगइन 2 के आसपास", आदि। " कोड बाद में जैसा दिखता है, लेकिन (शायद?) आलसी लोडिंग तरीके से "getNext" पॉपुलेटिंग प्लगइन जानकारी, और कैसे Magento के साथ पुनरावृत्ति से बचने के लिए यह सब स्पष्ट नहीं है, और यह मुश्किल है कि क्या एक बग, क्या एक सुविधा है।
एलन स्टॉर्म

Magento तरह प्लगइन वर्ग प्लगइन विधि नहीं।
कांडी

और प्लगइन्स की सूची को बदला जा सकता है, उदाहरण के लिए, यदि नया आरिया हमें लोड किया गया है।
कांड

वहाँ कुछ अंतर्निहित ज्ञान है जो आपके पास स्पष्ट नहीं है, क्योंकि "प्लगइन वर्ग को सॉर्ट करें और प्लगइन विधि नहीं" यह स्पष्ट नहीं करता है कि प्लगइन इंटरैक्शन के नियम क्या हैं या होने चाहिए।
एलन स्टॉर्म

शायद यह कड़ी उपयोगी होगी magehero.com/posts/472/magento-2-interception
KAndy
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.