Como escrever uma extensão personalizada?

143

Como tive muitos problemas recentemente com a extensão gratuita e comercial, decidi fazer esta pergunta e respondê-la com as etapas que normalmente sigo ao escrever uma extensão. Sinta-se livre para editar a resposta ou adicionar uma nova.
Na maioria dos casos, ao instalar uma extensão ou um tema, preciso passar algumas horas (às vezes mais, às vezes menos) para fazê-lo funcionar em todos os ambientes de que preciso:

  • dev: geralmente localhostonde o projeto está em uma subpasta
  • pré-produção e ao vivo

Isso aconteceu mesmo com extensões de grandes provedores de extensão (que devem permanecer sem nome, pelo menos até que eu fique realmente bravo e adicione seus nomes aqui).
Portanto, a questão principal é ... que etapas devo considerar ao escrever uma extensão para garantir a qualidade do código e tornar mais fácil para uma pessoa técnica e não técnica usá-lo e para uma pessoa técnica alterá-lo?

Marius
fonte
11
Parece que um dos grandes provedores de extensão não gostou desta questão e a votou com voto negativo. :)
Marius
1
Pessoalmente, absolutamente nenhum prob com Wyomind, mas eles criptografar seu código e ainda são "parceiros premium" :( (apenas para exemplo)
sv3n

Respostas:

186

Aqui está o que eu costumo fazer:

  1. Sempre desenvolva com error_reportingon.
  2. Sempre desenvolva com isDeveloperModedefinido como true. Basta adicionar SetEnv MAGE_IS_DEVELOPER_MODE 1ao seu httpd.confarquivo (ou arquivo correspondente ao Nginx ou algo mais)
  3. Se a extensão estiver vinculada a uma funcionalidade principal, adicione a dependência no arquivo de declaração <depends><Mage_Catalog /></depend>
  4. Se o módulo for para uso da comunidade, use communitycomo pool de códigos para dar aos desenvolvedores a chance de substituir algumas classes sem modificar o código diretamente
  5. Coloque seus arquivos de design de front-end app/design/frontend/base/default para disponibilizá-los para todos os temas.
  6. Coloque seus arquivos de design de administrador app/design/adminhtml/default/defaulte não altere o tema do administrador. Talvez eu queira alterá-lo em um dos meus módulos.
  7. Prefixe os nomes dos arquivos de layout e da pasta do modelo com o nome da empresa para facilitar o isolamento deles. easylife_articles.xmleapp/design/.../easylife_articles
  8. Coloque seus recursos estáticos (JavaScript, CSS e imagens) em uma pasta semelhante aos arquivos de modelo easylife_articles/images/doh.png
  9. Anexe um arquivo de texto simples com como desinstalar a extensão: quais arquivos precisam ser removidos, quais tabelas precisam ser eliminadas, quais configurações precisam ser removidas da core_config_datatabela.
  10. Não escreva consultas diretamente em modelos, blocos ou auxiliares, use um modelo de recursos para isso.
  11. Não escreva consultas usando os nomes da tabela diretamente Select * from sales_flat_order where .... Use Zend_Selectae transforme os nomes das tabelas usando ->getTable('sales/order').
  12. Use o URL base para incluir jsarquivos no modelo. Errado <script type="text/javascript" src="../js/some.js"></script> . Direito <script type="text/javascript" src="<?php echo Mage::getBaseUrl('js').'some.js'?>"></script>
  13. Não reescreva as aulas, a menos que seja necessário. Use observadores e se não for possível usar métodos auxiliares que recebem como parâmetro e instância de uma classe que você deseja substituir. Errado : Substitua Mage_Catalog_Model_Productpara adicionar o método getProductArticles(). Certo . No seu ajudante, adicione getProductArticles(Mage_Catalog_Model_Product $product)
  14. Se você substituir classes, coloque uma lista delas em um readme.txtarquivo
  15. Use o caminho padrão do administrador para a seção admin do seu módulo. URL de administrador incorreto articles/adminhtml_articles/index . URL de administrador correto admin/articles/index
  16. Adicione a ACL para as seções de administrador. Talvez eu queira restringir o acesso a alguns dos administradores.
  17. Não adicione outra estrutura JavaScript (jQuery, MooTools etc.) se não for necessário. Escreva seu código no protótipo.
  18. Torne seu modelo HTML W3C válido (isso é para desenvolvedores de TOC como eu).
  19. Não coloque imagens na mediapasta. Use skin. A media pasta geralmente não possui controle de versão e isso torna mais difícil mover o site para diferentes ambientes.
  20. Teste sua extensão com o catálogo plano ativado e desativado. Para não dobrar o tempo de desenvolvimento, use o Chaos Monkey .
  21. Teste sua extensão com cache one cache off.
  22. Evite usar letras maiúsculas nos nomes dos módulos e das classes. Se não for testado corretamente, isso poderá causar problemas em diferentes sistemas operacionais. Isso é mais uma recomendação, não um "obrigatório".
  23. Despache eventos no seu código para facilitar a alteração da funcionalidade pelos desenvolvedores.
  24. Siga os mesmos padrões de codificação usados ​​pelo Magento e comente seu código.
  25. Não use tags curtas do PHP ( <? $this->doSomething() ?>). Use tags completas ( <?php $this->doSomething()?>). Também não use tags de eco curtas, ainda. ( <?="D'oh";?>) Use ( <?php echo "D'oh";?>)
  26. Traduza seus textos usando $this->__e adicione o arquivo de tradução local com seus textos ( app/local/en_US/Easylife_Articles.csv) pelo menos para o en_USidioma. Nem todos os sites são construídos em inglês e a identificação dos textos a serem traduzidos é demorada.
  27. Se você vender uma extensão, ofereça pelo menos suporte básico. Ou pelo menos responda aos e-mails de suporte que você recebe.
  28. Não faça chamadas constantes para seus servidores através do seu ramal para validação de licença. Uma vez, a instalação é mais do que suficiente (também não gosto dessa abordagem, mas é melhor do que fazer chamadas o tempo todo). (Inspirado por esta pergunta )
  29. Desenvolva com o log ativado e, de tempos em tempos, dê uma olhada no var/log/system.logarquivo. Os erros listados aqui não são mostrados, mesmo com o modo de desenvolvedor ativado. Se houver pelo menos um erro, você acabará com um arquivo de log grande após alguns meses de execução da extensão.
  30. Se a sua extensão afetar o processo de pagamento ou os pedidos de alguma forma, verifique se ele funciona com várias remessas ou, se não deve funcionar com várias remessas, verifique se isso não afeta.
  31. Não substitua a barra de Notificação de administrador padrão (ou URL do feed). Se eu estiver interessado no que você tem a oferecer, assinarei sua newsletter. Deixe-me ver o que o Magento tem a dizer. É mais importante para mim.
  32. Se você criptografar seus arquivos de código com o Ioncube (ou qualquer outra coisa) ... bem ... eu odeio você e espero que sua empresa vá à falência

Isso é o que tem até agora. Acrescentarei mais assim que pensar em outra coisa.

Marius
fonte
Eu concordo com você, é definitivamente um bom começo. Com certeza, você também entenderá que nem sempre é possível cobrir todos os tipos diferentes de configuração e problemas; pelo menos, reduzirá o possível. A maioria dos problemas que encontro com outras extensões ou as pessoas encontram com a minha deve-se a conflitos com a substituição.
Sylvain Rayé 23/09
2
@ Marius, com certeza 1+ de me.it cobre a maioria dos casos e cenários que estamos enfrentando no desenvolvimento.
Liyakat
4
@ColinM. Antes de tudo, é uma honra ter seu comentário aqui. :). Concordo que há uma diferença, modificarei a resposta, mas ainda acho que os dois devem ser evitados, pelo menos até o PHP 5.3 se tornar o "novo PHP 4". Quero dizer, ainda é usado em larga escala.
Marius
4
@ Marius, seus pontos são muito úteis. Até o dia 31, eu estava seriamente focado em cada ponto, mas no 32 eu apenas soltei uma risada alta. +1 especialmente para o ponto # 32
MTM
1
If you encrypt your code files with Ioncube (or something else)...well...I just hate you and I hope your business goes bankruptEu sinto o mesmo. Existem algumas empresas que não oferecem a versão atualizada, você terá que pagar por elas, é realmente frustrante para mim e não entende por que elas querem vender o mesmo produto repetidamente (para ganhar dinheiro? Obviamente). Eu simplesmente não compro mais o produto deles. Você sabe de quem eu estou falando.
Adarsh ​​Khatri
31

