Mostrar la calificación de los productos y número de comentarios en la lista de productos de Prestashop 1.5

15 marzo, 2015 |

Si te gusta, compártelo ;)

Mostrar la calificación de un producto en el listado de productos de Prestashop
Independientemente de lo que vendamos, es una buena práctica poseer en nuestra tienda un sistema de calificación de productos, a fin de que nuestros clientes puedan opinar sobre los productos que vendamos, lo que a su vez sería útil para orientar en sus decisiones a potenciales clientes de nuestra tienda.
Prestashop 1.5 incorpora por defecto un módulo llamado "Comentario sobre el producto", el cual permite a los clientes opinar sobre los productos y calificarlos; pero este módulo solo muestra las calificaciones en la "Página de producto". Por lo tanto, vamos a dotar a Prestashop de una nueva funcionalidad; aprenderemos a mostrar la calificación de los productos y el número de comentarios en la lista de productos de Prestashop.

Versión usada: Prestashop 1.5.5.0
Módulo "Comentario sobre el producto": Versión: 2.3

Lo que vamos a hacer...
A modo de avance veamos lo que vamos a hacer.
  1. Insertaremos una línea en productcomments.php para registrar un nuevo hook.
  2. Agregaremos el hook en el archivo product-list.tpl de nuestra plantilla.
  3. Crearemos una función en productcomments.php. Ésta es la que hará el trabajo principal.
  4. Crearemos una plantilla que será la que muestre el trabajo de la función, es decir, la calificación media del producto en el listado de productos.
