Lexim/Seo/etc/frontend/events.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<!-- Detect 404 page and switch store -->
<!-- event controller_action_predispatch_cms_noroute_index. It will call only for 404 pages. -->
<event name="controller_action_predispatch_cms_noroute_index">
<observer name="check_404_and_redirect_to_fr" instance="Lexim\Seo\Observer\NotFoundRedirectHandler" />
</event>
</config>
Lexim/Seo/Observer/NotFoundRedirectHandler.php
<?php
declare(strict_types=1);
namespace Lexim\Seo\Observer;
use Magento\Framework\App\ActionFlag;
use Magento\Framework\App\ActionInterface;
use Magento\Framework\App\Request\Http;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\Http\Context as HttpContext;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\Store\Api\Data\StoreInterface;
use Magento\Store\Api\StoreCookieManagerInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\UrlRewrite\Model\UrlFinderInterface;
use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
/**
* Class NotFoundRedirectHandler
*
* @package Lexim\Seo\Observer
*/
class NotFoundRedirectHandler implements ObserverInterface
{
/** @var ResponseInterface */
private $_responseInterface;
/** @var Http */
private $_request;
/** @var ActionFlag */
private $_actionFlag;
/** @var StoreManagerInterface */
private $_storeManagerInterface;
/** @var UrlFinderInterface */
private $_urlFinder;
/** @var HttpContext */
private $_httpContext;
/** @var StoreCookieManagerInterface */
private $_storeCookieManager;
/**
* NotFoundRedirectHandler constructor.
*
* @param Http $request
* @param ActionFlag $actionFlag
* @param ResponseInterface $responseInterface
* @param StoreManagerInterface $_storeManagerInterface
* @param UrlFinderInterface $_urlFinder
* @param HttpContext $_httpContext
* @param StoreCookieManagerInterface $_storeCookieManager
*/
public function __construct(
Http $request,
ActionFlag $actionFlag,
ResponseInterface $responseInterface,
StoreManagerInterface $_storeManagerInterface,
UrlFinderInterface $_urlFinder,
HttpContext $_httpContext,
StoreCookieManagerInterface $_storeCookieManager,
)
{
$this->_request = $request;
$this->_actionFlag = $actionFlag;
$this->_responseInterface = $responseInterface;
$this->_storeManagerInterface = $_storeManagerInterface;
$this->_urlFinder = $_urlFinder;
$this->_httpContext = $_httpContext;
$this->_storeCookieManager = $_storeCookieManager;
}
/**
* @param Observer $observer
*
* @return void
*/
public function execute(Observer $observer)
{
$getFullActionName = $this->_request->getFullActionName(); // _noroute_index, cms_noroute_index
$getRequestString = $this->_request->getRequestString(); // "/what-is-adaptive-clothing-fr"
$getRequestString = ltrim($getRequestString, "/");
$isAjax = intval($this->_request->isAjax()); // 0, 1
$storeCode = $this->getCurrentStoreCode();
if (
in_array($getFullActionName, ['cms_noroute_index', '_noroute_index']) &&
$isAjax == 0 &&
$storeCode === 'english'
) {
$allStores = $this->getAllStores();
$frenchCode = 'french';
$frenchStore = $allStores[$frenchCode] ?? null;
if ($frenchStore) {
$frenchId = $frenchStore->getId();
$frRewrite = $this->findOneData($getRequestString, $frenchId);
if ($frRewrite) {
// Switch CA Store from english to french
$this->_httpContext->setValue('store', $frenchCode, $frenchCode);
$this->_storeCookieManager->setStoreCookie($frenchStore);
// Prevent the default action from being executed
$this->_actionFlag->set('', ActionInterface::FLAG_NO_DISPATCH, true);
// Redirect to the current URL in french
$this->_responseInterface->setRedirect($getRequestString);
}
}
}
}
/**
* @param $requestPath
* @param $storeId
*
* @return UrlRewrite|null
*/
protected function findOneData($requestPath, $storeId)
{
return $this->_urlFinder->findOneByData(
[
UrlRewrite::REQUEST_PATH => $requestPath,
UrlRewrite::STORE_ID => $storeId
]
);
}
/**
* @return StoreInterface[]
*/
protected function getAllStores(): array
{
$stores = $this->_storeManagerInterface->getStores(true, true);
if (isset($stores['admin'])) { // remove admin store
unset($stores['admin']);
}
return $stores;
}
/**
* @return string
* @throws NoSuchEntityException
*/
protected function getCurrentStoreCode(): string
{
$curStore = $this->getCurrentStore();
return $curStore->getCode(); // english, french, us
}
/**
* @return StoreInterface
* @throws NoSuchEntityException
*/
protected function getCurrentStore()
{
return $this->_storeManagerInterface->getStore();
}
}
No comments:
Post a Comment