En ocasiones nos toca modificar archivos nativos de PrestaShop porque necesitamos funcionalidades a medida o porque somos capaces de resolver algún pequeño bug que hemos encontrado en el sistema. El problema es que al realizar estas modificaciones directamente tocamos el Core de PrestaShop, algo que es totalmente desaconsejado y que, además, si actualizamos PrestaShop perdemos todos estos cambios realizados.
Para realizar estas modificaciones con seguridad y de manera correcta PrestaShop nos proporciona una herramienta para hacer overrides sobre sus principales archivos, o lo que es lo mismo, sustituir o sobrescribir el código o parte del código de una función por nuestro código a medida.
En muchos foros o servicios de soporte encontrarás cosas como: «Eso se soluciona haciendo un override sobre la función tal de la clase tal» o «Sobrescribe tal función» ¿Te suena a chino? Pues bien, a continuación te facilitamos un pequeño tutorial para que puedas hacer de manera correcta y con seguridad tus overrides o sobrescrituras.
1. Archivos que puedo sobrescribir
Lo primero que tenemos que tener en cuenta es conocer cuales son los archivos sobre los que podemos hacer un override: Son todos los archivos php incluidos en las siguientes carpetas:
- Classes: Todos los archivos .php contenidos en la carpeta principal y en todas su subcarpetas.
- Controllers/Admin: Todos los archivos .php contenidos en la carpeta principal y en todas su subcarpetas.
- Controllers/Front: Todos los archivos .php contenidos en la carpeta principal y en todas su subcarpetas.
- Modules: Solo se puede hacer override sobre las funciones del archivo principal del módulo, por ejemplo en modules/redsys solo podrás hacer override sobre redsys.php
Pongamos un ejemplo: Necesito que cuando consulto las provincias de un país, PrestaShop me devuelva las mismas ordenadas alfabéticamente.
En este caso tendré que sobrescribir la clase State (classes/State.php) porque es la encargada de realizar la consulta a la base de datos para obtener las provincias de un país, la declaración original de la clase es la siguiente:
class StateCore extends ObjectModel
Concretamente tenemos que hacer override sobre su función: getStatesByIdCountry declarada de la siguiente manera:
public static function getStatesByIdCountry($idCountry)
{
if (empty($idCountry)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT *
FROM `'._DB_PREFIX_.'state` s
WHERE s.`id_country` = '.(int) $idCountry
);
}
2. La carpeta override
Los overrides son archivos .php que se guardarán dentro de la carpeta override siguiendo la estructura de las carpetas classes, controllers y modules de PrestaShop, es decir:
- override
- classes
- controllers
- admin
- front
- modules
- carpetas de modulos
3. Creación del archivo override
Para realizar un override, tenemos que llamar al archivo php exactamente igual que el archivo original que queremos modificar y además debe de estar en su ruta concreta y correcta dentro de la carpeta override.
Siguiendo con el ejemplo anterior crearemos un nuevo archivo php llamado State.php dentro de la carpeta override en la siguiente ubicación: override/classes/State.php (el original se encuentra en classes/State.php)
4. Declaración de la clase
Veremos que el nombre de la clase de archivo original del que queremos hacer override es algo asi:
class ******Core
Es decir, el nombre del Objeto o de la case en cuestión más la palabra Core. En la declaración de nuestro archivo tendremos que utilizar el nombre del objeto y heredar funciones y atributos de la clase (Core) con el nombre original del archivo PrestaShop, lo vemos mejor siguiendo nuestro ejemplo:
El archivo State.php original situado en Classes/State.php tiene el siguiente nombre de clase:
class StateCore extends ObjectModel
Donde entendemos que:
- State – Es el nombre del objecto o de clase
- Core – Nos Indica que es un archivo del core de PrestaShop
- extends ObjectModel – Además hereda atributos y propiedades de la clase ObjectModel
Nuestra clase entonces en el archivo override/classes/State.php deberá declararse de la siguiente manera:
class State extends StateCore
En el caso de hacer override sobre un módulo la declaración de la clase se hará de la misma manera: colocando el archivo php dentro de la carpeta del modulo en override/modules. Por ejemplo: override/modules/redsys/redsys.php. Pero en este caso la declaración del nombre de la clase varia: tenemos que extender o heredar del nombre original del módulo y al nombre de la clase del override añadirle la palabra override. Lo vemos mejor con un ejemplo:
class Ps_ImageSliderOverride extends Ps_ImageSlider
5. Modificar la función
El siguiente paso es modificar las funciones o propiedades de la clase que deseamos cambiar, para ello definiremos en nuestro archivo el nombre de la función exactamente igual que en su archivo padre u orignal, con todos sus parámetros, definiciones etc. y modificaremos el código por el que necesitemos, podemos modificar tantas funciones como necesitemos. Veamos el ejemplo:
Esta es la función original de la clase State.php
public static function getStatesByIdCountry($idCountry)
{
if (empty($idCountry)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT *
FROM `'._DB_PREFIX_.'state` s
WHERE s.`id_country` = '.(int) $idCountry
);
}
En nuestro archivo sobrescrito hemos modificado la función para obtener el resultado ordenado por name:
public static function getStatesByIdCountry($idCountry)
{
if (empty($idCountry)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT *
FROM `'._DB_PREFIX_.'state` s
WHERE s.`id_country` = '.(int) $idCountry. ' ORDER BY name'
);
}
Este sería el contenido del archivo del override situado en override/classes/State.php
class State extends StateCore
{
/**
* Get states by Country ID
*
* @param int $idCountry Country ID
*
* @return array|false|mysqli_result|null|PDOStatement|resource
*/
public static function getStatesByIdCountry($idCountry)
{
if (empty($idCountry)) {
die(Tools::displayError());
}
return Db::getInstance()->executeS('
SELECT *
FROM `'._DB_PREFIX_.'state` s
WHERE s.`id_country` = '.(int) $idCountry. ' ORDER BY name'
);
}
}
Trucos y consideraciones finales
En algunas ocasiones, para que los overrides funcionen y hagan su efecto, tendrás que borrar el caché desde opciones avanzadas -> rendimiento. Además, en versiones PS 1.5 y PS 1.6 puede que tengas que borrar el archivo caches/class_index.php para que se vuelva a generar el mismo con la nueva estructura de clases del sistema.
Siempre que puedas intenta modificar el mínimo de código posible de la función y apóyate en el código de la clase padre a través de parent::nombre_de_funcion().
Asegúrate que desde opciones avanzadas -> rendimiento están permitidos los overrides para poder realizar los mismos.
Con esto y más ¡tu tienda online siempre preparada!
Magnifico artículo, se me ha quedado bastante claro el concepto. Muchas gracias.
Gracias Javier. Esperamos que te sirva de ayuda :)