Magento 2: ปลั๊กอินก่อน / หลัง / หลังการโต้ตอบ


32

ใน Magento 2 เมื่อคุณสร้างปลั๊กอิน "รอบ"

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

คุณสามารถดำเนินการต่อไปปลั๊กอินรอบต่อไปปิดท้ายด้วยการเรียกวิธีการเดิมที่เกิดขึ้นจริงโดยการเรียก / อัญเชิญผ่านใน$proceedวิธีการ นี่เป็นรูปแบบการออกแบบทั่วไปที่มักพบในการใช้มิดเดิลแวร์ PHP Frameworks

อย่างไรก็ตาม - มันนำเสนอความสับสนโดยไม่มีข้อมูลการใช้งาน เฉพาะ

หากนอกเหนือไปจากaroundPluginวัตถุ / คลาสยังมีการกำหนดbeforeหรือafterปลั๊กอินเมื่อใดพวกมันจะเริ่มสัมพันธ์กับสายโซ่ของปลั๊กอิน

คือวิธีทั้งหมดก่อนที่จะยิงก่อนที่จะมีวิธีการใด ๆ ไฟปลั๊กอิน? หรือก่อนที่ปลั๊กอินจะยิงก่อนที่ไฟสุดท้ายจะเกิดขึ้นจริงหรือไม่

ปัญหาเฉพาะฉันพยายามที่จะติดตามลงคือผมไม่สามารถดูเหมือนจะได้รับปลั๊กอินที่ติดอยู่กับวิธีการจัดส่งที่ควบคุมวีโอไอพี 2 หน้าเมื่อวีโอไอพีในโหมดแคชเต็มหน้า แคชเต็มหน้าดำเนินการโดยปลั๊กอินรอบ ๆ ที่ไม่ได้$proceed($response)โทร ฉันได้ลองขุดลงในโค้ดบางส่วนรอบ ๆ ปลั๊กอินเหล่านี้และพบว่าระบบนั้นยากที่จะให้เหตุผลโดยไม่ทราบว่าปลั๊กอินนั้นทำงานอย่างไร

ie - คำอธิบายในหน้าเอกสาร devจะปรากฏขึ้นในอินสแตนซ์ที่เฉพาะเจาะจงนี้อันใดอันหนึ่งที่ไม่ถูกต้อง มันไม่ชัดเจนหากเอกสารผิดหรือเป็นข้อผิดพลาดที่เพิ่งเปิดตัวหากเป็นกรณีขอบหรือหากการกำหนดค่าปลั๊กอินของฉันไม่ถูกต้อง

ไม่มีใครรู้โดยการสังเกตโดยตรงหรือโดยความรู้ทางวัฒนธรรมการจัดลำดับความสำคัญนี้ควรจะทำงานอย่างไร


อลันคุณมีกฎง่ายๆเมื่อใช้\closure $proceedกับ\callable $proceedในปลั๊กอินหรือไม่? เอกสารอย่างเป็นทางการเพียงกล่าวและไม่เคยสัมผัสกับ\callable \closure
thdoan

คำตอบ:


38

ปลั๊กอินจะเรียงลำดับตามการจัดเรียงก่อนจากนั้นตามด้วยคำนำหน้าวิธีการ

ตัวอย่าง: สำหรับเมธอดที่มี 3 ปลั๊กอิน (PluginA, PluginB, PluginC) ด้วยเมธอดและ sortOrder ต่อไปนี้:

  • PluginA (sortOrder = 10)
    • beforeDispatch ()
    • afterDispatch ()
  • PluginB (sortOrder = 20)
    • beforeDispatch ()
    • aroundDispatch ()
    • afterDispatch ()
  • PluginC (sortOrder = 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", "ก่อนปลั๊กอิน 1", ก่อนปลั๊กอิน 2, รอบปลั๊กอิน 1, รอบปลั๊กอิน 2 "ฯลฯ โค้ดดูเหมือนในภายหลัง แต่ "getNext" เติมข้อมูลปลั๊กอินในวิธีการโหลดแบบขี้เกียจ (หรืออาจ?) และวิธีที่วีโอไอพีหลีกเลี่ยงการเรียกซ้ำโดยรอบทำให้สิ่งนี้ไม่ชัดเจนและยากที่จะระบุว่ามีข้อบกพร่องอะไร
Alan Storm

Magento การจัดเรียงปลั๊กอินคลาสไม่ใช่วิธีการปลั๊กอิน
KAndy

และรายชื่อปลั๊กอินสามารถเปลี่ยนแปลงได้ตัวอย่างเช่นถ้าเราโหลดเพลงใหม่
KAndy

มีความรู้โดยนัยบางอย่างที่คุณไม่ชัดเจนเนื่องจาก "เรียงลำดับคลาสปลั๊กอินและไม่ใช่วิธีปลั๊กอิน" ไม่ทำให้ชัดเจนว่ากฎสำหรับการโต้ตอบกับปลั๊กอินคืออะไรหรือควรเป็นอย่างไร
Alan Storm

บางทีลิงค์นี้จะเป็นประโยชน์magehero.com/posts/472/magento-2-interception
KAndy
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.