cancel
Showing results for 
Search instead for 
Did you mean: 

get all Attributes in layered navigation even if it is active in magento 2.3

get all Attributes in layered navigation even if it is active in magento 2.3

Hello guys,

I want to get active filters in layered navigation (in filters.phtml), I want to send active filters with the items of filters, I have overridden the model attribute.php, category.php, and item.php in Magento\Catalog\Model\Layer\Filter

I know I need to rewire the _getItemsData method in Attribute.php but I'm not getting the idea of how it should be done.

Please help me if u know the answer

 

Attribute.php

<?php

namespace Mofosys\Filters\Model\Layer\Filter;

use Magento\Catalog\Model\Layer\Filter\AbstractFilter;

class Attribute extends AbstractFilter {

    /**
     * @var \Magento\Framework\Filter\StripTags
     */
    private $tagFilter;
    public $appliedFilter;
    public $filterPlus;

    /**
     * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Catalog\Model\Layer $layer
     * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder
     * @param \Magento\Framework\Filter\StripTags $tagFilter
     * @param array $data
     */
    public function __construct(
    \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Layer $layer, \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder, \Magento\Framework\Filter\StripTags $tagFilter, array $data = []
    ) {
        parent::__construct(
                $filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data
        );
        $this->tagFilter = $tagFilter;
        $this->appliedFilter = [];
        $this->filterPlus = false;

//        $this->_requestVar = 'attribute';
    }

    /**
     * Apply attribute option filter to product collection
     *
     * @param \Magento\Framework\App\RequestInterface $request
     * @return $this
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function apply(\Magento\Framework\App\RequestInterface $request) {


        $filter = $request->getParam($this->_requestVar);

        if (!$filter || is_array($filter)) {
            return $this;
        }

        $this->appliedFilter = $filter;
        $filters = explode(',', $filter);


        $attribute = $this->getAttributeModel();
        $productCollection = $this->getLayer()->getProductCollection();
        // apply filtter to collection
        $productCollection->addFieldToFilter($attribute->getAttributeCode(), ["finset" => $filters]);

        foreach ($filters as $option) {
            $text = $this->getOptionText($option);
            if ($option && strlen($text)) {
                $this->getLayer()->getState()->addFilter(
                        $this->_createItem($text, $option)
                );
            }
        }

        return $this;
    }

    public function isActive() {
        return $this->filterPlus;
    }

    /**
     * Get data array for building attribute filter items
     *
     * @return array
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    protected function _getItemsData() {
        $attribute = $this->getAttributeModel();

        /** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
        $productCollection = $this->getLayer()
                ->getProductCollection();
        $optionsFacetedData = $productCollection->getFacetedData($attribute->getAttributeCode());

        $isAttributeFilterable = $this->getAttributeIsFilterable($attribute) === static::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS;

        $activeFilters = [];
        if ($this->appliedFilter) {
            $activeFilters = explode(',', $this->appliedFilter);
        }
        if (count($optionsFacetedData) === 0 && !$isAttributeFilterable) {
            return $this->itemDataBuilder->build();
        }

        $productSize = $productCollection->getSize();

        $options = $attribute->getFrontend()
                ->getSelectOptions();
        foreach ($options as $option) {
            $active = in_array($option['value'], $activeFilters);
//            $this->itemDataBuilder->addItemData(
//                    $this->tagFilter->filter($option['label']), $option['value'], $count, $active, $this->filterPlus
//            );

            $this->buildOptionData($option, $isAttributeFilterable, $optionsFacetedData, $productSize, $active);
        }

        return $this->itemDataBuilder->build();
    }

    /**
     * Build option data
     *
     * @param array $option
     * @param boolean $isAttributeFilterable
     * @param array $optionsFacetedData
     * @param int $productSize
     * @return void
     */
    private function buildOptionData($option, $isAttributeFilterable, $optionsFacetedData, $productSize, $active) {
        $value = $this->getOptionValue($option);
        if ($value === false) {
            return;
        }
        $count = $this->getOptionCount($value, $optionsFacetedData);
        if ($isAttributeFilterable && (!$this->isOptionReducesResults($count, $productSize) || $count === 0)) {
            return;
        }

        $this->itemDataBuilder->addItemData(
                $this->tagFilter->filter($option['label']), $value, $count, $active
        );
    }

