Desenvolvimento

13 abr, 2012

Como criar um módulo de Magento

Publicidade

Neste artigo, vou mostrar como é o desenvolvimento de um módulo para plataforma de e-commerce open source Magento. O resultado final é extremamente simples. A principal ideia é apresentar o funcionamento do Magento e como seriam os primeiros passos para o desenvolvimento de um módulo para essa plataforma. O tópicos que abordados serão:

  • A pasta app/code;
  • A estrutura e a criação de um módulo para Magento;
  • Evento Observer do Magento;
  • Criando Logs;

Presumo que você já tenha o Magento instalado e rodando no seu servidor de desenvolvimento; e que tenha permissão para adicionar novos arquivos à estrutura do Magento. A versão instalada não fará diferença nesse caso, pois o conteúdo apresentado é de fundamentos do sistema e estão presentes em todas versões: Community, Professional e Enterprise.

Desabilitando o cache

A primeira lição para todo desenvolvedor Magento é desabilitar o cache. Isso deve ser feito pelo painel de administração do sistema, seguindo os passos: Painel de Administração ? Sistema ? Gerenciamento de Cache ? Selecionar Tudo ? Ações: Desabilitar ? Enviar. O cache é o principal amigo quando a loja está no servidor de produção, melhorando muito a performance do Magento. Mas, para o desenvolvedor, é o maior inimigo. Qualquer desenvolvedor de Magento já passou pela experiência de não visualizar suas modificações na loja, pelo simples problema do cache estar ativado! Então, este deve ser o primeiro passo a seguir.

A pasta app/code

Os principais arquivos do Magento podem ser encontrados em módulos individuais dentro da pasta app/code, que é dividida em três zonas: community, core e local.

  • CORE: O app/code/core é a pasta onde se encontram todas as funcionalidades de produtos, categorias, clientes, pagamentos e etc. Ainda que você saiba o que está fazendo, NÃO deve modificar arquivos presente nessa pasta. O Magento é estruturado de uma maneira que você pode alterar a funcionalidade de qualquer um desses arquivos sem precisar modificá-los diretamente, garantindo que sua aplicação continue à prova de atualizações do CORE.
  • COMMUNITY: Como o próprio nome sugere, a pasta app/code/community é o lugar onde devem estar os módulos fornecidos por terceiros (ou seja, equipe não oficial do Magento). Esses módulos podem ser encontrados para download na Magento Connect, e podem ser baixados diretamente pelo “Downloader” do sistema.
  • LOCAL: A pasta app/code/local é o caminho que vem vazio na instalação do Magento. É o local onde devem ficar os módulos feitos sobre medida para a sua instalação Magento. Este é o lugar em que vamos trabalhar para a construção do exemplo neste artigo.

Estruturando o módulo

Agora vamos iniciar a estruturação do módulo. Para isso, abra o seu editor de arquivos preferido e navegue até a pasta app/code/local, onde vamos criar novas pastas e arquivos. Importante neste momento você ter a aplicação rodando e a permissão para criação de novos arquivos e pastas.

Definindo o “Namespace” do módulo

O termo “Namespace” é usado para definir o local onde ficará o módulo na pasta local. Por convenção, o nome usado é o da empresa que vai desenvolver o módulo, ou o próprio nome do módulo. O Magento usa o “namespace” Mage. Para este artigo, vamos criar o “namespace” iMasters. Então, o próximo passo é criar a pasta app/code/local/iMasters.

Nome do módulo

A próxima pasta a ser criada será a do nosso módulo. Com isso, vamos usar o nome do nosso próprio módulo. Como vamos desenvolver um que irá criar logs a cada vez que um produto é criado ou atualizado, o nome do módulo será ProdutoLogs. Criaremos a pasta app/code/local/Imasters/ProdutoLogs. Fazendo uma pequena revisão até o momento, vamos ter a seguinte árvore de pastas criadas. Lembrando que essa criação de pastas é case-sensitive. Com isso, é importante capitalizar as palavras conforme abaixo:

app
-code
--local
---iMasters
----ProdutoLogs

