2

We've added a default filter for our product collection by adding a plugin:

<?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="filterCatalog" type="Silvan\StockStatus\Plugin\Catalog\Model\Layer" sortOrder="10"/>
    </type>
</config>

And the class:

<?php namespace Silvan\StockStatus\Plugin\Catalog\Model;

class Layer
{
    /**
     * afterGetProductCollection method
     *
     * @param                                                                $subject
     * @param \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $collection
     *
     * @return mixed
     */
    public function afterGetProductCollection($subject, $collection)
    {
        $collection->addAttributeToSelect('bgs_stock_status');
        $collection->addAttributeToFilter(
            [
                ['attribute' => 'bgs_stock_status', 'is' => new \Zend_Db_Expr('null')],
                ['attribute' => 'bgs_stock_status', 'lt' => 3],
            ]);

        $collection->getSize();

        return $collection;
    }
}

But as soon as we add the 'addAttributeToFilter' part, all Layered Navigation filter options are gone. If we remove this code it's shown again.

How can we filter our product collection, without losing the filter attributes? There are enough products to show filters.

UPDATE

I found out that the moment I add this filter, an error is thrown: https://www.dropbox.com/s/y71a032fe3n1pvr/Schermafbeelding%202017-11-30%20om%2010.21.17.png?dl=0

The filter does work fine, only this error is the real cause that the filter attributes don't show up.

0

Use addAttributeToFilter like this:

<?php 
namespace Silvan\StockStatus\Plugin\Catalog\Model;

class Layer
{
    /**
     * afterGetProductCollection method
     *
     * @param                                                                $subject
     * @param \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $collection
     *
     * @return mixed
     */
    public function afterGetProductCollection($subject, $collection)
    {
        $collection->addAttributeToSelect('bgs_stock_status');

        $collection->addAttributeToFilter(
        'bgs_stock_status', 
             array('lt' => 3)
             array('null' => TRUE)
        );

        $collection->getSize();

        return $collection;
    }
}
  • This does not work, by default the value of bgs_stock_status is null. If I filter on lt => 3 all products that don't have a value for bgs_stock_status will not show – Silvan Nov 23 '17 at 21:55
  • so you want to check both: Null and less then 3? – Abhishek Panchal Nov 23 '17 at 21:58
  • yes, if bgs_stock_status is null or less then 3 the product should show – Silvan Nov 23 '17 at 22:01
  • I updated my answer – Abhishek Panchal Nov 23 '17 at 22:01
  • 1
    thanks, unfortunately still not working. I don't think '' is equal to null right? – Silvan Nov 23 '17 at 22:03
0

I tested this and the Illegal State error doesn't seem to be coming from the addAttributeToFilter but seems to start when $collection->getSize(); is used (alteast in my case). This is on 2.1.8 installation but maybe try commenting that to see if your filters then show:

class Layer
{
/**
 * afterGetProductCollection method
 *
 * @param                                                                $subject
 * @param \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $collection
 *
 * @return mixed
 */
public function afterGetProductCollection($subject, $collection)
{
    $collection->addAttributeToSelect('bgs_stock_status');
    $collection->addAttributeToFilter(
        [
            ['attribute' => 'bgs_stock_status', 'is' => new \Zend_Db_Expr('null')],
            ['attribute' => 'bgs_stock_status', 'lt' => 3],
        ]);

    //$collection->getSize();

    return $collection;
}
}

There are a few issues however for me i noticed that the layered navigation counts were not updated correctly which is what getSize() should sort out.

This filter also didn't work as expected for me as null products were not showing so I did this however seems to be working fine for you thought i would mention anyway:

$collection->addAttributeToFilter('bgs_stock_status', 
        array('or'=> array(
            0 => array('lt' => '3'),
            1 => array('is' => new \Zend_Db_Expr('null')))
    ), 'left');

Update

Not sure if this is the same bug but has been mentioned and apparently fixed but i couldn't find a workaround:

https://github.com/magento/magento2/issues/9195

After looking again today i'm not sure this is the best approach for achieving an additional filter as there are lot of posts on here with issues with this method.

The 2 cases with a solution show a slightly more long winded approach of achieving this however works. See below answers that may help you further to get this working correctly:

How to update category page with custom filters, and also layered navigation, Magento 2.1

Magento 2.1.6 Product Grid page count and record count issue when programmatically adding filter using different methods

  • Removing the getSize() does not solve the filters not showing for me. – Silvan Jan 10 '18 at 15:50
  • Strange, i used your exact code and filters did not get removed at any point. The whole page would just show the Illegal State error when adding getSize however. This was in developer mode. – harri Jan 10 '18 at 15:58
  • So without it is the illegal state error there? Just wondering if this error is unrelated to your issue now? – harri Jan 10 '18 at 16:00
  • Hmm interesting, I get this error now: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'e.bgs_stock_status' in 'where clause' – Silvan Jan 10 '18 at 16:10
  • Hmm i remember having this issue once when i turned flat catalog off it was when making a new sort option however and had to find another way of making sure the attribute was available. Strange tho i never had this show up. – harri Jan 10 '18 at 18:03
0

I have a same kind of problem So I solved this way in my di.xml

<virtualType name="Magento\CatalogSearch\Model\Layer\Search\Context" type="Magento\Catalog\Model\Layer\Search\Context">
    <arguments>
        <argument name="collectionProvider" xsi:type="object">Vendor\Module\Model\Layer\ItemCollectionProvider</argument>
    </arguments>
</virtualType>
<virtualType name="Magento\CatalogSearch\Model\Layer\Category\Context" type="Magento\Catalog\Model\Layer\Category\Context">
    <arguments>
        <argument name="collectionProvider" xsi:type="object">Vendor\Module\Model\Layer\ItemCollectionProvider</argument>
    </arguments>
</virtualType>

and in my Vendor\Module\Model\Layer\ItemCollectionProvider file

public function getCollection(\Magento\Catalog\Model\Category $category){
     $collection = $this->collectionFactory->create();

   // here my code
       return $collection;
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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