Magento2 開發 – 使用 Plugin 改變原生行為(二)
上回帶大家實作before的Plugin,用來改寫傳入的參數值。今天要探究的是最常被使用到的around Plugin,因為它可以直接覆蓋掉目標方法裡的邏輯行為,是普遍的客製需求所在,所以實做變化較多,話不多說,直接進入主題!
沿用上回範例,我們以虛構類別Magento\Example\Model\SummaryAmount.php來覆寫,不過這回稍微為目標方法增加了額外行為:
未改寫前執行如下測試
$summaryAmount = \Magento\Framework\App\ObjectManager::getInstance()->get(‘Magento\Example\Model\SummaryAmount’);
echo ‘</br>[’ . $summaryAmount->calculate(2, 20, 1) . ‘]’;
會得到結果 2 * 20 * 1 * 1.5 = 60
[60]
本範例的第一個需求是,套件ExampleC,要在每次計算被呼叫時,印出輸入的參數。
跟before一樣,要先定義覆寫主客體
Custom/ExampleC/etc/di.xml
實作覆寫行為,仿照上回邏輯,在方法前加上around前綴,第一個參數一樣是被覆寫的物件,第二個參數是可被呼叫往下執行的Closure,從第三個參數開始,依序為輸入的參數值。
再次測試,就得到預期的畫面囉!
Qty – 2
Price – 20
Rate – 1
[60]
接著第二個需求, ExampleD負責移除calculate裡adjustRate的行為。這會需要改寫原始方法裡的邏輯,雖然改寫adjustRate,將其直接回傳$rate也可達到一樣效果,但考量其他地方可能直接呼叫adjustRate而受到非預期影響,選擇複寫calculate是較為合適的。
在定義Custom/ExampleD/etc/di.xml時, 將順序放在ExampleC之後。
實作覆寫內容
這次測試,會少掉rate加乘,得到結果如下
Qty – 2
Price – 20
Rate – 1
[40]
最後一項客製,ExampleE會在數量等於零時,不印出參數,而提示Error訊息。由於印出參數是ExampleC的客製行為,因此這個條件控制必須在ExampleC之前
Custom/ExampleE/etc/di.xml
覆寫內容
執行原本的 echo ‘</br>[’ . $summaryAmount->calculate(2, 20, 1) . ‘]’; 會維持一樣結果
Qty – 2
Price – 20
Rate – 1
[40]
當改執行 echo ‘</br>[’ . $summaryAmount->calculate(0, 20, 1) . ‘]’; 結果如下
ERROR
[0]
以上三個簡易例子,如果各位都能理解其覆寫排序與內容邏輯,基本上就能掌握around plugin的運用方式。不過在實務上,多少還是會遇到一些難題。例如,要調整覆寫內容時,遇上原內容使用了自身protected或private的方法,因此無法直接利用參數$subject來呼叫,這時就會需要將那些被保護的方法內容複製到plugin裡來使用。只是每個被複製的方法裡,可能又呼叫了其他的非公開方法,這樣一環扣一環,最終做工也不算少。Plugin畢竟只是覆寫的一種方式,遇到這種情形時,也可以考慮其他的覆寫方式是否可以達到一樣的目的。
最後提醒大家,還有一項after plugin,我們下回見唷!
如果您有更多疑問可以詢問我們,未來會撰寫更多電商網站相關文章,您想知道什麼嗎?歡迎在下方留言給我們。或追蹤我們的粉絲專頁及IG,也別忘了訂閱電子報,就不錯過最新文章喔!
想學習更多Magento設定嗎?請見:Magento教學導覽
我要留言