    /**
     * Retrieve option value if it exists
     *
     * @param array $option
     * @return bool|string
     */
    private function getOptionValue($option) {
        if (empty($option['value']) && !is_numeric($option['value'])) {
            return false;
        }
        return $option['value'];
    }

    /**
     * Retrieve count of the options
     *
     * @param int|string $value
     * @param array $optionsFacetedData
     * @return int
     */
    private function getOptionCount($value, $optionsFacetedData) {
        return isset($optionsFacetedData[$value]['count']) ? (int) $optionsFacetedData[$value]['count'] : 0;
    }

}

 

category.php

<?php

//Done

namespace Mofosys\Filters\Model\Layer\Filter;

use Magento\Catalog\Model\Layer\Filter\DataProvider\Category as CategoryDataProvider;
use Magento\Catalog\Model\Layer\Filter\DataProvider\CategoryFactory;

/**
 * Layer category filter
 */
class Category extends \Magento\Catalog\Model\Layer\Filter\AbstractFilter {

    /**
     * Active Category Id
     *
     * @var int
     */
    protected $_categoryId;

    /**
     * Applied Category
     *
     * @var \Magento\Catalog\Model\Category
     */
    protected $_appliedCategory;

    /**
     * Core data
     *
     * @var \Magento\Framework\Escaper
     */
    protected $_escaper;

    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry;

    /**
     * @var CategoryDataProvider
     */
    private $dataProvider;
    protected $filterPlus;

    /**
     * Construct
     *
     * @param \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Catalog\Model\Layer $layer
     * @param \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder
     * @param \Magento\Framework\Escaper $escaper
     * @param CategoryFactory $categoryDataProviderFactory
     * @param array $data
     */
    public function __construct(
    \Magento\Catalog\Model\Layer\Filter\ItemFactory $filterItemFactory, \Magento\Store\Model\StoreManagerInterface $storeManager, \Magento\Catalog\Model\Layer $layer, \Magento\Catalog\Model\Layer\Filter\Item\DataBuilder $itemDataBuilder, \Magento\Framework\Escaper $escaper, CategoryFactory $categoryDataProviderFactory, array $data = []
    ) {
        parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
        $this->_escaper = $escaper;
        $this->_requestVar = 'cat';
        $this->dataProvider = $categoryDataProviderFactory->create(['layer' => $this->getLayer()]);
        $this->appliedFilter = [];
        $this->filterPlus = false;
    }

    /**
     * Get filter value for reset current filter state
     *
     * @return mixed|null
     */
    public function getResetValue() {
        return $this->dataProvider->getResetValue();
    }

    /**
     * Apply category filter to layer
     *
     * @param   \Magento\Framework\App\RequestInterface $request
     * @return  $this
     */
    public function apply(\Magento\Framework\App\RequestInterface $request) {
//        echo 'hello';
        $categoryId = $request->getParam($this->_requestVar) ?: $request->getParam('id');
        if (empty($categoryId)) {
            return $this;
        }
        if ($request->getParam('id') != $categoryId) {

            if (!$this->filterPlus) {
                $this->filterPlus = true;
            }
            $productCollection->addCategoriesFilter(['in' => $categoryIds]);
            $category = $this->getLayer()->getCurrentCategory();
            $child = $category->getCollection()
                    ->addFieldToFilter($category->getIdFieldName(), ['in' => $categoryIds])
                    ->addAttributeToSelect('name');
            $categoriesInState = [];
            foreach ($categoryIds as $categoryId) {
                if ($currentCategory = $child->getItemById($categoryId)) {
                    $categoriesInState[$currentCategory->getId()] = $currentCategory->getName();
                }
            }
            foreach ($categoriesInState as $key => $category) {
                $state = $this->_createItem($category, $key);
                $this->getLayer()->getState()->addFilter($state);
            }
        }

        return $this;
    }

    /**
     * Get data array for building category filter items
     *
     * @return array
     */
    protected function _getItemsData() {

        $productCollection = $this->getLayer()->getProductCollection();
        $optionsFacetedData = $productCollection->getFacetedData('category');
        $category = $this->dataProvider->getCategory();
        $categories = $category->getChildrenCategories();
        $collectionSize = $productCollection->getSize();
        $activeFilters = [];

        if ($this->appliedFilter) {
            $activeFilters = explode(',', $this->appliedFilter);
        }

        $currentProductIds = $productCollection->getAllIds();

        $this->getLayer()->getProductCollection()->addCountToCategories($categories);
        if ($category->getIsActive()) {
            foreach ($categories as $category) {
//                print_r($optionsFacetedData[$category->getId()]);
                echo 'category';

                if ($category->getIsActive() && isset($optionsFacetedData[$category->getId()])
                ) {
                    $active = in_array($category->getId(), $activeFilters);
                    $this->_itemBuilder->addItemData(
                            $this->escaper->escapeHtml($category->getName()), $category->getId(), $optionsFacetedData[$category->getId()]['count'], $active, $this->filterPlus
                    );
                }
            }
        }
        return $this->itemDataBuilder->build();
    }

    /**
     * Get filter name
     *
     * @return \Magento\Framework\Phrase
     */
    public function getName() {
        return __('Category');
    }

}

 

item.php

<?php

/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
/**
 * Filter item model
 *
 * @author      Magento Core Team <core@magentocommerce.com>
 */

namespace Mofosys\Filters\Model\Layer\Filter;

class Item extends \Magento\Catalog\Model\Layer\Filter\Item {

    /**
     * Url
     *
     * @var \Magento\Framework\UrlInterface
     */
    protected $_url;

    /**
     * Html pager block
     *
     * @var \Magento\Theme\Block\Html\Pager
     */
    protected $_htmlPagerBlock;

    /**
     * Construct
     *
     * @param \Magento\Framework\UrlInterface $url
     * @param \Magento\Theme\Block\Html\Pager $htmlPagerBlock
     * @param array $data
     */
    public function __construct(
    \Magento\Framework\UrlInterface $url, \Magento\Theme\Block\Html\Pager $htmlPagerBlock
    ) {
        $this->_url = $url;
        $this->_htmlPagerBlock = $htmlPagerBlock;
    }

    /**
     * Get filter instance
     *
     * @return \Magento\Catalog\Model\Layer\Filter\AbstractFilter
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function getFilter() {
        $filter = $this->getData('filter');
        if (!is_object($filter)) {
            throw new \Magento\Framework\Exception\LocalizedException(
            __('The filter must be an object. Please set the correct filter.')
            );
        }
        return $filter;
    }

    /**
     * Get filter item url
     *
     * @return string
     */
    public function getUrl() {
        $filter = $this->getFilter();
        $filterUrlValue = $this->getValue();
//        echo $filterUrlValue;
//        print_r($filter->appliedFilter);
//        die;

        $query = [
            $this->getFilter()->getRequestVar() => $this->getValue(),
            // exclude current page from urls
            $this->_htmlPagerBlock->getPageVarName() => null,
        ];

        return $this->_url->getUrl('*/*/*', ['_current' => true, '_use_rewrite' => true, '_query' => $query]);
    }

    /**
     * Get url for remove item from filter
     *
     * @return string
     */
    public function getRemoveUrl() {
        $query = [$this->getFilter()->getRequestVar() => $this->getFilter()->getResetValue()];
        $params['_current'] = true;
        $params['_use_rewrite'] = true;
        $params['_query'] = $query;
        $params['_escape'] = true;
        return $this->_url->getUrl('*/*/*', $params);
    }

    /**
     * Get url for "clear" link
     *
     * @return false|string
     */
    public function getClearLinkUrl() {
        $clearLinkText = $this->getFilter()->getClearLinkText();
        if (!$clearLinkText) {
            return false;
        }

        $urlParams = [
            '_current' => true,
            '_use_rewrite' => true,
            '_query' => [$this->getFilter()->getRequestVar() => null],
            '_escape' => true,
        ];
        return $this->_url->getUrl('*/*/*', $urlParams);
    }

    /**
     * Get item filter name
     *
     * @return string
     */
    public function getName() {
        return $this->getFilter()->getName();
    }

    /**
     * Get item value as string
     *
     * @return string
     */
    public function getValueString() {
        $value = $this->getValue();
        if (is_array($value)) {
            return implode(',', $value);
        }
        return $value;
    }
    
    
     public function getTest() {
         
        return 'test';
    }

}