3

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.

1
  • did you found any solution for this. I am getting the same error for Layered navigation only on search result page. Commented Dec 30, 2019 at 12:20

3 Answers 3

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;
    }
}
8
  • 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
    Commented Nov 23, 2017 at 21:55
  • so you want to check both: Null and less then 3? Commented Nov 23, 2017 at 21:58
  • yes, if bgs_stock_status is null or less then 3 the product should show
    – Silvan
    Commented Nov 23, 2017 at 22:01
  • I updated my answer Commented Nov 23, 2017 at 22:01
  • 1
    thanks, unfortunately still not working. I don't think '' is equal to null right?
    – Silvan
    Commented Nov 23, 2017 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

7
  • Removing the getSize() does not solve the filters not showing for me.
    – Silvan
    Commented Jan 10, 2018 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
    Commented Jan 10, 2018 at 15:58
  • So without it is the illegal state error there? Just wondering if this error is unrelated to your issue now?
    – harri
    Commented Jan 10, 2018 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
    Commented Jan 10, 2018 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
    Commented Jan 10, 2018 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 and acknowledge you have read our privacy policy.

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