Sou um grande fã do uso do modman, para que eu possa desenvolver e controlar o código-fonte apenas minha extensão e deixar os arquivos principais e a estrutura de pastas inalterada. Também faz com que os testes em diferentes instalações sejam mais suaves.

Ah, e uma dica massiva sempre tenta instalar sua extensão empacotada localmente em uma instalação limpa do magento antes de carregá-la no Magento Connect, perdi arquivos tantas vezes no gerenciador de pacotes.

David Manners
fonte
3
Boa chamada sobre o 'instale sua extensão empacotada localmente'. Acho que isso se enquadra na categoria: 'Teste sua maldita extensão de cima para baixo'.
Marius
Eu já fui pego por isso antes também. Certifique-se de testar o pacote em uma instalação limpa que não seja a mesma em que o empacotou!
Joseph Leedy
22

Andreas von Studnitz e Dr. Nikolai Krambrock fizeram uma boa apresentação sobre a qualidade do código no Meet Magento DE 2014. Eles distinguem entre qualidade geral do código e qualidade específica do Magento. Em resumo, existem as seguintes regras gerais:

  • O uso de elementos de estrutura - assim como classes e métodos - deve ser organizado em classes intermediárias. Esses elementos da estrutura só fazem sentido quando são usados ​​para estruturar. Portanto, eles devem ser de tamanho médio. Considera-se usar 100-200 linhas de código para classes e 3-20 linhas de código para métodos.
  • Devido ao uso de "if" ou "while", o código é recuado. Se houver mais de 3 recuos, é melhor revisá-los. Muitos recuos são evidências da complexidade do código e, portanto, devem ser evitados.
  • O código morto deve ser evitado e excluído. As análises estáticas ajudam a encontrá-lo, se houver.

