Límite de productos en Prestashop 1.7

Si eres de los que acabas de lanzar una tienda online, seguramente te hayan recomendado la versión de Prestashop 1.7 al tratarse de la versión LTS, y teniendo en cuenta que en principio la versión de Prestashop 1.6 caducará en Septiembre de 2018, en cuanto a mantenimiento y parches se refiere, ha sido un acierto optar por esta nueva versión.

Si eres de los que han decidido migrar de la versión 1.6 de Prestashop a la 1.7 habrás notado que una de las funcionalidades más interesantes para vuestros clientes es que ellos puedan cambiar o personalizar los productos que desean ver por página.

En Prestashop 1.6 ésta funcionalidad se encontraba dentro del archivo orden de productos, pero nuestra sorpresa ha sido comprobar que en la última versión de Prestashop no viene incluida y hemos decido mejorar la funcionalidad de la plantilla con un pequeño cambio de programación. El objetivo es poder ver, al lado de la paginación y ordenación, el listado de productos.
productos-prestashop-1.png
Comenzaremos inicialmente modificando nuestra vista de diseño de la tienda online, entramos a la carpeta themes, y dentro elegimos el tema de nuestra tienda, allí tendremos la carpeta templetes -> catalog-> y sort-orders.tpl

Una vez localizado el fichero de ordenación añadiremos justo debajo del select:

<div class="selectorproductofpage">

                    <select id="selecproductofpage{if isset($paginationId)}_{$paginationId}{/if}" class="numberofpage form-control">

                           <option value="20">20</option>

                           <option value="40">40</option>

                           <option value="60">60</option>

                           <option value="10000">Todos</option>

                    </select>

             </div> 
 
   

En este caso hemos puesto todo con un value de 10000 productos por página.

Ahora debemos añadir la funcionalidad jQuery que nos permita realizar el cambio, para ello vamos a la carpeta asset-> js y dentro del fichero custom.js

Dentro de la función:

$(document).ready(function() { }

que nos indica que la tienda ha terminado de cargar. Añadimos:

       $(document).ready(function() {

             p = location.href.split('npages=');

             if(p[1] >1){

                    $('#selecproductofpage').val(p[1]);

             }else{

                    $('#selecproductofpage').val(20);

             }

            

       });
 
   

Con esto conseguimos que nuestro Select esté actualizado al valor de la variable.

Ahora debemos conseguir que cuando el desplegable cambie llame a la url para cambiar el límite establecido por Prestashop:

$(document).on('change', '#selecproductofpage', function(){

             p = location.href.split('npages=');

             if(p[1] >1){

                    var newUrl = location.href.replace("npages="+p[1], "npages="+$('#selecproductofpage').val());

             }else{

                    if(location.href.indexOf("?") == -1){

                           var newUrl = location.href + "&npages="+$('#selecproductofpage').val();

                    }else{

                           var newUrl = location.href + "&npages="+$('#selecproductofpage').val();

                    }

             }

             window.location.href = newUrl;

       });
 
   

Como veréis ya tenemos en el diseño web de la categoría de nuestra tienda el selector con una funcionalidad que cambiará nuestra url en base a qué valor elijamos. Ahora debemos dotar a Prestashop de un cambio dinámico de productos por página.

Para ello vamos hacer override de la función getProductSearchVariables que encontraremos en el controlador ProductListingFrontController.

Para ello creamos la carpeta controllers dentro de la carpeta override que encontraremos en la instalación de Prestashop, y dentro una llamada front.

productos-prestashop-2.png

Dentro de esta carpeta crearemos el fichero ProductListingFrontController.php

Ahora añadimos:

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;

use PrestaShop\PrestaShop\Core\Product\Search\Pagination;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;

use PrestaShop\PrestaShop\Core\Product\Search\Facet;

use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;

use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;

use PrestaShop\PrestaShop\Core\Product\Search\FacetsRendererInterface;





abstract class ProductListingFrontController extends ProductListingFrontControllerCore

{



}
 
   

Copiaremos la función getProductSearchVariables y reemplazaremos:

$resultsPerPage = (int) Tools::getValue('resultsPerPage');

        if ($resultsPerPage <= 0 || $resultsPerPage > 36) {

            $resultsPerPage = Configuration::get('PS_PRODUCTS_PER_PAGE');

        }
 
   

Por:

$resultsPerPage = (int) Tools::getValue('resultsPerPage');

        if ($resultsPerPage <= 0 || $resultsPerPage > 36) {

            $resultsPerPage = Configuration::get('PS_PRODUCTS_PER_PAGE');

        }

       

       

       

        //digitalDot

        $npages = Tools::getValue('npages');

        if (isset($npages) && $npages != $resultsPerPage){

          $_SESSION['nproductpage'] = Tools::getValue('npages');

        }

     

        if (isset( $_SESSION['nproductpage']) && $_SESSION['nproductpage'] > 0){

          $resultsPerPage = (int) $_SESSION['nproductpage'];

      }
 
   

También debemos incorporar dos funciones para que todo funcione correctamente:

private function prepareProductForTemplate(array $rawProduct)

       {

             $product = (new ProductAssembler($this->context))

             ->assembleProduct($rawProduct)

             ;

            

             $presenter = $this->getProductPresenter();

             $settings = $this->getProductPresentationSettings();

            

             return $presenter->present(

                           $settings,

                           $product,

                           $this->context->language

                           );

       }

      

       /**

        * This method is the heart of the search provider delegation

        * mechanism.

        *

        * It executes the `productSearchProvider` hook (array style),

        * and returns the first one encountered.

        *

        * This provides a well specified way for modules to execute

        * the search query instead of the core.

        *

        * The hook is called with the $query argument, which allows

        * modules to decide if they can manage the query.

        *

        * For instance, if two search modules are installed and

        * one module knows how to search by category but not by manufacturer,

        * then "ManufacturerController" will use one module to do the query while

        * "CategoryController" will use another module to do the query.

        *

        * If no module can perform the query then null is returned.

        *

        * @param ProductSearchQuery $query

        *

        * @return ProductSearchProviderInterface or null

        */

       private function getProductSearchProviderFromModules($query)

       {

             $providers = Hook::exec(

                           'productSearchProvider',

                           array('query' => $query),

                           null,

                           true

                           );

            

             if (!is_array($providers)) {

                    $providers = array();

             }

            

             foreach ($providers as $provider) {

                    if ($provider instanceof ProductSearchProviderInterface) {

                           return $provider;

                    }

             }

            

             return;

       }
 
   

Ahora debemos borrar la cache de nuestra tienda online y probar si tenemos activada el número de productos por página de forma dinámica.

Lo bueno de las funciones override es que no afectarán la seguridad de nuestra tienda online ni a la fiabilidad del sistema.

Si tienes una tienda online y tienes alguna duda sobre cómo mejorar sus funcionalidades puedes ponerte en contacto con el equipo de desarrollo web de digitalDot en Murcia y seguro que podrán ayudarte.