1

During a Magento 2 Enterprise Cloud Edition build, I have come across, when I search for a any product, the default sort order always gets set to Product Name.

I looked around but only one Magento GitHub link looks like reported similar issue.

https://github.com/magento/magento2/issues/9066

However, as of my writing Magento 2 core team has not released any fix yet.

1

Please see my answer on the same GitHub post

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.

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.