Blog

Actualización de un módulo PrestaShop a PrestaShop 9: qué falló y cómo lo solucionamos

Equipo de PrestaShopAddons 9 minutos de lectura

Block Sliding Cart es uno de los módulos más antiguos de nuestro catálogo. Se incluyó por primera vez en PrestaShop Addons en 2013 y, durante años, funcionó sin problemas. Luego llegó PrestaShop 8, no nos adaptamos a los cambios y, en 2023, la ficha quedó inactiva.

En 2026 lo recuperamos: un único código base para PrestaShop 1.7, 8 y 9, el tema Classic y Hummingbird. Esta es la lista de los problemas que surgieron durante el proceso y cómo se solucionó cada uno de ellos. Si tienes previsto actualizar a PrestaShop 9, la mayoría de estos problemas también afectarán a tus propios módulos.

Versión breve: La parte de PHP requirió menos cambios de lo previsto. La mayor parte del tiempo se dedicó al nuevo tema predeterminado y a superar la validación de los complementos, ya que una sola advertencia en una versión de PrestaShop puede hacer que se rechace toda la revisión.

1. PHP: ¿qué se ha eliminado o trasladado en la versión PrestaShop 9?

Tools::displayPrice() ya no está

El módulo formateaba los precios con siete decimales utilizando Tools::displayPrice(). El método llevaba mucho tiempo en desuso y, finalmente, en la versión PrestaShop 9 se eliminó, por lo que cada una de esas llamadas pasó a generar un error fatal.

El valor de sustitución es la configuración regional actual, que ya conoce el formato de moneda de la tienda. Hemos agrupado ambas rutas en un único ayudante, de modo que al resto del módulo nunca le importe en qué versión de PrestaShop se ejecute:

public function formatPrice($price)
{
    if (method_exists('Tools', 'displayPrice')) {
        // PrestaShop 1.7 / 8: keep the old behaviour
        return Tools::displayPrice((float) $price);
    }
    $locale = $this->context->getCurrentLocale();
    $isoCode = isset($this->context->currency) ? $this->context->currency->iso_code : '';

    return $locale->formatPrice((float) $price, $isoCode);
}

Las plantillas utilizan el mismo ayudante a través de un pequeño modificador de Smarty registrado por el módulo, por lo que {$price|scdisplayprice} funciona en todas las versiones.

Las clases de presentador han cambiado de espacio de nombres

El módulo muestra el carrito con el diseño propio de PrestaShop CartPresenter, por lo que los precios, los descuentos y los nombres de los productos se ven exactamente igual que en el resto de la tienda. Entre la 1.7 y la 8, esa clase se trasladó de Adapter\Cart a Adapter\Presenter\Cart. En lugar de class_alias trucos, el módulo resuelve el nombre de la clase una sola vez:

private function getCartPresenterClass()
{
    return class_exists('PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter')
        ? 'PrestaShop\\PrestaShop\\Adapter\\Presenter\\Cart\\CartPresenter'
        : 'PrestaShop\\PrestaShop\\Adapter\\Cart\\CartPresenter';
}

El mismo patrón se aplica a los expositores de productos utilizados para la venta cruzada. Un detalle más: en PrestaShop 8 y 9 present() devuelve un objeto de matriz «lazy», no una matriz normal, por lo que las indicaciones de tipo que indican array hay que permitir ArrayAccess también.

Se han realizado análisis estáticos en PrestaShop 9

El validador de complementos ejecuta PHPStan sobre el código fuente de PrestaShop 9. Una llamada que es totalmente segura en tiempo de ejecución, ya que se encuentra detrás de un method_exists() El error sigue apareciendo como “llamada a un método no definido”. Hemos reproducido el validador a nivel local (PHPStan con un bootstrap que carga los códigos fuente de PrestaShop 8 y 9) para poder comprobar cada corrección en cuestión de minutos, en lugar de tener que esperar a otra revisión.

2. Hummingbird: cuatro errores que solo aparecieron en el nuevo tema

Hummingbird es el tema predeterminado de PrestaShop 9 (código fuente en GitHub). Ninguno de los elementos que se muestran a continuación apareció en el análisis estático ni en PrestaShop 8 con el tema «Classic». Los cuatro se encontraron navegando por una tienda real de PrestaShop 9.

Las capas en cascada de CSS convirtieron la lista de la compra en una cuadrícula

