I am trying to write a module that filters products in a product collection. For that I have tried to override Magento\Catalog\Model\Layer. These are the files in the module:
/Viking/FilterProducts/registration.php
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE,
'Viking_FilterProducts',
__DIR__
);
?>
/Viking/FilterProducts/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">
<preference for="Magento\Catalog\Model\Layer" type="Viking\FilterProducts\Model\Layer" />
</config>
/Viking/FilterProducts/etc/module.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
<module name="Viking_FilterProducts" setup_version="1.0.0"/>
</config>
/Viking/FilterProducts/Module/Layer.php
<?php
namespace Viking\FilterProducts\Model;
class Layer extends \Magento\Catalog\Model\Layer{
protected $_customerSession;
protected $_resource;
public function __construct(
\Magento\Catalog\Model\Layer\ContextInterface $context,
\Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
AttributeCollectionFactory $attributeCollectionFactory,
\Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
\Magento\Store\Model\StoreManagerInterface $storeManager,
\Magento\Framework\Registry $registry,
CategoryRepositoryInterface $categoryRepository,
array $data = []
) {
$this->_resource = $resource;
$this->_customerSession = $customerSession;
parent::__construct(
$context,
$layerStateFactory,
$attrubuteCollectionFactory,
$catalogProduct,
$registry,
$categoryRopository,
$data
);
}
//Old funciton with print statement
public function getProductCollection(){
if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
$collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
} else {
$collection = $this->collectionProvider->getCollection($this->getCurrentCategory());
//Will filter products here
$this->prepareProductCollection($collection);
$this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
}
echo 'New Layer <br />';
return $collection;
}
}
?>
It is still the old Layer that is called. I have overridden other classes in the same way but this time it doesn't work and I don't know why.Been stuck at this point really long now. No error messages.
removing constructor (which will be used) does not make any difference.
Edit
I changed the module.xml file as @dersam suggested but it did not help. I also added an composer.json file in Viking/FilterProducts that look like this:
{
"name": "Viking/FilterProducts",
"type": "magento2-module",
"version": "1.0.0",
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0",
"magento/module-catalog": "~100.0"
}
}
This did not make any difference either but I am not sure if it is correct. (I ran disable/enable command and then setup and compile commands). The module shows up as enabled when running module:status.
Best Answer
I think I know the problem. You are overriding the incorrect class. Layer model used in layered navigation is created in a constructor of
Magento\LayeredNavigation\Block\Navigation
class by this piece of code$layoutResolver->get()
method looks like this:So it creates a class based on a list of layerPool property which is set in layoutResover class constructor. By default this array contain 2 values:
So either create a preference for the class you want to change it, probably
Magento\Catalog\Model\Layer\Category
or change the class name passed to layoutResolver class. The original setup can be found inMagento_Catalog/etc/di.xml
: