How to redirect to specific category if product url is 404 due to product disabled in magento 2.3?
-
14-04-2021 - |
Domanda
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?
Soluzione
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;
}
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a magento.stackexchange