Hummingbird aplica el estilo al .products clase como una cuadrícula de dos columnas en el interior @layer ps-components. Nuestra lista de la cesta utilizaba el mismo nombre de clase por motivos de compatibilidad, por lo que, en el panel lateral, los productos aparecían de repente en dos columnas estrechas. Aumentar la especificidad no sirve de ayuda frente a las capas de la forma habitual; lo que sí ayuda es que el CSS sin capas tenga prioridad sobre el CSS con capas. Una breve regla sin capas en la hoja de estilos del módulo lo solucionó:

#sclist .products,
#sclist .product_list_widget {
    display: block;
    grid-template-columns: none;
}

La ventana modal del carrito del tema requiere su propio código HTML

El módulo solía abrir su ventana emergente de “añadido al carrito” a través de prestashop.blockcart.showModal. Hummingbird sustituye esa función por su propia versión, que busca un elemento con data-ps-ref="blockcart-modal" y da un error cuando se le proporciona un código HTML diferente. La solución consistió en utilizar siempre el renderizador modal del propio módulo en lugar del del tema.

Una referencia a un elemento obsoleto en la animación “ir al carrito”

La animación guardaba el icono del carrito al hacer clic en el botón y leía su posición 250 ms después. En Hummingbird, el carrito del encabezado se vuelve a renderizar entretanto, por lo que el elemento guardado ya no se encontraba en la página y offset() devolvido undefined. Ahora, el módulo vuelve a buscar el icono en el momento en que lo necesita y omite la animación si el tema no tiene ningún icono de carrito disponible. El panel en sí se abre de todas formas.

Un botón fijo que se sale del panel en el móvil

En los móviles, el botón de pago es position: fixed en la parte inferior del panel lateral. Un elemento fijo se coloca en relación con el antepasado más cercano con un transform — y el panel solo tiene uno mientras está abierto. Cuando el panel se cerraba, el botón se fijaba a la ventana de visualización y flotaba en la parte inferior de cada página. Limitar el ámbito de la regla al estado abierto (.sc-widget-panel-open) lo resolvió.

3. Validación de complementos: qué es lo que comprueba realmente la revisión

Para que un módulo volviera a aparecer en la lista, había que pasar por el Validador PrestaShop y, a continuación, una revisión de cumplimiento en la que se instaló el módulo en varias versiones de PrestaShop con el modo de depuración activado. Estos fueron los aspectos que más tiempo nos llevaron.

Todas las variables de Smarty deben escaparse

Las plantillas más antiguas se basaban en el escape automático. Ahora, en la revisión, cualquier salida sin escape se considera un error grave. Hemos revisado las siete plantillas de la oficina de atención al público: |escape:'html':'UTF-8' para texto, direcciones URL y atributos, |intval para los números de identificación y las cantidades, |escape:'javascript':'UTF-8' dentro de los scripts en línea.

nofilter se notifica como un problema de seguridad, incluso cuando está justificado

El módulo permite al propietario de la tienda pegar su propio código HTML de icono (una etiqueta de Font Awesome o un archivo SVG). Esa salida se utilizó nofilter, con un comentario en el que se explicaba el motivo. El revisor lo marcó como problema de todos modos. La solución aceptada fue un modificador personalizado de Smarty que depura el código HTML — elimina <script> y <style> bloques, controladores de eventos en línea y javascript: URL — por lo que la plantilla ya no necesita nofilter en absoluto.

No se permite código HTML dentro de PHP

Se creó un pequeño panel de ayuda en la página de configuración como una cadena HTML en PHP. Se trasladó a su propia plantilla de administración. Una dificultad: en PrestaShop 8.1, la política de seguridad de Smarty para la administración bloquea un $this->context->smarty->fetch() de un archivo en la carpeta del módulo. Utiliza en su lugar el recurso del módulo:

$output .= $this->fetch('module:yourmodule/views/templates/admin/support.tpl');

Una advertencia en modo de depuración puede hacer que la revisión sea rechazada

Para esto tuve que intentarlo tres veces. El informe de cumplimiento indicaba que “no se podía acceder” a la página de configuración en PrestaShop 8.1 y 9.0, sin que apareciera ningún mensaje de error. Resultó que la causa era un único aviso: Undefined array key "is_default" en la plantilla HelperForm. Language::getLanguages() Si no devuelve esa clave, la plantilla del formulario la lee para cada idioma, y el modo de depuración estricto de la revisión convierte ese aviso en un error de página. En una tienda de prueba normal con el modo de depuración activado, solo aparece como una advertencia, por lo que era fácil pasarla por alto.