O próximo passo é criar as configurações do nosso módulo. Para isso, vamos criar uma pasta chamada etc, onde ficarão os arquivos XML responsáveis pelas configurações dos módulos. Com isso, criamos o arquivos app/code/local/iMasters/ProdutoLogs/etc/config.xml. Esse arquivo é responsável por mostrar para o Magento onde se encontram os arquivos do módulo, a versão e os eventos do sistema a observar. Por enquanto, vamos apenas criar o arquivo simples, conforme código abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- O nó raiz para a configuração do módulo Magento -->
<config>
<!-- Nó do módulo contém informações básicas sobre cada módulo Magento -->
<modules>
<!--
Este nó deve corresponder exatamente o nome do namespace e módulos,
separando as pastas com underline.
-->
<Imasters_ProdutoLogs>
<!-- A versão do módulo. Estamos iniciando na versão 0.0.1 -->
<version>0.0.1</version>
</Imasters_ProdutoLogs>
</modules>
</config>

Ativando o módulo

O próximo passo é ativar o módulo. Para isso, precisamos dizer ao Magento que ele existe, criando um arquivo XML na pasta de módulos do sistema app/etc/modules. O nome do arquivo XML pode ser o de sua preferência. De qualquer maneira, o Magento irá ler todos os arquivos presentes na pasta, e interpretar o conteúdo de cada um. Mas, por convenção, vamos manter o nome do módulo, evitando que tenhamos arquivos “perdidos” na pasta de módulos do sistema. Vamos criar app/etc/modules/iMasters_ ProdutosLog.xml com o seguinte conteúdo:

<?xml version="1.0" encoding="UTF-8"?>
<config>
<modules>
<iMasters_ProdutoLogs>
<!-- Dizemos se o módulo está ativo: true or false -->
<active>true</active>
<!-- Qual local o módulo está criado. -->
<codePool>local</codePool>
</iMasters_ProdutoLogs>
</modules>
</config>

Verificando o módulo

Agora já podemos verificar se a instalação feita até o momento está funcionando. Claro que o módulo não executa nenhuma ação até o momento, mas é possível ver se o Magento identificou corretamente o módulo ProdutoLogs. Para isso, é necessário fazer o seguinte caminho no sistema: Painel de Administração ? Sistema ? Configurações ? Avançado ? Avançado. Nessa tela, haverá a opção de visualizar os módulos ativos no sistema. O módulo iMasters_ProdutoLogs deverá estar presente na lista. Caso não esteja, pode haver algo errado na configuração. O primeiro passo é verificar se o cache do Magento está desabilitado. Caso ele esteja, volte alguns passos e verifique novamente o que pode estar errado no seu módulo. Vamos ver qual a estrutura de nosso módulo até o momento:

app
-code
--local
---iMasters
----ProdutoLogs
-----etc
------config.xml

-etc
--modules
---iMasters_ProdutoLogs.xml

Definindo o evento Observer

O evento Observer é uma ferramenta poderosa e rápida para você conseguir estender funcionalidades do sistema, podendo, assim, fazer rewrite ou overwrite de qualquer método ou classe. O que queremos observar nesse módulo é a ação que o sistema dispara após salvar um produto no painel de administração. Então, o código que nos interessa é catalog_product_save_after. Descobrir qual ação precisamos cobrir requer um conhecimento mais avançado das regras de negócio do Magento. Isso foge do escopo deste artigo – mas vou mostrar em artigo futuro, fiquem tranquilos. Agora, vamos precisar modificar o arquivo config.xml de nosso módulo, conforme abaixo:

<?xml version="1.0" encoding="UTF-8"?>
<!-- O nó raiz para a configuração do módulo Magento -->
<config>
<!-- Nó do módulo contém informações básicas sobre cada módulo Magento -->
<modules>
<!--
Este nó deve corresponder exatamente o nome do namespace e módulos,
separando as pastas com underline.
-->
<Imasters_ProdutoLogs>
<!-- A versão do módulo. Estamos iniciando na versão 0.0.1 -->
<version>0.0.1</version>
</iMasters_ProdutoLogs>
</modules>
<!-- Configuramos o módulo para ter comportamento no escopo global do sistema -->
<global>
<!-- Definindo o evento observer -->
<events>
<!-- O código do evento que queremos observar -->
<catalog_product_save_after>
<!-- Definição de um observador para este evento -->
<observers>
<!--
Identificador único no nó catalog_product_save_after.
Por convenção, colocamos o nome do módulo em minúsculo.
-->
<iMasters_produtologs>
<!-- O modelo a ser instanciado -->
<class>Imasters_produtologs/observer</class>
<!-- O método do modelo acima, para ser chamado -->
<method>logUpdate</method>
<!-- Geralmente usam o tipo singleton para os observadores -->
<type>singleton</type>

