Jump to content

Override SearchProvider Facetedsearch


Miguel86

Recommended Posts

Hi:
I'm using Prestashop 8 with latest version and I trying to override the facetedsearch to add few extra sort options in the category page.

I tried to create an override of the ps_facetedsearch.php

I put the file in override/modules/ps_facetedsearch/ps_facetedsearch.php

<?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;
use PrestaShop\Module\FacetedSearch\Filters\DataAccessor;
use PrestaShop\Module\FacetedSearch\Filters\Provider;
class Ps_FacetedsearchOverride extends Ps_Facetedsearch
{
    public function hookProductSearchProvider($params)
    {
        $query = $params['query'];
        if ($query->getIdCategory()) {
            $urlSerializer = new URLSerializer();
            $dataAccessor = new DataAccessor($this->getDatabase());
            $provider = new Provider($this->getDatabase());
            return new SearchProviderOverride(
                $this,
                new Converter(
                    $this->getContext(),
                    $this->getDatabase(),
                    $urlSerializer,
                    $dataAccessor,
                    $provider
                ),
                $urlSerializer,
                $dataAccessor,
                null,
                $provider
            );
        } else {
            return null;
        }
    }
}

 

And the SearchProviderOverride.php

I put it in override/modules/ps_facetedsearch/src/Product/SearchProvider.php

<?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;
use PrestaShop\Module\FacetedSearch\Product\SearchFactory;

class SearchProviderOverride extends SearchProvider
{
    private $_module;

    public function __construct(
        Ps_Facetedsearch $module,
        Filters\Converter $converter,
        URLSerializer $serializer,
        Filters\DataAccessor $dataAccessor,
        SearchFactory $searchFactory = null,
        Filters\Provider $provider
    ) {
        $this->module = $module;
        $this->filtersConverter = $converter;
        $this->urlSerializer = $serializer;
        $this->dataAccessor = $dataAccessor;
        $this->searchFactory = $searchFactory === null ? new SearchFactory() : $searchFactory;
        $this->provider = $provider;
    }

    private function getAvailableSortOrders($query)
    {
        $sortSalesDesc = new SortOrder('product', 'sales', 'desc');
        $sortPosAsc = new SortOrder('product', 'position', 'asc');
        $sortNameAsc = new SortOrder('product', 'name', 'asc');
        $sortNameDesc = new SortOrder('product', 'name', 'desc');
        $sortPriceAsc = new SortOrder('product', 'price', 'asc');
        $sortPriceDesc = new SortOrder('product', 'price', 'desc');
        $sortDateAsc = new SortOrder('product', 'date_add', 'asc');
        $sortDateDesc = new SortOrder('product', 'date_add', 'desc');
        $sortRefAsc = new SortOrder('product', 'reference', 'asc');
        $sortRefDesc = new SortOrder('product', 'reference', 'desc');
        $translator = $this->module->getTranslator();

        $sortOrders = [
            $sortSalesDesc->setLabel(
                $translator->trans('Sales, highest to lowest', [], 'Shop.Theme.Catalog')
            ),
            $sortPosAsc->setLabel(
                $translator->trans('Relevance', [], 'Shop.Theme.Catalog')
            ),
            $sortNameAsc->setLabel(
                $translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog')
            ),
            $sortNameDesc->setLabel(
                $translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog')
            ),
            $sortPriceAsc->setLabel(
                $translator->trans('Price, low to high', [], 'Shop.Theme.Catalog')
            ),
            $sortPriceDesc->setLabel(
                $translator->trans('Price, high to low', [], 'Shop.Theme.Catalog')
            ),
            $sortRefAsc->setLabel(
                $translator->trans('Reference, A to Z', [], 'Shop.Theme.Catalog')
            ),
            $sortRefDesc->setLabel(
                $translator->trans('Reference, Z to A', [], 'Shop.Theme.Catalog')
            ),
        ];

        if ($query->getQueryType() == 'new-products') {
            $sortOrders[] = $sortDateAsc->setLabel(
                $translator->trans('Date added, oldest to newest', [], 'Shop.Theme.Catalog')
            );
            $sortOrders[] = $sortDateDesc->setLabel(
                $translator->trans('Date added, newest to oldest', [], 'Shop.Theme.Catalog')
            );
        }

        return $sortOrders;
    }
}

 

 

However the website returns a 500 error:
 

