1

I want to use 'Display out of stock products at last' solution as module. I changed vendor\magento\module-catalog\Model\Layer.php and it worked.

public function getProductCollection()
{
    if (isset($this->_productCollections[$this->getCurrentCategory()->getId()])) {
        $collection = $this->_productCollections[$this->getCurrentCategory()->getId()];
    } else {
        $collection = $this->collectionProvider->getCollection($this->getCurrentCategory());
        $this->prepareProductCollection($collection);
        $this->_productCollections[$this->getCurrentCategory()->getId()] = $collection;
        $collection->getSelect()->joinLeft(
         ['_inventory_table' => 'cataloginventory_stock_item'], 
         "_inventory_table.product_id = e.entity_id", ['is_in_stock']
          );
          $collection->getSelect()->order(['is_in_stock desc']);
        }
    return $collection;
}

then I tried to create a module but I couldn't. could anyone help me for di.xml and model file please?

2

Use Plugins to achieve this

  1. create write following code inside di.xml

    <?xml version="1.0"?>
    <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="seedolabs-catalog-layer-model" type="Vendor\Module\Plugin\Model\Layer"/>
      </type>
    </config>
    
  2. Create Plugin file Layer.php as we mentioned in type in di.xml file Vendor/Module/Plugin/Model/Layer.php

paste the following code inside Layer.php

<?php

namespace Vendor\Module\Plugin\Model;

use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Catalog\Model\ResourceModel\Product\Attribute\CollectionFactory as AttributeCollectionFactory;

class Layer
{
/**
 * Product collections array
 *
 * @var array
 */
protected $_productCollections = [];

/**
 * Key which can be used for load/save aggregation data
 *
 * @var string
 */
protected $_stateKey = null;

/**
 * Core registry
 *
 * @var \Magento\Framework\Registry
 */
protected $registry = null;

/**
 * Store manager
 *
 * @var \Magento\Store\Model\StoreManagerInterface
 */
protected $_storeManager;

/**
 * Catalog product
 *
 * @var \Magento\Catalog\Model\ResourceModel\Product
 */
protected $_catalogProduct;

/**
 * Attribute collection factory
 *
 * @var AttributeCollectionFactory
 */
protected $_attributeCollectionFactory;

/**
 * Layer state factory
 *
 * @var \Magento\Catalog\Model\Layer\StateFactory
 */
protected $_layerStateFactory;

/**
 * @var \Magento\Catalog\Model\Layer\ItemCollectionProviderInterface
 */
protected $collectionProvider;

/**
 * @var \Magento\Catalog\Model\Layer\Category\StateKey
 */
protected $stateKeyGenerator;

/**
 * @var \Magento\Catalog\Model\Layer\Category\CollectionFilter
 */
protected $collectionFilter;

/**
 * @var CategoryRepositoryInterface
 */
protected $categoryRepository;

/**
 * @param Layer\ContextInterface $context
 * @param Layer\StateFactory $layerStateFactory
 * @param AttributeCollectionFactory $attributeCollectionFactory
 * @param \Magento\Catalog\Model\ResourceModel\Product $catalogProduct
 * @param \Magento\Store\Model\StoreManagerInterface $storeManager
 * @param \Magento\Framework\Registry $registry
 * @param CategoryRepositoryInterface $categoryRepository
 * @param array $data
 */
public function __construct(
    \Magento\Catalog\Model\Layer\StateFactory $layerStateFactory,
    AttributeCollectionFactory $attributeCollectionFactory,
    \Magento\Catalog\Model\ResourceModel\Product $catalogProduct,
    \Magento\Store\Model\StoreManagerInterface $storeManager,
    \Magento\Framework\Registry $registry,
    CategoryRepositoryInterface $categoryRepository,
    array $data = []
) {
    $this->_layerStateFactory = $layerStateFactory;
    $this->_attributeCollectionFactory = $attributeCollectionFactory;
    $this->_catalogProduct = $catalogProduct;
    $this->_storeManager = $storeManager;
    $this->registry = $registry;
    $this->categoryRepository = $categoryRepository; 

}

public function afterGetProductCollection(\Magento\Catalog\Model\Layer $subject, $result)
{
    $result->setOrder('is_in_stock ', 'DESC');
    return $result;
}
}
  1. Delete var/generation and run php bin/magento cache:flush.

Chech now it will work It worked for me.Hope It will help you too

2
  • This solution works for out of stock products. but what if I want to sort by some other custom attribute.?
    – Abid Malik
    Aug 25 '19 at 10:34
  • This worked for me public function afterGetProductCollection(\Magento\Catalog\Model\Layer $subject, $result) { $result ->getSelect() ->reset('order') ->order('is_salable DESC') ->order('cat_index_position ASC'); return $result; }
    – Trevor Orr
    Oct 18 '19 at 18:40
1

Update your di.xml under

app/code/Vendor/Module/etc/di.xml

by 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">
    <preference for="Magento\Catalog\Model\Layer" type="Vendor\Module\Model\Catalog\Layer" />
</config>

And create Layer.php under

app/code/Vendor/Module/Model/Catalog/Layer.php

and add the code like below:

<?php
namespace Vendor\Module\Model\Catalog;

class Layer extends \Magento\Catalog\Model\Layer
{
    public function getProductCollection()
    {
        //Your code goes here
    }
}
1
  • Thanks @Sukimar but it didn't work
    – Benyo
    Jul 10 '18 at 5:27
1

use the following Setups

create di.xml file in Folder NAMESPACE/YOUR_MODULE/etc/frontend

<?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\Layer" type="NAMESPACE\YOUR_MODULE\Model\Layer" />
</config>

create Layer.php Model file in Folder

NAMESPACE/NAMESPACE/Model/Rewrite/Catalog

<?php

namespace NAMESPACE\NAMESPACE\Model\Rewrite\Catalog;

class Layer extends \Magento\Catalog\Model\Layer
{
    public function getProductCollection()
    {
        // Do your stuff here
        return parent::getProductCollection();
    }

}
5
  • 1
    Thanks @Prashant. unfotunately it didn't work too
    – Benyo
    Jul 10 '18 at 5:27
  • any error show ? Jul 10 '18 at 5:56
  • no. it just didn't work
    – Benyo
    Jul 10 '18 at 6:23
  • answer update can you check Move your /etc/di.xml to /etc/frontend/di.xml Jul 10 '18 at 6:44
  • I moved di.xml and updated Layer.php, but it didn't work yet
    – Benyo
    Jul 10 '18 at 6:59

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.