I have added a custom sorting option in default sorting menu by overriding toolbar.php file

  1. I want to display products with the highest discount on top using sorting and product with no discount should also be displayed after all discounted product

Following is my Toolbar.php file

 namespace Vendor\ModuleName\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 $subject,
    \Closure $proceed,
) {
    // die(print_r($subject));
    $currentOrder = $subject->getCurrentOrder();
    $result = $proceed($collection);
    if ($currentOrder) {
        // if ($currentOrder == 'price_desc') {
        //     $subject->getCollection()->setOrder('price', 'desc');
        // } elseif ($currentOrder == 'price_asc') {
        //     $subject->getCollection()->setOrder('price', 'asc');
        // }
        if ($currentOrder == 'created_at_new') {
            $subject->getCollection()->setOrder('created_at', 'desc');
        elseif ($currentOrder == 'created_at_old') {
            $subject->getCollection()->setOrder('created_at', 'asc');
        elseif ($currentOrder == 'bestseller') {
            'e.entity_id = sales_order_item.product_id', 
            ->order('qty_ordered desc');
        elseif ($currentOrder == 'onsale') {


    return $result;

Following Image Is Output of Sorting Menu

enter image description here


try below code.

public function aroundSetCollection(\Magento\Catalog\Block\Product\ProductList\Toolbar $subject, \Closure $proceed, $collection)
    $returnValue = $proceed($collection);
    if ($subject->getCurrentOrder() == 'onsale') {
        $collection->addAttributeToSelect('*')->setOrder('price', 'ASC');
    return $collection;
  • Its not showing result as expected it shows non sale product also on top i want to show non sale products after all on sale products are listed and thanks for your answer – Harsh Jayswal Apr 4 at 6:29
  • @HarshJayswal Then create one attribute and assign to attribute set. if sale product set yes other than set no. Now setOrder('attribute_name', 'ASC');. It will work. – Bojjaiah Apr 4 at 6:43
  • @HarshJayswal If add attribute add one more line ->joinField('attribute_name=1') before $collection->load();. – Bojjaiah Apr 4 at 7:03
  • it still shows incorrect result it might possible that i am not making it properly can you please update the answer – Harsh Jayswal Apr 4 at 7:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.