1

I am able to enable 'Layered Navigation' on Catalog Search Result-Page "http://127.0.0.1/catalogsearch/result/index/" (see image below) by just enabling the storefront properties 'Use in Search Results Layered Navigation' of my two attributes. enter image description here

How can I enable same 'Layered Navigation' also on Catalog Search ADVANCED Result-Page "http://127.0.0.1/catalogsearch/advanced/result/" ?

ps: I have tried the solution from "Magento 2 Layered Navigation in Advance Search Result" but it gives me an error:

  1. My Catalog Search ADVANCED Result-Page looks now (after trying above solution) like this:

enter image description here

As you can see the layered navigation price-filter shows all items from inventory, instead of just the 4 items that were found as result (see arrows).

  1. When I click on a price-filter option like '€0.00 - €999.99 (5)', Magento displays an error:

enter image description here

1
  • Why don't you try using Magento 2 Layer Navigation Extension from Mageplaza Commented Aug 25, 2022 at 7:03

1 Answer 1

0

When ever your try to filter product based on price using advanced search form this sent header value like

http://mage26.net/catalogsearch/advanced/result/?name=&sku=&description=&short_description=&price%5Bfrom%5D=1&price%5Bto%5D=10

Price value goes to array form like from and to.

But, if you try to filter layered navigation its goes to string not a array like from and to

http://mage26.net/catalogsearch/advanced/result/?description=&name=&price=-10000&short_description=&sku=

-10000 means price 0-10000

10000- means price 10000- above.

I tried Below Solution its works fine.

Override this Model Class: vendor/magento/module-catalog-search/Model/Advanced.php.

Create di.xml file with in directory app/code/Vendor/Module/etc/di.xml.

di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">

        <preference for="Magento\CatalogSearch\Model\Advanced" type="Clorida\AddFilter\Model\Rewrite\Advanced" />
    </config>

Then Create Advanced.php in with in app/code/Vendor/Module/Model/Rewrite/Advanced.php

