Cursos Magento

Criando um Evento no Magento 2

,

Publicado em 07 de novembro de 2019

Aqui no Magenteiro nós já vimos como usar eventos e observers no Magento 1, e como criar Observers para eventos existentes no Magento 2 (e no M1 também). Hoje veremos como criar um evento personalizado no Magento 2 para que outros módulos (ou o nosso próprio módulo) faça uso dele.

O que são Events e Observers?

Já falamos sobre isso no outro artigo sobre Observers no Magento 2, e tomo a liberdade de me repetir:

Eventos são pontos de interrupção inseridos em classes PHP que buscam por outras classes que estejam “escutando” aquela interrupção.

Os eventos existem em lugares estratégicos, como por exemplo, na finalização de um pedido, ou no registro de um novo cliente.

Já os Observers, são classes que observam estes eventos e recebem parâmetros passados pelos eventos.

Porque criar um Evento? O Magento já tem muitos.

No Magento 1, era uma boa prática criarmos Eventos personalizados dentro dos nossos módulos. Isso facilitaria a vida de quem fosse realizar alguma customização em um lugar específico sem ter que sobrescrever uma classe inteira para alterar um único método. Veja um exemplo de uso de Eventos personalizados no Magento 1 no meu módulo PagSeguro.

No Magento 2 no entanto, temos os Plugins* para nos ajudar.

Mesmo assim, acredito que os Eventos podem ser úteis nos casos de integrações e logs. Ou seja, caso queiramos possibilitar outros módulos “observarem” o que está acontecendo em determinado momento para fins de logs ou integrações.

* Assunto amplamente abordado no curso de Magento 2. Você pode assistir a aula inteira sobre o assunto clicando no link de preview gratuito na página do curso.

Como criar um Evento personalizado no Magento 2

Sem mais delongas, a criação de um evento personalizado no Magento 2 é bem simples.

Tudo que você precisará fazer é injetar ou iniciar a classe \Magento\Framework\Event\ManagerInterface e invocar o método dispatch().

Veja alguns exemplos.

Usando o ObjectManager (não recomendável):

O exemplo acima pode ser visto em \Magento\Framework\App\Cron::launch e dispara o evento default.

Usar o ObjectManager não é uma boa prática. Ao invés disso, devemos injetar a classe no construtor, como no exemplo abaixo.

Usando Injeção de Dependência (Recomendável)

Na classe \Magento\Sales\Model\Order\Email\Sender\OrderCommentSender podemos ver o evento email_order_comment_set_template_vars_before sendo disparado com alguns parâmetros.

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\Sales\Model\Order\Email\Sender;

use Magento\Sales\Model\Order;
use Magento\Sales\Model\Order\Email\Container\OrderCommentIdentity;
use Magento\Sales\Model\Order\Email\Container\Template;
use Magento\Sales\Model\Order\Email\NotifySender;
use Magento\Sales\Model\Order\Address\Renderer;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\DataObject;

/**
 * Class OrderCommentSender
 */
class OrderCommentSender extends NotifySender
{
    /**
     * @var Renderer
     */
    protected $addressRenderer;

    /**
     * Application Event Dispatcher
     *
     * @var ManagerInterface
     */
    protected $eventManager;

    /**
     * @param Template $templateContainer
     * @param OrderCommentIdentity $identityContainer
     * @param Order\Email\SenderBuilderFactory $senderBuilderFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param Renderer $addressRenderer
     * @param ManagerInterface $eventManager
     */
    public function __construct(
        Template $templateContainer,
        OrderCommentIdentity $identityContainer,
        \Magento\Sales\Model\Order\Email\SenderBuilderFactory $senderBuilderFactory,
        \Psr\Log\LoggerInterface $logger,
        Renderer $addressRenderer,
        ManagerInterface $eventManager
    ) {
        parent::__construct($templateContainer, $identityContainer, $senderBuilderFactory, $logger, $addressRenderer);
        $this->addressRenderer = $addressRenderer;
        $this->eventManager = $eventManager;
    }

    /**
     * Send email to customer
     *
     * @param Order $order
     * @param bool $notify
     * @param string $comment
     * @return bool
     */
    public function send(Order $order, $notify = true, $comment = '')
    {
        $this->identityContainer->setStore($order->getStore());

        $transport = [
            'order' => $order,
            'comment' => $comment,
            'billing' => $order->getBillingAddress(),
            'store' => $order->getStore(),
            'formattedShippingAddress' => $this->getFormattedShippingAddress($order),
            'formattedBillingAddress' => $this->getFormattedBillingAddress($order),
        ];
        $transportObject = new DataObject($transport);

        /**
         * Event argument `transport` is @deprecated. Use `transportObject` instead.
         */
        $this->eventManager->dispatch(
            'email_order_comment_set_template_vars_before',
            ['sender' => $this, 'transport' => $transportObject->getData(), 'transportObject' => $transportObject]
        );

        $this->templateContainer->setTemplateVars($transportObject->getData());

        return $this->checkAndSend($order, $notify);
    }
}

Simples, né?

Últimos posts por Ricardo Martins (exibir todos)
Comentários

Deixe seu comentário

[fbcomments url="https://www.magenteiro.com/blog/magento-2/criando-um-evento-no-magento-2/"]