2

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?

2

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;
    }
}
6
  • what will be the use of system.xml here? Jul 29 '20 at 10:45
  • setting up custom message you can remove it if you dont need it
    – Pramod
    Jul 29 '20 at 10:48
  • moreover you can customize the code to suite your requirements you can remove the getMessage() function
    – Pramod
    Jul 29 '20 at 10:49
  • Thanks this is working....one more thing if product is not found in the website then what will be do? Jul 29 '20 at 11:10
  • please ask a different question someone might have done that and if this worked for you then accept so that other finds it helpful
    – Pramod
    Jul 29 '20 at 11:11

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.