Advanced.php

        <?php
        /**
         * Copyright © 2013-2017 Magento, Inc. All rights reserved.
         * See COPYING.txt for license details.
         */
        namespace Vendor\Module\Model\Rewrite;

        use Magento\Catalog\Model\Config;
        use Magento\Catalog\Model\Product\Visibility;
        use Magento\Catalog\Model\ProductFactory;
        use Magento\Catalog\Model\ResourceModel\Eav\Attribute;
        use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;
        use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollectionFactory;
        use Magento\CatalogSearch\Model\ResourceModel\Advanced\Collection as ProductCollection;
        use Magento\CatalogSearch\Model\ResourceModel\AdvancedFactory;
        use Magento\Directory\Model\CurrencyFactory;
        use Magento\Eav\Model\Entity\Attribute as EntityAttribute;
        use Magento\Framework\Model\Context;
        use Magento\Framework\Exception\LocalizedException;
        use Magento\Framework\Registry;
        use Magento\Store\Model\StoreManagerInterface;

        /**
         * Catalog advanced search model
         * @method \Magento\CatalogSearch\Model\ResourceModel\Advanced getResource()
         * @method int getEntityTypeId()
         * @method \Magento\CatalogSearch\Model\Advanced setEntityTypeId(int $value)
         * @method int getAttributeSetId()
         * @method \Magento\CatalogSearch\Model\Advanced setAttributeSetId(int $value)
         * @method string getTypeId()
         * @method \Magento\CatalogSearch\Model\Advanced setTypeId(string $value)
         * @method string getSku()
         * @method \Magento\CatalogSearch\Model\Advanced setSku(string $value)
         * @method int getHasOptions()
         * @method \Magento\CatalogSearch\Model\Advanced setHasOptions(int $value)
         * @method int getRequiredOptions()
         * @method \Magento\CatalogSearch\Model\Advanced setRequiredOptions(int $value)
         * @method string getCreatedAt()
         * @method \Magento\CatalogSearch\Model\Advanced setCreatedAt(string $value)
         * @method string getUpdatedAt()
         * @method \Magento\CatalogSearch\Model\Advanced setUpdatedAt(string $value)
         *
         * @author      Magento Core Team <[email protected]>
         * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
         */
        class Advanced extends \Magento\CatalogSearch\Model\Advanced
        {
            /**
             * User friendly search criteria list
             *
             * @var array
             */
            protected $_searchCriterias = [];

            /**
             * Product collection
             *
             * @var ProductCollection
             */
            protected $_productCollection;

            /**
             * Initialize dependencies
             *
             * @var Config
             */
            protected $_catalogConfig;

            /**
             * Catalog product visibility
             *
             * @var Visibility
             */
            protected $_catalogProductVisibility;

            /**
             * Attribute collection factory
             *
             * @var AttributeCollectionFactory
             */
            protected $_attributeCollectionFactory;

            /**
             * Store manager
             *
             * @var \Magento\Store\Model\StoreManagerInterface
             */
            protected $_storeManager;

            /**
             * Product factory
             *
             * @var ProductFactory
             */
            protected $_productFactory;

            /**
             * Currency factory
             *
             * @var CurrencyFactory
             */
            protected $_currencyFactory;

            /**
             * Advanced Collection Factory
             *
             * @var ProductCollectionFactory
             */
            protected $productCollectionFactory;

            protected  $logger;

            /**
             * Construct
             *
             * @param Context $context
             * @param Registry $registry
             * @param AttributeCollectionFactory $attributeCollectionFactory
             * @param Visibility $catalogProductVisibility
             * @param Config $catalogConfig
             * @param CurrencyFactory $currencyFactory
             * @param ProductFactory $productFactory
             * @param StoreManagerInterface $storeManager
             * @param ProductCollectionFactory $productCollectionFactory
             * @param AdvancedFactory $advancedFactory
             * @param array $data
             *
             * @SuppressWarnings(PHPMD.ExcessiveParameterList)
             */
            public function __construct(
                Context $context,
                Registry $registry,
                AttributeCollectionFactory $attributeCollectionFactory,
                Visibility $catalogProductVisibility,
                Config $catalogConfig,
                CurrencyFactory $currencyFactory,
                ProductFactory $productFactory,
                StoreManagerInterface $storeManager,
                ProductCollectionFactory $productCollectionFactory,
                AdvancedFactory $advancedFactory,
                \Psr\Log\LoggerInterface $loggerinterface,
                array $data = []
            ) {
                $this->_attributeCollectionFactory = $attributeCollectionFactory;
                $this->_catalogProductVisibility = $catalogProductVisibility;
                $this->_catalogConfig = $catalogConfig;
                $this->_currencyFactory = $currencyFactory;
                $this->_productFactory = $productFactory;
                $this->_storeManager = $storeManager;
                $this->productCollectionFactory = $productCollectionFactory;
                $this->logger = $loggerinterface;
                parent::__construct(
                    $context,
                    $registry,
                    $attributeCollectionFactory,
                    $catalogProductVisibility,
                    $catalogConfig,
                    $currencyFactory,
                    $productFactory,
                    $storeManager,
                    $productCollectionFactory,
                    $advancedFactory,
                    $data
                );
            }

            /**
             * Add advanced search filters to product collection
             *
             * @param   array $values
             * @return  $this
             * @throws LocalizedException
             * @SuppressWarnings(PHPMD.CyclomaticComplexity)
             * @SuppressWarnings(PHPMD.NPathComplexity)
             */
            public function addFilters($values)
            {
                $attributes = $this->getAttributes();
                $allConditions = [];

                foreach  ($attributes as $attribute) {
                    /* @var $attribute Attribute */
                    if (!isset($values[$attribute->getAttributeCode()])) {
                        continue;
                    }
                    $value = $values[$attribute->getAttributeCode()];

                    $preparedSearchValue = $this->getPreparedSearchCriteria($attribute, $value);
                    if (false === $preparedSearchValue) {
                        continue;
                    }
                    $this->addSearchCriteria($attribute, $preparedSearchValue);

                    if ($attribute->getAttributeCode() == 'price') {
                        $rate = 1;
                        $store = $this->_storeManager->getStore();
                        $currency = $store->getCurrentCurrencyCode();
                        if ($currency != $store->getBaseCurrencyCode()) {
                            $rate = $store->getBaseCurrency()->getRate($currency);
                        }

                        if(is_array($value)){
                            $value['from'] = (isset($value['from']) && is_numeric($value['from']))
                                ? (float)$value['from'] / $rate
                                : '';
                            $value['to'] = (isset($value['to']) && is_numeric($value['to']))
                                ? (float)$value['to'] / $rate
                                : '';
                        }else{


                        }


                    }

                    if ($attribute->getBackendType() == 'datetime') {
                        $value['from'] = (isset($value['from']) && !empty($value['from']))
                            ? date('Y-m-d\TH:i:s\Z', strtotime($value['from']))
                            : '';
                        $value['to'] = (isset($value['to']) && !empty($value['to']))
                            ? date('Y-m-d\TH:i:s\Z', strtotime($value['to']))
                            : '';
                    }
                    $condition = $this->_getResource()->prepareCondition(
                        $attribute,
                        $value,
                        $this->getProductCollection()
                    );
                    if ($condition === false) {
                        continue;
                    }

                    $table = $attribute->getBackend()->getTable();
                    if ($attribute->getBackendType() == 'static') {
                        $attributeId = $attribute->getAttributeCode();
                    } else {
                        $attributeId = $attribute->getId();
                    }
                    $allConditions[$table][$attributeId] = $condition;
                }
                if ($allConditions) {
                    $this->_registry->register('advanced_search_conditions', $allConditions);
                    $this->getProductCollection()->addFieldsToFilter($allConditions);
                } else {
                    throw new LocalizedException(__('Please specify at least one search term.'));
                }

                return $this;
            }

            /**
             * Retrieve array of attributes used in advanced search
             *
             * @return array|\Magento\Catalog\Model\ResourceModel\Product\Attribute\Collection
             */
            public function getAttributes()
            {
                $attributes = $this->getData('attributes');
                if ($attributes === null) {
                    $product = $this->_productFactory->create();
                    $attributes = $this->_attributeCollectionFactory
                        ->create()
                        ->addHasOptionsFilter()
                        ->addDisplayInAdvancedSearchFilter()
                        ->addStoreLabel($this->_storeManager->getStore()->getId())
                        ->setOrder('main_table.attribute_id', 'asc')
                        ->load();
                    foreach ($attributes as $attribute) {
                        $attribute->setEntity($product->getResource());
                    }
                    $this->setData('attributes', $attributes);
                }
                return $attributes;
            }

            /**
             * Retrieve advanced search product collection
             *
             * @return Collection
             */
            public function getProductCollection()
            {
                if ($this->_productCollection === null) {
                    $collection = $this->productCollectionFactory->create();
                    $this->prepareProductCollection($collection);
                    if (!$collection) {
                        return $collection;
                    }
                    $this->_productCollection = $collection;
                }

                return $this->_productCollection;
            }

            /**
             * Prepare product collection
             *
             * @param Collection $collection
             * @return $this
             */
            public function prepareProductCollection($collection)
            {
                $collection
                    ->addAttributeToSelect($this->_catalogConfig->getProductAttributes())
                    ->setStore($this->_storeManager->getStore())
                    ->addMinimalPrice()
                    ->addTaxPercents()
                    ->addStoreFilter()
                    ->setVisibility($this->_catalogProductVisibility->getVisibleInSearchIds());

                return $this;
            }

            /**
             * @param EntityAttribute $attribute
             * @param mixed $value
             * @return void
             */
            protected function addSearchCriteria($attribute, $value)
            {
                if (!empty($value)) {
                    $this->_searchCriterias[] = ['name' => $attribute->getStoreLabel(), 'value' => $value];
                }
            }

            /**
             * Add data about search criteria to object state
             *
             * @todo: Move this code to block
             *
             * @param   EntityAttribute $attribute
             * @param   mixed $value
             * @return  string|bool
             * @SuppressWarnings(PHPMD.CyclomaticComplexity)
             * @SuppressWarnings(PHPMD.NPathComplexity)
             */
            protected function getPreparedSearchCriteria($attribute, $value)
            {
                if (is_array($value)) {
                    if (isset($value['from']) && isset($value['to'])) {
                        if (!empty($value['from']) || !empty($value['to'])) {
                            if (isset($value['currency'])) {
                                /** @var $currencyModel Currency */
                                $currencyModel = $this->_currencyFactory->create()->load($value['currency']);
                                $from = $currencyModel->format($value['from'], [], false);
                                $to = $currencyModel->format($value['to'], [], false);
                            } else {
                                $currencyModel = null;
                            }

                            if (strlen($value['from']) > 0 && strlen($value['to']) > 0) {
                                // -
                                $value = sprintf(
                                    '%s - %s',
                                    $currencyModel ? $from : $value['from'],
                                    $currencyModel ? $to : $value['to']
                                );
                            } elseif (strlen($value['from']) > 0) {
                                // and more
                                $value = __('%1 and greater', $currencyModel ? $from : $value['from']);
                            } elseif (strlen($value['to']) > 0) {
                                // to
                                $value = __('up to %1', $currencyModel ? $to : $value['to']);
                            }
                        } else {
                            return '';
                        }
                    }
                }

                if (($attribute->getFrontendInput() == 'select' ||
                        $attribute->getFrontendInput() == 'multiselect') && is_array($value)
                ) {
                    foreach ($value as $key => $val) {
                        $value[$key] = $attribute->getSource()->getOptionText($val);

                        if (is_array($value[$key])) {
                            $value[$key] = $value[$key]['label'];
                        }
                    }
                    $value = implode(', ', $value);
                } elseif ($attribute->getFrontendInput() == 'select' || $attribute->getFrontendInput() == 'multiselect') {
                    $value = $attribute->getSource()->getOptionText($value);
                    if (is_array($value)) {
                        $value = $value['label'];
                    }
                } elseif ($attribute->getFrontendInput() == 'boolean') {
                    $value = $value == 1
                        ? __('Yes')
                        : __('No');
                }

                return $value;
            }

            /**
             * Returns prepared search criterias in text
             *
             * @return array
             */
            public function getSearchCriterias()
            {
                return $this->_searchCriterias;
            }
        }

With in the Price Section, I have change like this.

   if ($attribute->getAttributeCode() == 'price') {
            $rate = 1;
            $store = $this->_storeManager->getStore();
            $currency = $store->getCurrentCurrencyCode();
            if ($currency != $store->getBaseCurrencyCode()) {
                $rate = $store->getBaseCurrency()->getRate($currency);
            }

            if(is_array($value)){
                $value['from'] = (isset($value['from']) && is_numeric($value['from']))
                    ? (float)$value['from'] / $rate
                    : '';
                $value['to'] = (isset($value['to']) && is_numeric($value['to']))
                    ? (float)$value['to'] / $rate
                    : '';
            }else{


            }

        }

Then, Clear cache and Check it let me know if you have issue.

3
  • 1
    How to add Layered navigation on Custom Product Collection? I am displaying products by brand using custom controller.
    – Magecode
    Commented Sep 1, 2017 at 4:53
  • same problem plz suggest how to add layered Navigation in advance search result My M2 ver: 2.3.0 plz help my XML code below Comment screenshot > prnt.sc/rx7f9m
    – DK Thakur
    Commented Apr 11, 2020 at 8:13
  • <referenceContainer name="sidebar.main"> <block class="Magento\LayeredNavigation\Block\Navigation\Search" name="catalogsearch.leftnav" before="-" template="Magento_LayeredNavigation::layer/view.phtml"> <block class="Magento\LayeredNavigation\Block\Navigation\State" name="catalogsearch.navigation.state" as="state" /> <block class="Magento\LayeredNavigation\Block\Navigation\FilterRenderer" name="catalogsearch.navigation.renderer" as="renderer" template="Magento_LayeredNavigation::layer/filter.phtml"/> </block></referenceContainer>
    – DK Thakur
    Commented Apr 11, 2020 at 8:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.