Magento – magento 2: Customize collection of product not effecting in layer & toolbar area

layered-navigationmagento2product-listtoolbar

I extend the collection query using event 'catalog_block_product_list_collection'. Query displaying proper data, as well as showing proper record in product list page.
But same collection is not loading for layer & toolbar section.

here is my code

events.xml

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="catalog_block_product_list_collection">
        <observer name="review" instance="PR\Catalog\Observer\CatalogBlockProductCollectionBeforeToHtmlObserver" shared="false" />
    </event>
</config>

CatalogBlockProductCollectionBeforeToHtmlObserver.php

namespace PR\Catalog\Observer;

use Magento\Framework\Event\ObserverInterface;

class CatalogBlockProductCollectionBeforeToHtmlObserver implements ObserverInterface
{
    /**
     * Review model
     *
     * @var \Magento\Review\Model\ReviewFactory
     */
    protected $_vendorProductFactory;

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $productCollection = $observer->getEvent()->getCollection();
        if ($productCollection instanceof \Magento\Framework\Data\Collection) {

           $productCollection->getSelect()->join(array(
                    'vendor_product' =>  'pr_vendor_product'), 
                    "e.entity_id = vendor_product.marketplace_product_id and vendor_product.status = 1", 
                    array('vendor_product.*')
                    );
            $productCollection->getSelect()->group('marketplace_product_id');
        }         
    }
}

enter image description here

Best Answer

I successfully applied my custom product collection on category page's layered navigation and toolbar.

For example, I am fetching the collection of those products whose price is less than 100.

Step 1: Add below code snippet

app/code/Vendor/Module/etc/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">

    <type name="Magento\Catalog\Model\Layer">
        <plugin name="custom_product_model_layer" type="Vendor\Module\Plugin\Layer" />
    </type>

    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="custom_product_toolbar" type="Vendor\Module\Plugin\Toolbar" />
    </type>

    <virtualType name="categoryFilterList" type="Magento\Catalog\Model\Layer\FilterList">
        <arguments>
            <argument name="filters" xsi:type="array">
                <item name="attribute" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Attribute</item>
                <item name="price" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Price</item>
                <item name="decimal" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Decimal</item>
                <item name="category" xsi:type="string">Magento\Catalog\Model\Layer\Filter\Category</item>
            </argument>
        </arguments>
    </virtualType>

</config>

Step 2: Create plugin for product collection

app/code/Vendor/Module/Plugin/Layer.php

<?php
namespace Vendor\Module\Plugin;
class Layer
{
  public function aroundGetProductCollection(
    \Magento\Catalog\Model\Layer $subject,
    \Closure $proceed
  ) {

    $result = $proceed();
    $result->addAttributeToFilter('price', array('lt' => 100));
    return $result;
  }
}

Step 3: Create plugin for toolbar

app/code/Vendor/Module/Plugin/Toolbar.php

<?php
namespace Vendor\Module\Plugin;
class Toolbar
{

  protected $_objectManager;
  protected $request;

  public function __construct(
    \Magento\Framework\ObjectManagerInterface $objectmanager,
    \Magento\Framework\App\Request\Http $request
  ) {
    $this->_objectManager = $objectmanager;
    $this->request = $request;
  }

  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
    \Closure $proceed,
    $request
  ) {
    $result = $proceed($request);

    $this->_collection = $request;
    $category = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
    if($category)
    {
      $page = $this->request->getParam('p');
      if($page == '')
      {
        $page = 1;
      }
      $this->_collection->getCurPage();
      $this->_collection->setCurPage($page);  
    }
    else
    {
      $this->_collection->setCurPage($this->getCurrentPage());
    }

    return $result;
  }

}
Related Topic