For this your requirement, you need to use Custom routers
instead of plugin on FrontControllerInterface
etc.
Custom router has the ability to handle the custom URL as per as business logic.
Custom router internally hit the Magento Standard router Url www.example.com/<front-name>/<controller-name>/<action-name>
.At Magento ,if you want to output/render from an Action then your URL must be hit <front-name>/<controller-name>/<action-name>
directly or indirectly
A good example is the Magento Cms module' router Magento\Cms\Controller\Router
.
$page = $this->_pageFactory->create();
$pageId = $page->checkIdentifier($identifier, $this->_storeManager->getStore()->getId());
if (!$pageId) {
return null;
}
$request->setModuleName('cms')->setControllerName('page')->setActionName('view')->setParam('page_id', $pageId);
$request->setAlias(\Magento\Framework\Url::REWRITE_REQUEST_PATH_ALIAS, $identifier);
return $this->actionFactory->create(\Magento\Framework\App\Action\Forward::class);
You need when a user is hit cms page identifier then it's internally hit magento www.example/cms/page/view
with params page_id/$pageId
You need to build the same logic for this requirement.
Declare Custom router at di.xml
First create di.xml
at app/code/{VendorName}/{ModuleName}/etc/frontend
.
And Defined Custom router here.
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<!--Add Custom route-->
<type name="Magento\Framework\App\RouterList">
<arguments>
<argument name="routerList" xsi:type="array">
<item name="crankycyclops" xsi:type="array">
<item name="class" xsi:type="string">VendorName\ModuleName\Controller\Router</item>
<item name="disable" xsi:type="boolean">false</item>
<item name="sortOrder" xsi:type="string">31</item>
</item>
</argument>
</arguments>
</type>
</config>
Custom router Class
After that create Custom router class VendorName\ModuleName\Controller\Router
where you build the logic for /page/path/discount/COUPON_CODE
routing.
Assume that Url is www.example.com/myurlone/myurltwo/discount/COUPON_CODE
.
Here: www.example.com/myurlone/myurltwo/discount/COUPON_CODE
hit
= www.example.com/routing/index/index/discount_code/COUPON_CODE
Code
<?php
declare(strict_types=1);
namespace VendorName\ModuleName\Controller;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\Action\Forward;
class Router implements \Magento\Framework\App\RouterInterface {
/**
* @var ActionFactory
*/
private $actionFactory;
public function __construct(
ActionFactory $actionFactory
) {
$this->actionFactory = $actionFactory;
}
public function match(\Magento\Framework\App\RequestInterface $request) {
$identifier = trim($request->getPathInfo(), '/');
$condition = new \Magento\Framework\DataObject(['identifier' => $identifier, 'continue' => true]);
$identifier = $condition->getIdentifier();
if (strpos($identifier, 'myurlone/myurltwo/discount') === false) {
return null;
}
/**
* Split myurlone/myurltwo/discount/COUPON_CODE by /
*/
$urlParts = explode('/', $identifier);
/**
* if $urlParts count is more then 4 or less then custom route return null means not match
*/
if(count($urlParts) > 4 && count($urlParts) <3 ){
return null;
}
if($urlParts[0] !== 'myurlone' || $urlParts[1] !== 'myurltwo'
|| $urlParts[2] !== 'discount'){
return null;
}
$discountCode = $urlParts[3]; // $urlParts[3] = COUPON_CODE
/**
* here assume that COUPON_CODE is NOT match
* Changes the logic as per your requirement
*/
if($discountCode === 'NOT MATCH'){
return null;
}
/**
* if match
*/
$request->setModuleName('routing');
$request->setControllerName('index');
$request->setActionName('index');
$request->setParams([
'discount_code' => $discountCode
]);
return $this->actionFactory->create(Forward::class, ['request' => $request]);
}
}