El resultado será este:
Mostrar la calificación de los productos en la lista de productos de Prestashop
Comencemos...
Para mostrar la calificación media (las estrellitas) y el número de comentarios de un producto en el listado de productos de Prestashop necesitaremos crear un nuevo hook. Por lo tanto, busquemos y abramos el archivo ../prestashop/modules/productcomments/productcomments.php
Una vez abierto el archivo busquemos la función install, y añadamos esta línea...
!$this->registerHook('productInList') ||
... a la función de forma que quede así:
public function install()
 {
  if (!file_exists(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
   return false;
  else if (!$sql = file_get_contents(dirname(__FILE__).'/'.self::INSTALL_SQL_FILE))
   return false;
  $sql = str_replace(array('PREFIX_', 'ENGINE_TYPE'), array(_DB_PREFIX_, _MYSQL_ENGINE_), $sql);
  $sql = preg_split("/;\s*[\r\n]+/", trim($sql));

  foreach ($sql as $query)
   if (!Db::getInstance()->execute(trim($query)))
    return false;
  if (parent::install() == false ||
   !$this->registerHook('productTab') ||
   !$this->registerHook('extraProductComparison') ||
   !$this->registerHook('productTabContent') ||
   !$this->registerHook('header') ||
   !$this->registerHook('productOutOfStock') ||
   !$this->registerHook('productInList') ||
   !Configuration::updateValue('PRODUCT_COMMENTS_MINIMAL_TIME', 30) ||
   !Configuration::updateValue('PRODUCT_COMMENTS_ALLOW_GUESTS', 0) ||
   !Configuration::updateValue('PRODUCT_COMMENTS_MODERATE', 1))
    return false;
  return true;
 }
    
Con esta línea lograremos que el módulo se registre en el hook que hemos creado, pero para que pueda registrarse, debemos reiniciar el módulo en nuestro Back-office desde la lista de módulos.
Reiniciar el módulo de comentarios sobre el producto de Prestashop
Una vez reiniciado, simulando que somos un usuario de nuestra tienda, hagamos un calificación de dos o tres productos para ir preparando el terreno. Démosle a cada producto una calificación diferente. Hecho esto, verifiquemos que el módulo funciona bien comprobando si el comentario ha aparecido en la "Página de Producto"
Agregar el hook a la plantilla product-list.tpl
Abramos el archivo product-list.tpl, ubicado en ../prestashop/themes/nuestro_tema. Vamos a hacerlo con la plantilla por defecto.
Busquemos esta etiqueta <h3> en el código; no importa que no coincida con la de nuestra plantilla, solo hay una etiqueta <h3> en el código:
<h3>{if isset($product.pack_quantity) && $product.pack_quantity}{$product.pack_quantity|intval|cat:' x '}{/if}<a href="{$product.link|escape:'htmlall':'UTF-8'}" title="{$product.name|escape:'htmlall':'UTF-8'}">{$product.name|truncate:35:'...'|escape:'htmlall':'UTF-8'}</a></h3>
Después de esta etiqueta debemos añadir la siguiente línea:
{hook h='productInList' idproduct=$product.id_product}
Aprovechamos la nueva forma de añadir hooks (disponible a partir de Prestashop 1.5); y en consecuencia, podemos pasar cualquier número de argumentos al hook. En este caso pasamos como parámetro el id del producto, que se encuentra disponible gracias a que estamos dentro de un bucle foreach, que pone a nuestra disposición este parámetro.
Creando la función de nuestro hook...
Ahora que tenemos el hook disponible en la plantilla, debemos crear la función relativa a éste en el archivo productcomments.php. Así que, al final de este archivo, (antes de la llave de cierre de la clase), añadir esta función:
function hookProductInList($params)
{
    echo 'Si aparezco es que ha funcionado';
}
Guardar cambios en el archivo y actualizar una página de categoría en nuestra tienda; deberíamos ver esto:
Lista de productos de Prestashop
Si no vemos lo de la imagen, volver atrás y repetir los pasos, pues es posible que el hook no se esté procesando. Si ha funcionado podemos avanzar y cambiar el código de nuestra función, tal que así:
function hookProductInList($params)
{
    require_once(dirname(__FILE__).'/ProductComment.php');
    require_once(dirname(__FILE__).'/ProductCommentCriterion.php');
 
    $id_product = $params['idproduct'];
    $product_average = 0;
 
    $grades = ProductComment::getAveragesByProduct($id_product, $this->context->language->id);
    $criterions = ProductCommentCriterion::getByProduct($id_product, $this->context->language->id);
    $grade_total = 0;
}
Como vemos en este fragmento llamamos a los archivos ProductComment.php y ProductCommentCriterion.php, pues necesitamos sus clases.
A continuación definimos el id del producto como variable. Seguimos con la declaración de las variables $grades y $criterions, que obtienen la calificación media de cada producto y el número de votos registrados respectivamente , por último, establecer un valor predeterminado para la calificación total, para evitar problemas de variables no declaradas.
Sigamos. Después del código anterior añadamos lo siguiente:
if (count($grades) > 0)
{
    foreach ($criterions as $criterion)
    {
        if (isset($grades[$criterion['id_product_comment_criterion']]))
        {
            $grade_total += (float)($grades[$criterion['id_product_comment_criterion']]);
        }
    }
 
    $product_average = $grade_total / count($criterions);

}
En este fragmento se comprueba si hay calificaciones (estrellitas) sobre algún producto, y si es así, a cada voto (si el array $grades contiene datos sobre una calificación), se le añade el número correspondiente de estrellitas.
Hasta este momento hemos sumado todas las estrellitas. Después del bucle se obtiene la puntuación total (mediante la variable $product_average), diviendo el número total de calificaciones (estrellitas) recibidas, por el número de veces que se ha votado un producto.
De esta manera obtenemos una calificación media de todos los productos votados.
Como paso final de esta función asignamos el numero resultante de $product_average al parámetro average_total. Obtenemos el número de comentarios llamando a la función getCommentNumber y asignando el resultado de ésta a nbComments.
Por último, llamamos a una plantilla que todavía tenemos que crear:
$this->context->smarty->assign('average_total', (int)$product_average);
                        
// Obtener el número de comemtarios
$this->context->smarty->assign('nbComments', (int)ProductComment::getCommentNumber($id_product));
                        
return $this->display(__FILE__, '/product-list-rating.tpl');
La función completa:
public function hookProductInList($params)
 {
     require_once(dirname(__FILE__).'/ProductComment.php');
     require_once(dirname(__FILE__).'/ProductCommentCriterion.php');
 
     $id_product = $params['idproduct'];
     $product_average = 0;
 
     $grades = ProductComment::getAveragesByProduct($id_product, $this->context->language->id);
     $criterions = ProductCommentCriterion::getByProduct($id_product, $this->context->language->id);
     $grade_total = 0;
  
  if (count($grades) > 0)
  {
      foreach ($criterions as $criterion)
      {
          if (isset($grades[$criterion['id_product_comment_criterion']]))
          {
              $grade_total += (float)($grades[$criterion['id_product_comment_criterion']]);
          }
      }
 
      $product_average = $grade_total / count($criterions);
                
      $this->context->smarty->assign('average_total', (int)$product_average);
                        
      // Obtener el número de comemtarios
      $this->context->smarty->assign('nbComments', (int)ProductComment::getCommentNumber($id_product));
                        
      return $this->display(__FILE__, '/product-list-rating.tpl');

  }
 }
Crear la plantilla que mostrará la calificación
Crear un archivo .tpl en ../prestashop/modules/productcomments y llamémoslo product-list-rating.tpl. Si no sabéis como crear un archivo .tpl desde cero, simplemente copiar uno existente y cambiar el nombre de la copia por el que indicado anteriormente. Borrar todo el código del archivo (el que está comentado no es necesario borrarlo) y añadir este:
<div class="star_content clearfix">

{section name="i" start=0 loop=5 step=1}
 {if $smarty.section.i.index < $average_total}
  <div class="star star_on"><a href= "#"></a></div>
        
 {else}
  <div class="star"><a href="#"></a></div>
 {/if}
{/section}

</div>
<span class="nb-comments"><span>{$nbComments}</span> {l s='Review(s)' mod='productcomments'}</span>
Como vemos en este código, hacemos uso de la función {section} que smarty ofrece, la cual nos permite iterar un bloque de código un número determinado de veces, en este caso 5.
Dentro del bucle, comprobamos el promedio total de calificaciones y votos sobre el producto, si el índice de iteración actual es menor que el promedio total aparecerá una estrellita activa, si no, la estrellita aparecerá atenuada.
Para terminar, algo de estilo...
A fin de ajustar un poco la posición de las estrellitas y cambiar el cursor al sobrevolar éstas, añadiremos un poco de CSS. Por lo tanto debemos ir a la carpeta de nuestro tema y abrir el archivo css/product_list.css. Al final del archivo añadir este código:
#product_list li h3 {padding:0 0 1px 0;}
#product_list li a {color:#000;text-decoration:none}
div.star_on a {cursor:default}
div.star a:hover {background-position:inherit;cursor:default}
div.star_on a {background-position:0 -12px!important}
ul#criterions_list div.star a:hover {background-position:0 -12px!important;cursor:pointer}
#product_list li .star_content {display:inline-block;margin-bottom:10px}
Guardamos cambios y actualizamos la tienda. Con esto ya hemos terminado. Deberíamos ver la imagen que vimos al principio del artículo. Llévame al resultado.

No hay comentarios: