Magento 1: resolviendo conflictos entre módulos

Magento conflictos entre modulos

Magento es muy grande, aguanta carros y carretas, pudiéndole añadir gran cantidad de módulos. Uno de los proyectos en los que he participado alcanzó la friolera de 131 módulos, siendo algunos de estos módulos mega-módulos. Ha requerido mucho esfuerzo, todo hay que decirlo. Casi nunca suele ser “copiar y pegar los ficheros y ya está” como aquel que dice. Por el camino hay que resolver los conflictos, y tratamos día a día de evitar el añadir módulos si no es bien necesario. Hacemos limpieza de todos los que no se usen, y tratamos de actualizar todos los que se puedan, depende del tiempo que haya. Siempre surgen conflictos, y supone mucho tiempo hacer funcionar todas las opciones de ciertos módulos que entran en conflicto entre sí. Esto es el día a día del mantenimiento de los Magentos.

Origen de los problemas

Los desarrolladores hacen los módulos en un Magento limpio, recién instalado, sin que se requiera ningún otro módulo para su funcionamiento. Este es el entorno ideal, un Magento recién instalado. Pero la realidad nunca es así.

El principal de los conflictos es el de los rewrites, con el que directamente los módulos dejan de ejecutar sus funcionalidades. Es decir, si dos módulos modifican la misma funcionalidad de Magento, entran en conflicto entre sí. Magento comenzará a no funcionar o a funcionar raro. Otros problemas pueden ser el enganche a eventos, los llamados observers, aunque esto es difícil de que interfieran unos módulos con otros, pero si lo hacen con los datos que utilizan, puede ser realmente complicado encontrar los problemas. Y el tercer de los principales problemas que me he encontrado ha sido el del sistema de plantillas o layouts, en la parte de front, que cuando añades un nuevo módulo que toca el front necesitas adaptarlo al estilo visual de la plantilla que tengas.

Voy a centrarme en los rewrites en este post..

Los rewrites

Esta es una forma de reescribir partes de Magento para mejorar su funcionamiento. Para revisar esto podemos ir directamente a los ficheros y directorios siguientes, y revisar estos rewrites:

/app/code/community/desarrollador/modulo/etc/ficheroDeConfiguracion.xml
/app/code/core/desarrollador/modulo/etc/ficheroDeConfiguracion.xml
/app/code/local/desarrollador/modulo/etc/ficheroDeConfiguracion.xml

Si dos módulos tienen rewrites sobre lo mismo de Magento, hay que encadenarlos. Tendremos que encadenar estos rewrites extendiendo las clases de PHP. Por ejemplo si extienden un modelo de Magento podría ser así:

Vendor1/Modulo1_Model_Clase1 -> Vendor2/Modulo2_Model_Clase2 -> Mage/Core_Model_ClaseM

Tendremos que revisar cada rewrite y juntar las modificaciones en el modulo1 para que convivan y todo funcione. Al extender como que se van acumulando las funciones de una clase en la última clase. Abajo un caso de ejemplo para entenderlo fácilmente.

Un módulo de ayuda para localizar los rewrites

Magento 1 resolviendo conflictos con Aleksean/ModuleConflictDetector

Un módulo que va muy bien es el Alekseon/ModulesConflictDetector, que es gratis, y te añade una sección en el panel de control con los módulos que hay en conflicto. También puedes buscar el tag <rewrite> entre los ficheros de configuración de todos los módulos para encontrarlos, pero te tendrás que hacer tú mismo esta tabla que te hace el módulo 😉

Resolviendo un conflicto entre Ebizmarts/MailChimp y Aschroder/SMTPPro

Vamos a ver el conflicto del rewrite de Mage_Core_Model_Email_Queue, el primero de la imagen de arriba. Tenemos estos dos módulos que hacen rewrite de esta clase. Si miramos en el config.xml de ambos módulos encontraremos estas líneas:

..
<models>
 ..
 <core>
  <rewrite>
   <email_queue>Ebizmarts_MailChimp_Model_Email_Queue</email_queue>
  </rewrite>
 </core>
 ..
</models>
..

En el módulo de Aschroder/SMTPPro encontramos también:

..
<models>
 ..
 <core>
  <rewrite>
   <email_queue>Aschroder_SMTPPro_Model_Email_Queue</email_queue>
  </rewrite>
 </core>
 ..
</models>
..

Ambos módulos hacen rewrite del email_queue de Magento, es decir, de la clase de PHP llamada Mage_Core_Model_Email_Queue, que se encuentra en el directorio app/code/core/Mage/Core/Model/Email/Queue.

Resolviendo, soluciones

Vamos a resolverlo, una forma es simplemente comentar en el XML de configuración uno de los dos rewrites. Esto deja sin funcionar parte del módulo que comentemos.

Otra forma es priorizar haciendo que un módulo dependa del otro. Así forzamos que se cargue uno primero y luego el otro. El último en cargar sobreescribirá directamente el modelo del otro, si hay funciones iguales podemos tener un problema, también puede ocasionar problemas ya que si contamos con una funcionalidad del módulo que carga primero no la tendremos si el último la sobreescribe. Esto se hace poniendo en el fichero este:

app/etc/modules/Aschroder_SMTPPro.xml

..lo siguiente:

<?xml version="1.0"?>
<config>
 <modules>
  <Aschroder_SMTPPro>
   <active>true</active>
   <codePool>local</codePool>
   <depends>
    <Ebizmarts_MailChimp />
   </depends>
  </Aschroder_SMTPPro>
 </modules>
</config>

La última forma y mejor, sería hacer esto de antes, pero además extender una clase de otra. Fusionando las funciones comunes revisando el código línea a línea. Es decir, hasta aquí tenemos que antes de cargar Aschroder_SMTPPro le decimos que este módulo depende de Ebizmarts_MailChimp, y además hacemos que extienda el modelo modificando en:

app/code/local/Aschroder/SMTPPro/Model/Email/Queue.php

..la declaración de la clase, para que extienda así:

class Aschroder_SMTPPro_Model_Email_Queue extends Ebizmarts_MailChimp_Model_Email_Queue
//Mage_Core_Model_Email_Queue
{

Hasta aquí resulta que tenemos que Ebizmarts_MailChimp_Model_Email_Queue tiene dos funciones:

  • send
  • getMail

Y Aschroder_SMTPPro_Model_Email_Queue tiene sólo una que está sobreescribiendo (al extender) a la de Ebizmarts_MailChimp_Model_Email_Queue:

  • send

Esta función send es el último punto de conflicto. Tenemos que revisar línea a línea la función send de Ebizmarts_MailChimp_Model_Email_Queue porque se ha perdido su funcionalidad al extender con la clase Aschroder_SMTPPro_Model_Email_Queue. Si queremos algo de la función send de Ebizmarts_MailChimp_Model_Email_Queue, tendremos que añadir manualmente código a la función send de Aschroder_SMTPPro_Model_Email_Queue.

Terminando

Si todo ha ido bien, usando el módulo de Alekseon/ModulesConflictDetector se tiene que ver ahora así:

Magento 1 resolviendo conflictos 2

Sólo me queda añadir que para resolver los otros ‘conflictos’ entre módulos, los de observers o del front, no hay más opciones que leer y leer el código fuente. Hay que escudriñar los módulos para comprender cómo funcionan y cómo adaptarlos entre sí. En este punto ya solo queda tener una buena documentación de cada módulo, que sea un módulo de calidad, con código bien legible, y paciencia.

Siempre está la comunidad de desarrolladores de Magento, que andamos compartiendo muchas soluciones por Internet 😉

Un saludo.

Compartir..

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

siete − dos =