Desenvolvimento

Desativar o plugin de um módulo de terceiro no Magento 2

O módulo que você comprou tem um plugin que atrapalha uma coisa só. Editar o vendor você não pode, e desligar o módulo inteiro derruba o que funciona. Existe o meio-termo.

Por Roger Takemiya · Publicado em · 5 min de leitura

Situação de quinta-feira à noite: o módulo de frete que a loja comprou tem um plugin no processador de layout do checkout, e esse plugin some com um campo que você precisa. O resto do módulo funciona. Você não vai editar vendor/, porque o próximo composer update apaga. E module:disable derruba o frete inteiro.

O Magento tem uma saída para exatamente isso, e ela cabe num atributo. A documentação da Adobe diz em uma linha: para desativar um plugin, coloque disabled como true na declaração dele. O padrão é false.

Ache o nome exato do plugin

O name do plugin é uma string que o fornecedor inventou. Ela é a chave de merge do di.xml, então você precisa dela igualzinha. Comece grepando o módulo do fornecedor:

grep -rn "<plugin " vendor/fornecedor/*/etc/ --include="di.xml"

Ou pergunte ao próprio Magento quem está pendurado na classe:

php bin/magento dev:di:info 'Magento\Checkout\Block\Checkout\LayoutProcessor' frontend

O segundo argumento é a área, e ele é posicional: frontend, adminhtml, webapi_rest, crontab. Sem passar nada, o comando olha só o escopo global, e plugin de checkout simplesmente não aparece na lista.

Anote três coisas antes de escrever qualquer arquivo: o valor de <type name="...">, o name do plugin e em qual arquivo ele mora — etc/di.xml ou etc/frontend/di.xml. A área importa mais do que parece, e volto nisso no fim.

O módulo de três arquivos

Não precisa de classe PHP nenhuma. Só isso:

app/code/Loja/DesligaPlugin/registration.php
app/code/Loja/DesligaPlugin/etc/module.xml
app/code/Loja/DesligaPlugin/etc/frontend/di.xml

No etc/module.xml, declare o módulo do fornecedor dentro de <sequence>. Segundo a Adobe, o sequence é o que garante que os arquivos de configuração daquele componente já estejam carregados quando o seu entrar:

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Loja_DesligaPlugin">
        <sequence>
            <module name="Fornecedor_Modulo"/>
        </sequence>
    </module>
</config>

E o etc/frontend/di.xml, que é a parte que faz o trabalho. Repare que não tem type do plugin: você só cita o nome e desliga.

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Block\Checkout\LayoutProcessor">
        <plugin name="ProcessPaymentConfiguration" disabled="true"/>
    </type>
</config>

Esse exemplo não é inventado: é o que o Magento_Vault faz com o plugin ProcessPaymentConfiguration, que o Magento_Payment declara no etc/frontend/di.xml dele. E sim, o Vault tem o Magento_Payment no sequence. Copiar o core costuma ser um bom plano.

Para valer:

php bin/magento module:enable Loja_DesligaPlugin
php bin/magento setup:upgrade
php bin/magento setup:di:compile
php bin/magento cache:flush

Em modo developer o setup:di:compile não é obrigatório, mas apague o generated/ antes de testar. Interceptor velho em cache já me fez perder uma tarde jurando que o disabled não funcionava.

Os quatro tropeços

1. Nome errado é silêncio. Se você digitar ProcessPaymentConfig em vez de ProcessPaymentConfiguration, o Magento cria um nó novo, desligado, que não corresponde a plugin nenhum. Ninguém reclama e o plugin original continua rodando. Copie e cole do arquivo do fornecedor.

2. Área errada. Plugin declarado em etc/frontend/di.xml se desliga em etc/frontend/di.xml. Se ele está no etc/di.xml global, o seu também vai no global. Espelhe o caminho do arquivo do fornecedor e você não erra.

3. O nome da classe no type. A própria documentação da Adobe avisa: a classe pode ser escrita com barra inicial ou sem, e você precisa usar o mesmo formato que foi usado na declaração. Copie a linha inteira.

4. Desligar plugin não é desligar módulo. module:disable tira rotas, tabelas e configuração do ar; o disabled="true" só cala aquele interceptor. Se o que te incomoda é a ordem em que dois plugins rodam, não desligue nada — mexa no sortOrder, que existe para isso.

Um aviso que eu dou para todo cliente: plugin de módulo pago quase sempre está fazendo alguma coisa que o resto do módulo espera. Desligar um after que grava dado no quote pode quebrar o pedido lá na frente, e o suporte do fornecedor vai olhar o seu app/code e encerrar o chamado. Teste em homologação com pedido de ponta a ponta antes de subir. Se você ainda está montando o esqueleto do módulo, o guia de desenvolvimento de módulos tem o registration.php e o module.xml prontos.

Perguntas rápidas

Preciso repetir o type do plugin para desligar?

Não. Basta o nome e o atributo disabled. O tipo já veio na declaração original e o merge do di.xml junta os dois nós pelo nome.

Isso sobrevive ao composer update do módulo do fornecedor?

Sim, porque o seu código está em app/code e não em vendor. O único risco é o fornecedor renomear o plugin numa versão nova. Aí o seu disabled deixa de casar e volta a rodar, em silêncio.

Dá para desligar um plugin do próprio core do Magento?

Dá, é o mesmo procedimento. Só tenha em mente que muita coisa do core depende desses interceptors, então a chance de quebrar outra funcionalidade é bem maior do que com módulo de terceiro.

Pra conferir na fonte

  1. Plugins (interceptors) — Adobe Developer
  2. Component load order — Adobe Developer
  3. Magento_Vault etc/frontend/di.xml — GitHub
  4. Magento_Payment etc/frontend/di.xml — GitHub

plugin di.xml modulo

Precisa de um orçamento? Ficarei feliz em ajudar. Clique Aqui