1

Currently, I am not getting the out-of-stock products from the configurable product on the product page (product/view controller).

File :

<?php
/**
 * Product view controller
 */
namespace Magento\ProductRedirection\Controller\Index;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Design;
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Forward;
use Magento\Framework\Controller\Result\ForwardFactory;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Json\Helper\Data;
use Magento\Framework\View\Result\PageFactory;
use Magento\Catalog\Controller\Product as ProductAction;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;
use Magento\Catalog\Model\Product;

/**
 * View a product on storefront. Needs to be accessible by POST because of the store switching
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class View extends \Magento\Catalog\Controller\Product\View
{
    /**
     * @var \Magento\Catalog\Helper\Product\View
     */
    protected $viewHelper;

    /**
     * @var ForwardFactory
     */
    protected $resultForwardFactory;

    /**
     * @var PageFactory
     */
    protected $resultPageFactory;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var Data
     */
    private $jsonHelper;

    /**
     * @var Design
     */
    private $catalogDesign;

    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\CatalogInventory\Api\StockStateInterface
     */
    protected $_stockState;

    /**
     * Constructor
     *
     * @param Context $context
     * @param \Magento\Catalog\Helper\Product\View $viewHelper
     * @param ForwardFactory $resultForwardFactory
     * @param PageFactory $resultPageFactory
     * @param LoggerInterface|null $logger
     * @param Data|null $jsonHelper
     * @param Design|null $catalogDesign
     * @param ProductRepositoryInterface|null $productRepository
     * @param StoreManagerInterface|null $storeManager
     */
    public function __construct(
        Context $context,
        \Magento\Catalog\Helper\Product\View $viewHelper,
        ForwardFactory $resultForwardFactory,
        PageFactory $resultPageFactory,
        ?LoggerInterface $logger = null,
        ?Data $jsonHelper = null,
        ?Design $catalogDesign = null,
        ?ProductRepositoryInterface $productRepository = null,
        ?StoreManagerInterface $storeManager = null,
        \Magento\CatalogInventory\Api\StockStateInterface $stockState,
        \Magento\Catalog\Model\ProductFactory $_productloader,
        \Magento\Catalog\Model\CategoryRepository $categoryRepository
    ) {
        parent::__construct($context,$viewHelper,$resultForwardFactory,$resultPageFactory,$logger,$jsonHelper,$catalogDesign,$productRepository,$storeManager);
        $this->viewHelper = $viewHelper;
        $this->resultForwardFactory = $resultForwardFactory;
        $this->resultPageFactory = $resultPageFactory;
        $this->logger = $logger ?: ObjectManager::getInstance()
        ->get(LoggerInterface::class);
        $this->jsonHelper = $jsonHelper ?: ObjectManager::getInstance()
        ->get(Data::class);
        $this->catalogDesign = $catalogDesign ?: ObjectManager::getInstance()
        ->get(Design::class);
        $this->productRepository = $productRepository ?: ObjectManager::getInstance()
        ->get(ProductRepositoryInterface::class);
        $this->storeManager = $storeManager ?: ObjectManager::getInstance()
        ->get(StoreManagerInterface::class);
        $this->_stockState = $stockState;
        $this->_productloader = $_productloader;
        $this->categoryRepository = $categoryRepository;
    }

    /**
     * Redirect if product failed to load
     *
     * @return Redirect|Forward
     */
    protected function noProductRedirect()
    {
        $store = $this->getRequest()->getQuery('store');
        if (isset($store) && !$this->getResponse()->isRedirect()) {
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setPath('');
        } elseif (!$this->getResponse()->isRedirect()) {
            $resultForward = $this->resultForwardFactory->create();
            $resultForward->forward('noroute');
            return $resultForward;
        }
    }

    /**
     * Category redirection
     *
     * @return Forward|Redirect
     */
    public function categoryRedirect($productId)
    {   
        $product = $this->_productloader->create()->load($productId);
        // Check if product is configurable.
        if($product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE){
            $allChildrenproducts = $product->getTypeInstance()->getUsedProducts($product);
            foreach ($allChildrenproducts as $childrednProducts) {
                $qty = $this->_stockState->getStockQty($childrednProducts->getID());

                if($qty < 1){
                    $categories = $product->getCategoryIds();
                    foreach($categories as $category){
                        $categorydata = $this->categoryRepository->get($category);
                        $categoryurl = $categorydata->getUrl();
                        return $categoryurl;
                    }
                }
            }
        } else {
            $qty = $this->_stockState->getStockQty($productId);
            if($qty < 1){
                $categories = $product->getCategoryIds();
                foreach($categories as $category){
                    $categorydata = $this->categoryRepository->get($category);
                    $categoryurl = $categorydata->getUrl();
                    return $categoryurl;
                }
            }
        } 
    }
    /**
     * Product view action
     *
     * @return Forward|Redirect
     */
    public function execute()
    {
        // Get initial data from request
        $categoryId = (int) $this->getRequest()->getParam('category', false);
        $productId = (int) $this->getRequest()->getParam('id');
        $specifyOptions = $this->getRequest()->getParam('options');
        $redirectOosProduct = $this->categoryRedirect($productId);
        if($redirectOosProduct){
            $resultRedirect = $this->resultRedirectFactory->create();
            $resultRedirect->setUrl($redirectOosProduct)->setHttpResponseCode('301');
            return $resultRedirect;
        }
        if ($this->getRequest()->isPost() && $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
            $product = $this->_initProduct();

            if (!$product) {
                return $this->noProductRedirect();
            }

            if ($specifyOptions) {
                $notice = $product->getTypeInstance()->getSpecifyOptionMessage();
                $this->messageManager->addNoticeMessage($notice);
            }

            if ($this->getRequest()->isAjax()) {
                $this->getResponse()->representJson(
                    $this->jsonHelper->jsonEncode(
                        [
                            'backUrl' => $this->_redirect->getRedirectUrl()
                        ]
                    )
                );
                return;
            }
            $resultRedirect = $this->resultRedirectFactory->create();
            $resultRedirect->setUrl($this->_url->getCurrentUrl());
            return $resultRedirect;
        }

        // Prepare helper and params
        $params = new DataObject();
        $params->setCategoryId($categoryId);
        $params->setSpecifyOptions($specifyOptions);

        // Render page
        try {
            $this->applyCustomDesign($productId);
            $page = $this->resultPageFactory->create();
            $this->viewHelper->prepareAndRender($page, $productId, $this, $params);
            return $page;
        } catch (NoSuchEntityException $e) {
            return $this->noProductRedirect();
        } catch (\Exception $e) {
            $this->logger->critical($e);
            $resultForward = $this->resultForwardFactory->create();
            $resultForward->forward('noroute');
            return $resultForward;
        }
    }

    /**
     * Apply custom design from product design settings
     *
     * @param int $productId
     * @throws NoSuchEntityException
     */
    private function applyCustomDesign(int $productId): void
    {
        $product = $this->productRepository->getById($productId, false, $this->storeManager->getStore()->getId());
        $settings = $this->catalogDesign->getDesignSettings($product);
        if ($settings->getCustomDesign()) {
            $this->catalogDesign->applyCustomDesign($settings->getCustomDesign());
        }
    }
}
1
  • Any thoughts on this ?
    – user104369
    Dec 10, 2022 at 12:48

