In order to add a custom filter to the Layered Navigation, I overrode the class Magento\LayeredNavigation\Block\Navigation\Category to load my own FilterList class instead of the one from core.
My custom FilterList simply adds another step when determining which Filter class to apply. The custom Filter class simply applies a stepping of 4 on a decimal attribute (instead of the standard steppings).
But, as soon as I use this custom FilterList class instead of the one from the Magento 2 module, the Layered Navigation always shows the pagination options as well as the wrong Collection size. The filtering is done correctly (only the filtered products show up), but also the pagination shows with the wrong size:
There is a total of 13 products in this category, but the Collection that is used to determine the pagination always has a size of 13, no matter what filter I activate.
This error does not occur when I load the default FilterList class in Magento\LayeredNavigation\Block\Navigation\Category.
The custom FilterList class:
class FilterList extends \Magento\Catalog\Model\Layer\FilterList
{
const CUSTOM_FILTER_STRING = 'customString';
protected $filterTypes = [
self::CATEGORY_FILTER => \Magento\Catalog\Model\Layer\Filter\Category::class,
self::ATTRIBUTE_FILTER => \Magento\Catalog\Model\Layer\Filter\Attribute::class,
self::PRICE_FILTER => \Magento\Catalog\Model\Layer\Filter\Price::class,
self::DECIMAL_FILTER => \Magento\Catalog\Model\Layer\Filter\Decimal::class,
self::CUSTOM_FILTER => \Vendor\Module\Model\Layer\Filter\CustomFilter::class
];
protected function getAttributeFilterClass(\Magento\Catalog\Model\ResourceModel\Eav\Attribute $attribute)
{
$filterClassName = $this->filterTypes[self::ATTRIBUTE_FILTER];
if ($attribute->getAttributeCode() == 'price') {
$filterClassName = $this->filterTypes[self::PRICE_FILTER];
} elseif (substr($attribute->getAttributeCode(), 0, 9) == 'customStr') {
$filterClassName = $this->filterTypes[self::CUSTOM_FILTER];
} elseif ($attribute->getBackendType() == 'decimal') {
$filterClassName = $this->filterTypes[self::DECIMAL_FILTER];
}
return $filterClassName;
}
}
The etc/frontend/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">
<virtualType name="Magento\LayeredNavigation\Block\Navigation\Category" type="Vendor\Module\Block\LayeredNavigation\Navigation">
<arguments>
<argument name="filterList" xsi:type="object">categoryFilterList</argument>
</arguments>
</virtualType>
<!-- Override the Interface class to avoid an Interface Instantiation error from Magento. -->
<preference for="Magento\Catalog\Model\Layer\FilterableAttributeListInterface" type="Magento\Catalog\Model\Layer\Category\FilterableAttributeList"/>
</config>