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