Magento – create module and override Magento\Catalog\Model\Layer.PHP

magento2magento2.2

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?

Best Answer

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