1 Answer 1

0

This should work.

<?php
/**
 * Product view controller
 */
namespace Magento\ProductRedirection\Controller\Index;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Model\Design;
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
use Magento\Framework\App\Action\HttpGetActionInterface as HttpGetActionInterface;
use Magento\Framework\App\Action\Context;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Controller\Result\Forward;
use Magento\Framework\Controller\Result\ForwardFactory;
use Magento\Framework\Controller\Result\Redirect;
use Magento\Framework\DataObject;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Framework\Json\Helper\Data;
use Magento\Framework\View\Result\PageFactory;
use Magento\Catalog\Controller\Product as ProductAction;
use Magento\Store\Model\StoreManagerInterface;
use Psr\Log\LoggerInterface;
use Magento\Catalog\Model\Product;
use Magento\Framework\App\ResourceConnection;

/**
 * View a product on storefront. Needs to be accessible by POST because of the store switching
 *
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
 */
class View extends \Magento\Catalog\Controller\Product\View
{
    /**
     * @var \Magento\Catalog\Helper\Product\View
     */
    protected $viewHelper;

    /**
     * @var ForwardFactory
     */
    protected $resultForwardFactory;

    /**
     * @var PageFactory
     */
    protected $resultPageFactory;

    /**
     * @var LoggerInterface
     */
    private $logger;

