Magento 2 : Rating Filter in Layered Navigation
create one file Called Rating.php as of now i did in core module only which can be implemented in your custom module vendor\magento\module-catalog\Model\Layer\Filter\Rating.php
<?php
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Catalog\Model\Layer\Filter;
use Magento\Catalog\Model\Category as CategoryModel;
use Magento\Catalog\Model\CategoryFactory as CategoryModelFactory;
use Magento\Catalog\Model\Layer;
use Magento\Framework\Registry;
/**
* Layer category filter
*
* @author Magento Core Team <[email protected]>
*/
class Rating 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;
/**
* 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,
array $data = []
) {
parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
$this->_escaper = $escaper;
$this->_requestVar = 'rat';
}
/**
* 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)
{
/**
* Filter must be string: $fromPrice-$toPrice
*/
$filter = $request->getParam($this->getRequestVar());
if (!$filter) {
return $this;
}
$filter = explode('-', $filter);
list($from, $to) = $filter;
$collection = $this->getLayer()->getProductCollection();
$collection->getSelect()->joinLeft(array('rova'=> 'rating_option_vote_aggregated'),'e.entity_id =rova.entity_pk_value',array("percent"))
->where("rova.percent between ".$from." and ".$to)
->group('e.entity_id');
//$this->getLayer()->getState()->addFilter($this->_createItem($text, $filter));
//$collection->printlogquery(true);
return $this;
}
/**
* Get filter name
*
* @return \Magento\Framework\Phrase
*/
public function getName()
{
return __('Rating');
}
/**
* Get data array for building attribute filter items
*
* @throws \Magento\Framework\Exception\LocalizedException
* @return array
*/
protected function _getItemsData()
{
$facets = array(
'0-20'=>'1 Start',
'21-40'=>'2 Start',
'41-60'=>'3 Start',
'61-80'=>'4 Start',
'81-100'=>'5 Start'
);
$collection = $this->getLayer()->getProductCollection();
$data = [];
if (count($facets) > 1) { // two range minimum
$i=1;
foreach ($facets as $key => $label) {
$count=$this->prepareData($key,$collection,$i);
$i++;
$this->itemDataBuilder->addItemData(
$this->_escaper->escapeHtml($label),
$key,
$count
);
}
}
return $this->itemDataBuilder->build();
/* $this->itemDataBuilder->addItemData(
$this->tagFilter->filter('5 star'),
'80-100',
1
);
return $this->itemDataBuilder->build(); */
}
/**
* @param string $key
* @param int $count
* @return array
*/
private function prepareData($filter,$collection,$i)
{
$filter = explode('-', $filter);
list($from, $to) = $filter;
/** @var \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection $productCollection */
$collection->getSelect()->joinLeft(array('rova'.$i=> 'rating_option_vote_aggregated'),'e.entity_id =rova'.$i.'.entity_pk_value',array("percent"))
->where("rova".$i.".percent between ".$from." and ".$to)
->group('e.entity_id');
//$collection->printlogquery(true); echo '<br>............................<br>';
return $collection->getSize();
}
}
and in vendor\magento\module-catalog\Model\Layer\FilterList.php add rating filter option if you wrote custom module add this option by plugin
public function getFilters(\Magento\Catalog\Model\Layer $layer)
{
if (!count($this->filters)) {
$this->filters = [
$this->objectManager->create($this->filterTypes[self::CATEGORY_FILTER], ['layer' => $layer]),
$this->objectManager->create($this->filterTypes['Magento\Catalog\Model\Layer\Filter\Rating'], ['layer' => $layer]),
];
foreach ($this->filterableAttributes->getList() as $attribute) {
$this->filters[] = $this->createAttributeFilter($attribute, $layer);
}
}
return $this->filters;
}
it will bring rating filter and do filter with product collection but still product count and adding to state i not done if some one did please pot it