Gintas
Gintas

Reputation: 285

How can I add a custom product "Sort by" field in prestashop?

I am new to Prestashop and I am trying to add a new "Sort by" field ( where by default you have: "Relevance" , "Name, A to Z" , "Name, Z to A", "Price, low to high", "Price, high to low" )

As you guys know, the functionality is located in the module called: "Ps_facetedsearch" , link here.

I tried:

So my questions are:

  1. How can you add the additional "Sort by" field in the products listing (front) in a most elegant/easiest way possible?I would love to hear for any other approaches to this problem.
  2. Can you do this without override/s, if you, for e.g, have bought another module that overrides the main module ( "Ps_facetedsearch", so that two overrides would not conflict)

Any tips are appreciated!!!

PrestaShop version: 1.7.4.2

The lines in the Ps_facetedsearch module that I need to copy/paste in order to add an additional "Sort by" field:

private function getAvailableSortOrders()
{
    return [
        (new SortOrder('product', 'position', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Relevance', array(), 'Modules.Facetedsearch.Shop')
        ),
        (new SortOrder('product', 'name', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Name, A to Z', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'name', 'desc'))->setLabel(
            $this->module->getTranslator()->trans('Name, Z to A', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'price', 'asc'))->setLabel(
            $this->module->getTranslator()->trans('Price, low to high', array(), 'Shop.Theme.Catalog')
        ),
        (new SortOrder('product', 'price', 'desc'))->setLabel(
            $this->module->getTranslator()->trans('Price, high to low', array(), 'Shop.Theme.Catalog')
        )
        // copy and paste here for another one, but lose the upgradability
       // of a module.
    ];

}

Found in Ps_FacetedsearchProductSearchProvider.php (lines 117-136)

Upvotes: 2

Views: 10233

Answers (3)

Marek J.
Marek J.

Reputation: 317

Since ps_facetedsearch module gone through some changes lately here is version for latest PS 1.7.7.1 release, based on @Divjesh answer:

  1. Add file ps_facetedsearch.php in folder override/modules/ps_facetedsearch (create folders if not exists) and put below code into this file.
    <?php
    if (!defined('_PS_VERSION_')) {
        exit;
    }
    
    require_once implode(DIRECTORY_SEPARATOR, array(
        __DIR__, 'src', 'Product', 'SearchProvider.php',
    ));
    
    use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;
    use PrestaShop\Module\FacetedSearch\URLSerializer;
    use PrestaShop\Module\FacetedSearch\Filters\Converter;
    
    class Ps_FacetedsearchOverride extends Ps_Facetedsearch
    {
        public function hookProductSearchProvider($params)
        {
            $query = $params['query'];
             if ($query->getIdCategory()) {
                $urlSerializer = new URLSerializer();
                return new SearchProviderOverride(
                    $this,
                    new Converter(
                        $this->getContext(),
                        $this->getDatabase(),
                        $urlSerializer
                    ),
                    $urlSerializer
                );
            } else {
                return null;
            }
        }
    }
  1. Add file SearchProvider.php in folder override/modules/ps_facetedsearch/src/Product/ (create folders if not exists) and add put below code in it:
<?php

use PrestaShop\Module\FacetedSearch\Filters;
use PrestaShop\Module\FacetedSearch\URLSerializer;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;

use PrestaShop\Module\FacetedSearch\Product\SearchProvider;

class SearchProviderOverride extends SearchProvider
{
    private $_module;
    
    public function __construct(
        Ps_Facetedsearch $module,
        Filters\Converter $converter,
        URLSerializer $serializer,
        SearchFactory $searchFactory = null
    ) {
        parent::__construct($module, $converter, $serializer, $searchFactory);
        $this->_module = $module;
    }   
    
    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        $result = parent::runQuery($context, $query);
        $result->setAvailableSortOrders($this->getMyAvailableSortOrders());
        return $result;
    }
    
    private function getMyAvailableSortOrders()
    {
        // define your SortOrders here for example:
        $sortDateDesc = new SortOrder('product', 'date_add', 'desc');
        $translator = $this->_module->getTranslator();
        return [
            $sortDateDesc->setLabel(
                $translator->trans('Newest', [], 'Modules.Facetedsearch.Shop')
            ),
        ];
    }
}

Upvotes: 2

Sahin S.
Sahin S.

Reputation: 51

For 1.7.4.x

  • Go to /modules/ps_facetedsearch/src
  • Open Ps_FacetedsearchProductSearchProvider.php
  • Find private function getAvailableSortOrders() line
  • and add what you want like:

(new SortOrder('product', 'date_add', 'desc'))->setLabel( $this->module->getTranslator()->trans('Date added: latest first', array(), 'Modules.Facetedsearch.Shop') ), (new SortOrder('product', 'date_add', 'asc'))->setLabel( $this->module->getTranslator()->trans('Date added: earliest first', array(), 'Modules.Facetedsearch.Shop') ), (new SortOrder('product', 'position', 'asc'))->setLabel( $this->module->getTranslator()->trans('Relevance', array(), 'Modules.Facetedsearch.Shop') ),

for 1.7.6.x

You can find the file in /modules/ps_facetedsearch/src/Product/SearchProvider.php

and find:

private function getAvailableSortOrders()

for old versions: - themes/default/product-sort.tpl - add like:

<option value="date_add:desc" {if $orderby eq 'date_add' AND $orderway eq 'desc'}selected="selected"{/if}>{l s='Date added: latest first'}</option>

Upvotes: 2

Divyesh Prajapati
Divyesh Prajapati

Reputation: 985

You can add custom sort by option by overriding Ps_Facetedsearch module.

You can follow below steps to add custom sort by order.

1) Add file ps_facetedsearch.php in folder override/modules/ps_facetedsearch; (create folders if not exists) and below code in this file.

<?php
/**
 * @override Ps_Facetedsearch
 */

if (!defined('_PS_VERSION_')) {
    exit;
}

require_once implode(DIRECTORY_SEPARATOR, array(
    __DIR__, 'src', 'Ps_FacetedsearchProductSearchProvider.php',
));

class Ps_FacetedsearchOverride extends Ps_Facetedsearch
{
    public function hookProductSearchProvider($params)
    {
        $query = $params['query'];
        // do something with query,
        // e.g. use $query->getIdCategory()
        // to choose a template for filters.
        // Query is an instance of:
        // PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery
        if ($query->getIdCategory()) {
            return new Ps_FacetedsearchProductSearchProviderOverride($this);
        } else {
            return null;
        }
    }
}

2) Add file Ps_FacetedsearchProductSearchProvider.php in folder override/modules/ps_facetedsearch/src; (create folders if not exists) and add below code in it.

<?php

require_once implode(DIRECTORY_SEPARATOR, array(
    __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchProductSearchProvider.php',
));

require_once implode(DIRECTORY_SEPARATOR, array(
    __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchFiltersConverter.php',
));

require_once implode(DIRECTORY_SEPARATOR, array(
    __DIR__, '..', '..', '..', '..', 'modules', 'ps_facetedsearch', 'src', 'Ps_FacetedsearchFacetsURLSerializer.php',
));

use PrestaShop\PrestaShop\Core\Product\Search\URLFragmentSerializer;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchProviderInterface;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery;
use PrestaShop\PrestaShop\Core\Product\Search\ProductSearchResult;
use PrestaShop\PrestaShop\Core\Product\Search\Facet;
use PrestaShop\PrestaShop\Core\Product\Search\FacetCollection;
use PrestaShop\PrestaShop\Core\Product\Search\Filter;
use PrestaShop\PrestaShop\Core\Product\Search\SortOrder;

class Ps_FacetedsearchProductSearchProviderOverride extends Ps_FacetedsearchProductSearchProvider
{
    private $module;

    public function __construct(Ps_Facetedsearch $module)
    {
        $this->module = $module;
    }

    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        $facetedSearch = new Ps_FacetedsearchProductSearchProvider($this->module);
        $result = $facetedSearch->runQuery($context, $query);

        $sortOrders = $this->getAvailableSortOrders();
        foreach ($sortOrders as $sortOrder) {
            $result->addAvailableSortOrder($sortOrder);
        }

        return $result;
    }

    /**
     * New sort order that needs to be appended
     * 
     * @return array
     */
    private function getAvailableSortOrders()
    {
        return [
            // add your custom sort by orders here;
        ];
    }
}

3) Make sure overrides is enabled in backend; from Advance Parameters > Performance

4) To load you overrides you need to re-index autoloads and to do so you need to delete class_index.php file; delete class_index.php file from var/cache/dev and var/cache/prod folders.

5) Check you shop; new custom sort order will be added.

Hope it helps!

Upvotes: 5

Related Questions