1

I am trying to sort the Product collection based on the attribute option value,

I used below plugin

Vendor/Module/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\Layer">
       <plugin name="custom_product_model_layer" type="Vednor\Module\Plugin\Layer" />
    </type>
</config>

Then in Vendor/Module/Plugin/Layer.php

namespace Vendor\Module\Plugin;

class Layer
{
    private $logger;

    public function __construct(
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->logger = $logger;
    }

    public function aroundGetProductCollection(
        \Magento\Catalog\Model\Layer $subject,
        \Closure $proceed
    ) {

        $result = $proceed();
        $result->addAttributeToSort('brand', 'puma');

        return $result;
    }
}

Second Method:

di.xml

<type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
    <plugin name="custom_product_toolbar" type="Vendor\Module\Plugin\Toolbar" />
</type>

Then Vendor/Module/Plugin/Toolbar.php

namespace Vendor\Module\Plugin;

class Toolbar
{

    protected $_objectManager;
    protected $request;
    private $logger;

    public function __construct(
        \Magento\Framework\ObjectManagerInterface $objectmanager,
        \Magento\Framework\App\Request\Http $request,
        \Psr\Log\LoggerInterface $logger
    ) {
        $this->_objectManager = $objectmanager;
        $this->request        = $request;
        $this->logger         = $logger;
    }

    public function aroundSetCollection(
        \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
        \Closure $proceed,
        $request
    ) {
        $result = $proceed($request);

        $this->_collection = $request;
        $currentOrder      = $subject->getCurrentOrder();
        $category          = $this->_objectManager->get('Magento\Framework\Registry')->registry('current_category');
        if ($category) {
            $page = $this->request->getParam('p');
            if ($page == '') {
                $page = 1;
            }
            $this->_collection->getCurPage();
            $this->_collection->setCurPage($page);
        }
        if ($currentOrder) {
            if ($currentOrder == 'relevance') {
                // Suggest me the logic here
            }
        }

        return $result;
    }
}

I have created a attribute called "brand" so whenever the product is searched, I need to load the products on top which are set as "puma" option for that particular attribute.

I am trying with Both methods, but both are not working, can I get any help on this. Thanks in advance!!

1 Answer 1

3

You can't sort by attribute options value. You can sort by asc or desc by attirbute using addAttributeToSort().

This is core issue generated in github. You can get reference about that by this below link :

https://github.com/Smile-SA/elasticsuite/issues/450

If you want to sort by attribute name then, you can use after plugin method instead of around and modify your collection :

Create di.xml file and add plugin and add this below code :

app/code/RH/AfterPlugin/etc/frontend/di.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright 2015 Magento. All rights reserved.
 * See COPYING.txt for license details.
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\Layer">
    <plugin name="rh_afterplugin_model_layer" type="RH\AfterPluginCode\Plugin\SortCollection" sortOrder="3"  />
</type>
</config>

Create SortCollection.php plugin file and add this below code :

app/code/RH/AfterPlugin/Plugin/SortCollection.php

<?php

/**
  * Copyright 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */

namespace RH\AfterPluginCode\Plugin;

class SortCollection {

    public function afterGetProductCollection(\Magento\Catalog\Model\Layer $subject, $result) {
        $result->addAttributeToSort('brand','ASC'); //DESC for descending.
        //$result->addAttributeToSort('sku');
        //$result->setOrder('brand','ASC'); For dropdown type attribute you can use this.
        return $result;
    }
}
8
  • hi @Rohan, Thanks for your answer, I've removed all my code and tried your answer, getting this exception, "You cannot define a correlation name 'brand_t1' more than once"
    – Manjunath
    Nov 28, 2019 at 10:06
  • brand_t1 is attribute options? Nov 28, 2019 at 10:13
  • No, "brand" is the attribute_code, once the plugin code added, getting that error
    – Manjunath
    Nov 28, 2019 at 10:20
  • Then, can you pls tell me what is brand_t1? Nov 28, 2019 at 10:20
  • 1
    yes @Rohan, Thank you, its working now, if any suggestions for sorting particular option on top, you can update, Thanks!!
    – Manjunath
    Nov 28, 2019 at 12:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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