I try add custom product filters.
Add filter code
<?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 <core@magentocommerce.com> */ 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; }
Filter is work but not work correct pagination. $collection->getSize() - is not correct count.