¿Cómo escribir una extensión personalizada?

143

Debido a que últimamente tuve muchos problemas con la extensión gratuita y comercial, decidí hacer esta pregunta y responderla con los pasos que generalmente sigo al escribir una extensión. Siéntase libre de editar la respuesta o agregar una nueva.
En la mayoría de los casos, cuando instalo una extensión o un tema, tengo que pasar unas horas (a veces más, a veces menos) para que funcione en todos los entornos que necesito:

  • dev: generalmente localhostdonde el proyecto está en una subcarpeta
  • preprod & live

Esto ha sucedido incluso con extensiones de grandes proveedores de extensiones (que deberían permanecer sin nombre al menos hasta que me enoje mucho y agregue sus nombres aquí)
Entonces, la pregunta principal es ... ¿qué pasos debo tener en cuenta al escribir una extensión para garantizar la calidad? del código y hacer que sea más fácil para una persona técnica y no técnica usarlo y que una persona técnica lo cambie?

Marius
fuente
11
Parece que a uno de los grandes proveedores de extensiones no le gustó esta pregunta y la rechazó. :)
Marius
1
Personalmente, absolutamente no hay problema con Wyomind, pero cifran su código y siguen siendo "socios premium" :( (solo por ejemplo)
sv3n

Respuestas:

186

Esto es lo que suelo hacer:

  1. Desarrollar siempre con error_reportingencendido.
  2. Desarrollar siempre con isDeveloperModeset to true. Simplemente agréguelo SetEnv MAGE_IS_DEVELOPER_MODE 1a su httpd.confarchivo (o el archivo correspondiente para Nginx u otra cosa)
  3. Si la extensión está vinculada a una funcionalidad central, agregue la dependencia en el archivo de declaración <depends><Mage_Catalog /></depend>
  4. Si el módulo es para uso comunitario, communityúselo como codepool para dar a los desarrolladores la oportunidad de anular algunas clases sin modificar el código directamente
  5. Ponga sus archivos de diseño frontend app/design/frontend/base/default para que estén disponibles para todos los temas.
  6. Ponga sus archivos de diseño de administrador app/design/adminhtml/default/defaulty no cambie el tema de administrador. Es posible que desee cambiarlo en uno de mis módulos.
  7. Prefije los nombres de los archivos de diseño y el nombre de la carpeta de la plantilla con el nombre de la empresa para que sea más fácil aislarlos. easylife_articles.xmlyapp/design/.../easylife_articles
  8. Coloque sus recursos estáticos (JavaScript, CSS e imágenes) en una carpeta similar a los archivos de plantilla easylife_articles/images/doh.png
  9. Adjunte un archivo de texto simple con la forma de desinstalar la extensión: qué archivos deben eliminarse, qué tablas deben eliminarse, qué configuraciones deben eliminarse de la core_config_datatabla.
  10. No escriba consultas directamente en modelos, bloques o ayudantes, use un modelo de recursos para eso.
  11. No escriba consultas utilizando los nombres de las tablas directamente Select * from sales_flat_order where .... Usa ay Zend_Selecttransforma los nombres de las tablas usando ->getTable('sales/order').
  12. Use la URL base para incluir jsarchivos en la plantilla. Equivocada <script type="text/javascript" src="../js/some.js"></script> . Derecho <script type="text/javascript" src="<?php echo Mage::getBaseUrl('js').'some.js'?>"></script>
  13. No reescriba las clases a menos que sea necesario. Use observadores y si no es posible usar métodos auxiliares que reciban como parámetro e instancia de una clase que desea anular. Incorrecto : anular Mage_Catalog_Model_Productpara agregar el método getProductArticles(). Derecho . En su ayudante agregue getProductArticles(Mage_Catalog_Model_Product $product)
  14. Si anula las clases, ponga una lista de ellas en un readme.txtarchivo
  15. Use la ruta de administrador predeterminada para la sección de administración de su módulo. URL de administrador incorrecta articles/adminhtml_articles/index . URL de administrador correcta admin/articles/index
  16. Agregue ACL para sus secciones de administrador. Es posible que desee restringir el acceso a algunos de los administradores.
  17. No agregue otro marco de JavaScript (jQuery, MooTools, etc.) si no es necesario. Escribe tu código en el prototipo.
  18. Haga que su plantilla HTML W3C sea válida (esto es para desarrolladores de OCD como yo).
  19. No coloque imágenes en la mediacarpeta. Utilizar skin. La media carpeta generalmente no está versionada y esto hace que sea más difícil mover el sitio web a diferentes entornos.
  20. Pruebe su extensión con el catálogo plano activado y desactivado. Para no duplicar el tiempo de desarrollo, usa Chaos Monkey .
  21. Prueba tu extensión con caché ony caché off.
  22. Evite usar letras mayúsculas en el módulo y los nombres de clase. Si no se prueba adecuadamente, esto puede causar problemas en diferentes sistemas operativos. Esto es más una recomendación, no un "deber".
  23. Distribuya eventos en su código para que sea más fácil para los desarrolladores alterar la funcionalidad.
  24. Siga los mismos estándares de codificación que utiliza Magento y comente su código.
  25. No use etiquetas cortas PHP ( <? $this->doSomething() ?>). Use etiquetas completas ( <?php $this->doSomething()?>). Tampoco use etiquetas de eco cortas, todavía. ( <?="D'oh";?>) Usar ( <?php echo "D'oh";?>)
  26. Traduzca sus textos usando $this->__y agregue el archivo de traducción de la configuración regional con sus textos ( app/local/en_US/Easylife_Articles.csv) al menos por en_USidioma. No todos los sitios web están construidos en inglés y la identificación de textos para traducir lleva mucho tiempo.
  27. Si vende una extensión, ofrezca al menos soporte básico. O al menos responda los correos electrónicos de soporte que reciba.
  28. No realice llamadas constantes a sus servidores a través de su extensión para la validación de la licencia. Una vez, en la instalación es más que suficiente (tampoco me gusta este enfoque, pero es mejor que hacer llamadas todo el tiempo). (Inspirado por esta pregunta )
  29. Desarrolle con el registro activado y de vez en cuando eche un vistazo al var/log/system.logarchivo. Los errores enumerados aquí no se muestran incluso con el modo desarrollador activado. Si hay al menos un error, terminará con un archivo de registro grande después de unos meses de ejecutar la extensión.
  30. Si su extensión afecta el proceso de pago o los pedidos de alguna manera, asegúrese de que funcione con envío múltiple, o si no debería funcionar con envío múltiple, asegúrese de que no lo afecte.
  31. No reemplace la barra de notificaciones de administrador predeterminada (o la URL del feed). Si estoy interesado en lo que tiene para ofrecer, me suscribiré a su boletín. Déjame ver lo que Magento tiene que decir. Es mas importante para mi.
  32. Si encriptas tus archivos de código con Ioncube (u otra cosa) ... bueno ... simplemente te odio y espero que tu negocio vaya a la quiebra

Eso es lo que tenemos hasta ahora. Agregaré más tan pronto como piense en otra cosa.

Marius
fuente
Estoy de acuerdo contigo, definitivamente es un buen comienzo. Sin duda, también comprenderá que no siempre es posible cubrir todos los diferentes tipos de configuración y problemas, al menos reducirá el posible. La mayoría de los problemas que encuentro con otras extensiones o las personas con las mías se deben a conflictos con la sobrescritura.
Sylvain Rayé
2
@ Marius, seguro 1+ de mí. Cubre la mayoría de los casos y escenarios de lo que estamos enfrentando en el desarrollo.
liyakat
44
@ColinM. En primer lugar, es un honor tener tu comentario aquí. :). Estoy de acuerdo en que hay una diferencia, modificaré la respuesta, pero sigo pensando que ambos deben evitarse, al menos hasta que PHP 5.3 se convierta en el "nuevo PHP 4". Quiero decir que todavía se usa a gran escala.
Marius
44
@ Mario, tus puntos son muy útiles. Hasta el n. ° 31 me estaba centrando seriamente en cada punto, pero en el n. ° 32 solté una carcajada. +1 especialmente para el punto # 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 bankruptSiento lo mismo. Hay algunas compañías que no ofrecen una versión actualizada, tendrá que pagar por ellas, es realmente frustrante para mí y no entiendo por qué quieren vender el mismo producto una y otra vez (¿para ganar dinero? Obviamente). Simplemente ya no compro su producto. Sabes de quién estoy hablando.
Adarsh ​​Khatri
31

