TransWikia.com

How to add rating in leyerd navigation in Magento 2

Magento Asked on January 10, 2021

Add rating tab in layered navigation in magento 2

I want override MagentoCatalogModelLayerFilterList to
VenderModulenameModelLayerFilterList

<preference for="MagentoCatalogModelLayerFilterList" type="VenderModulenameModelLayerFilterList" />

But it’s not working

Magento 2 : Rating Filter in Layered Navigation

also try to above link it’s working fine but how to implement in our module b’coz it’s core file

Can anyone give me suggestion.

3 Answers

in app/code/Vender/Modulename/etc/di.xml

<type name="MagentoCatalogModelLayerFilterList">
        <plugin name="filterlist" type="VenderModulenameModelLayerFilterList"/>
</type>

app/code/Vender/Modulename/Model/Layer/FilterList.php

<?php
/**
 * Copyright © 2016 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace VenderModulenameModelLayer;


    class FilterList 
    {


        public function __construct(
            MagentoCatalogBlockProductContext $context,
            MagentoFrameworkObjectManagerInterface $objectManager


        ) {
            $this->objectManager = $objectManager;                  

        }


        public function aroundGetFilters( MagentoCatalogModelLayerFilterList $subject, Closure $proceed, MagentoCatalogModelLayer $layer)
        {


            $result = $proceed($layer);
            $result[] = $this->objectManager->create('VenderModulenameModelLayerFilterRating', ['layer' => $layer]);

            return $result;

        }


    }
    ?>

app/code/Vender/Modulename/Model/Layer/Filter/Rating.php

<?php
/**
 * Copyright © 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vender/ModulenameModelLayerFilter;


use MagentoCatalogModelCategory as CategoryModel;
use MagentoCatalogModelCategoryFactory as CategoryModelFactory;
use MagentoCatalogModelLayer;
use MagentoFrameworkRegistry;
/**
 * Layer category filter
 *
 * @author      Magento Core Team <[email protected]>
 */
class Rating extends MagentoCatalogModelLayerFilterAbstractFilter
{
    /**
     * Active Category Id
     *
     * @var int
     */
    protected $_categoryId;

    /**
     * Applied Category
     *
     * @var MagentoCatalogModelCategory
     */
    protected $_appliedCategory;

    /**
     * Core data
     *
     * @var MagentoFrameworkEscaper
     */
    protected $_escaper;

    /**
     * Core registry
     *
     * @var MagentoFrameworkRegistry
     */
    protected $_coreRegistry;

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

