Magento Asked on December 26, 2021
I have a custom product attribute brands
, this is a dropdown option that has dynamic select value, basically i want to add a custom layer navigation filter to check whether the product attribute value is filled or not, I tried to create a custom filter for layered navigation like this:
app/code/Vendor/Module/etc/di.xml
<type name="MagentoCatalogModelLayerFilterList">
<plugin disabled="false" name="custom_filter_plugin" sortOrder="10" type="VendorModulePluginMagentoCatalogModelLayerFilterList"/>
</type>
app/code/Vendor/Module/Plugin/Magento/Catalog/Model/Layer/FilterList.php
class FilterList
{
const IS_BRANDS_FILTER_CLASS = 'VendorModuleModelLayerFilterIsBrands';
public function __construct(
MagentoFrameworkObjectManagerInterface $objectManager
) {
$this->_objectManager = $objectManager;
}
public function beforeGetFilters(
MagentoCatalogModelLayerFilterList $subject,
$layer
) {
//Your plugin code
$layer->getProductCollection()->addAttributeToSelect('brands');
return [$layer];
}
public function afterGetFilters(
MagentoCatalogModelLayerFilterList $subject,
$result,
$layer
) {
$result[] = $this->_objectManager->create(
self::IS_BRANDS_FILTER_CLASS,
['layer' => $layer]
);
return $result;
}
}
app/code/Vendor/Module/Model/Layer/Filter/IsBrands.php
class IsBrands extends MagentoCatalogModelLayerFilterAbstractFilter
{
const FILTER_IS_BRANDS = 1;
const FILTER_IS_NOT_BRANDS = 2;
protected $_activeFilter = false;
protected $_requestVar = 'is_brands';
/**
* @param MagentoCatalogModelLayerFilterItemFactory $filterItemFactory
* @param MagentoStoreModelStoreManagerInterface $storeManager
* @param MagentoCatalogModelLayer $layer
* @param MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder
* @param array $data
*/
public function __construct(
MagentoCatalogModelLayerFilterItemFactory $filterItemFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelLayer $layer,
MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder,
array $data = []
) {
parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
$this->_requestVar = 'is_brands';
}
/**
* @param MagentoFrameworkAppRequestInterface $request
* @return $this
*/
public function apply(MagentoFrameworkAppRequestInterface $request)
{
$filter = $request->getParam($this->getRequestVar(), null);
if (is_null($filter)) {
return $this;
}
$this->_activeFilter = true;
$filter = $filter;
$collection = $this->getLayer()->getProductCollection();
if ($filter == self::FILTER_IS_BRANDS) {
// $select->where('`e`.`brands` IS NOT NULL');
$collection->addAttributeToFilter('brands',array('gteq','1'));
} else {
// $select->where('(`e`.`brands` IS NULL OR `e`.`brands` = 0)');
$collection->addAttributeToFilter('brands',array('lt','1'));
}
$this->getLayer()->getState()->addFilter(
$this->_createItem($this->getLabel($filter), $filter)
);
return $this;
}
/**
* Get filter name
*
* @return string
*/
public function getName()
{
return __('Is Brands');
}
/**
* Get data array for building status filter items
*
* @return array
*/
protected function _getItemsData()
{
// if ($this->getLayer()->getProductCollection()->getFlag(self::IN_STOCK_COLLECTION_FLAG)) {
// return [];
// }
$data = [];
foreach ($this->getStatuses() as $status) {
$data[] = [
'label' => $this->getLabel($status),
'value' => $status,
'count' => $this->getProductsCount($status)
];
}
return $data;
}
/**
* get available statuses
* @return array
*/
public function getStatuses()
{
return [
self::FILTER_IS_BRANDS,
self::FILTER_IS_NOT_BRANDS
];
}
/**
* @return array
*/
public function getLabels()
{
return [
self::FILTER_IS_BRANDS => __('Is Brands'),
self::FILTER_IS_NOT_BRANDS => __('Is not Brands'),
];
}
/**
* @param $value
* @return string
*/
public function getLabel($value)
{
$labels = $this->getLabels();
if (isset($labels[$value])) {
return $labels[$value];
}
return '';
}
/**
* @param $value
* @return string
*/
public function getProductsCount($value)
{
$collection = $this->getLayer()->getProductCollection();
$select = clone $collection->getSelect();
// reset columns, order and limitation conditions
$select->reset(Zend_Db_Select::COLUMNS);
$select->reset(Zend_Db_Select::ORDER);
$select->reset(Zend_Db_Select::LIMIT_COUNT);
$select->reset(Zend_Db_Select::LIMIT_OFFSET);
// $select->where('stock_status_index.stock_status = ?', $value);
if ($value == self::FILTER_IS_BRANDS) {
// $select->where('`e`.`brands` IS NOT NULL');
$collection->addAttributeToFilter('brands',array('gteq','1'));
} else {
// $select->where('(`e`.`brands` IS NULL OR `e`.`brands` = 0)');
$collection->addAttributeToFilter('brands',array('lt','1'));
}
$select->columns(
[
'count' => new Zend_Db_Expr("COUNT(e.entity_id)")
]
);
return $collection->getConnection()->fetchOne($select);
}
}
but I always get an error in a phtml when trying to get active filters
<?php $activeFilters = $block->getActiveFilters() ?>
Exception #0 (MagentoFrameworkExceptionLocalizedException): The attribute model is not defined.
Please update the contractor as below in this file and try app/code/Vendor/Module/Model/Layer/Filter/IsBrands.php
From:
public function __construct(
MagentoCatalogModelLayerFilterItemFactory $filterItemFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelLayer $layer,
MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder,
array $data = []
) {
parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
$this->_requestVar = 'is_brands';
}
To:
public function __construct(
MagentoCatalogModelLayerFilterItemFactory $filterItemFactory,
MagentoStoreModelStoreManagerInterface $storeManager,
MagentoCatalogModelLayer $layer,
MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder,
MagentoEavModelEntityAttribute $entityAttribute,
array $data = []
) {
parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
$attribute = $entityAttribute->loadByCode('catalog_product', 'brands');
$this->setAttributeModel($attribute);
$this->_requestVar = 'is_brands';
}
Answered by Ritesh Santra on December 26, 2021
Get help from others!
Recent Questions
Recent Answers
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP