Cursos Magento

Trabalhando com Eventos e Observers no Magento 1

, ,

Atualizado em 01 de setembro de 2021

Sempre que precisamos modificar uma funcionalidade existente no Magento, ou realizar uma integração, a primeira coisa que devemos fazer é buscar os eventos que cercam aquela entidade ou recurso que queremos mexer.

Evite sobrescrever

Ao invés de sair sobrescrevendo classes e módulos nativos do core do Magento, o uso de events e observers é uma prática bem mais recomendada e menos invasiva, que garante mais compatibilidade com outros módulos, e evita conflitos de sobrescrita em classes que já foram substituídas por outros módulos anteriormente.

O que são os eventos

Pode-se dizer que o Magento é uma plataforma baseada em eventos, e esta é uma das grandes sacadas para sua alta flexibilidade.

Os eventos são pontos de interrupção presentes em diversas partes do núcleo da plataforma. Uma vez que um evento é chamado, o Magento busca todos os módulos que estão “escutando” aquele evento e os chama, passando parâmetros relevantes que podem ser modificados por esses módulos ou utilizados por eles para realizar integrações ou disparar novas ações.

Veja alguns dos eventos presentes do Magento e muito utilizados:

  • sales_order_place_after – disparado logo após a realização de um pedido
  • sales_order_invoice_pay – disparado logo após o pagamento de uma fatura (quando o pedido é pago)
  • checkout_cart_product_add_after – chamado logo após um produto ser adicionado ao carrinho
  • checkout_cart_save_after – chamado após uma modificação no carrinho ter sido realizada
  • admin_user_authenticate_after – chamado após uma tentativa de login no admin da loja

O Magento 1.9 tem aproximadamente 430 eventos em diversos lugares, além de eventos que possuem nomes dinâmicos, construídos com base em variáveis de ambiente e requisição (como por exemplo 'controller_action_predispatch_' . $this->getFullActionName() ).

Uma lista com todos os eventos pode ser obtida através de uma busca por chamadas do método Mage::dispatchEvent() em toda a loja, mas é claro que eu vou facilitar seu trabalho no final deste post.

Usando Observers

Após criar um módulo básico para Magento 1, você pode facilmente adicionar pontos de observação (observers) ao seu módulo. Uma vez que este ponto de observação é atingido, um método e uma classe especificado por você é chamada.

No exemplo abaixo adicionarei um observer para o evento core_block_abstract_to_html_after, declarado em app/code/core/Mage/Core/Block/Abstract.php. Este evento é chamado antes da saída html de todos os blocos do Magento, e como podemos ver, um parâmetro “block” e “transport” são passados, contendo o bloco que está sendo renderizado e um elemento _transportObject que é usado para pegar o html de saída.

final public function toHtml()
{
	// …
	Mage::dispatchEvent('core_block_abstract_to_html_after',
	array('block' => $this, 'transport' => self::$_transportObject));
	$html = self::$_transportObject->getHtml();
	// …
}

Agora o nosso módulo:

<?xml version="1.0"?>
<config>
    <modules>
        <Magenteiro_EventListener>
            <version>1.0.0</version>
        </Magenteiro_EventListener>
    </modules>
    <global>
        <models>
            <magenteiro_eventlistener>
                <class>Magenteiro_EventListener_Model</class>
            </magenteiro_eventlistener>
        </models>
        <events>
            <core_block_abstract_to_html_after>
                <observers>
                    <magenteiro_eventlistener>
                        <type>model</type>
                        <class>Magenteiro_EventListener_Model_Observer</class>
                        <method>addHello</method>
                    </magenteiro_eventlistener>
                </observers>
            </core_block_abstract_to_html_after>
        </events>
    </global>
</config>

Note que declaramos um Model chamado Magenteiro_EventListener_Model_Observer e que o método addHello será chamado.
O nome do nosso módulo neste caso é Magenteiro_EventListener, mas pode ser qualquer coisa.

A propriedade type especifica como o Magento chamará a classe do nosso Observer. Este valor pode ser:

  • disabled – desabilitará o nosso observer
  • object ou model – fará o Magento iniciar nossa classe como um Model
  • singleton (ou omitido) – faz o Magento reaproveitar uma instância do objeto caso ele já exista, instanciando-o como Singleton
class Magenteiro_EventListener_Model_Observer
{
    public function addHello(Varien_Event_Observer $observer)
    {
        $block = $observer->getEvent()->getBlock();
        Mage::log($block->getNameInLayout(), null, 'magenteiro.log', true);
    }
}

Nosso Model Magenteiro_EventListener_Model_Observer não é obrigado a estender nenhuma outra classe, como ocorre com os Models tradicionais. Ele deve apenas conter um método chamado addHello que recebe apenas um parâmetro ($observer).

Note que para pegar o parâmetro “block” passado pelo app/code/core/Mage/Core/Block/Abstract.php precisamos apenas chamar o método getEvent()->getBlock() ou getEvent()->getData('block').

No nosso exemplo, eu forço a gravação de um arquivo em var/log/magenteiro.log que gravará o nome do bloco que foi chamado, usando o método nativo Mage::log.

Assista o resultado…

Modificando valores com eventos

Enquanto no Magento 2 a boa prática não recomenda que modifiquemos os valores passados para Observers, no Magento 1 esta é uma prática bastante comum. Seguindo nossas modificações na classe acima, eu adicionarei um “Hello” no começo do bloco “footer”.

class Magenteiro_EventListener_Model_Observer
{
    public function addHello(Varien_Event_Observer $observer)
    {
        $block = $observer->getEvent()->getData('block');
        if ($block->getNameInLayout() == 'footer') {
            $transport = $observer->getEvent()->getTransport();
            $htmlAtual = $transport->getHtml();
            $transport->setHtml('< h1>hello</h1 >' . $htmlAtual);
        }
    }
}
Hello antes do Footer

E o resultado:

Não faça isso em casa

Este foi apenas um exemplo de como podemos alterar um objeto com o uso de observers, sem precisar sobrescrever a classe inteira, e não de mostrar como inserir um html antes de um bloco. Por favor, não utilize o exemplo acima para este fim. Para isso existem os arquivos de template e layout xml que servem este propósito de forma muito mais eficiente e performática.

Lista de Eventos disponíveis

Quer receber uma lista de eventos disponíveis no Magento 1.9? Informe seu e-mail abaixo e receba um PDF para consulta, com todos os Observers do Magento 1 e onde encontrar a definição deles.

Quer saber mais?

No curso Criação de Módulos e Desenvolvimento Backend para Magento (aula 31) você assiste este e outros exemplos de Observers em vídeo, e ainda pode fazer download de alguns módulos usados como exemplo ao longo do curso.

Imagem principal: Pixabay

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

Deixe seu comentário

[fbcomments url="https://www.magenteiro.com/blog/magento-1/desenvolvimento/backend/eventos-e-observers/"]