This article is a solution If you want to add new custom sorter or filter options such as below:
New product,
Name, Instock,
Price Low to high,
Price High to Low.
Create a custom module and follow the below step.
1. Create file di.xml on app/code/Magemonkeys/Sorting/etc
<?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="MagentoCatalogModelConfig">
<plugin name="Magemonkeys_Sorting::addCustomSortOptions" type="MagemonkeysSortingPluginModelConfig" />
</type>
<type name="MagentoCatalogBlockProductProductListToolbar">
<plugin name="Magemonkeys_Sorting::implementCustomSortOptions" type="MagemonkeysSortingPluginProductProductListToolbar" />
</type>
</config>
2. Create file Config.php on app/code/Magemonkeys/Sorting/Plugin
<?php
namespace MagemonkeysSortingPluginModel;
class Config
{
public function afterGetAttributeUsedForSortByArray(MagentoCatalogModelConfig $catalogConfig, $options)
{
//Remove default sorting options
unset($options['position']);
unset($options['name']);
unset($options['price']);
//New sorting options
$options['newest'] = __('New product');
$options['is_salable'] = __('Stock');
$options['name'] = __('Name');
$options['price_desc'] = __('Price High to Low');
$options['price_asc'] = __('Price Low to High');
return $options;
}
}
3. Create file Toolbar.php on app/code/Magemonkeys/Sorting/Product/ProductList
<?php
namespace MagemonkeysSortingPluginProductProductList;
class Toolbar
{
public function aroundSetCollection(
MagentoCatalogBlockProductProductListToolbar $toolbar,
Closure $proceed,
$collection
) {
$this->_collection = $collection;
$currentOrder = $toolbar->getCurrentOrder();
$currentDirection = $toolbar->getCurrentDirection();
$result = $proceed($collection);
if ($currentOrder) {
switch ($currentOrder) {
case 'newest':
if ($currentDirection == 'desc') {
$this->_collection->getSelect()->order('e.created_at ASC');
} elseif ($currentDirection == 'asc') {
$this->_collection->getSelect()->order('e.created_at DESC');
}
break;
case 'is_salable':
if ($currentDirection == 'desc') {
$this->_collection->getSelect()->order('qty ASC');
} elseif ($currentDirection == 'asc') {
$this->_collection->getSelect()->order('qty DESC');
}
break;
case 'name':
if ($currentDirection == 'desc') {
$this->_collection->getSelect()->order('name ASC');
} elseif ($currentDirection == 'asc') {
$this->_collection->getSelect()->order('name DESC');
}
break;
case 'price_desc':
if ($currentDirection == 'desc') {
$this->_collection->getSelect()->order('price ASC');
} elseif ($currentDirection == 'asc') {
$this->_collection->getSelect()->order('price DESC');
}
break;
case 'price_asc':
if ($currentDirection == 'desc') {
$this->_collection->getSelect()->order('price DESC');
} elseif ($currentDirection == 'asc') {
$this->_collection->getSelect()->order('price ASC');
}
break;
default:
$this->_collection
->setOrder($currentOrder, $currentDirection);
break;
}
}
//var_dump($currentDirection);
return $result;
}
}

