Question

I need a help ASAP related to sort by functionality in magento 2

1] I need to remove default sort by options.

2] I need to add my own sorting options.

I tried a custom module in which I have override the block file

vendor/magento/module-catalog/Block/Product/ProductList/Toolbar.php

In which I have override the setCollection() function

I have define custom options like:

class Toolbar extends \Magento\Catalog\Block\Product\ProductList\Toolbar {
  public function setCollection($collection) {
    $this->_collection = $collection;
    $this->_collection->setCurPage($this->getCurrentPage());
    $limit = (int) $this->getLimit();
    if ($limit) {
        $this->_collection->setPageSize($limit);
    }
    if ($this->getCurrentOrder()) {
        switch ($this->getCurrentOrder()) {
            case 'created_at_desc':                
                    $this->_collection
                            ->addAttributeToSort('name');
                            //->order('e.created_at ASC');
                break;
        case 'created_at_asc':
                    $this->_collection
                            ->addAttributeToSort('name');
                            //->order('e.created_at DESC');                
                break;
        case 'price_low_to_high':
                $this->_collection
                        ->addAttributeToSort('price');
                        //->order('price_index.price ASC');
                break;
        case 'price_high_to_low'://need to change
                $this->_collection
                        ->addAttributeToSort('price');                       
                break;
        case 'model'://need to change
                $this->_collection
                        ->getSelect()
                        ->joinLeft(
                                ['admin' => $collection->getTable('cataloginventory_stock_status')], 'e.entity_id = admin.product_id')->where('admin.stock_status = 1');
                break;
            case 'new_to_old':
                $this->_collection
                            ->getSelect()
                            ->order('e.created_at DESC');
                break;
            case 'old_to_new':
                $this->_collection
                            ->getSelect()
                            ->order('e.created_at ASC'); 
                break;
            default:
                $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
                break;
        }
    }
    return $this;
  }
}

I get the 'old_to_new' and 'new_to_old' code and its working fine, but need the other remaining following options too. I tries all possible options but can't get the result.

This are the following remaining options I need :

-created_at_desc--- name by asc(A-Z)

-created_at_asc--- name by desc(Z-A)

-price_low_to_high--- price low to high

-price_high_to_low--- price high to low

Thanks

Was it helpful?

Solution

You need to a custom extension with plugins, I followed this

app/code/Company/CustomSort/etc/di.xml

<?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="Magento\Catalog\Model\Config">
   <plugin name="Company_CustomSort::addCustomOptions" type="Company\CustomSort\Plugin\Model\Config" />
  </type>
  <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
   <plugin name="Company_CustomSort::addPriceDecendingFilterInToolbar" type="Company\CustomSort\Plugin\Product\ProductList\Toolbar" />
  </type>
</config>

Now we need to define our config labels and new options.

app/code/Company/CustomSort/Plugin/Model/Config.php

<?php
namespace Company\CustomSort\Plugin\Model;

class Config
{

/**
* Adding custom options and changing labels
*
* @param \Magento\Catalog\Model\Config $catalogConfig
* @param [] $options
* @return []
*/
public function afterGetAttributeUsedForSortByArray(\Magento\Catalog\Model\Config $catalogConfig, $options)
{

 //Remove specific default sorting options(if require)
 unset($options['position']);
 unset($options['name']);
 unset($options['price']);

 //Changing label(if require)
 $newOption['position'] = __('Any Thing');

 //New sorting options
 $newOption['price_desc'] = __('High to Low');
 $newOption['price_asc'] = __('Low to High');
 $newOption['created_at'] = __('New');

 //Merge default sorting options with new options
 $options = array_merge($newOption, $options);

 return $options;
 }
}

We declared all required options, now we need to implement these options and overwrite Magento default sorting method.

app/code/Company/CustomSort/Plugin/Product/ProductList/Toolbar.php

<?php
 namespace Company\CustomSort\Plugin\Product\ProductList;
 class Toolbar
 {
 /**
  * Plugin
  *
  * @param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
  * @param \Closure $proceed
  * @param \Magento\Framework\Data\Collection $collection
  * @return \Magento\Catalog\Block\Product\ProductList\Toolbar
  */
  public function aroundSetCollection(
    \Magento\Catalog\Block\Product\ProductList\Toolbar $toolbar,
    \Closure $proceed,
    $collection
  ) {
    $currentOrder = $toolbar->getCurrentOrder();
    $result = $proceed($collection);

    if ($currentOrder) {
        switch ($this->getCurrentOrder()) {

        case 'created_at':

            if ( $this->getCurrentDirection() == 'asc' ) {

                $this->_collection
                    ->getSelect()
                    ->order('e.created_at DESC');


            } elseif ( $this->getCurrentDirection() == 'desc' ) {

                $this->_collection
                    ->getSelect()
                    ->order('e.created_at ASC');

            }

            break;
        case 'price_desc':
                $this->_collection
                     ->getSelect()
                     ->setOrder('price', 'desc');
        case 'price_asc':
                $this->_collection
                     ->getSelect()
                     ->setOrder('price', 'asc');

        default:

            $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
            break;

    }
    }

    return $this;
 }
}

Now you need to run

php bin/magento setup:upgrade
and it should work like charm.

Happy coding.

OTHER TIPS

Paste the follwing code inside plugin/config.php

<?php
namespace ModuleName\VenderName\Plugin;

class Config
{

    const NEWEST_SORT_BY = 'newest';
    const OLDEST_SORT_BY = 'oldest';

    /**
     * Adding new sort option
     *
     * @param \Magento\Catalog\Model\Config $catalogConfig
     * @param [] $result
     * @return []
     */
    public function afterGetAttributeUsedForSortByArray(
        \Magento\Catalog\Model\Config $subject, 
        $result
    ) {
        unset($result['position']);
        unset($result['name']);
        unset($result['price']); 

        return array_merge(
            $result, 
            [
                self::NEWEST_SORT_BY => __('Newest'),
                self::OLDEST_SORT_BY => __('Oldest'),
                'position' => __('Position'),
                'name' => __('Name'),
                'price' => __('Price')
            ]
        );
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top