6
$myattr = $this->catalogSession->getData('myattribute');
if(!empty($myattr)){
    $collection = $this->_catalogLayer->getProductCollection();
    $attribute = $this->eavConfig->getAttribute('catalog_product', 'myattribute');
    $option_id = $attribute->getSource()->getOptionId($myattr);
    $collection->addAttributeToFilter('myattribute',array('finset'=>$option_id));
}

in Block/Category/MyattributeChooser.php in the _prepareLayout function

This works if I have caching disabled OR I select any filter at all. It does not work if caching is enabled but I used my custom chooser and no other filters are displayed.

I need to know how to make it work. This is on a categories page. I could just totally turn off caching for the chooser but that isn't a very good answer.

I've found too that although it works it doesn't recalculate pagination either. $collection->getSize() results in an Illegal State error and $collection->clear() and $collection->resetData() have no effect on anything whatsoever. $collection->isLoaded() returns NULL.

2
  • Can you provide more details ? what are you trying to do ? Mar 18, 2017 at 7:15
  • What I want to do is very easy or so I thought. The store is a parts store. You select your year, make, line, model using a custom chooser I made. This all works. Then when you select the car it needs to filter by those attributes. So if the part fits then show it and if it doesn't then don't. Basically all I need to do is add a where condition to the sql select before magento does all it's weird stuff on it this seemed the route to go.
    – user44406
    Mar 18, 2017 at 18:59

1 Answer 1

2

In MyCompany/MyModule/etc/di.xml:

<?xml version="1.0"?>
<!--
/**
 * @copyright Copyright (c) 2016 https://chillydraji.wordpress.com
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
        <plugin name="AddFilter" type="MyCompany\MyModule\Model\Plugin\AddFilter"/>
    </type>
</config>

In MyCompany/MyModule/Model/Plugin/AddFilter.php

<?php namespace MyCompany\MyModule\Model\Plugin;

use Magento\Catalog\Model\ResourceModel\Product\Collection as ProductCollection;

class AddFilter
{
    /**
     * aroundAddFieldToFilter method
     *
     * @param \Magento\Catalog\Model\ResourceModel\Product\Collection $collection
     * @param \Closure                                                $proceed
     * @param                                                         $fields
     * @param null                                                    $condition
     *
     * @return \Magento\Catalog\Model\ResourceModel\Product\Collection
     */
    public function aroundAddFieldToFilter(ProductCollection $collection, \Closure $proceed, $fields, $condition = null)
    {
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $eavConfig = $objectManager->create('\Magento\Eav\Model\Config');
        $session = $objectManager->create('\Magento\Catalog\Model\Session');
        $attribute = $eavConfig->getAttribute('catalog_product', 'carfilter');
        $car_attr = $session->getData('car_attr');
        if(!empty($car_attr)){
            $option_id = $attribute->getSource()->getOptionId($car_attr);
            $collection->addAttributeToFilter('carfilter',array('finset'=>$option_id));
        }

        return $fields ? $proceed($fields, $condition) : $collection;
    }
}

Info on how to do the di.xml and class taken from here: Magento2 - How to filter product collection on category view

However, it still is really esoteric and I don't like it but it works and no one answered me.

Additionally, for filters to work with cache being enabled you have to utilize adding the filter value to the URL as a GET string, or fetch such a page with AJAX, this is how the layered navigation does it.

1
  • 3
    Don't use $objectManager = \Magento\Framework\App\ObjectManager::getInstance().
    – Sohel Rana
    Mar 21, 2017 at 3:59

Your Answer

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