Continuando com os estudos de Plugin, neste artigo nós falaremos sobre a ordem de execução de plugins no Magento 2 Plugin Sort Order.
Magento 2 Plugin Sort Order
Voltamos ao nosso módulo e adicionamos o seguinte ao nosso di.xml
<type name="ForMage\Learning\Controller\Page\Index"> <plugin name="plugin-controller-one" type="ForMage\Learning\Plugin\PluginOne" sortOrder="10"></plugin> </type>
Note o atributo sortOrder
em <plugin>. Através desse atributo, nós podemos controlar a ordem de execução de nossos plugins.
A documentação do Magento diz o seguinte sobre isso:
Magento executa plug-ins usando essas regras durante a execução de cada plug-in em dois fluxos principais:
- Antes da execução do método observado, começando do mais baixo para o mais alto
sortOrder
.- Magento executa o
before
método do plugin atual . - Em seguida, o
around
método do plugin atual é chamado.- A primeira parte do
around
método do plugin é executada. - O
around
método executa ocallable
.- Se houver outro plug-in na cadeia, todos os plug-ins subsequentes são agrupados em um loop de sequência independente e a execução inicia outro fluxo.
- Se o plugin atual for o último da cadeia, o método observado é executado.
- A segunda parte do
around
método é executada.
- A primeira parte do
- Magento segue para o próximo plugin.
- Magento executa o
- Seguindo o fluxo de execução, começando do menor para o maior
sortOrder
no loop de plug-ins da sequência atual.- O
after
método do plugin atual é executado. - Magento segue para o próximo plugin.
- O
A documentação nos informa que ordem de execução de plugins é do menor para o maior sortOrder
Em nossa classe PluginOne fizemos a seguinte modificação:
<?php namespace ForMage\Learning\Plugin; class PluginOne { // public function beforeSetName(\Magento\Catalog\Model\Product $subject, $name) // { // return "Plugin Before | ".$name; // } // // public function afterGetName(\Magento\Catalog\Model\Product $subject, $result) // { // return $result. " | Plugin After"; // } // // public function aroundGetName(\Magento\Catalog\Model\Product $subject, callable $proceed) // { // echo " --- Before Proceed"."<br/>"; // $name = $proceed(); // echo $name."<br/>"; // echo " --- After Proceed"."<br/>"; // return $name; // } public function beforeExecute(\ForMage\Learning\Controller\Page\Index $subject) { echo "BEFORE SORT ORDER 10"."<br/>"; } public function afterExecute(\ForMage\Learning\Controller\Page\Index $result) { echo "AFTER SORT ORDER 10"."<br/>"; } }
E em nosso Controller
<?php namespace ForMage\Learning\Controller\Page; use Magento\Framework\App\Action\Context; use Magento\Framework\App\ResponseInterface; use ForMage\Learning\Api\SizeInterface; use ForMage\Learning\Api\ColorInterface; use ForMage\Learning\Model\Product\Shoe; use ForMage\Learning\Model\Product\Shirt; class Index extends \Magento\Framework\App\Action\Action { protected $size; protected $color; protected $product; protected $shirt; public function __construct( Context $context, SizeInterface $size, ColorInterface $color, Shoe $product, Shirt $shirt ) { parent::__construct($context); $this->size = $size; $this->color = $color; $this->product = $product; $this->shirt = $shirt; } public function execute() { echo "MAIN CONTENT"."<br/>"; // $objecManager = \Magento\Framework\App\ObjectManager::getInstance(); // $product = $objecManager->create('Magento\Catalog\Model\Product')->load(164); // $product->setName('Samsung Galaxy'); // $product->getName(); } }
Importante: por enquanto, abordaremos somente a ordem de execução do Plugin Before e After.
Ao executar a nossa rota, temos o seguinte resultado:
-
- Primeiro, executa o conteúdo do método
beforeExecute()
- Depois, executa o conteúdo do próprio método interceptado
execute()
- Então, executa o conteúdo do método
afterExecute()
- Primeiro, executa o conteúdo do método
Agora, vamos criar mais dois plugins: PluginTwo e PluginThree com o seguinte conteúdo:
<?php namespace ForMage\Learning\Plugin; class PluginTwo { public function beforeExecute(\ForMage\Learning\Controller\Page\Index $subject) { echo "BEFORE SORT ORDER 20"."<br/>"; } public function afterExecute(\ForMage\Learning\Controller\Page\Index $result) { echo "AFTER SORT ORDER 20"."<br/>"; } }
<?php namespace ForMage\Learning\Plugin; class PluginThree { public function beforeExecute(\ForMage\Learning\Controller\Page\Index $subject) { echo "BEFORE SORT ORDER 30"."<br/>"; } public function afterExecute(\ForMage\Learning\Controller\Page\Index $result) { echo "AFTER SORT ORDER 30"."<br/>"; } }
Voltando ao nosso di.xml, temos a seguinte alteração:
<type name="ForMage\Learning\Controller\Page\Index"> <plugin name="plugin-controller-one" type="ForMage\Learning\Plugin\PluginOne" sortOrder="10"></plugin> <plugin name="plugin-controller-two" type="ForMage\Learning\Plugin\PluginTwo" sortOrder="20"></plugin> <plugin name="plugin-controller-three" type="ForMage\Learning\Plugin\PluginThree" sortOrder="30"></plugin> </type>
Agora, nós temos três classes de Plugin interceptando o mesmo método. Ao acessar a nossa rota:
Assim, vimos como o Magento prioriza a ordem de execução dos Plugins Before e After e como utilizá-lo em nosso dia-a-dia como desenvolvedores Magento 2.
Para mais informações sobre Plugins
Dúvidas? Posta aí!
Um abraço.