Como criar eventos e Observers personalizados no Magento 2
Tags: php, magento2, braziliandevs, tutorial
Published: 2021-11-08 12:18:41

## Contextualizando

### O que é o padrão pub-sub?

É um padrão de mensagens onde os publicadores das mensagens (*Publishers*) categorizam as mensagens publicadas em classes sem conhecimentos dos inscritos (*Subscribers*). Os publicadores não programam as mensagens para serem enviadas diretamente para os inscritos e os inscritos não manifestam interesses em uma ou mais classes e só recebem as mensagens que possuem interesse, sem saber quais publicadores existem.

### Eventos e Observadores no Magento

Os eventos e observadores são baseados no padrão pub-sub, onde eventos são disparados quando certas ações são ativadas, podendo passar dados para qualquer observador configurado para observar o evento.
Observadores são capazes de modificar o comportamento da aplicação, porque são dinamicamente injetados no fluxo da execução.

### Boas práticas

Utilizar eventos e observadores é uma das principais maneiras de estender as funcionalidades do Magento. Eventos podem impactar em problemas de instabilidade no fluxo do Magento, então é recomendado manter os observadores simples e eficientes (alguns eventos são comumente disparados).
Os observadores não devem possuir lógica de negócio, o observador deve chamar as classes que encapsulam as lógicas de negócio. É recomendado que essas classes que possuam a regra de negócio não disparem eventos, que em cascata, disparem o evento original.
Não abordaremos nesse artigo os escopos de lojas, mas recomendo que sempre que for implementar um observador, busque sobre os escopos e em qual área deve ser aplicado.

---

## Código para disparar eventos

Eventos podem ser disparados utilizando a classe `\Magento\Framework\Event\ManagerInterface`. Esta classe pode ser instanciada através de injeção de dependência no construtor.
Para disparar um evento é utilizado o método `dispatch()` da classe de gerenciador de eventos passando como parâmetro o nome do evento que você queira disparar e como um segundo parâmetro um *array* com os dados que deseja disponibilizar para o observador.

```php
<?php

namespace {Vendor}\{Module}\{Directory};

use Magento\Framework\Event\ManagerInterface;

class {ClassName}
{
    public function __construct(
        private ManagerInterface $eventManager
    ) {
    }

    public function {methodName}(): {type}
    {
        $this->eventManager->dispatch('{event_name}', ['{paramName}' => $paramName]);
        // Code here
    }
}
```

## Código para Observers

### events.xml

Eventos personalizados podem ser disparados passando o nome do evento para o gerenciador de eventos quando o método `dispatch()` for chamado.
O evento possui um nome único e é referenciado no arquivo `events.xml` onde é definido qual será a classe *Observer* que reagirá a quando o evento for disparado. Esses arquivos devem seguir a estruturas de pastas `\{Vendor}\{Module}\etc\{area}\events.xml`.

```xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="{event_name}">
        <observer name="{observer_name}" instance="{Vendor}\{Module}\Observer\{ObserverName}" />
    </event>
</config>
```

- **Event name**: é um atributo obrigatório que registra o nome do evento que será chamado através do método dispatch pelo gerenciador de eventos;
- **Observer name**: é um atributo obrigatório que nomeia o observador;
- **Observer instance**: é um atributo no qual deve ser inserido o caminho da classe do observador;
- **Observer disabled**: é um atributo opcional que determina se o observador está ativo ou não (o valor padrão é *true*).

### Observer

Observadores são classes que afetam e podem influenciar no comportamento geral do sistema, performance ou alteração na regra de negócio. Observadores são sempre executados quando o evento que ele está configurado é chamado pelo gerenciador de eventos através do método `dispatch()`.
O observador deve seguir a estrutura de pastas `\{Vendor}\{Module}\Observer\{ObserverName}` e deve implementar a classe `\Magento\Framework\Event\ObserverInterface`, que obriga a classe a  implementar o método `execute(\Magento\Framework\Event\Observer $observer)`.
Os observadores são capazes de utilizar parâmetros passados ao disparar os eventos.

```php
<?php

namespace {Vendor}\{Module}\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Event\Observer;

class {ObserverName} implements ObserverInterface
{
    public function execute(Observer $observer): {type}
    {
        $observer->getData('{param}');
        // Code here
    }
}
```

---

## Finalizando

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


### Habilitando as alterações

Execute o comando PHP para limpar todos os caches de armazenamento em cache do processos.

```
php bin/magento cache:clean
php bin/magento flush
```

### Diretórios e Arquivos

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

```
- app/
  - code/
    - {Vendor}/
        - {Module}/
          - etc/
            - events.xml
            - module.xml
          - Observer/
            - {Observername}.php
          - registration.php
          - composer.json
```