    /**
     * @var Data
     */
    private $jsonHelper;

    /**
     * @var Design
     */
    private $catalogDesign;

    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var \Magento\CatalogInventory\Api\StockStateInterface
     */
    protected $_stockState;

    protected $resourceConnection;

    /**
     * Constructor
     *
     * @param Context $context
     * @param \Magento\Catalog\Helper\Product\View $viewHelper
     * @param ForwardFactory $resultForwardFactory
     * @param PageFactory $resultPageFactory
     * @param LoggerInterface|null $logger
     * @param Data|null $jsonHelper
     * @param Design|null $catalogDesign
     * @param ProductRepositoryInterface|null $productRepository
     * @param StoreManagerInterface|null $storeManager
     */
    public function __construct(
        Context $context,
        \Magento\Catalog\Helper\Product\View $viewHelper,
        ForwardFactory $resultForwardFactory,
        PageFactory $resultPageFactory,
        ?LoggerInterface $logger = null,
        ?Data $jsonHelper = null,
        ?Design $catalogDesign = null,
        ?ProductRepositoryInterface $productRepository = null,
        ?StoreManagerInterface $storeManager = null,
        \Magento\CatalogInventory\Api\StockStateInterface $stockState,
        \Magento\Catalog\Model\ProductFactory $_productloader,
        \Magento\Catalog\Model\CategoryRepository $categoryRepository,
        ResourceConnection $resourceConnection
    ) {
        parent::__construct($context,$viewHelper,$resultForwardFactory,$resultPageFactory,$logger,$jsonHelper,$catalogDesign,$productRepository,$storeManager);
        $this->viewHelper = $viewHelper;
        $this->resultForwardFactory = $resultForwardFactory;
        $this->resultPageFactory = $resultPageFactory;
        $this->logger = $logger ?: ObjectManager::getInstance()
        ->get(LoggerInterface::class);
        $this->jsonHelper = $jsonHelper ?: ObjectManager::getInstance()
        ->get(Data::class);
        $this->catalogDesign = $catalogDesign ?: ObjectManager::getInstance()
        ->get(Design::class);
        $this->productRepository = $productRepository ?: ObjectManager::getInstance()
        ->get(ProductRepositoryInterface::class);
        $this->storeManager = $storeManager ?: ObjectManager::getInstance()
        ->get(StoreManagerInterface::class);
        $this->_stockState = $stockState;
        $this->_productloader = $_productloader;
        $this->categoryRepository = $categoryRepository;
        $this->resourceConnection = $resourceConnection;
    }

    /**
     * Redirect if product failed to load
     *
     * @return Redirect|Forward
     */
    protected function noProductRedirect()
    {
        $store = $this->getRequest()->getQuery('store');
        if (isset($store) && !$this->getResponse()->isRedirect()) {
            $resultRedirect = $this->resultRedirectFactory->create();
            return $resultRedirect->setPath('');
        } elseif (!$this->getResponse()->isRedirect()) {
            $resultForward = $this->resultForwardFactory->create();
            $resultForward->forward('noroute');
            return $resultForward;
        }
    }

