Magento – Magento 2 override the product collection(Magento\Catalog\Model\ResourceModel\Product\Collection.php)

catalogmagento2overridesproductresource-model

We want to override the product collection model class(Magento\Catalog\Model\ResourceModel\Product\Collection.php)

We flow the below process to override the addAttributeToSort method but not working.

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">
  <preference for="Magento\Catalog\Model\ResourceModel\Product\Collection" type="MyModule\SortByQty\Model\ResourceModel\Product\Collection" />
</config>

Collection.php

<?php
/**
 * Copyright © 2013-2017 Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

// @codingStandardsIgnoreFile

namespace MyModule\SortByQty\Model\ResourceModel\Product;


class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
{
    public function addAttributeToSort($attribute, $dir = self::SORT_ORDER_ASC)
    {
        if ($attribute == 'position') {
            if (isset($this->_joinFields[$attribute])) {
                $this->getSelect()->order($this->_getAttributeFieldName($attribute) . ' ' . $dir);
                return $this;
            }
            if ($this->isEnabledFlat()) {
                $this->getSelect()->order("cat_index_position {$dir}");
            }
            // optimize if using cat index
            $filters = $this->_productLimitationFilters;
            if (isset($filters['category_id']) || isset($filters['visibility'])) {
              $this->getSelect()->joinLeft(
            array('_inventory_table'=>'cataloginventory_stock_item'),
            "_inventory_table.product_id = e.entity_id ",
            array('qty')
        )->order(array('_inventory_table.qty DESC'));
            } else {
                $this->getSelect()->order('e.entity_id ' . $dir);
            }

            return $this;
        } elseif ($attribute == 'is_saleable') {
            $this->getSelect()->order("is_saleable " . $dir);
            return $this;
        }

        $storeId = $this->getStoreId();
        if ($attribute == 'price' && $storeId != 0) {
            $this->addPriceData();
            if ($this->_productLimitationFilters->isUsingPriceIndex()) {
                $this->getSelect()->order("price_index.min_price {$dir}");
                return $this;
            }
        }

        if ($this->isEnabledFlat()) {
            $column = $this->getEntity()->getAttributeSortColumn($attribute);

            if ($column) {
                $this->getSelect()->order("e.{$column} {$dir}");
            } elseif (isset($this->_joinFields[$attribute])) {
                $this->getSelect()->order($this->_getAttributeFieldName($attribute) . ' ' . $dir);
            }

            return $this;
        } else {
            $attrInstance = $this->getEntity()->getAttribute($attribute);
            if ($attrInstance && $attrInstance->usesSource()) {
                $attrInstance->getSource()->addValueSortToCollection($this, $dir);
                return $this;
            }
        }

        return parent::addAttributeToSort($attribute, $dir);
    }
}

Please, can you help on above issue? any references and suggestion are highly appreciated.

Best Answer

Kindly use plugin for this.

put below code in Namespace/Module/etc/di.xml

<type name="Magento\Catalog\Model\ResourceModel\Product\Collection">
    <plugin name="product-collection-sorting" type="Namespace\Module\Plugin\Product\Collection" sortOrder="1"/>
</type>

Create Namespace\Module\Plugin\Product\Collection.php and pasted below code in your file:

<?php
namespace Namespace\Module\Plugin\Product;

class Collection
{

    public function afterAddAttributeToSort(\Magento\Catalog\Model\ResourceModel\Product\Collection $subject, $result)
    {
         // do your stuff here
        return $result;
    }
}

Hope this will help you....!

Related Topic