[18-Mar-2024 15:40:42 Europe/Madrid] PHP Fatal error:  Uncaught Error: Call to a member function createFacetedSearchFiltersFromQuery() on null in /home/testewebsite/public_html/modules/ps_facetedsearch/src/Product/SearchProvider.php:163
Stack trace:
#0 /home/testewebsite/public_html/classes/controller/ProductListingFrontController.php(357): PrestaShop\Module\FacetedSearch\Product\SearchProvider->runQuery(Object(PrestaShop\PrestaShop\Core\Product\Search\ProductSearchContext), Object(PrestaShop\PrestaShop\Core\Product\Search\ProductSearchQuery))
#1 /home/testewebsite/public_html/override/controllers/front/listing/CategoryController.php(111): ProductListingFrontControllerCore->getProductSearchVariables()
#2 /home/testewebsite/public_html/controllers/front/listing/CategoryController.php(138): CategoryController->doProductSearch('catalog/listing...', Array)
#3 /home/testewebsite/public_html/classes/controller/Controller.php(319): CategoryControllerCore->initContent()
#4 /home/testewebsite/public_html/classes/Dispatcher.php(510): ControllerCore->run()
#5 /home/testewebsite/public_html/index.php(28): DispatcherCore->dispatch()
#6 {main}
  thrown in /home/testewebsite/public_html/modules/ps_facetedsearch/src/Product/SearchProvider.php on line 163

 

Link to comment
Share on other sites

  • 1 month later...

Hi,
I think the problem is that you need to call the parent methods in the SearchProvider.php override:

class SearchProviderOverride extends SearchProvider
{
    private $_module;

    public function __construct(
        Ps_Facetedsearch $module,
        Filters\Converter $converter,
        URLSerializer $serializer,
        Filters\DataAccessor $dataAccessor,
        SearchFactory $searchFactory = null,
        Filters\Provider $provider
    ) {
        parent::__construct($module, $converter, $serializer, $dataAccessor, $searchFactory, $provider);
        $this->_module = $module;
    }

    public function runQuery(
        ProductSearchContext $context,
        ProductSearchQuery $query
    ) {
        $result = parent::runQuery($context, $query);
        $result->setAvailableSortOrders($this->getCustomSorting($query));
        return $result;
    }

    /**
     * @param ProductSearchQuery $query
     *
     * @return array
     */
    private function getCustomSorting($query)
    {
        // Existing Sorting Options
        $sortSalesDesc = new SortOrder('product', 'sales', 'desc');
        $sortPosAsc = new SortOrder('product', 'position', 'asc');
        $sortNameAsc = new SortOrder('product', 'name', 'asc');
        $sortNameDesc = new SortOrder('product', 'name', 'desc');
        $sortPriceAsc = new SortOrder('product', 'price', 'asc');
        $sortPriceDesc = new SortOrder('product', 'price', 'desc');
        $sortDateAsc = new SortOrder('product', 'date_add', 'asc');
        $sortDateDesc = new SortOrder('product', 'date_add', 'desc');
        $sortRefAsc = new SortOrder('product', 'reference', 'asc');
        $sortRefDesc = new SortOrder('product', 'reference', 'desc');

        $translator = $this->_module->getTranslator();
        $sortOrders = [
            $sortSalesDesc->setLabel(
                $translator->trans('Sales, highest to lowest', [], 'Shop.Theme.Catalog')
            ),
            $sortPosAsc->setLabel(
                $translator->trans('Relevance', [], 'Shop.Theme.Catalog')
            ),
            $sortNameAsc->setLabel(
                $translator->trans('Name, A to Z', [], 'Shop.Theme.Catalog')
            ),
            $sortNameDesc->setLabel(
                $translator->trans('Name, Z to A', [], 'Shop.Theme.Catalog')
            ),
            $sortPriceAsc->setLabel(
                $translator->trans('Price, low to high', [], 'Shop.Theme.Catalog')
            ),
            $sortPriceDesc->setLabel(
                $translator->trans('Price, high to low', [], 'Shop.Theme.Catalog')
            ),
            $sortRefAsc->setLabel(
                $translator->trans('Reference, A to Z', [], 'Shop.Theme.Catalog')
            ),
            $sortRefDesc->setLabel(
                $translator->trans('Reference, Z to A', [], 'Shop.Theme.Catalog')
            ),
        ];

        if ($query->getQueryType() == 'new-products') {
            $sortOrders[] = $sortDateAsc->setLabel(
                $translator->trans('Date added, oldest to newest', [], 'Shop.Theme.Catalog')
            );
            $sortOrders[] = $sortDateDesc->setLabel(
                $translator->trans('Date added, newest to oldest', [], 'Shop.Theme.Catalog')
            );
        }

        return $sortOrders;
    }
}

I was trying to remove some of the options and this worked for me but I had problems with ps_facetedsearch css and javascript files as they were not being loaded anymore. After reading this I went with hook registering which seems much cleaner and more elegant than overriding.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...