Soy un gran fanático del uso de modman para poder desarrollar y controlar la fuente solo mi extensión y dejar los archivos centrales y la estructura de carpetas sin cambios. También hace que las pruebas en diferentes instalaciones sean más fluidas.

Ah, y una sugerencia masiva siempre intente instalar su extensión empaquetada localmente en una instalación limpia de magento antes de cargarla en Magento Connect, me he perdido los archivos tantas veces en el administrador de paquetes.

David modales
fuente
3
Buena llamada sobre 'instalar su extensión empaquetada localmente'. Creo que esto cae en la categoría: 'Prueba tu maldita extensión de arriba a abajo'.
Marius
Esto también me ha sorprendido antes. ¡Asegúrese de probar el paquete en una instalación limpia que no sea la misma en la que lo empaquetó!
Joseph Leedy
22

Andreas von Studnitz y el Dr. Nikolai Krambrock hicieron una buena presentación sobre la calidad del código en el Meet Magento DE 2014. Distinguen entre la calidad del código general y la calidad del código específico de Magento. En resumen, existen las siguientes reglas generales:

  • El uso de elementos de estructura, al igual que las clases y los métodos, debe organizarse en clases intermedias. Estos elementos de la estructura solo tienen sentido cuando se usan para estructurar. Por lo tanto, deben ser de tamaño mediano. Se considera que utiliza 100-200 líneas de código para las clases y 3-20 líneas de código para los métodos.
  • Debido al uso de "if" o "while", el código está sangrado. Si hay más de 3 muescas, es mejor revisarlas. Demasiadas hendiduras son evidencia de la complejidad del código y, por lo tanto, deben evitarse.
  • El código muerto debe evitarse y eliminarse. Los análisis estáticos ayudan a encontrarlo si existe.

