TransWikia.com

Magento 2.3 Custom Filter Layer Navigation Error: The attribute model is not defined

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.

One Answer

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

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP