Magento 2 Custom Filter Not Affecting Layered Navigation – Troubleshooting Guide

attributesfilterlayered-navigationmagento2magento2.3

I have a filter in My list.phtml like below:

    $_productCollection = $block->getLoadedProductCollection();
    if($_COOKIE['selectToGarageList']){
        $dat = $_COOKIE['selectToGarageList'];
        $dat = json_decode($dat,true);
        print_r($dat);
        //$allCatPros = $_productCollection->addAttributeToSelect('*');
        $allCatPros = $cateinstance->create()->load($category['entity_id'])->getProductCollection()->addAttributeToSelect('*')->addFieldToFilter('sku',['in' => $dat]);    
        $args =  $_SERVER['QUERY_STRING']; 
        parse_str($args, $get_array);
        if(count($get_array)>0){
            print_r($get_array);
            foreach($get_array as $value=>$key){
              $allCatPros->addFieldToFilter($value,['eq'=>  $key]);
            }        
        }
    }else{
        $allCatPros = $_productCollection;
    }

This filter is working fine and filter product list but not changing the layered navigation filters.

I couldn't find ways to add filter to this block

initializeProductCollection

of Magento\Catalog\Block\Product\ListProduct
class

Best Answer

Vendor\Module\etc\di.xml

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

    <type name="Magento\CatalogSearch\Model\Search\IndexBuilder">
      <plugin name="Custom_Layernavigation::CustomLayernavigation"
      type="Vendor\Module\Plugin\CatalogSearch\Model\Search\IndexBuilder" />
    </type>
</config>

Vendor\Module\Plugin\CatalogSearch\Model\Search\IndexBuilder.php

<?php

namespace Vendor\Module\Plugin\CatalogSearch\Model\Search;

use Magento\Framework\DB\Select;
use Magento\Framework\Search\Request\FilterInterface;
use Magento\Framework\Search\Request\Filter\BoolExpression;
use Magento\Framework\Search\Request\Query\Filter;
use Magento\Framework\Search\RequestInterface;
use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface;
use Magento\Framework\App\ResourceConnection;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Catalog\Model\CategoryFactory;

class IndexBuilder
{
    /**
    * @var \Magento\Framework\App\Config\ScopeConfigInterface
    */
    protected $scopeConfig;

    /**
    * @var \Magento\Store\Model\StoreManagerInterface
    */
    protected $storeManager;
    protected $_stockFilter;
    private $layerResolver;
    protected $categoryRepository;
    protected $_categoryCollectionFactory;
    /**
     * @var Magento\Catalog\Model\CategoryFactory
     */
    protected $_categoryFactory;
    protected $registry;
    protected $_request;

    public function __construct(
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        \Magento\Catalog\Model\Product\Visibility $productVisibility,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Framework\Registry $registry,
        \Magento\CatalogInventory\Helper\Stock $stockFilter,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        CategoryRepositoryInterface $categoryRepository,
        \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory,
        CategoryFactory $categoryFactory,
        \Magento\Framework\App\Request\Http $request
    ) {
        $this->storeManager = $storeManager;
        $this->_productCollectionFactory = $productCollectionFactory; 
        $this->_productVisibility = $productVisibility;
        $this->categoryHelper = $categoryHelper;
        $this->registry = $registry;
        $this->_stockFilter = $stockFilter;
        $this->layerResolver = $layerResolver;
        $this->categoryRepository = $categoryRepository;
        $this->_categoryCollectionFactory = $categoryCollectionFactory;
        $this->_categoryFactory = $categoryFactory;
        $this->_request = $request;
    }

    /**
    * Build index query
    *
    * @param $subject
    * @param callable $proceed
    * @param RequestInterface $request
    * @return Select
    * @SuppressWarnings(PHPMD.UnusedFormatParameter)
    */
    public function aroundBuild($subject, callable $proceed, RequestInterface $request) {
        $select = $proceed($request);
        $storeId = $this->storeManager->getStore()->getStoreId();
        $rootCatId = $this->storeManager->getStore($storeId)->getRootCategoryId();
        $productUniqueIds = $this->getCustomCollectionQuery();
        $select->where('search_index.entity_id IN (' . join(',', $productUniqueIds) . ')');

        return $select;
    }

    /**
    *
    * @return ProductIds[]
    */
    public function getCustomCollectionQuery() {
        $websiteId = $this->storeManager->getStore()->getWebsiteId();
        $collection = $this->_productCollectionFactory->create();
        $collection->addAttributeToSelect('*');
        $collection->addAttributeToSelect(array('entity_id','sku'));
        $collection->addWebsiteFilter($websiteId);
        $collection->setVisibility($this->_productVisibility->getVisibleInSiteIds());
        $collection->addAttributeToFilter('status',\Magento\Catalog\Model\Product\Attribute\Source\Status::STATUS_ENABLED);
       /*You can write your custom logic here...*/

        $getProductAllIds = $collection->getAllIds();
        $getProductUniqueIds = array_unique($getProductAllIds);
        return $getProductUniqueIds;
    }



}

I hope this code will be helpful.It worked perfectly fine in my case.