</iMasters_produtologs>
</observers>
</catalog_product_save_after>
</events>
</global>
</config>

Configurando a pasta dos models

No evento que definimos acima, fizemos referência a um model que ainda não está criado no artigo. Precisamos mostrar para o Magento onde encontrar nossos models, atualizando o arquivo config.xml com o seguinte código:

<?xml version="1.0" encoding="UTF-8"?>
<!-- O nó raiz para a configuração do módulo Magento -->
<config>
<!-- Nó do módulo contém informações básicas sobre cada módulo Magento -->
<modules>
<!--
Este nó deve corresponder exatamente o nome do namespace e módulos,
separando as pastas com underline.
-->
<iMasters_ProdutoLogs>
<!-- A versão do módulo. Estamos iniciando na versão 0.0.1 -->
<version>0.0.1</version>
</iMasters_ProdutoLogs>
</modules>
<!-- Configuramos o módulo para ter comportamento no escopo global do sistema -->
<global>
<!-- Definindo os models -->
<models>
<!--
Identificador único no nó de models.
Por convenção, colocamos o nome do módulo em minúsculo.
-->
<iMasters_produtologs>
<!--
O caminho para o nosso diretório de modelos,
com separadores de diretório substituído por underlines
-->
<class>iMasters_ProdutoLogs_Model</class>
</iMasters_produtologs>
</models>

<!-- Definindo o evento observer -->
<events>
<!-- O código do evento que queremos observar -->
<catalog_product_save_after>
<!-- Definição de um observador para este evento -->
<observers>
<!--
Identificador único no nó catalog_product_save_after.
Por convenção, colocamos o nome do módulo em minúsculo.
-->
<iMasters_produtologs>
<!-- O modelo a ser instanciado -->
<class>iMasters_produtologs/observer</class>
<!-- O método do modelo acima, para ser chamado -->
<method>logUpdate</method>
<!-- Geralmente usam o tipo singleton para os observadores -->
<type>singleton</type>
</iMasters_produtologs>
</observers>
</catalog_product_save_after>
</events>
</global>
</config>

Criando um Observer Model

Agora vamos criar o arquivo que será instanciado no momento em que o evento for disparado. Para isso, vamos criar o arquivo app/code/local/Imasters/ProdutoLogs/Model/Observer.php, com o seguinte código:

<?php

class iMasters_ProdutoLogs_Model_Observer {

/**
* O Magento irá passar a Varien_Event_Observer object como
* o primeiro parâmetro de eventos despachados.
*/
public function logUpdate(Varien_Event_Observer $observer) {
// Recuperar o produto que está sendo atualizado a partir do observador evento
$product = $observer->getEvent()->getProduct();

// Escrevendo uma nova linha no var/log/product-updates.log
$name = $product->getName();
$sku = $product->getSku();
Mage::log("{$name} ({$sku}) updated", null, 'atualizacoes-produtos.log');
}

}

Está pronto! Com isso, chegamos ao fim do artigo. Se todos os passos foram seguidos corretamente, você deve ter a estrutura abaixo:

app
-code
--local
---iMasters
----ProdutoLogs
-----Model
------Observer.php

-----etc
------config.xml

-etc
--modules
---iMasters_ProdutoLogs.xml

Agora, cada vez que você salvar ou criar um produto no Magento, um registro de log deve ser criado na pasta var/log, dentro do arquivo atualizacoes-produtos.log. Se o arquivo não aparecer na pasta, procure verificar as permissões de escrita da pasta. Ainda é necessário verificar se o Magento está habilitado para exibir os logs. O caminho para isso é Painel de Administração ? Sistema ? Configurações ? Desenvolvedor ? Configurações de Log ? Ativar.

O que foi passado neste artigo é um pouco do funcionamento do Magento. Após desenvolver o que ensinei neste artigo, recomendo que passe um tempo explorando a pasta app/code/core do Magento, assim você vai poder ter uma boa ideia de todo o funcionamento do sistema. Dúvidas e feedback são bem-vindos, é só deixar um comentário!

***

Este artigo foi escrito originalmente no blog Smashing Magazine, por Joseph McDermott. Traduzido e adaptado por Fausto Schneider.