Ainda mais importantes são as regras específicas do Magento:

  • Módulos devem funcionar de forma independente. Eles devem ter pouca dependência de outros módulos e nenhuma dependência de modelos. Uma solução é usar atualizações de layout (base / padrão) em vez de adaptação a arquivos de modelo e um módulo que cubra funções adicionais do modelo.
  • Para manter a capacidade de atualizações no núcleo do Magento, os hacks e os módulos externos devem ser evitados. Uma maneira melhor é o uso de reescritores ou observadores.
  • Para alterações, é melhor usar scripts de instalação em vez de alterações diretas do banco de dados ou do administrador. Graças a elas, as alterações precisam ser feitas apenas uma vez.

Aqui estão mais alguns detalhes e um vídeo da apresentação: http://www.code4business.de/code-quality-magento/

user3743859
fonte
1
Mas se você tivesse uma versão em inglês do link que postou, seria ainda melhor.
Marius
Uma versão em inglês desta apresentação será escrita em breve. Manterei você atualizado e compartilharei o novo link assim que a versão em inglês for publicada.
user3743859
Uma versão em inglês da apresentação está online agora. Aqui está o link para ele: code4business.de/code-quality-magento
user3743859
Hã? Ainda está em alemão. Mas aconteceu de assistir a esta apresentação em inglês no MeetMagentRo cerca de duas semanas atrás. Coisas boas.
Marius
18

Se você vender sua extensão ou compartilhá-la com outras pessoas, pense em escrever um código legível por humanos.

  1. não torne o método muito complexo
  2. adicione blocos DOC aos seus métodos *
  3. use nomes de variáveis ​​apropriados, como em $productIdsvez de$ids
  4. o mesmo para os métodos, public function myOnProductSaveMethod() {...}diz ... nada, mas tryDisableInternetOnProductSave()dará uma dica que o planejado
  5. use dicas de tipo onde faz sentido someMethod(Varien_Data_Db_Collection $collection)
  6. evite números e cordas mágicas **
  7. se você usar modelos, configure a $_eventPrefixpropriedade (e $_eventObject) para torná-los mais acessíveis aos observadores
  8. se você adicionar campos de configuração do sistema
    • defina os valores padrão em config.xml
    • adicione <validate>nós aos campos emsystem.xml
    • adicionar recursos da ACL a adminhtml.xml
  9. não adicione entradas de menu de primeiro nível inúteis / publicitárias no back-end do administrador - nem na barra superior nem nas seções de configuração
  10. adicione recursos ACL para todas as ações do controlador (massagens também!)
  11. verifique se suas consultas funcionam com prefixos de tabela do banco de dados
  12. pense em (não) compatibilidade retroativa (isso é realmente baseado em opiniões)
    • não suporta Mysql4aulas
    • não use métodos obsoletos
  13. garanta que sua extionão funcione conforme o esperado em todos os casos - adicione UnitTests (PhpUnit, por exemplo)
  14. além de David Manners ... adicione um composer.jsontambém para facilitar a implantação
  15. Como o PHP5.6 é EOL, escreva seu código para o PHP7. Use declare(strict_types=1);e defina seus tipos de entrada e saída
  16. Magento2: verifique seu código com ferramentas de análise de código estático, como o phpstan . Suporte para métodos mágicos aqui . (o commit mais recente funciona com 2.3, antes para 2.1 / 2.2 - que requer phpstan 0.8.5)

* Blocos DOC:

Se você verificar seu código Magento-1 com PHP_CodeSniffer para PSR2 padrão ou PHPMD, talvez queira adicionar essas linhas (onde faz sentido) ...

  • para aulas
    • @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
    • @phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore - propriedades herdadas
    • @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
    • @SuppressWarnings(PHPMD.CamelCaseClassName)
    • @SuppressWarnings(PHPMD.CamelCasePropertyName) - propriedades herdadas
  • para métodos
    • @SuppressWarnings(PHPMD.CamelCaseMethodName) - métodos herdados
    • @SuppressWarnings(PHPMD.StaticAccess)- se você usa Mage::ou outras chamadas estáticas

** Usado frequentemente:

  • ID da loja do administrador
    • 0 > Mage_Core_Model_App::ADMIN_STORE_ID
  • produtos status
    • 1 > Mage_Catalog_Model_Product_Status::STATUS_ENABLED
    • 2> Mage_Catalog_Model_Product_Status::STATUS_DISABLED (não 0como o esperado)
  • produtos type
    • simple > Mage_Catalog_Model_Product_Type::TYPE_SIMPLE
    • bundle > Mage_Catalog_Model_Product_Type::TYPE_BUNDLE
    • configurable > Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
    • grouped > Mage_Catalog_Model_Product_Type::TYPE_GROUPED
    • virtual > Mage_Catalog_Model_Product_Type::TYPE_VIRTUAL
  • produtos visibity
    • 1 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_NOT_VISIBLE
    • 2 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_CATALOG
    • 3 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH
    • 4 > Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH

O mesmo para a ordem SQL ASCvs Zend_Db_Select::SQL_ASC (por exemplo) .

Dizendo "não é necessário porque nunca vai mudar" ? Por exemplo, o ID da entidade para os catalog_productatributos mudou em algum lugar entre o Magento 1.5 e 1.9 de 10para 4, para que isso possa danificar sua extensão:

$collection->addFieldToFilter('entity_type_id', 10)

Usar isso adiciona uma consulta, mas você estará seguro ...

$entityTypeId = Mage::getModel('eav/config')
    ->getEntityType(Mage_Catalog_Model_Product::ENTITY)
    ->getEntityTypeId();

$collection->addFieldToFilter('entity_type_id', $entityTypeId)
sv3n
fonte
8

@ marius, em relação aos padrões de codificação (ponto 24 da sua lista).

Eu gosto de usar PHP_CodeSniffer junto com EQP e ECG CS para aplicar automaticamente esses padrões.

Usando o PHP_CodeSniffer, você não precisa se preocupar em esquecer coisas como substituir array()por [], evitar o uso is_null, deixar variáveis ​​locais não utilizadas ou até mesmo um método sem o bloco PHPDoc.

PHP_CodeSniffer sempre falará sobre isso.

diazwatson
fonte
Acordado! Possível howto: magento.stackexchange.com/questions/178640/…
sv3n
Eu acho que não há como configurar o CS no PHPStorm (para quem usa o PHPStorm), mas você sempre pode usar o terminal para verificar o CS no seu código. Também existem ferramentas como grumphp github.com/phpro/grumphp que ajudam um pouco.
Diazwatson 30/07/2017
Pode ser que você ajude magento.stackexchange.com/questions/200022/… #
Pramod Kharade