    /**
     * Category redirection
     *
     * @return Forward|Redirect
     */
    public function categoryRedirect($productId)
    {   
        $product = $this->_productloader->create()->load($productId);
        // Check if product is configurable.
        if($product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE){
            $allChildrenproducts = $product->getTypeInstance()->getUsedProducts($product);
            
            $connection = $this->resourceConnection->getConnection();
            $sql = "SELECT catalog_product_relation.child_id 
            FROM `catalog_product_entity` 
            INNER JOIN `catalog_product_relation` 
            ON catalog_product_entity.entity_id=catalog_product_relation.parent_id 
            where catalog_product_entity.entity_id  = ".$productId."";
            $result = $connection->fetchAll($sql);
            foreach ($result as $childrednProducts) {
                $childProductId = $childrednProducts['child_id'];
                $qty = $this->_stockState->getStockQty($childProductId); echo'</br>';
                if($qty < 1){
                    $categories = $product->getCategoryIds();
                    foreach($categories as $category){
                        $categorydata = $this->categoryRepository->get($category);
                        $categoryurl = $categorydata->getUrl();
                        return $categoryurl;
                    }
                }
            }
        } else {
            $qty = $this->_stockState->getStockQty($productId);
            if($qty < 1){
                $categories = $product->getCategoryIds();
                foreach($categories as $category){
                    $categorydata = $this->categoryRepository->get($category);
                    $categoryurl = $categorydata->getUrl();
                    return $categoryurl;
                }
            }
        } 
    }
        /**
     * Product view action
     *
     * @return Forward|Redirect
     */
        public function execute()
        {
        // Get initial data from request
            $categoryId = (int) $this->getRequest()->getParam('category', false);
            $productId = (int) $this->getRequest()->getParam('id');
            $specifyOptions = $this->getRequest()->getParam('options');
            $redirectOosProduct = $this->categoryRedirect($productId);
            if($redirectOosProduct){
                $resultRedirect = $this->resultRedirectFactory->create();
                $resultRedirect->setUrl($redirectOosProduct)->setHttpResponseCode('301');
                return $resultRedirect;
            }
            if ($this->getRequest()->isPost() && $this->getRequest()->getParam(self::PARAM_NAME_URL_ENCODED)) {
                $product = $this->_initProduct();

                if (!$product) {
                    return $this->noProductRedirect();
                }

                if ($specifyOptions) {
                    $notice = $product->getTypeInstance()->getSpecifyOptionMessage();
                    $this->messageManager->addNoticeMessage($notice);
                }

                if ($this->getRequest()->isAjax()) {
                    $this->getResponse()->representJson(
                        $this->jsonHelper->jsonEncode(
                            [
                                'backUrl' => $this->_redirect->getRedirectUrl()
                            ]
                        )
                    );
                    return;
                }
                $resultRedirect = $this->resultRedirectFactory->create();
                $resultRedirect->setUrl($this->_url->getCurrentUrl());
                return $resultRedirect;
            }

        // Prepare helper and params
            $params = new DataObject();
            $params->setCategoryId($categoryId);
            $params->setSpecifyOptions($specifyOptions);

        // Render page
            try {
                $this->applyCustomDesign($productId);
                $page = $this->resultPageFactory->create();
                $this->viewHelper->prepareAndRender($page, $productId, $this, $params);
                return $page;
            } catch (NoSuchEntityException $e) {
                return $this->noProductRedirect();
            } catch (\Exception $e) {
                $this->logger->critical($e);
                $resultForward = $this->resultForwardFactory->create();
                $resultForward->forward('noroute');
                return $resultForward;
            }
        }

                /**
     * Apply custom design from product design settings
     *
     * @param int $productId
     * @throws NoSuchEntityException
     */
                private function applyCustomDesign(int $productId): void
                {
                    $product = $this->productRepository->getById($productId, false, $this->storeManager->getStore()->getId());
                    $settings = $this->catalogDesign->getDesignSettings($product);
                    if ($settings->getCustomDesign()) {
                        $this->catalogDesign->applyCustomDesign($settings->getCustomDesign());
                    }
                }
            }

Your Answer

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