    /**
     * Construct
     *
     * @param MagentoCatalogModelLayerFilterItemFactory $filterItemFactory
     * @param MagentoStoreModelStoreManagerInterface $storeManager
     * @param MagentoCatalogModelLayer $layer
     * @param MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder
     * @param MagentoFrameworkEscaper $escaper
     * @param CategoryFactory $categoryDataProviderFactory
     * @param array $data
     */
    public function __construct(
        MagentoCatalogModelLayerFilterItemFactory $filterItemFactory,
        MagentoStoreModelStoreManagerInterface $storeManager,
        MagentoCatalogModelLayer $layer,
        MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder,
        MagentoFrameworkEscaper $escaper,
        MagentoFrameworkObjectManagerInterface $objectManager,
        MagentoCatalogModelProduct $productModel,
        MagentoCatalogModelProductAttributeSourceStatus $productStatus,
        MagentoCatalogModelProductVisibility $productVisibility,
        array $data = []
    ) {
        parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
        $this->_escaper = $escaper;
        $this->objectManager = $objectManager; 
        $this->_productModel = $productModel;
        $this->productStatus = $productStatus;
        $this->productVisibility = $productVisibility;
        $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   MagentoFrameworkAppRequestInterface $request
     * @return  $this
     */
    public function apply(MagentoFrameworkAppRequestInterface $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 MagentoFrameworkPhrase
     */
    public function getName()
    {
        return __('Rating');
    }





       /**
     * Get data array for building attribute filter items
     *
     * @throws MagentoFrameworkExceptionLocalizedException
     * @return array
     */
    protected function _getItemsData()
    {
        $s1='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                        <div class="rating-result" title="20%">
                                            <span style="width:20%"><span>1</span></span>
                                        </div>
                                    </div>';

        $s2='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                        <div class="rating-result" title="40%">
                                            <span style="width:40%"><span>2</span></span>
                                        </div>
                                    </div>';

        $s3='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                        <div class="rating-result" title="60%">
                                            <span style="width:60%"><span>3</span></span>
                                        </div>
                                    </div>';

        $s4='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                        <div class="rating-result" title="80%">
                                            <span style="width:80%"><span>4</span></span>
                                        </div>
                                    </div>';

        $s5='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                        <div class="rating-result" title="100%">
                                            <span style="width:100%"><span>5</span></span>
                                        </div>
                                    </div>';


        $facets = array(
            '0-20'=>$s1,
            '21-40'=>$s2,
            '41-60'=>$s3,
            '61-80'=>$s4,
            '81-100'=>$s5,
            );

        $data = [];
        if (count($facets) > 1) { // two range minimum
            $i=1;
            foreach ($facets as $key => $label) {
            // $count=$this->prepareData($key,$collection,$i);
             $count='';
            $filter = explode('-', $key);
            list($from, $to) = $filter;

           $collection = $this->getLayer()->getProductCollection();

            $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'); 

            $count=count($collection);



               $i++;
              // echo $count;
               if($count > 0){
                   $this->itemDataBuilder->addItemData(
                        //$this->_escaper->escapeHtml($label),
                        $label,
                        $key,
                        $count
                    );

                    $count=0;
               }
            }
        }

        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 MagentoCatalogSearchModelResourceModelFulltextCollection $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();
    }
}
?>

Correct answer by John on January 10, 2021

I have used the following code for custom prices.

    <?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="MagentoCatalogModelLayerFilterList">
        <plugin disabled="false" name="BA_BasysPriceLayeredNav_Layer_FilterList" sortOrder="10" type="BABNavPluginFrontendMagentoCatalogModelLayerFilterList"/>
    </type>
</config>

app/code/BA/BNav/Plugin/Frontend/Magento/Catalog/Model/Layer/FilterList.php

    <?php
namespace BABasysPriceLayeredNavPluginFrontendMagentoCatalogModelLayer;

class FilterList
{
    const CUSTOM_PRICE      = 'custom_price';

    protected $filterTypes = [
       self::CUSTOM_PRICE => BABasysPriceLayeredNavModelLayerFilterCustomPrice::class,
    ];
    public function __construct(
        MagentoFrameworkObjectManagerInterface $objectManager
    ) {
        $this->objectManager = $objectManager;
    }

    public function afterGetFilters(
        MagentoCatalogModelLayerFilterList $subject,
        $result,
        $layer
    ) {
        $result[] = $this->objectManager->create($this->filterTypes[self::CUSTOM_PRICE], ['layer' => $layer]);
        return $result;
    }
}

app/code/BA/BNav/Model/Layer/Filter/CustomPrice.php

    <?php
namespace BABNavModelLayerFilter;

use PsrLogLoggerInterface;

class CustomPrice extends MagentoCatalogModelLayerFilterAbstractFilter
{
   
    /**
     * @var PsrLogLoggerInterface
     */
    protected $logger;
    protected $resource;
    protected $connection;

    /**
     * Construct
     *
     * @param MagentoCatalogModelLayerFilterItemFactory $filterItemFactory
     * @param MagentoStoreModelStoreManagerInterface $storeManager
     * @param MagentoCatalogModelLayer $layer
     * @param MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder
     * @param MagentoFrameworkEscaper $escaper
     * @param CategoryFactory $categoryDataProviderFactory
     * @param array $data
     */
    public function __construct(
        MagentoCatalogModelLayerFilterItemFactory $filterItemFactory,
        MagentoStoreModelStoreManagerInterface $storeManager,
        MagentoCatalogModelLayer $layer,
        MagentoCatalogModelLayerFilterItemDataBuilder $itemDataBuilder,
        MagentoFrameworkPricingPriceCurrencyInterface $priceCurrency,
        array $data = [],
        LoggerInterface $logger,
        MagentoFrameworkAppResourceConnection $resource
    ) {
        parent::__construct($filterItemFactory, $storeManager, $layer, $itemDataBuilder, $data);
        $this->_requestVar = 'ba_price';
        $this->logger = $logger;
        $this->resource = $resource;
        $this->priceCurrency = $priceCurrency;
    }

    /**
     * Apply category filter to layer
     *
     * @param   MagentoFrameworkAppRequestInterface $request
     * @return  $this
     */
    public function apply(MagentoFrameworkAppRequestInterface $request)
    {
        
        $filter = $request->getParam($this->getRequestVar());
        if (!$filter) {
            return $this;
        }
        $filter = explode('-', $filter);
        list($from, $to) = $filter;
        $collection = $this->getLayer()->getProductCollection();
        $collection->getSelect()
        ->join(['mapp'=>'catalog_product_map'], 'e.entity_id = mapp.entity_id')
        ->join(['productprice'=>'catalog_product_price'], 'productprice.b_id = mapp.b_id')
        ->where('productprice.price BETWEEN '.$from.' and '.$to);
        $this->logger->info($collection->getSelect()->__toString());
        
        $this->getLayer()
        ->getState()
        ->addFilter(
            $this->_createItem($this->_renderRangeLabel(empty($from) ? 0 : $from, $to), $filter)
        );
        return $this;
    }

    /**
     * Get filter name
     *
     * @return MagentoFrameworkPhrase
     */
    public function getName()
    {
        return __('Custom Price');
    }

    /**
     * Prepare text of range label
     *
     * @param float|string $fromPrice
     * @param float|string $toPrice
     * @return float|MagentoFrameworkPhrase
     */
    protected function _renderRangeLabel($fromPrice, $toPrice)
    {
        $formattedFromPrice = $this->priceCurrency->format($fromPrice);
        if ($toPrice === '') {
            return __('%1 and above', $formattedFromPrice);
        } else {
            return __('%1 - %2', $formattedFromPrice, $this->priceCurrency->format($toPrice));
        }
    }

    /**
     * Get data array for building category filter items
     *
     * @return array
     */
    protected function _getItemsData()
    {
        $ranges = [
            '0-4.99'=>'£0 - £4.99',
            '5-9.99'=>'£5 - £9.99',
            '10-20'=>'£10 - £20'
        ];
        $this->connection = $this->resource->getConnection();

        foreach ($ranges as $key => $label) {
            $count = $this->prepareData($key);
                $this->itemDataBuilder->addItemData(
                    $label,
                    $key,
                    $count
                );
        }
        return $this->itemDataBuilder->build();
    }

    private function prepareData($filter)
    {
        $filter = explode('-', $filter);
        list($from, $to) = $filter;
      
        $query = $this->connection->fetchAll('SELECT * FROM catalog_product_entity 
        WHERE price BETWEEN '.$from.' and '.$to);
        return count($query);
    }
}

Answered by Liz Eipe C on January 10, 2021

 protected function _getItemsData()
{
    $s1='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                    <div class="rating-result" title="20%">
                                        <span style="width:20%"><span>1</span></span>
                                    </div>
                                </div>';

    $s2='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                    <div class="rating-result" title="40%">
                                        <span style="width:40%"><span>2</span></span>
                                    </div>
                                </div>';

    $s3='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                    <div class="rating-result" title="60%">
                                        <span style="width:60%"><span>3</span></span>
                                    </div>
                                </div>';

    $s4='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                    <div class="rating-result" title="80%">
                                        <span style="width:80%"><span>4</span></span>
                                    </div>
                                </div>';

    $s5='<div class="rating-summary" style="display: inline-block;margin-top: -5px;">
                                    <div class="rating-result" title="100%">
                                        <span style="width:100%"><span>5</span></span>
                                    </div>
                                </div>';


    $facets = array(
        '0-20'=>$s1,
        '21-40'=>$s2,
        '41-60'=>$s3,
        '61-80'=>$s4,
        '81-100'=>$s5,
    );

    $data = [];
    if (count($facets) > 1) { // two range minimum
        $i=1;
        foreach ($facets as $key => $label) {
            // $count=$this->prepareData($key,$collection,$i);
            $count='';
            $filter = explode('-', $key);
            list($from, $to) = $filter;

            //$collection = $this->getLayer()->getProductCollection();
            $collection=  $this->getLayer()->getCurrentCategory()->getProductCollection();

            $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->getSelect()->from('rating_option_vote_aggregated')->where("rating_option_vote_aggregated.percent between".$from."and".$to);
            //echo $collection->getSelect()->__toString();die;
           // $this->getLayer()->getState()->addFilter($this->_createItem($collection, $filter));

            $count = $collection->count();

            $i++;

            // echo $count;
            if($count > 0){
                $this->itemDataBuilder->addItemData(
                //$this->_escaper->escapeHtml($label),
                    $label,
                    $key,
                    $count
                );

                $count=0;
            }
        }
    }

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

    /* $this->itemDataBuilder->addItemData(
        $this->tagFilter->filter('5 star'),
        '80-100',
        1
    );
    return $this->itemDataBuilder->build(); */
}

Answered by Syed M. Own Zaidi on January 10, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP