Buenas practicas para modulos PrestaShop
Actualizado: 2024-12-01
Desarrollar modulos de calidad para PrestaShop requiere seguir una serie de buenas practicas que garantizan seguridad, rendimiento y compatibilidad. Esta guia resume los puntos mas importantes del desarrollo profesional de modulos.
#Seguridad obligatoria
Reglas de seguridad en todos los archivos PHP
php
<?php
// 1. OBLIGATORIO en todos los archivos PHP del modulo
if (!defined('_PS_VERSION_')) { exit; }
// 2. Sanitizar SIEMPRE las entradas del usuario
$name = pSQL(Tools::getValue('name', '')); // escape para SQL
$idItem = (int) Tools::getValue('id_item', 0); // cast a int
$html = Tools::purifyHTML(Tools::getValue('desc')); // sanitizar HTML
$text = htmlspecialchars(Tools::getValue('text')); // escape HTML
// 3. Usar siempre parametros preparados o escape de DB
Db::getInstance()->insert('mytable', [
'name' => pSQL($name), // BIEN
'price' => (float) $price, // BIEN
]);
// MAL — vulnerable a SQL injection:
// Db::getInstance()->execute('SELECT * FROM mytable WHERE name = \'' . $_GET['name'] . '\'');
// BIEN — con escape:
Db::getInstance()->execute(
'SELECT * FROM `' . _DB_PREFIX_ . 'mytable`
WHERE name = \'' . pSQL($_GET['name']) . '\''
);
// 4. Verificar tokens en formularios del BO
if (Tools::isSubmit('submitMyForm') && !Tools::checkToken()) {
die('Invalid token');
}
// 5. Permisos en AdminControllers
public function initContent(): void
{
if (!$this->access('view')) {
Tools::redirectAdmin(self::$currentIndex . '&token=' . $this->token);
}
}
#Rendimiento
| Practica | Impacto | Como implementar |
|---|---|---|
| Cachear queries pesadas | Alto | Cache::getInstance()->remember() |
| Usar indices en columnas de busqueda | Alto | ADD INDEX en install() |
| Evitar N+1 queries en hooks | Alto | Una sola query con JOIN |
| Cargar CSS/JS solo cuando se necesitan | Medio | Verificar $controller->php_self |
| Usar LazyLoad en imagenes del modulo | Medio | loading='lazy' en |
| No hacer peticiones HTTP en hooks sync | Alto | Usar jobs/cron en lugar de peticiones en hooks |
#Instalacion y desinstalacion limpias
install() y uninstall() completos y limpios
php
<?php
public function install(): bool
{
// Orden: padre primero, luego tabla, luego hooks
return parent::install()
&& $this->createTable()
&& $this->registerHook('displayHeader')
&& $this->registerHook('actionOrderStatusUpdate');
}
public function uninstall(): bool
{
// Limpiar TODO lo creado por el modulo
return $this->dropTable()
&& $this->cleanConfiguration()
&& parent::uninstall();
}
private function createTable(): bool
{
return Db::getInstance()->execute(
'CREATE TABLE IF NOT EXISTS `' . _DB_PREFIX_ . 'mymodule_data` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`value` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=' . _MYSQL_ENGINE_ . ' DEFAULT CHARSET=utf8mb4'
);
}
private function dropTable(): bool
{
return Db::getInstance()->execute(
'DROP TABLE IF EXISTS `' . _DB_PREFIX_ . 'mymodule_data`'
);
}
private function cleanConfiguration(): bool
{
$keys = ['MYMODULE_KEY1', 'MYMODULE_KEY2', 'MYMODULE_KEY3'];
foreach ($keys as $key) {
Configuration::deleteByName($key);
}
return true;
}
#Convencion de nombres
| Elemento | Convencion | Ejemplo |
|---|---|---|
| Nombre del modulo | lowercase, sin guiones, < 32 chars | mymodule, ecompayments |
| Clases PHP | PascalCase | MyModule, MyModuleItem |
| Metodos PHP | camelCase | getOrderTotal, processPayment |
| Claves Configuration | MAYUSCULAS_CON_NOMBRE_MODULO | MYMODULE_API_KEY |
| Tablas DB | prefijo_modulo_entidad | ps_mymodule_orders |
| Hooks registrados | camelCase del nombre del hook | hookDisplayHeader |
| Archivos de modulo | snake_case o kebab-case | my_module_item.php |
| IDs de CSS/JS | kebab-case con prefijo modulo | mymodule-main-style |
#Checklist antes de publicar
| Item | Verificacion |
|---|---|
| Seguridad | if (!defined('_PS_VERSION_')) en todos los PHP |
| SQL | pSQL() en todas las entradas, (int) en IDs |
| XSS | htmlspecialchars() o escape:'html' en templates |
| Instalacion | install() devuelve false correctamente en errores |
| Desinstalacion | uninstall() limpia TODOS los datos del modulo |
| Upgrade | Scripts en upgrade/ para cada cambio de schema |
| Traducciones | Todas las strings en trans() o l() |
| Compatibilidad | Probado en PS 8.x y PHP 8.1+ |
| Rendimiento | Queries con indices, sin N+1 |
| index.php | Archivo de seguridad en todos los subdirectorios |
Descargar en Markdown
Pensado para pegar en ChatGPT, Claude u otra IA. Incluye solo el contenido de esta pagina.