0

I want to extend the Catalog Widget to filter Out Of Stock products.

To do this, I have created a component to extend the Catalog Widget's ProductsList class, which contains the following code to replace its createCollection function.

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{

    public function createCollection(
    )
    {
        /** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
        $collection = $this->productCollectionFactory->create();
        $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
        $this->_stockFilter = $objectManager->create('Magento\CatalogInventory\Helper\Stock');
        $this->_stockFilter->addInStockFilterToCollection($collection);

        ... CODE CONTINUES AS PER THE FUNCTION IN app\vendor\magento\module-catalog-widget\Block\Product\ProductsList.php

        return $collection;
    }

} 

This works as I want it to. However, I know we should not use the object manager to load Magento\CatalogInventory\Helper\Stock

I've tried adding a __construct function, but this just causes a "Type Error occurred when creating object" error.

How should I be loading the Stock helper?

1 Answer 1

0

You should leverage dependency injection. Don't forget to empty generated directory to refresh generated code.

<?php

class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList
{

    /**
     * @var \Magento\CatalogInventory\Helper\Stock
     */
    protected $_stockFilter;

    /**
     * ProductsList constructor.
     *
     * @param \Magento\Catalog\Block\Product\Context                         $context
     * @param \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory
     * @param \Product\Visibility                                            $catalogProductVisibility
     * @param \Magento\Framework\App\Http\Context                            $httpContext
     * @param \Magento\Rule\Model\Condition\Sql\Builder                      $sqlBuilder
     * @param \Magento\CatalogWidget\Model\Rule                              $rule
     * @param \Magento\Widget\Helper\Conditions                              $conditionsHelper
     * @param \Magento\CatalogInventory\Helper\Stock                         $stockFilter
     * @param array                                                          $data
     * @param \Magento\Framework\Serialize\Serializer\Json|null              $json
     * @param \Magento\Framework\View\LayoutFactory|null                     $layoutFactory
     * @param \Magento\Framework\Url\EncoderInterface|null                   $urlEncoder
     */
    public function __construct(
        \Magento\Catalog\Block\Product\Context $context,
        \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
        Product\Visibility $catalogProductVisibility,
        \Magento\Framework\App\Http\Context $httpContext,
        \Magento\Rule\Model\Condition\Sql\Builder $sqlBuilder,
        \Magento\CatalogWidget\Model\Rule $rule,
        \Magento\Widget\Helper\Conditions $conditionsHelper,
        \Magento\CatalogInventory\Helper\Stock $stockFilter,
        array $data = [],
        \Magento\Framework\Serialize\Serializer\Json $json = null,
        \Magento\Framework\View\LayoutFactory $layoutFactory = null,
        \Magento\Framework\Url\EncoderInterface $urlEncoder = null
    ) {
        parent::__construct(
            $context,
            $productCollectionFactory,
            $catalogProductVisibility,
            $httpContext,
            $sqlBuilder,
            $rule,
            $conditionsHelper,
            $data,
            $json,
            $layoutFactory,
            $urlEncoder
        );
        $this->_stockFilter = $stockFilter;
    }

    public function createCollection()
    {
        /** @var $collection \Magento\Catalog\Model\ResourceModel\Product\Collection */
        $collection = $this->productCollectionFactory->create();
        $this->_stockFilter->addInStockFilterToCollection($collection);

        //... CODE CONTINUES AS PER THE FUNCTION IN app\vendor\magento\module-catalog-widget\Block\Product\ProductsList.php

        return $collection;
    }

}
1
  • This throws the error Type Error occurred when creating object: XXX\YYY\Block\Product\ProductsList\Interceptor I have run setup:di:compile and cache:clean, as well as deleting the generated code.
    – RichardB
    Commented Aug 12, 2020 at 13:30

Your Answer

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

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