Compatibilidad de PrestaShop: entornos de ejecución, API y migración de módulos
Crea y prueba módulos para versiones de PrestaShop. Revisa rangos de PHP, API eliminadas, controladores Symfony, hooks, temas y vías de actualización.
Construye una única base de código del módulo en torno a las API que realmente difieren entre versiones de PrestaShop. Mantén alineados los requisitos de ejecución, el código auxiliar de compatibilidad y las pruebas en tiendas instaladas antes de declarar compatibilidad. Una instalación correcta es solo la primera comprobación: los permisos, las actualizaciones, los pagos, el correo y las integraciones necesitan sus propias pruebas en la versión exacta, el entorno PHP y el tema.
Qué haríamos
El trabajo que necesita un módulo depende de lo que hace en la tienda y de dónde se ejecuta: la versión de destino, las tiendas antiguas que sigue admitiendo, el tema, las integraciones con las que se comunica y cualquier cambio a medida a su alrededor. Haríamos un inventario de las dependencias y responsabilidades comerciales del módulo y probaríamos después los flujos de mayor riesgo en una copia protegida de la tienda prevista. Conserva un módulo existente mantenido y compatible cuando supere las pruebas. Adapta el código a medida cuando el requisito siga siendo útil y sustitúyelo solo cuando la alternativa cubra el flujo real y sus datos.
Para un comerciante que traslada toda la tienda, la compatibilidad de los módulos es una parte de una vía más amplia. Esa vía depende de los módulos, integraciones, tema y datos de la tienda existente. La vía segura habitual es una tienda de destino limpia en pruebas más una migración de datos ensayada. Actualizar una copia de pruebas es otra opción cuando la configuración existente lo permite. Prueba el conjunto de módulos ensamblado con los datos propios de la tienda y haz después el cambio a una hora planificada. La lista de comprobación de actualización y migración cubre ese plan para la tienda. Esta guía da al desarrollador el trabajo concreto y las pruebas de aceptación que debe aportar.
Si quieres que nos encarguemos de todo el traslado, el PrestaShop Upgrade Service empieza con una comprobación gratuita de tu versión, PHP, alojamiento, tema y módulos, ofrece un presupuesto fijo por escrito antes de empezar y trabaja en una copia de pruebas mientras la tienda en producción sigue recibiendo pedidos.
Si un requisito necesita un módulo a medida, el PrestaShop Custom Module Development Service empieza con una especificación escrita y un presupuesto fijo para el alcance acordado, con pruebas, un lanzamiento controlado y un plan de vuelta atrás incluidos en la entrega.
Empieza por los riesgos comerciales del módulo
Ordena el trabajo de compatibilidad según lo que pararía antes el negocio, no según qué código parece más antiguo.
| Función del módulo | Qué inspeccionar primero | Pruebas necesarias |
|---|---|---|
| Proceso de compra, pago o entrega | Totales del carrito, ciclo de pago, callbacks, selección de transportista y creación de pedidos. | Los recorridos de invitado y con cuenta, los descuentos, los fallos y cancelaciones, los callbacks y los registros de preparación de pedidos coinciden. |
| Herramientas del back office | Dependencias de controladores, rutas, permisos, formularios, AJAX y operaciones masivas. | Las acciones autorizadas funcionan, las cuentas de empleados restringidas reciben la denegación y los filtros, exportaciones y escrituras funcionan. |
| Visualización en el front office | Hooks, datos presentados, cambios de plantillas, selectores y recursos. | Visualización e interacción correctas en los temas compatibles, móvil y escritorio, sin errores del navegador. |
| ERP, feeds o tareas programadas | Contrato de la API, credenciales, contexto de tienda, entorno de ejecución y reintentos. | Los datos de prueba realistas llegan a los registros externos correctos sin duplicar operaciones comerciales. |
| Correo y notificaciones | API de correo, configuración del transporte, plantillas, destinatarios y adjuntos. | Los mensajes representativos llegan a un buzón de pruebas con el contenido y los adjuntos correctos. |
Enumera el código a medida y los datos propios del módulo que hay detrás de cada responsabilidad. Una sustitución debe conservar el comportamiento necesario y ofrecer una vía de migración para esos datos.
Por ejemplo, una herramienta de administración puede abrir su panel correctamente y fallar cuando un empleado de almacén exporta una lista filtrada o ejecuta una acción masiva. Un módulo de transportista puede mostrar sus ajustes y fallar solo al solicitar una etiqueta. Prioriza esas acciones frente a una refactorización meramente estética de los controladores e identifica los accesos a entornos de pruebas o proveedores necesarios para ejecutarlas.
Centraliza las decisiones de compatibilidad
Una capa de compatibilidad proporciona a tu módulo una interfaz pequeña y estable para las API que difieren entre versiones de PrestaShop. Mantén ahí las comprobaciones de versión en lugar de repetirlas en controladores, hooks y plantillas. Prueba cada módulo dentro de su propio intervalo de compatibilidad declarado.
| Ámbito | Qué encapsular en el código auxiliar |
|---|---|
| Respuestas AJAX | Codificación JSON, tipo de contenido, renderizado nativo de respuestas y terminación de la solicitud. |
| Plantillas de módulo | Búsqueda y renderizado nativos de plantillas, incluidos los recursos de módulos heredados. |
| Traducción | Llamadas modernas de traducción y alternativas de traducción de módulos heredados. |
| Inserción en la tienda | El hook disponible para la ubicación requerida o un resultado explícito de no disponibilidad. |
| Formato de precios | Formato heredado cuando esté disponible y formato adaptado a la configuración regional en las versiones modernas. |
| Recursos | Registro moderno de recursos y llamadas antiguas a addCSS/addJS. |
Por ejemplo, MyPrestaRocks\Compat\PriceFormatter::format() delega en ToolsCompat::displayPrice(). Ese código auxiliar comprueba la API nativa, resuelve la moneda y recurre al formateador regional actual como alternativa.
Algunas capacidades no se pueden recrear cambiando el nombre de un método. En PrestaShop 1.6 no hay un hook de filtro de salida del documento final. Una alternativa al inicio del cuerpo mediante displayBanner también depende de su ubicación en el tema. Informa de esa limitación y utiliza un cambio deliberado de plantilla cuando la función necesite un punto de inserción exacto.
Separa la sintaxis PHP mínima del entorno de ejecución de la tienda
La restricción de PHP de una biblioteca no define qué versión de PHP puede ejecutar la tienda. El código compartido puede conservar una sintaxis compatible con PHP 7.1 mientras una versión concreta de PrestaShop requiere un entorno de ejecución más reciente. PHP 7.1 ha llegado al final de su vida útil y no es una recomendación de alojamiento.
| Destino | Compatibilidad de PHP | Qué registrar |
|---|---|---|
| PrestaShop 1.6 y 1.7 | Utiliza los requisitos de la versión histórica exacta. | Versiones exactas de tienda, módulo y PHP. El soporte heredado no hace seguro un entorno de ejecución obsoleto. |
| PrestaShop 8.0 a 8.2 | El intervalo oficial es PHP 7.2.5 a 8.1; PHP 8.1 es la versión recomendada en la documentación. | Utiliza PHP 8.1 para una prueba de compatibilidad con 8.2. PHP 8.2 queda fuera de este intervalo oficial. |
| PrestaShop 9.0 | PHP 8.1 a 8.4. | Prueba los límites inferior y superior de ejecución admitidos que sean relevantes para tu módulo. |
| PrestaShop 9.1 | PHP 8.1 a 8.5. | Incluye Hummingbird y los indicadores de funciones instalados. |
| PrestaShop 9.2 | Comprueba los requisitos de la compilación de destino exacta. | Incluye sus cambios de proceso de compra y configuración de servicios en la validación. |
Utiliza los requisitos de PrestaShop 8 y los requisitos de PrestaShop 9 al crear tu matriz. Una ejecución experimental satisfactoria fuera de un intervalo documentado no equivale al soporte oficial de la plataforma. PHP 8.1 alcanzó el final de su vida útil en el proyecto original el 31 de diciembre de 2025. Conserva un entorno 8.1 para pruebas de compatibilidad cuando sea necesario y planifica una actualización de la tienda y del entorno de ejecución que también tenga soporte de seguridad vigente para PHP.
Registra la versión de parche exacta, la versión de PHP, la compilación del módulo, el tema y las dependencias relevantes de cada entorno de pruebas, con la fecha de la prueba. Una compilación de PrestaShop 9 que supera las pruebas no es una prueba válida para todas las versiones menores o de parche posteriores. Prueba las versiones de PHP más baja y más alta que declares solo cuando esa versión de PrestaShop las admita, y no combines intervalos admitidos por separado en una pareja no válida.
PHP analiza un archivo antes de ejecutar una rama de versión. Una condición alrededor de una expresión exclusiva de PHP 8 no puede hacer que ese archivo se cargue en PHP 7.1. Mantén las propiedades tipadas, los argumentos con nombre, los enums, match y otra sintaxis más reciente fuera de los archivos que se cargan en entornos antiguos, o carga una implementación independiente solo en el entorno correspondiente. Si un único paquete no puede cubrir con seguridad todos los entornos que admites, distribuye compilaciones compatibles independientes en lugar de abandonar sin avisar las tiendas existentes.
Resuelve las dependencias de Composer con respecto a la versión de PHP más baja que anuncias. Ejecuta también composer check-platform-reqs en el destino instalado: una plataforma simulada es un ajuste de resolución de dependencias, no una prueba de ejecución.
{
"require": {"php": ">=8.1 <8.6"},
"config": {"platform": {"php": "8.1.0"}}
}
Este ejemplo describe una política de dependencias de módulo de PHP 8.1 a 8.5. No afirma que todas las versiones de PrestaShop admitan todas esas versiones. Mantén coherentes ps_versions_compliancy del módulo, las restricciones de Composer, las versiones de dependencias y las combinaciones probadas. Un techo como 9.99.99 también admite futuras versiones 9.x no probadas.
Combina comprobaciones de versión y de capacidades
Utiliza version_compare() para un cambio de comportamiento conocido. Utiliza method_exists(), is_callable() o class_exists() cuando necesites saber si una API está disponible. La existencia de un método no demuestra un comportamiento idéntico entre versiones, y un número de versión no demuestra que un entorno personalizado exponga todos los servicios esperados.
Este ejemplo de recursos muestra una comprobación de capacidades dentro de un manejador actionFrontControllerSetMedia. Mantén una vía de registro heredada separada si también admites una versión que no ejecute ese hook.
public function hookActionFrontControllerSetMedia($params)
{
$controller = $this->context->controller;
if (!isset($controller->php_self) || $controller->php_self !== 'product') {
return;
}
if (is_callable(array($controller, 'registerStylesheet'))) {
$controller->registerStylesheet(
'mymodule-front',
'modules/' . $this->name . '/views/css/front.css',
array('media' => 'all', 'priority' => 150)
);
} elseif (is_callable(array($controller, 'addCSS'))) {
$controller->addCSS($this->_path . 'views/css/front.css');
}
}
Centraliza ese punto de adaptación en lugar de repetir la rama en cada punto de llamada. Haz visible al componente que llama una capacidad no admitida en lugar de informar silenciosamente de un éxito. Conserva el comportamiento relevante, incluidos la configuración regional, la moneda, el contexto de tienda y la terminación de la respuesta.
Clasifica cada hallazgo antes de cambiar el código
Para cada posible incompatibilidad, registra el símbolo o comportamiento, la versión exacta afectada, las pruebas de su código fuente o de la documentación para desarrolladores y el flujo que la reproduce. La clasificación decide el trabajo:
| Hallazgo | Qué implica para el trabajo |
|---|---|
| Eliminación en el destino elegido | El módulo usa una API, un hook o una dependencia ausente. Sustitúyelo o inclúyelo explícitamente y prueba la vía afectada. |
| Función obsoleta en el destino elegido | La vía existente sigue disponible en las condiciones indicadas. Registra la advertencia y el plan de migración sin describirla como ya eliminada. |
| Cambio de diseño recomendado | La inyección, un hook compatible o un controlador con enrutamiento pueden facilitar el mantenimiento. Comprueba si la implementación actual falla realmente antes de ampliar la reescritura. |
Busca llamadas antiguas de formato de precios como Tools::displayPrice(), clases base de controladores y acceso a servicios con $this->get(), anotaciones de seguridad, Context::getContext(), hooks heredados de inicio de sesión y de la página de producto, bibliotecas de correo e importaciones directas de dependencias. Son candidatos a inspeccionar, no una lista de eliminaciones: las secciones siguientes muestran que algunos se han eliminado, otros están obsoletos y otros siguen siendo compatibles. Comprueba cada uno frente al destino exacto y no uses una búsqueda y sustitución masiva como prueba de que la alternativa se comporta igual.
Redacta cada hallazgo de forma que un desarrollador pueda resolverlo: el archivo y el símbolo, el destino exacto, la clasificación, las pruebas del código fuente, el recorrido afectado, el cambio propuesto y la nueva prueba. Una entrada que solo dice «controlador antiguo» no permite actuar. Una entrada que dice «la acción de exportación no puede resolver su dependencia en este destino; esta es la excepción y esta la ruta» da al desarrollador un fallo reproducible.
Una obsolescencia no bloquea por sí sola una actualización. Registra su impacto y la sustitución prevista según tu política de soporte, distingue una advertencia de una vía no disponible y conserva una vía compatible que funcione salvo que los requisitos de la versión o un comportamiento demostrado justifiquen sustituirla.
Sustituye las API eliminadas sin cambiar el contrato público
Formato de precios
Tools::displayPrice() quedó obsoleto en PrestaShop 1.7.6 y se eliminó en 9.0. En una solicitud de tienda moderna, utiliza la configuración regional con el código ISO de la moneda. En código que abarque varias versiones, llama en su lugar a tu código auxiliar de compatibilidad.
$context = Context::getContext();
$formatted = $context->getCurrentLocale()->formatPrice(
19.95,
$context->currency->iso_code
);
// With the shared compatibility package installed and autoloaded:
$formatted = \MyPrestaRocks\Compat\PriceFormatter::format(
19.95,
$context->currency
);
Inicializa explícitamente el contexto requerido en el código CLI o de procesos de trabajo. Un formateador alternativo sencillo no puede reproducir todas las reglas de moneda y configuración regional.
Respuestas AJAX
Sustituye las llamadas eliminadas a ajaxDie() por la vía de respuesta del controlador admitida. El ajaxRender() heredado renderiza contenido, pero por sí solo no proporciona el mismo contrato de terminación. Un componente auxiliar de compatibilidad para respuestas puede codificar arrays en JSON, establecer el tipo de contenido, invocar el renderizador nativo y terminar. En los controladores Symfony, devuelve un JsonResponse.
Dependencias
PrestaShop 9 eliminó dependencias que los módulos antiguos podían tomar prestadas del núcleo, como Guzzle, SwiftMailer, Tactician Bundle y PEAR Archive_Tar. Busca en tus importaciones y en todas las vías de ejecución diferida, e inspecciona el módulo empaquetado además de la lista de dependencias del destino. Una pantalla de configuración puede funcionar mientras falla la primera llamada HTTP o el primer correo programados.
| Dependencia antigua | Decisión de migración |
|---|---|
| Guzzle | Incluye tu propia dependencia compatible o migra la interfaz del cliente HTTP y la gestión de errores. |
| SwiftMailer | Utiliza la vía de correo admitida de la tienda o migra la creación y el transporte de mensajes a Symfony Mailer. |
| Tactician | Revisa la integración del bus de comandos y la configuración de los manejadores. Un bus distinto no es un sustituto directo. |
| Archive_Tar | Incluye la implementación necesaria o utiliza una biblioteca que admita el formato de archivo real. El soporte ZIP no lee archivos TAR. |
Para migrar un cliente HTTP, conserva la URL base, los parámetros de consulta, la autenticación, los tiempos de espera y las comprobaciones de la respuesta. Una solicitud de Symfony HttpClient puede usar auth_bearer y decodificar JSON mediante toArray(); gestiona las excepciones de transporte, HTTP y decodificación. Para migrar a Mailer, crea un Email con remitente, destinatario, asunto, cuerpo y adjuntos y envíalo después mediante un MailerInterface configurado. Registra o incluye explícitamente las dependencias que necesite tu módulo. Una biblioteca incluida puede entrar en conflicto con una versión cargada por el núcleo u otro módulo, así que comprueba la autocarga en la tienda ensamblada.
La configuración de correo de PrestaShop 9 cambió con Symfony Mailer. Prueba el relay SMTP real, el puerto, el cifrado y la autenticación. La implementación de correo asigna cualquier valor de cifrado antiguo distinto de off al indicador TLS, por lo que una actualización no rompe necesariamente todos los relays configurados antes con SSL. Envía cada tipo de mensaje transaccional a un buzón de pruebas e inspecciona sus variables, remitente, traducciones, encabezados y adjuntos.
Migra los controladores Symfony y verifica los permisos
PrestaShop 9 utiliza Symfony 6.4. Los nuevos controladores Symfony del back office deben extender PrestaShopAdminController y recibir las dependencias mediante inyección en el constructor o en la acción. El antiguo FrameworkBundleAdminController permanece como puente de compatibilidad obsoleto: su get() todavía puede resolver servicios públicos del contenedor global. No tomes ese puente como prueba de que la configuración de dependencias ya no necesite atención.
El siguiente ejemplo para PHP 8.1+ inyecta un servicio de contexto del núcleo registrado y protege una acción de lectura. Presupone que el autocargador de tu módulo asigna Acme\Compat\ a src/ y que una pestaña AdminAcmeCompat proporciona la correspondencia de permisos prevista.
<?php
namespace Acme\Compat\Controller;
use PrestaShop\PrestaShop\Core\Context\CurrencyContext;
use PrestaShopBundle\Controller\Admin\PrestaShopAdminController;
use PrestaShopBundle\Security\Attribute\AdminSecurity;
use Symfony\Component\HttpFoundation\Response;
final class CompatibilityController extends PrestaShopAdminController
{
private CurrencyContext $currencyContext;
public function __construct(CurrencyContext $currencyContext)
{
$this->currencyContext = $currencyContext;
}
#[AdminSecurity("is_granted('read', request.get('_legacy_controller'))")]
public function indexAction(): Response
{
return new Response($this->currencyContext->getIsoCode());
}
}
Registra el controlador como servicio y expón la ruta. Mantén la correspondencia de control de acceso alineada con la pestaña instalada. Usa el permiso de creación, actualización o eliminación adecuado para una acción que cambie el estado y añade protección CSRF. Que la inyección automática funcione en una instalación limpia no ejercita todas las combinaciones de tienda, así que prueba la ruta real, el descubrimiento de servicios y los argumentos de la acción en el conjunto de módulos del comerciante.
# config/services.yml
services:
Acme\Compat\Controller\CompatibilityController:
public: true
autowire: true
autoconfigure: true
tags: ['controller.service_arguments']
# config/routes.yml
acme_compat_index:
path: /acme-compat
methods: [GET]
defaults:
_controller: 'Acme\Compat\Controller\CompatibilityController::indexAction'
_legacy_controller: AdminAcmeCompat
Atributos, anotaciones y listeners de eventos
Migra individualmente las declaraciones de rutas, AdminSecurity y DemoRestricted. Los atributos de seguridad modernos utilizan PrestaShopBundle\Security\Attribute. La vía conservada de anotaciones de AdminSecurity sigue aplicándose en PrestaShop 9, aunque está obsoleta.
Prueba cada ruta sin iniciar sesión y con empleados con distintos permisos. Confirma que el acceso de lectura no conceda escritura. Verifica también las restricciones del modo demo y todas las rutas AJAX. Que una página se renderice correctamente no es una prueba de permisos.
- Abre la lista o el formulario reales con un empleado autorizado. Ejecuta un filtro, una exportación, una acción de fila, una operación AJAX y una acción masiva cuando el módulo las ofrezca.
- Repite las operaciones protegidas con un empleado que no tenga el permiso correspondiente. Confirma que la denegación deja los registros sin cambios; un botón oculto no es una prueba.
- Prueba cada protección por separado en el entorno de pruebas: datos no válidos con un token CSRF válido y después datos válidos con un token ausente o no válido. Prueba también un método HTTP no permitido. Comprueba la respuesta y confirma que cada escritura rechazada deja los registros sin cambios.
Puedes conservar los listeners de eventos etiquetados en YAML o utilizar el atributo AsEventListener de Symfony en un servicio registrado con configuración automática. Un atributo no registra una clase que no se haya descubierto por otra vía. Si utilizas getSubscribedServices() durante la migración, fusiona las suscripciones del padre y declara explícitamente los servicios necesarios.
Compatibilidad con dos generaciones de controladores
Si un módulo admite PS 8 y 9, una pequeña clase padre de compatibilidad puede elegir la clase disponible. Esto solo elige la herencia; no normaliza todas las diferencias de métodos o del contenedor de servicios.
<?php
namespace Acme\Compat\Controller;
if (class_exists('PrestaShopBundle\Controller\Admin\PrestaShopAdminController')) {
abstract class CompatibleAdminController extends \PrestaShopBundle\Controller\Admin\PrestaShopAdminController
{
}
} else {
abstract class CompatibleAdminController extends \PrestaShopBundle\Controller\Admin\FrameworkBundleAdminController
{
}
}Configura servicios, contexto y comandos de consola para la versión de destino
Configuración de servicios
En versiones anteriores a 9.2, conserva config/services.yml como punto de entrada de los servicios del módulo. Puede importar explícitamente configuración PHP. Mantener un services.php independiente a su lado no hace que los cargadores antiguos seleccionen ese archivo automáticamente.
# config/services.yml on an older target
imports:
- { resource: services.php }
En 9.2, la prioridad de archivos de servicio es services.php, después services-9.2.yml, después services-9.yml y finalmente services.yml. Trata el archivo seleccionado como punto de entrada e importa todo lo demás que necesite. La inyección automática sigue necesitando valores explícitos para los argumentos escalares y asociaciones explícitas cuando las interfaces tienen varias implementaciones.
Un YAML que funciona no necesita reescribirse en PHP por estética: consérvalo mientras el destino lo cargue y se resuelvan los servicios necesarios. Cambiar solo el formato no es una prueba de aceptación.
Revisa la decoración de servicios con el conjunto completo de módulos instalados. El orden de decoración, la visibilidad del servicio y la configuración de otro módulo pueden cambiar qué implementación recibe una llamada.
Contexto y autenticación de empleados
Context::getContext() sigue disponible. Prioriza los servicios de contexto inyectados para el código Symfony nuevo y establece el contexto de tienda, idioma, moneda y empleado que necesiten los comandos o procesos de trabajo.
Los servicios de contexto incluyen EmployeeContext, ShopContext, LanguageContext, CurrencyContext, CountryContext, ApiClientContext y LegacyControllerContext. Utiliza CurrencyContext::getId(), getIsoCode() o getConversionRate() para el valor que necesites. No existe CurrencyContext::getCurrency().
El back office usa Symfony Security para la autenticación de empleados. Lee la identidad del empleado mediante el contexto de empleado o el servicio de seguridad admitidos en lugar de tratar los campos de la cookie heredada como la autoridad de autenticación. EmployeeContext::getEmployee() puede devolver null, e inyectar un servicio de contexto no inicia la sesión de un empleado para un comando o proceso de trabajo. Usa RequestStack para los datos de sesión de tus propias solicitudes y gestiona la ausencia de solicitud o sesión fuera de la ejecución HTTP.
Kernels de consola
PrestaShop 9 tiene kernels de aplicación admin, admin-api y front. Inspecciona la lista de comandos y la ayuda de la consola instalada para la versión exacta, confirmando sus identificadores de aplicación y las opciones admitidas antes de usar los ejemplos siguientes. Comprueba tu comando y tus servicios en el kernel donde se ejecutan. No des por hecho que un comando registrado en una aplicación esté disponible en otra.
php bin/console list --app-id=admin
php bin/console debug:container 'Acme\Compat\Controller\CompatibilityController' --app-id=admin
php bin/console debug:event-dispatcher kernel.request --app-id=front
php bin/console debug:router --app-id=admin-api
Usa list, debug:container y la configuración de servicios para diagnosticar el descubrimiento. Registra los comandos de consola con la configuración de Symfony admitida para el kernel de destino. Inspecciona la definición de servicio y las etiquetas del comando en ese kernel, y ejecuta los comandos programados con el binario PHP CLI y la cuenta de ejecución que usa realmente el programador de tareas.
Ejemplo: la página de ajustes funciona, la exportación programada falla
Supón que la página de ajustes guarda correctamente, pero que la exportación carga por primera vez una biblioteca HTTP cuando se ejecuta una tarea programada. Prueba ese comando desde el paquete entregado con el PHP CLI y la cuenta de ejecución previstos, e inspecciona la disponibilidad y la configuración de la biblioteca y la respuesta externa. Una instalación correcta nunca ejercitó esa vía.
Compara después el contexto de tienda e idioma del comando con la solicitud de administración. Un proceso de trabajo no debe heredar sin avisar la última tienda que seleccionó un empleado. Confirma que lee los registros previstos y escribe en la cuenta remota prevista, y después reintenta una exportación fallida en el sandbox y comprueba si hay registros externos duplicados.
Comprueba hooks, datos del tema y endpoints enrutados
Hooks y migraciones de páginas
El sistema de hooks sigue disponible, pero cada hook ejecutado pertenece a una vía concreta de código. El editor de productos migrado ya no ejecuta los antiguos hooks de ciclo de vida actionAdminProductsController*. Se conservan algunos hooks heredados de inicio de sesión: actionAdminLoginControllerSetMedia para recursos y displayAdminLogin para HTML. Utiliza actionBackOfficeLoginForm y actionEmployeeRequestPasswordResetForm para ampliar esos formularios, eventos de Symfony Security para la lógica de autenticación y hooks modernos de formulario de producto para los campos de producto.
En las páginas de la tienda que utilicen presentadores, lee los datos presentados en lugar de asumir una estructura de objeto antigua. Los datos de imagen pueden ser ahora un array con URL específicas por tamaño, como $manufacturer.image.medium.url en Smarty. Prioriza el hook actionPresent* correspondiente para los cambios de datos cuando esté disponible.
Smarty, Twig y Hummingbird
PrestaShop utiliza ambos sistemas de plantillas. Los temas de la tienda y las páginas heredadas del back office utilizan Smarty. Las páginas Symfony migradas del back office utilizan Twig. El paso a Symfony no sustituyó a Smarty en toda la plataforma.
Hummingbird es el tema predeterminado de las instalaciones nuevas de 9.1; una actualización no sustituye automáticamente el tema existente de la tienda. Prueba Classic, Hummingbird y cada tema que anuncies, además del tema real del comerciante. Comprueba las fichas de producto, los cambios de combinación, el carrito, el proceso de compra, la cuenta del cliente, las ubicaciones de los hooks, los selectores y los eventos JavaScript. Las suposiciones sobre el marcado de un tema concreto pueden fallar aunque las API PHP sigan funcionando: un hook puede mostrar el texto correcto mientras el marcado distinto de un tema impide que un selector o un manejador de clics encuentre el control. Mantén visibles los errores del navegador en el entorno de pruebas protegido.
AJAX y notificaciones externas
Lleva los scripts ajax.php y callback.php de la raíz del módulo que se pueden llamar directamente al ciclo de vida de controladores admitido. Mientras no lo hagas, no des por hecho que un archivo así falle en PrestaShop 9 ni que sea seguro: inspecciona su autenticación, su contexto y su gestión de solicitudes. Un ModuleFrontController da a la solicitud una vía normal de enrutamiento y contexto. No autoriza automáticamente tu operación comercial.
Para un controlador AJAX heredado que exponga displayAjaxProcess(), activa el despacho AJAX además de elegir una acción. Una URL de módulo generada puede contener ajax=1 y action=process. En PrestaShop 9, una solicitud Accept: application/json también activa la detección AJAX. La presencia de action=process por sí sola no basta.
$url = $this->context->link->getModuleLink(
$this->name,
'ajax',
array('ajax' => 1, 'action' => 'process'),
true
);
Exige autenticación del cliente y comprobaciones de titularidad para los datos de clientes. Exige permisos de empleado y protección CSRF para las acciones de administración. Valida la firma del proveedor en los callbacks externos y aplica sus reglas de gestión de duplicados; cambiar la URL no establece confianza. Mantén las comprobaciones de token o firma en el servidor, usa los métodos HTTP adecuados y devuelve el estado y el tipo de contenido previstos.
Prueba los callbacks del proveedor con las herramientas de sandbox del propio proveedor: una verificación ausente o no válida, el evento válido normal y una entrega repetida. Un evento rechazado no debe realizar la operación comercial, y una repetición no debe duplicarla.
Durante la migración de un endpoint, coordina la nueva dirección con el servicio externo y pruébala antes del cambio definitivo. No dejes disponible la dirección anterior como alternativa sin documentar. Acuerda cómo llegan al endpoint correcto los eventos retrasados durante el despliegue y consérvalos para la conciliación sin dejar que modifiquen una base de datos migrada a medias.
Contratos de integración que siguen disponibles
La API Webservice heredada sigue disponible junto a la Admin API más reciente. Elige la API según sus recursos admitidos y su contrato de autenticación en lugar de sustituir una integración solo por su nombre, y verifica permisos, cargas útiles, identificadores y comportamiento de reintentos antes de cambiarla. El descriptor del módulo, Db::getInstance(), Configuration::get(), Configuration::updateValue() y ObjectModel siguen disponibles. Clases o métodos obsoletos concretos necesitan migraciones individuales; los ObjectModel de las entidades del núcleo no están obsoletos en bloque.
Consulta la guía de hooks, la guía de la API Webservice y la lista de comprobación de seguridad para el flujo completo de extensión, integración y refuerzo de la seguridad.
Controla los conflictos y el comportamiento específico de cada tienda
Prioriza los hooks, los servicios admitidos y la decoración de servicios cuando proporcionen el punto de extensión requerido. Evita editar archivos del núcleo. Los cambios directos en el núcleo dificultan la comparación de comportamientos, la aplicación de actualizaciones y la reproducción de un fallo.
Un override de clase normalmente extiende la clase Core instalada. Sus métodos heredados siguen procediendo de ese núcleo. La lógica copiada dentro de un método sobrescrito puede quedar desactualizada, y una firma incompatible puede fallar después de una actualización.
El instalador de módulos puede fusionar métodos, propiedades y constantes que no entren en conflicto en un override de clase existente. Dos módulos que extiendan Product no son automáticamente incompatibles. Los conflictos surgen cuando definen el mismo miembro o introducen un comportamiento incompatible. Documenta los miembros afectados y comprueba el override ensamblado y la caché del índice de clases después de los cambios.
Las excepciones deben ser visibles: un módulo puede incluir un override justificado de una clase PDF, por ejemplo. Pregunta qué cambia, cómo interactúa con otros módulos instalados, cómo se prueban las actualizaciones y qué elimina la desinstalación. La desinstalación puede conservar datos deliberadamente y no puede prometer deshacer todos los efectos externos.
Prueba el entorno además del número de versión:
- Comportamiento de reescritura de Apache, Nginx o LiteSpeed y permisos de archivos.
- Extensiones PHP necesarias, límites de memoria, OPcache y versiones de PHP de las tareas en segundo plano.
- Contextos de tienda única, grupo de tiendas y todas las tiendas, incluida la herencia de configuración.
- Grupos de clientes, precios de grupo, precios específicos, impuestos, monedas, idiomas y redondeo.
- Otros módulos que utilicen los mismos hooks, servicios, plantillas o miembros de clase.
- Archivos del núcleo modificados, temas personalizados y datos históricos de versiones anteriores del módulo.
Valida los datos entrantes de los hooks y los estados inesperados. Mantén las traducciones en la API apropiada. Cuando falte una capacidad, explica qué función no está disponible y cómo proceder. Las etiquetas, los valores predeterminados y los textos de ayuda claros reducen los errores de configuración.
Mantén ligero y mantenible el código de compatibilidad
Sal pronto de los hooks cuando la página actual no necesite tu función. Limita las hojas de estilo y JavaScript a los controladores que los utilizan. Un hook de cabecera puede ejecutarse en muchas páginas de la tienda, así que evita una consulta o un renderizado de plantilla innecesarios en cada solicitud.
Almacena en caché resultados de consulta reutilizables solo cuando la clave incluya todos los contextos relevantes de tienda, idioma, moneda y cliente. Inválidalos cuando cambien los datos subyacentes. La caché local de la solicitud y la caché persistente tienen duraciones distintas.
Mide la sobrecarga con datos representativos mediante un analizador de rendimiento. En un entorno de pruebas, _PS_DEBUG_PROFILING_ puede ayudar junto con el modo de desarrollo. Compara la misma ruta, estado de caché y datos antes y después del cambio. No existe una asignación universal de milisegundos por módulo que demuestre que una tienda será rápida.
Mantén la envoltura más pequeña que el problema que resuelve. Utiliza métodos claros, flujo de control normal y una alternativa bien definida. Las correcciones compartidas deben llegar a todos los módulos consumidores mediante una actualización controlada de dependencias y sus comprobaciones de publicación. Elimina deliberadamente las funciones no utilizadas y convierte las consultas recurrentes de soporte en mejor documentación o casos de prueba reproducibles.
Prueba el ZIP instalado y todas las vías de actualización anunciadas
Empieza con una instalación limpia para cada combinación de plataforma admitida, usando el ZIP entregado y no la copia de trabajo del desarrollador: las dependencias presentes solo en el equipo del desarrollador no demuestran que el comerciante reciba un módulo completo. Usa después una copia de pruebas con la forma de la tienda real: un tamaño de catálogo representativo, historial de pedidos, idiomas, tema y conjunto de módulos. Protege los datos de clientes y mantén separadas las credenciales de prueba de pagos, correo e integraciones. Aísla la copia antes de la primera ejecución de la aplicación, de un proceso de trabajo o de una tarea programada, con una base de datos independiente, credenciales de sandbox, un buzón de pruebas y un acceso externo controlado, para que las pruebas no puedan contactar con clientes reales ni preparar pedidos reales.
| Área | Ejecuta estas comprobaciones |
|---|---|
| Ciclo de vida del módulo | Instala el ZIP de la versión, activa, desactiva, restablece cuando se admita, actualiza desde las compilaciones antiguas anunciadas y desinstala. Inspecciona tablas, hooks, pestañas, valores predeterminados, permisos y datos conservados. |
| Administración moderna | Resuelve servicios y rutas; prueba cada acción con el modo de depuración activado y con permisos de empleado restringidos. |
| Administración heredada | Filtros de listas, acciones de fila, acciones masivas, ventanas modales, exportaciones, URL con token y respuestas AJAX. |
| Tienda | Salida de productos y listados, hooks, diseño adaptable, traducciones, páginas de cuenta y errores de la consola del navegador en cada tema admitido. |
| Proceso de compra | Pedidos de invitados y cuentas, descuentos, precios por impuestos y grupos, notificaciones de pago y todos los flujos de transportistas admitidos. Incluye el proceso de compra en una página de 9.2 cuando sea tu destino. |
| Integraciones | Autenticación de Webservice o API Admin, exportaciones, tareas, reintentos, tiempos de espera y respuestas de error. |
| Correo | Todas las vías de mensajes, ajustes del relay, plantillas, destinatarios, encabezados y adjuntos. |
| Diagnóstico | Advertencias de PHP, avisos de obsolescencia, errores de aplicación, consultas lentas, errores del contenedor y registros ocultos en modo de producción. |
Mantén PS 9.0 o 9.1 en la matriz mientras anuncies su compatibilidad. Añade explícitamente las versiones posteriores. En 9.1, revisa los indicadores de funciones de descuentos y envíos múltiples instalados, los hooks de ciclo de vida y configuración y las operaciones CLI. En 9.2, incluye la selección del archivo de servicios y el contrato del proceso de compra en una página. Utiliza los cambios de 9.0, los cambios de 9.1 y los cambios de 9.2 para identificar las comprobaciones específicas de cada versión.
- Haz un inventario de los controladores, dependencias, hooks, tareas, endpoints y suposiciones de plantillas del módulo.
- Corrige las API eliminadas y la responsabilidad sobre las dependencias, y después migra los servicios de controlador y los controles de acceso.
- Verifica los resultados tanto de la instalación nueva como de la actualización del módulo. No des por hecho que lleguen al mismo estado.
- Ejercita las vías de código diferidas, incluidas las tareas programadas, las acciones masivas y los correos.
- Repite el flujo pertinente con el tema real y los demás módulos instalados.
- Publica las versiones exactas probadas, las limitaciones y las instrucciones de reversión con la versión.
Haz que cada prueba sea reproducible
Usa la misma hoja de trabajo para el destino del comerciante y para los entornos antiguos que sigues admitiendo. Registra estos campos en el informe de pruebas:
- Entorno: versiones exactas de PrestaShop y PHP, tema, contexto de tienda, dependencias relevantes y fecha.
- Paquete: versión del módulo y paquete distribuible exacto probado, con la versión de origen del módulo si se trata de una actualización.
- Datos iniciales: ajustes y registros guardados representativos, idiomas, monedas y perfil del empleado.
- Acción y resultado esperado: la tarea del cliente o del personal y su resultado comercial previsto.
- Observación: resultado correcto o fallo, registros o capturas relacionados, limitación conocida y responsable.
Ejemplo: conservar los ajustes del comerciante al actualizar un módulo
Usa un conjunto de datos de pruebas con ajustes editados por el comerciante, registros del módulo y las asociaciones de tiendas pertinentes. Guarda los valores importantes antes de ejecutar la actualización admitida. Después, compara el esquema, los hooks, las pestañas y los permisos previstos con el diseño de destino y confirma que las opciones existentes y los registros vinculados se han conservado. Una instalación nueva puede establecer nuevos valores predeterminados; una actualización no debe sobrescribir las opciones válidas de un comerciante solo para que coincidan con esos valores.
No restablezcas ni desinstales un módulo para que una prueba de actualización salga bien: eso puede eliminar precisamente los datos que la actualización debe conservar.
Despliega con un plan de vuelta atrás
No sustituyas una ejecución completa de pruebas por una declaración amplia de compatibilidad. Antes del despliegue, conserva una compilación anterior del módulo instalable y una copia coherente de la base de datos y los archivos. Antes de cambios de esquema, eliminaciones o sustituciones, restaura esa copia en pruebas y ensaya la reversión, y verifica después los recorridos necesarios de clientes y personal tanto tras restaurar como tras actualizar.
Acuerda la ventana de despliegue, el motivo que desencadena la reversión y cómo conciliar los pedidos o las escrituras externas aceptados después de la instantánea. Despliega el paquete probado, repite las comprobaciones esenciales, vigila los ciclos programados y de negocio pertinentes y confirma que la salida de depuración pública está desactivada. Entrega el paquete, el código fuente, las notas de dependencias y configuración, los resultados de las pruebas y el procedimiento de recuperación.
Qué preguntar al desarrollador antes de dar el visto bueno
- ¿Qué entornos exactos y actualizaciones con datos existentes superaron las pruebas y cuáles siguen sin probarse?
- ¿Qué hallazgos eran incompatibilidades reales y qué cambios eran mantenimiento opcional?
- ¿Qué ajustes del cliente y registros del módulo se compararon antes y después de actualizar?
- ¿Puede otro desarrollador compilar y desplegar el paquete entregado a partir de su código fuente documentado?
- ¿Quién se encarga de coordinar a los proveedores, los fallos de despliegue y la conciliación tras una reversión?
Si un cambio falla, conserva las pruebas y usa la guía de resolución de problemas para aislar la vía que falla antes de aplicar más migraciones u otro cambio en producción.