Question

If I have disabled any product then it will redirect to 404. But I want to redirect that product url from 404 not found page to the category url in which this product is assigned.

That means I want to redirect to the related category of that 404 not found(Product url).

How can I achieve this in magento 2.3?

Was it helpful?

Solution

First Create a custom module https://www.mageplaza.com/magento-2-module-development/

now follow below steps to achieve this

system.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <tab id="test" translate="label" sortOrder="200">
            <label>Product Redirect</label>
        </tab>
        <section id="test2" translate="label" type="text" sortOrder="110" showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Disabled Products Redirect</label>
            <tab>syng</tab>
            <resource>Vendor_Module::disabledproductsredirect</resource>
            <group id="disabled_products_redirect" translate="label" type="text" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
                <label>Redirection Message</label>
                <field id="redirection_message" translate="label comment" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1" canRestore="1">
                    <label>Message for users who try to go to a disabled product URL</label>
                    <comment>Leave empty if you want the defaul message: "The product you tried to view is not available but here are some other options instead"</comment>
                </field>
            </group>
        </section>
    </system>
</config>

di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Controller\Product\View">
        <plugin name="test_disabled_products_redirect" type="Vendor\Module\Plugin\ProductsRedirect"/>
    </type>
</config>

ProductsRedirect.php

<?php
namespace Vendor\Module\Plugin;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Catalog\Api\CategoryRepositoryInterface;
use Magento\Framework\Message\ManagerInterface;
use Magento\Framework\Controller\Result\RedirectFactory;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\Request\Http;
use \Magento\Catalog\Controller\Product as ProductController;

class ProductsRedirect
{
    
    private $productRepository;
    private $categoryInterface;
    private $messageManager;
    private $resultRedirectFactory;
    private $scopeConfig;
    private $request;
    public function __construct(
        ProductRepositoryInterface $productRepository,
        CategoryRepositoryInterface $categoryInterface,
        ManagerInterface $messageManager,
        RedirectFactory $resultRedirectFactory,
        ScopeConfigInterface $scopeConfig,
        Http $request
    ) {
        $this->productRepository = $productRepository;
        $this->categoryInterface = $categoryInterface;
        $this->messageManager = $messageManager;
        $this->resultRedirectFactory = $resultRedirectFactory;
        $this->scopeConfig = $scopeConfig;
        $this->request = $request;
    }
    /**
     * @param ProductController $subject
     */
    public function aroundExecute(ProductController $subject, callable $proceed)
    {
        $productId = (int) $this->request->getParam('id');
        $product =  $this->productRepository->getById($productId);
        if ($product->isDisabled()) {
            $cats = $product->getCategoryIds();
            if ($cats) {
                try {
                    $firstCategoryId = $cats[0];
                    $category = $this->categoryInterface->get($firstCategoryId);
                    if ($category->getIsActive()) {
                        $message = $this->getMessage();
                        $categoryUrl = $category->getUrl();
                        $this->messageManager->addNoticeMessage($message);
                        $resultRedirect = $this->resultRedirectFactory->create();
                        $resultRedirect->setHttpResponseCode(301);
                        return $resultRedirect->setPath($categoryUrl);
                    } else {
                        // TODO consider cases where category can't be displayed, maybe check other categories
                        throw new \Magento\Framework\Exception\LocalizedException(__('First category is not active'));
                    }
                } catch (\Exception $e) {
                    return $proceed();
                }
            }
        }
        return $proceed();
    }
    private function getMessage()
    {
        $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
        $message =  $this->scopeConfig->getValue(
            'test2/disabled_products_redirect/redirection_message',
            $storeScope
        );
        if (!$message) {
            $message = __('The product you tried to view is not available but here are some other options instead');
        }
        return $message;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top