Prestashop – Análisis técnico

Esta historia empieza porque llevo unos días intentado montar una API pública en Ulabox, que a la larga servirá para servir la web, comunicarse con el backoffice, aplicaciones de Iphone, Android, etc…

La verdad es que Symfony2 me simplifica mucho la vida, pero nuestra base de datos actual sigue estando basada en Prestashop y aún hay mucha acción de Modelos que sigue funcionando con las funciones de esta plataforma y la API tiene que usar estos métodos para ser coherente con el sistema actual. Y la verdad es que Prestashop es un absoluto desastre a nivel programación y arquitectura técnica.

Dies all around

Estamos en 2011. Pero el mundillo PHP todavía arrastra miserias de hace 7 años, cuando no había PHP5, no había excepciones y lo único que se podía hacer era sobreescribir la función trigger_error o hacer dies para terminar nuestros scripts ante algún error. Eso valía en aquellos tiempos donde las páginas web eran un simple catálogo, un área de noticias y la cutre zona de administración, pero actualmente hacer dies ante un error de BBDD es un suicidio.

Y algunos diréis, pero y por qué? Si WordPress, Drupal, PHPBB y muchos libros de PHP avanzado dicen que esa es la manera correcta! Pues bien, ese es el gran mal de la comunidad PHP. Mucha gente aprende a programar webs en PHP cogiendo el código de estas plataformas que están en todas partes o leyendo algún libro de apoyo. Y todo esto está mal! Aún hay libros de PHP5.3 que rezan:

<?php
 if(!$db = @mysql_connect('localhost', 'root', ''))
   die('Error conectando a BBDD');
?>

Esto funciona correctamente, pero cuando tenemos todo un Prestashop, esto está en las profundidades del ObjectModel.php, al cual se llama desde todas partes y nuestro cliente, que quiere que gastar un dineral en nuestro gran e-commerce, verá por pantalla este fantástico error que tan poca confianza da al dar un número de VISA.

No solo eso, un die da un HTTP Status: 200 OK. Vamos que para Google, el nuevo contenido de nuestro catálogo de productos es este texto y así nos indexará mientras no se levante la BBDD.

Es muchísimo mejor ante este tipo de errores hacer un throw new Exception(‘Error BBDD’, 500); y en nuestro bootstrap recoger estos errores (400, 403, 500, etc…) y lanzar el header correspondiente para que Google no lo interprete como un 200. Otra cosa que me gusta hacer es que ante un error 500, que se suele asociar a sistema, es una buena práctica grabar en logs y/o enviar un mail al administrador del sistema, informando de lo que ha pasado y en qué condiciones.

Quedaría algo así:

<?php
// En el ObjectModel.php o Mysql.php (y lo mismo en las querys, etc...)
 if(!$db = @mysql_connect('localhost', 'root', ''))
   throw new Exception('Error conectando a BBDD', 500);
 
// Y el bootstrap, algo como
try {
  // Aquí irían el autoload, el bootstrapping, 
  // la carga de clases y el proceso MVC
} catch(Exception $ex) {
 
    switch ($ex->getCode()) {
        case 403:
            header('HTTP/1.0 403 Forbidden');
            echo '<h2>Access denied</h2>';
            break;
        case 404:
            header('HTTP/1.0 404 Not Found');
            // Aquí podríamos displayar una de esas páginas molonas de 404
            // De hecho esto se hace en Prestashop en el archivo 404.php
            break;
        case 400:
            header('HTTP/1.0 400 Bad Request');
            // Aquí ya depende... normalmente esto son parámetros mal enviados pero puede ser un
            // intento de SQL Injection, XSS, ... podéis enviar un mail al admin con el contenido
            // de $_SERVER, $_POST y $_GET por si las moscas
            break;
        case 500:
            header('HTTP/1.1 500 Internal Server Error');
            // Esto puede ser un error motivado por muchas causas, conveniente avisar de alguna manera
            // como comento en el punto anterior
            break;
        default:
            header('HTTP/1.1 500 Internal Server Error');
            // Como lo anterior
            break;
    }
}
 
?>

Uso de variables global

Con lo poco que cuesta hacer un objeto con variables de sistema y tenerlo todo ahí controlado… pues no global $errors que me traigo la variable y ale… a funcionar! Ojalá algún día se considere la instrucción global algo DEPRECATED

¿Transacciones?

El engine por defecto al instalar Prestashop con MySQL es InnoDB. Y el encoding UTF-8. Algo hemos avanzado respecto a épocas más oscuras. Pero claro, tenemos InnoDB y no usamos las transacciones! Ni se hace START TRANSACTION, ni COMMIT / ROLLBACK… que es un e-commerce! Que mueve dinero!

Y si peta la vuelta de Sermepa o Paypal a medio proceso? El cliente ha pagado pero no nos hemos enterado! Y se generan pedidos fantasma y este tipo de cosas tan chulas que hacen tener que cuadrar a mano los pagos con las múltiples plataformas de pago.

Validate

La idea de tener una clase estática para las validaciones, en sí no es mala, pero hay muchas expresiones regulares incorrectas o cuanto menos, no 100% rigurosas con las Specs. Además, desde PHP 5.2 existe filter_var que nos soporta la mayoría de cosas que se comprueban a mano. Tambén tenemos las funciones ctype_* para muchas cosas… pues no, expresion regular a mano, y encima no del todo fina (por ejemplo la de los mails)

Acoplamiento total de Smarty

Smarty2 ha servido muy bien a la comunidad desde hace muchos años. Pero se ha hecho mayor. Hay muchos engines de templating nuevos, mucho mejores y más rápidos (Twig, Smarty3). No es que sea muy grave y seguro que con un poco de tunning se puede adaptar. Bien es cierto que si quieres dar una solución cerrada hay que escoger uno y Smarty v2 sigue siendo el más usado.

Todo es public en los objetos

Esto puede ser cómodo, pero desde el punto de vista de la programación orientada a objetos, solo debe ser público aquello que sea necesario… y el resto funciones protected/private solo accedidas desde donde toca. Se usan clases, sí, pero muy a lo PHP4.

Y podríamos seguir y seguir…

Ideas finales

Hay quien dice que criticar a Prestashop es solo una opinión. Hay quien dice que todo esto son detalles. Y bien es cierto que hay cosas mucho más graves que otras.

Pero para mí es una vergüenza que un e-commerce no use transacciones y control de errores. Una cosa es un sistema de foros, un blog personal… pero una tienda, que mueve dinero, donde la gente pone sus visas y sus ahorros debe estar bien hecha. Por lo menos el sistema de pagos, control de stocks, etc… y esto sin transacciones y con dies sencillamente no es así.

Como punto positivo, es cierto que Prestashop te lo descargas y con un poco de tunning que te puede hacer cualquier empresilla puedes tener una tienda bastante digna. Y si es solo un añadido a una tienda física, o no vas a tener nunca más de 10 pedidos al día, etc… puede valer ya que no vas a invertir 10mil euros en construir algo mínimamente decente.

También es cierto que si eres una Startup, necesitas inversores. Y si necesitas inversores, deben creer en el proyecto. Y para creer, tienes que poder vender, mientras no puedes vender no eres más que humo. Por tanto, no es una mala solución arrancar con un Prestashop tuneadito mientras buscas inversión, y empiezas a hacer la plataforma de verdad.

Pero si la tienda crece, tienes un problema. De escalabilidad, de transaccionalidad y de control de tus datos. Y en ese momento tienes una deuda técnica muy grande ya que no es fácil huir de Prestashop a algo bien hecho.

Mucha gente se dedica a tunear estas plataformas cambiando los CSS, haciendo algún modulito y todo va bien, son expertos en maquillar Prestashop. Pero nadie se mira las tripas, que es donde está realmente el negocio, y ahí es donde Prestashop y todas estas plataformas prefabricadas son un desastre.

You may also like...