Plugins para getters / setters mágicos

9

Estou tentando tornar o status de uma revisão em approvedvez de pendingquando o usuário a publica no front-end no Magento 2.
E eu adotei essa abordagem. Criar um plugin antes, disponível apenas na área de frontend, para o método setStatusIdpara os Magento\Review\Model\Reviewque se parece com isso

public function beforeSetStatusId(\Magento\Review\Model\Review $review, $status)
{
    return [\Magento\Review\Model\Review::STATUS_APPROVED];
}

Pareceu-me uma boa ideia. E deve funcionar, pois estou retornando o status aprovado. O método real deve então pegar isso como um parâmetro.
mas, para minha surpresa, não funcionou.
Então eu descobri e descobri que o método setStatusIdnão existe no modelo de revisão. É chamado magicamente e realmente é executado setData('status_id', $status).
Dei uma olhada no interceptador gerado e, de fato, não há setStatusIdmétodo.

Como posso pluginizar os getters / setters mágicos no magento 2? É mesmo possível?

Nota: não preciso de uma solução para tornar as revisões aprovadas automaticamente. Eu sei que posso adotar outras abordagens, como os save_beforeeventos. Isso não é importante por enquanto.

Marius
fonte

Respostas:

14

É mesmo possível?

Sim.

Como posso pluginizar os getters / setters mágicos no magento 2?

Da mesma maneira que outro método público. Você precisa declarar o plugin na di.xmlconfiguração e adicionar seu código personalizado ao plugin.

public function before__call(\Magento\Review\Model\Review $review, $method, $args)
{
    if ($method == 'setStatusId') {
        if (isset($args[0])) {
            $args[0] = \Magento\Review\Model\Review::STATUS_APPROVED;
            return [$method, $args];
        }
    }
    //leave everything unchanged
    return null;
}

Mas a plug-in de classes DTO não é uma boa ideia. Tente personalizar os controladores / serviços apropriados para modificar o comportamento do aplicativo e não adicione plugins no objeto DTO. Essa personalização destruirá as camadas do aplicativo . Eu entendo que você usa a maneira mais rápida e fácil, mas em alguns casos é uma estratégia errada.

Máx.
fonte
Eu concordo com você na personalização. Esta foi apenas uma prova de conceito.
Marius
@Marius sim, arrefecer
Max
Adotei essa abordagem, mas isso falhará quando / se o módulo de revisão for refatorado para usar contratos de serviço. Está tudo bem por enquanto. Obrigado.
Marius
sim, com certeza, mas sua pergunta foi "Como posso pluginizar os getters / setters mágicos no magento 2? Isso é possível?". A melhor opção seria usar plugins apenas para métodos e serviços de API pública, mas em alguns módulos magento não há APIs ou é ruim.
Max
4

Uma vez tive um problema semelhante. Eu acabei com o pluginize setData()-method, embora na minha opinião isso gere um tremendo desperdício de recursos ... :-(

Giel Berkers
fonte
Está bem. essa é uma abordagem de trabalho. +1. Mas estou esperando por uma opção mais limpa (desde que exista).
Marius
Eu espero o mesmo. Eu ainda choro até dormir todas as noites porque essa correção parece tão suja. Eu acho que toda a razão pela qual ainda existem métodos mágicos é por causa do código legado do Magento 1. Acho que, desde que o modelo de revisão ainda não seja refatorado para um modelo de dados, você não terá sorte com este.
Giel Berkers
Percebi que isso é por causa do código legado. E eu aprendi uma boa lição disso. Não confie na mágica para módulos CRUD personalizados.
Marius
Adotei a abordagem explicada por Max aqui principalmente porque meu plug-in será chamado apenas quando um setter mágico for chamado e não para todas as setDatachamadas. Não é perfeito, mas é um pouco melhor do que usar setData. Talvez você possa mudar sua abordagem também e dormir um pouco melhor à noite. :)
Marius