Miguel86 Posted March 18, 2024 Share Posted March 18, 2024 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 More sharing options...
buzzvicky Posted May 2, 2024 Share Posted May 2, 2024 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 More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now