DEV Community

Lucas Teixeira dos Santos Santana
Lucas Teixeira dos Santos Santana

Posted on

Como criar plugins no Magento 2

Contextualizando

Um plugin, ou interceptor, é uma classe que modifica o comportamento de funções públicas de outras classes, interceptando uma chamada de função. Isso permite estender ou substituir o comportamento de métodos públicos originais para qualquer classe ou interface.

Essa abordagem de interceptação reduz conflitos entre extensões que alteram o comportamento da mesma classe ou método. A implementação da classe do tipo plugin altera o comportamento de uma função da classe especificada no di.xml, mas não altera a classe em si. O Magento chama os interceptors sequencialmente de acordo com a ordem de classificação, então não podem ter conflitos uns com os outros.


Código para criar plugin

di.xml

O primeiro argumento para os métodos before, after e around é o objeto que fornece o acesso a todos os métodos públicos da classe do método observado. Estes tipo de funcionalidade deve ser implementada dentro do arquivo di.xml, seguindo a estruturas de pastas \{Vendor}\{Module}\etc\{area}\di.xml. Já os arquivos com a lógica que serão executados devem seguir a estrutura de pastas \{Vendor}\{Module}\Plugin\{PluginName} e não devem estender nenhuma classe, apenas conter o nome do método que será adicionado a funcionalidade com o sufixo necessário.

Parâmetros obrigatórios para a declaração de um plugin:

  • Type name: uma classe ou interface que o plugin irá observar
  • Plugin name: um nome que identifica o plugin. Também utilizado para mesclar configurações do plugin.
  • Plugin type: nome da classe do plugin ou nome do tipo virtual.

Parâmetros não obrigatórios para a declaração de um plugin:

  • Plugin sort order: plugins que chamam o mesmo método seguem a ordem crescente desse atributo
  • Plugin disabled: para desabilitar um plugin, deve definir esse atributo como true. O valor padrão é false
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <type name="{Vendor}\{Module}\{Directory}\{ClassName}"> <plugin name="{plugin_name}" type="{Vendor}\{Module}\Plugin\{PluginName}" disabled="false" sortOrder="10" /> </type> </config> 
Enter fullscreen mode Exit fullscreen mode

Before

O Magento executa todos os métodos before antes da chamada para o método observado.

É possível utilizar métodos before para alterar argumentos de um método observado, retornando um argumento modificado. Se existirem muitos argumentos, o método deve retornar um array com todos os argumentos. Se o método não alterar o argumento do método observado, ele deverá retornar null.

<?php namespace {Vendor}\{Module}\Plugin; use {Vendor}\{Module}\{Directory}\{ClassName}; class {PluginName} { public function before{MethodName}({ClassName} $subject): void { // Code here } } 
Enter fullscreen mode Exit fullscreen mode

After

O Magento executa todos os métodos after após a conclusão da execução do método observado. Esse tipo de método é obrigatório ter um retorno. É possível utilizar métodos after para alterar o resultado de um método observado. modificando o resultado original e retornando o valor alterado no final do método.

Os métodos after possuem acesso a todos os argumentos do método observado. Quando o método observado termina sua execução, o Magento passa o resultado e os argumentos para o método after seguinte (caso exista mais de um método after para o mesmo método observado). Se o método observado não possui retorno (void), então o método after deverá retornar null.

Os métodos after não precisam declarar todos os argumentos do método observado, exceto o argumento que o método do plugin irá utilizar e todos os seus anteriores (os posteriores não são necessários).

<?php namespace {Vendor}\{Module}\Plugin; use {Vendor}\{Module}\{Directory}\{ClassName}; class {PluginName} { public function after{MethodName}({ClassName} $subject): {type} { // Code here } } 
Enter fullscreen mode Exit fullscreen mode

Around

Evite usar plugins com métodos around quando eles não forem necessários, pois eles aumentam a stack trace e afetam a performance.

Antes da lista de argumentos do método observado, métodos around recebe um callable que permitirá a chamada do próximo método da cadeia. Quando o método executar o callable, o Magento chama o próximo plugin ou a função observada.

Se o método around não chamar o callable, ele prevenirá a execução de todos os seguintes plugins da cadeia e o método observado.

Quando o método around envolve um método observado que possui argumentos, o método around deve aceitar esses argumentos e encaminhá-los ao invocar a chamada do proceed. Deve-se ter cuidado ao combinar os parâmetros padrões e seus type hints da assinatura do método observado.

Caso o método observado possua argumentos com valores padrões, devem ser inseridos os mesmos valores padrões dos argumentos no método around.

<?php namespace {Vendor}\{Module}\Plugin; use {Vendor}\{Module}\{Directory}\{ClassName}; class {PluginName} { public function around{MethodName}( {ClassName} $subject, callable $proceed ): {type} { // Code before here $proceed(); // Code after here } } 
Enter fullscreen mode Exit fullscreen mode

Finalizando

Valores entre chaves ({test}) devem ser alterados na implementação do código.

Habilitando as alterações

Apague os arquivos que são gerados na compilação do Magento e execute o comando PHP para gerar a configuração das injeções de dependência e todas as classes ausentes que precisam ser geradas (proxys, interceptors, etc) e para limpar todos os caches de armazenamento em cache do processos.

rm -rf var/generation/ rm -rf generated/ php bin/magento setup:di:compile php bin/magento cache:clean php bin/magento flush 
Enter fullscreen mode Exit fullscreen mode

Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

- app/ - code/ - {Vendor}/ - {Module}/ - etc/ - di.xml - module.xml - Plugin/ - {PluginName}.php - registration.php - composer.json 
Enter fullscreen mode Exit fullscreen mode

Top comments (0)