$languages = Language::getLanguages(false);
$idDefaultLang = (int) Configuration::get('PS_LANG_DEFAULT');
foreach ($languages as $k => $lang) {
    $languages[$k]['is_default'] = ((int) $lang['id_lang'] === $idDefaultLang) ? 1 : 0;
}

La lección: antes de enviar los datos, abre la página de configuración en PrestaShop 8 y 9 con el modo de depuración activado y trata cada aviso como si fuera un error.

Normas de codificación, con un conflicto

El validador aplica las reglas de PHP-CS-Fixer. Dos detalles nos han costado un reenvío cada uno: en un archivo sin espacio de nombres, escribe catch (Throwable $e), no \Throwable; y mantén el bloque de documentación de la licencia justo después de <?php, sin línea en blanco. Una configuración genérica de PHP-CS-Fixer intentará insertar esa línea en blanco, así que aplica las reglas del validador, no un ajuste preestablecido genérico.

Lista de comprobación para tus propios módulos antes de actualizar a la versión PrestaShop 9

  • Prueba nuestra aplicación gratuita Comprobador de compatibilidad PrestaShop 9 en el módulo. En él se enumeran las clases, los métodos y los hooks eliminados que se tratan en los siguientes puntos, indicando el archivo y la línea.
  • Busca en el código Tools::displayPrice y otros métodos eliminados en la versión 9.0 (el Documentación para desarrolladores de PrestaShop 9 (enumera los cambios).
  • Busca las clases a las que se hace referencia mediante sus antiguos espacios de nombres, sobre todo los presentadores y los adaptadores.
  • Instala el módulo en una unidad PrestaShop 9 con el modo de depuración activado y abre su página de configuración. Lee todas las indicaciones.
  • Prueba el front office en el Hummingbird, no solo en la versión Classic: ventanas emergentes, el carrito de la cabecera, las listas de productos y el diseño para móviles.
  • Comprueba si hay variables sin escapar en las plantillas y nofilter.
  • Comprueba el rango de compatibilidad declarado del módulo. Debe coincidir con las versiones que hayas probado realmente.

¿Preparas toda la tienda y no solo un módulo? Sigue nuestra checklist de 12 pasos para actualizar PrestaShop 1.7 a 9.

Dónde se encuentra ahora el módulo

Block Sliding Cart funciona en PrestaShop 1.7, 8 y 9, ha superado la validación de complementos y vuelve a aparecer en la lista, con su historial y sus 36 reseñas (4,7★) intactos. Puedes mira cómo funciona aquí, y las razones por las que se utiliza un carrito AJAX se explican en Carrito AJAX frente a la recarga de la página y Experiencia de usuario del carrito móvil para PrestaShop.

Si algún módulo de tu tienda ha dejado de funcionar tras una actualización, o si quieres saber qué es lo que dejará de funcionar antes de actualizar, ese es precisamente nuestro trabajo. Dinos qué te pasa y te responderemos con algunas preguntas o con un presupuesto.

Preguntas frecuentes

¿Es Tools::displayPrice() ¿Se ha eliminado en PrestaShop 9?

Sí. Utiliza en su lugar la configuración regional actual: $this->context->getCurrentLocale()->formatPrice($price, $currencyIsoCode). Si tu módulo también debe ser compatible con PrestaShop 1.7, incluye ambas rutas en un único método auxiliar.

¿Funcionan los módulos PrestaShop 1.7 en el PrestaShop 9?

Algunos funcionan sin necesidad de cambios. Los módulos que utilizan métodos del núcleo que ya no existen, espacios de nombres de clases antiguos o código JavaScript específico de un tema necesitan actualizaciones. Al instalar el módulo en una copia de PrestaShop 9 con el modo de depuración activado, la mayoría de los problemas se detectan en cuestión de minutos.

¿Por qué mi módulo parece que no funciona bien en Hummingbird, pero sí en Classic?

Hummingbird utiliza un marcado diferente, capas en cascada de CSS y su propio código JavaScript para el carrito. Los módulos que reutilizan nombres de clases de Classic o que llaman a las funciones del carrito del tema son los más afectados.

¿Por qué falla la revisión de cumplimiento de los complementos en la página de configuración?

La revisión instala el módulo en varias versiones de PrestaShop con el modo de depuración estricto, en las que aparecen avisos como “clave de matriz no definida” que provocan que la página deje de funcionar. Abre tú mismo la página de configuración en las versiones 8 y 9 de PrestaShop con el modo de depuración activado y corrige todos los avisos antes de enviar los cambios.