Please see my answer on the same GitHub post
https://github.com/magento/magento2/issues/9066
In a custom module, I utilised plugin (which uses Interceptor Design Pattern) for getCurrentOrder method in `Magento\Catalog\Block\Product\ProductList\Toolbar`.
For this example, I would use an arbitrary module named `Namesapce_Modulename`. So, once the module is created, in `etc/frontend/di.xml` use the following code:
<?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\Block\Product\ProductList\Toolbar">
<plugin name="namespace_modulename_catalog_product_list_toolbar_after_get_current_order"
type="Namespace\Modulename\Plugin\Catalog\Block\Product\ProductList\Toolbar"
sortOrder="1"
disabled="false"
/>
</type>
</config>
Now inside the plugin class
`Namespace/Modulename/Plugin/Catalog/Block/Product/ProductList/Toolbar.php`
use the following code:
<?php
namespace Namespace\Modulename\Plugin\Catalog\Block\Product\ProductList;
use Magento\Catalog\Model\Product\ProductList\Toolbar as ToolbarModel;
use Magento\Catalog\Model\Session as CatalogSession;
use Namespace\Modulename\Helper\Data as Helper;
class Toolbar extends \Magento\Framework\View\Element\Template
{
protected $toolbarModel;
protected $paramsMemorizeAllowed = true;
protected $catalogSession;
protected $helper;
public function __construct(
ToolbarModel $toolbar,
CatalogSession $catalogSession,
Helper $helper
) {
$this->toolbarModel = $toolbar;
$this->catalogSession = $catalogSession;
$this->helper = $helper;
}
public function afterGetCurrentOrder(
\Magento\Catalog\Block\Product\ProductList\Toolbar $subject
) {
if (!$this->helper->getSearchSortOrderByRelevance()) {
return;
}
$order = $subject->_getData('_current_grid_order');
$orders = $subject->getAvailableOrders();
$toolbarOrder = $this->toolbarModel->getOrder();
if ($order && !isset($orders['relevance'])) {
return $order;
} else if ($order
&& isset($orders['relevance'])
&& $toolbarOrder == null
) {
$keys = array_keys($orders);
$defaultOrder = $keys[2];
} else {
$keys = array_keys($orders);
$defaultOrder = $keys[0];
}
if (!$order || !isset($orders[$toolbarOrder])) {
$order = $defaultOrder;
}
if ($order != $defaultOrder) {
$this->memorizeParam('sort_order', $order);
}
$subject->setData('_current_grid_order', $order);
return $order;
}
protected function memorizeParam($param, $value)
{
if ($this->paramsMemorizeAllowed && !$this->catalogSession->getParamsMemorizeDisabled()) {
$this->catalogSession->setData($param, $value);
}
return $this;
}
}
I also created a “Yes/No” admin configuration setting to make sure when Magento core team implement the fix this plugin can be disabled without touching any code. And using a helper return method getSearchSortOrderByRelevance, I am checking if we need to set the search result order to relevance.
Hope this helps someone.
Cheers!