Aún más importantes son las reglas específicas de Magento:

  • Los módulos deberían funcionar de forma independiente. Solo deberían tener poca dependencia de otros módulos y ninguna dependencia de las plantillas. Una solución es usar las actualizaciones de diseño (base / predeterminada) en lugar de la adaptación a los archivos de plantilla y un módulo que cubre funciones adicionales de la plantilla.
  • Para mantener la capacidad de actualizaciones en Magento, se deben evitar los hacks centrales y los hacks de módulos externos. Una mejor manera es el uso de reescritores u observadores en su lugar.
  • Para los cambios, es mejor usar scripts de configuración en lugar de cambios directos de la base de datos o del administrador. Gracias a ellos, los cambios deben hacerse solo una vez.

Aquí hay más detalles y un video de la presentación: http://www.code4business.de/code-quality-magento/

usuario3743859
fuente
1
Pero si tuviera una versión en inglés del enlace que publicó, sería aún mejor.
Marius
Pronto se redactará una versión en inglés de esta presentación. Los mantendré actualizados y compartiré el nuevo enlace tan pronto como se publique la versión en inglés.
user3743859
Una versión en inglés de la presentación está en línea ahora. Aquí está el enlace: code4business.de/code-quality-magento
user3743859
eh? Todavía está en alemán. Pero acabo de asistir a esta presentación en inglés en MeetMagentRo hace aproximadamente 2 semanas. Buena cosa.
Marius
18

Si vende su extensión o la comparte con otras personas, piense en escribir código que sea legible para los humanos.

  1. no hagas el método demasiado complejo
  2. agregue bloques DOC a sus métodos *
  3. usar nombres de variables apropiados, como en $productIdslugar de$ids
  4. lo mismo para los métodos, public function myOnProductSaveMethod() {...}dice ... nada, pero tryDisableInternetOnProductSave()dará una pista de que lo planeado
  5. use sugerencias de tipo donde tenga sentido someMethod(Varien_Data_Db_Collection $collection)
  6. evita los números y cuerdas mágicos **
  7. si usa la $_eventPrefixpropiedad set de modelos (y $_eventObject) para hacerlos más accesibles a los observadores
  8. si agrega campos de configuración del sistema
    • establecer valores predeterminados en config.xml
    • agregar <validate>nodos a los campos ensystem.xml
    • agregar recursos de ACL a adminhtml.xml
  9. no agregue entradas de menú de primer nivel inútiles / publicitarias en el backend de administración, ni en la barra superior ni en las secciones de configuración
  10. agregue recursos de ACL para todas las acciones del controlador (¡también masacres!)
  11. asegúrese de que sus consultas funcionen con prefijos de tabla DB
  12. pensar en (no) compatibilidad hacia atrás (esto realmente está basado en una opinión)
    • no apoyar Mysql4clases
    • no use métodos obsoletos
  13. asegúrese de que su extionion funcione como se espera en todos los casos: agregue UnitTests (PhpUnit por ejemplo)
  14. además de David Manners ... agregue composer.jsontambién para facilitar la implementación
  15. como PHP5.6 es EOL, escriba su código para PHP7. Use declare(strict_types=1);y defina sus tipos de entrada y salida
  16. Magento2: verifique su código con herramientas de análisis de código estático como phpstan . Soporte para métodos mágicos aquí . (el último commit funciona con 2.3, antes para 2.1 / 2.2 - requiere phpstan 0.8.5)

* Bloques DOC:

Si verifica su código Magento-1 con PHP_CodeSniffer para el estándar PSR2 o PHPMD , tal vez desee agregar estas líneas (donde tenga sentido) ...

  • a las clases
    • @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
    • @phpcs:disable PSR2.Classes.PropertyDeclaration.Underscore - propiedades heredadas
    • @phpcs:disable Squiz.Classes.ValidClassName.NotCamelCaps
    • @SuppressWarnings(PHPMD.CamelCaseClassName)
    • @SuppressWarnings(PHPMD.CamelCasePropertyName) - propiedades heredadas
  • a los métodos
    • @SuppressWarnings(PHPMD.CamelCaseMethodName) - métodos heredados
    • @SuppressWarnings(PHPMD.StaticAccess)- si usa Mage::u otras llamadas estáticas

** Utilizado a menudo:

  • ID de la tienda admin
    • 0 > Mage_Core_Model_App::ADMIN_STORE_ID
  • producto status
    • 1 > Mage_Catalog_Model_Product_Status::STATUS_ENABLED
    • 2> Mage_Catalog_Model_Product_Status::STATUS_DISABLED (no 0como se esperaba)
  • producto 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
  • producto 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

Lo mismo para el orden SQL ASCvs Zend_Db_Select::SQL_ASC (por ejemplo) .

¿Decir "no es necesario porque nunca cambiará" ? Por ejemplo, la identificación de entidad para los catalog_productatributos cambiaron en algún lugar entre Magento 1.5 y 1.9 de 10a 4, por lo que esto podría romper su extensión:

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

Usar esto agrega una consulta, pero estarás seguro ...

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

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

@ marius, con respecto a los estándares de codificación (punto 24 de su lista).

Me gusta usar PHP_CodeSniffer junto con EQP y ECG CS para aplicar automáticamente estos estándares.

Usando PHP_CodeSniffer usted no tiene que preocuparse por olvidar las cosas como reemplazar array()con [], evitar el uso is_null, deje variables locales no utilizados o incluso un método sin bloque PHPDoc.

PHP_CodeSniffer siempre te lo contará.

diazwatson
fuente
¡Convenido! Posible tutorial
sv3n
Creo que no hay forma de configurar ambos CS en PHPStorm (para aquellos que usan PHPStorm) pero siempre puede usar el terminal para verificar el CS en su código. También hay herramientas como grumphp github.com/phpro/grumphp que ayudan un poco.
diazwatson
Podría ser de ayuda magento.stackexchange.com/questions/200022/…
Pramod Kharade