0

My site is supposed to show out of stock products in some places in the catalogue, so the Catalog > Inventory > Display Out of Stock Products setting is set to "Yes." But I do not want out of stock products to show up in the search. Before upgrading to M2.3, we accomplished this by overriding \Magento\CatalogInventory\Model\Plugin\Layer's beforePrepareProductCollection() function:

 public function beforePrepareProductCollection(
        \Magento\Catalog\Model\Layer $subject,
        \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection $collection
    ) {

        $_category = $subject->getCurrentCategory();
        if (is_object($_category) and in_array($_category->getId(), array(161, 184)))// don't apply to Recently Sold, Our Archive categories
        {
            return;
        }

        parent::beforePrepareProductCollection($subject, $collection);
        $stockFlag = 'has_stock_status_filter';
        if (!$collection->hasFlag($stockFlag)) {
            $resource = $this->getStockStatusResource();
            $resource->addStockDataToCollection(
                $collection,
                true // force
            );
            $collection->setFlag($stockFlag, true);
        }
    }

    protected function getStockStatusResource()
    {
        if (empty($this->stockStatusResource)) {
            $this->stockStatusResource = $this->stockStatusFactory->create();
        }
        return $this->stockStatusResource;
    }

Now that Layer.php is gone in Magento 2.3, I don't know where to start with trying to hide out of stock products in search. I thought maybe I could use Magento\CatalogInventory\Model\Plugin\ProductSearch, but that isn't used at all as far as I can tell.

4
  • Setting the visibility in the product to only catalog will fulfill your need I guess. – Rizwan Khan Sep 30 '20 at 4:33
  • Hoping for an automated solution; we have a lot of products. – Chloe Sep 30 '20 at 13:04
  • You can update them via import export firebearstudio.com/blog/… – Rizwan Khan Sep 30 '20 at 13:15
  • 1
    Even with the import/export, this would still need to be done manually each time a product is purchased, wouldn't it? – Chloe Sep 30 '20 at 14:52
1

I solved this by adding the Layer plugin directly to my module Wfx_Stock which previously extended Layer.php

in di.xml:

<type name="Magento\Catalog\Model\Layer">
        <plugin name="addStockStatusOnPrepareFrontCollection" type="Wfx\Stock\Model\Plugin\Layer" sortOrder="1"/>
</type>

Then in app\code\Wfx\Stock\Model\Plugin\Layer.php

<?php
namespace Wfx\Stock\Model\Plugin;

class Layer
{

    /**
     * @param \Magento\CatalogInventory\Helper\Stock $stockHelper
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param StatusFactory $stockStatusFactory
     */
    public function __construct(
        \Magento\CatalogInventory\Helper\Stock $stockHelper,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\CatalogInventory\Model\ResourceModel\Stock\StatusFactory $stockStatusFactory
    ) {
        $this->stockStatusFactory  = $stockStatusFactory;
        $this->stockHelper = $stockHelper;
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * Before prepare product collection handler
     *  - Hide out of stock products in search, unless in "Recently Sold" or Our Archive
     *
     * @param \Magento\Catalog\Model\Layer $subject
     * @param \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection $collection
     *
     * @return void
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function beforePrepareProductCollection(
        \Magento\Catalog\Model\Layer $subject,
        \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection $collection
    ) {
        $_category = $subject->getCurrentCategory();
        if (is_object($_category) and in_array($_category->getId(), array(161, 184)))// Recently Sold, Our Archive
        {
            return;
        }
        
        $stockFlag = 'has_stock_status_filter';
        if (!$collection->hasFlag($stockFlag)) {
            $resource = $this->getStockStatusResource();
            $resource->addStockDataToCollection(
                $collection,
                true // force
            );
            $collection->setFlag($stockFlag, true);
        }
    }
    
    /**
     * Get config value for 'display out of stock' option
     *
     * @return bool
     */
    protected function _isEnabledShowOutOfStock()
    {
        return $this->scopeConfig->isSetFlag(
            'cataloginventory/options/show_out_of_stock',
            \Magento\Store\Model\ScopeInterface::SCOPE_STORE
        );
    }

    /**
     * @return Status
     */
    protected function getStockStatusResource()
    {
        if (empty($this->stockStatusResource)) {
            $this->stockStatusResource = $this->stockStatusFactory->create();
        }
        return $this->stockStatusResource;
    }

}

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.