⚠️ Breaking Changes en PrestaShop 9.1
Esta guia documenta TODOS los breaking changes entre PS 8.x y PS 9.1. Revisa cada seccion antes de actualizar modulos o temas.
#Resumen de cambios criticos
PrestaShop 9.1 introduce cambios significativos en la arquitectura del core. A diferencia de la transicion 1.7→8.0 (relativamente suave), PS 9 marca una ruptura real con el legacy. Los cambios principales son:
#Soporte PHP 8.5
PHP 8.5 pasa a ser la version recomendada. PHP 8.1, 8.2, 8.3 y 8.4 siguen soportados. Revisa que tu modulo no use funciones eliminadas o deprecadas en PHP 8.5.
// En tu modulo, verifica la version de PHP si necesitas
if (PHP_VERSION_ID < 80100) {
throw new PrestaShopException('Este modulo requiere PHP 8.1 o superior');
}
// Nuevas features de PHP 8.5 que puedes usar:
// - pipe operator |>
// - Closures in const expressions
// - Asymmetric visibility (readonly promoted props)
#Symfony 6.4 — Cambios clave
PrestaShop 9 usa Symfony 6.4 LTS. El cambio mas importante para los modulos es que $this->get() esta deprecated en los controladores. Debes usar constructor injection.
// ANTES (PS 8) — funciona pero deprecated en PS 9
class MyAdminController extends FrameworkBundleAdminController
{
public function indexAction()
{
$formHandler = $this->get('my_module.form.handler');
$twig = $this->get('twig');
// ...
}
}
// AHORA (PS 9) — usar constructor injection
class MyAdminController extends FrameworkBundleAdminController
{
public function __construct(
private readonly FormHandlerInterface $formHandler,
private readonly Environment $twig,
) {
parent::__construct();
}
public function indexAction()
{
$form = $this->formHandler->getForm();
// ...
}
}
Si tu modulo debe funcionar en PS 8 Y PS 9, puedes usar un patron hibrido: constructor injection con fallback a $this->get() si el servicio no se inyecto.
#Theme::getDefaultTheme() ya no devuelve 'classic'
En PS 8, Theme::getDefaultTheme() siempre devolvia 'classic' hardcodeado. En PS 9.1 devuelve el tema por defecto configurado en la tienda. Si tu modulo asumia que el tema era 'classic', debes actualizar tu logica.
// ❌ ANTES — asumir que siempre es 'classic'
if (Theme::getDefaultTheme() === 'classic') {
// logica especifica...
}
// ✅ AHORA — comparar contra el tema activo
$currentTheme = $this->context->shop->theme_name;
if ($currentTheme === 'hummingbird') {
// Logica para Hummingbird (Bootstrap 5, Twig-ready)
} else {
// Logica para Classic u otros temas
}
#Actualizacion D3 y NVD3
Las librerias de graficas D3 y NVD3 se actualizaron a versiones mas recientes. Si tu modulo crea widgets de dashboard con estas librerias, necesitas verificar la compatibilidad. Los cambios principales afectan a la API de selectores y transiciones.
#jQuery deprecated — ruta a PS 10
jQuery esta oficialmente deprecated en PrestaShop 9. Sera eliminado completamente en PrestaShop 10. Migra tu codigo JavaScript a vanilla JS o usa los nuevos eventos nativos de PrestaShop.
// ❌ ANTES (jQuery)
$(document).ready(function() {
$('.add-to-cart').on('click', function() {
$.ajax({
url: prestashop.urls.base_url + 'module/mymodule/ajax',
type: 'POST',
data: { action: 'add', id_product: $(this).data('id') },
success: function(response) {
prestashop.emit('updateCart', { reason: response });
}
});
});
});
// ✅ AHORA (Vanilla JS + eventos PS nativos)
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('[data-ps-action="add-to-cart"]').forEach(btn => {
btn.addEventListener('click', async (e) => {
const response = await fetch(
`${prestashop.urls.base_url}module/mymodule/ajax`,
{
method: 'POST',
body: JSON.stringify({ action: 'add', id_product: btn.dataset.psRef }),
headers: { 'Content-Type': 'application/json' }
}
);
const data = await response.json();
prestashop.emit('updateCart', { reason: data });
});
});
});
#Bootstrap 5.3.3 en Hummingbird
El tema Hummingbird de PS 9 usa Bootstrap 5.3.3 (vs 4.0.0-alpha.5 en Classic). Esto implica renombramiento masivo de clases CSS:
| Bootstrap 4 (Classic) | Bootstrap 5 (Hummingbird) | Notas |
|---|---|---|
| .ml-, .mr- | .ms-, .me- | margin-start / margin-end (RTL-ready) |
| .pl-, .pr- | .ps-, .pe- | padding-start / padding-end |
| .btn-block | .d-grid > .btn | Ya no es clase directa del boton |
| .close | .btn-close | Componente dedicado |
| .custom-control | .form-check | Checkboxes y radios unificados |
| .custom-switch | .form-check .form-switch | Switch es modificador |
| .float-left / .float-right | .float-start / .float-end | Logico para RTL |
| data-toggle | data-bs-toggle | Prefijo bs- obligatorio |
| data-target | data-bs-target | Prefijo bs- obligatorio |
| data-dismiss | data-bs-dismiss | Prefijo bs- obligatorio |
| .badge-pill | .rounded-pill | Ya no es clase de badge |
| .card-deck | .row > .col > .card | Grid nativo |
| .media | Eliminado — usar flexbox | Sin reemplazo directo |
Si tu modulo inyecta HTML en el front con clases Bootstrap 4, se rompera visualmente en tiendas con Hummingbird. Debes detectar el tema activo y usar las clases correspondientes.
#Nuevos atributos data-ps-*
PrestaShop 9 introduce una nueva convencion para selectores JavaScript: en lugar de clases CSS o IDs, usa atributos data-ps-*:
<!-- ❌ PS 8 — selectores CSS -->
<button class="add-to-cart js-add-to-cart" data-id="42">
<!-- ✅ PS 9 — atributos data-ps-* -->
<button data-ps-action="add-to-cart" data-ps-ref="42">
#$this->get() deprecated en controladores
Symfony 6.4 depreca el Service Locator en controladores. En PS 9, usa dependency injection via constructor. Esto aplica tanto a controladores admin como a servicios.
services:
MyModule\Controller\AdminMyController:
arguments:
$formHandler: '@my_module.form.handler'
$translator: '@translator'
$entityManager: '@doctrine.orm.entity_manager'
tags:
- { name: 'controller.service_arguments' }
Evita Context::getContext() dentro de servicios. En PS 9, inyecta los datos que necesites via constructor o usa los servicios de PrestaShop que proveen esa informacion (ej: prestashop.adapter.legacy.context).
#Guia de migracion 8.x → 9.1
Checklist para migrar un modulo de PS 8 a PS 9.1: