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'; } }