1

I want to override this class class Base implements \Magento\Framework\App\RouterInterface this class is located in vendor/magento/framework/App/Router/Base.

So here is my custom module looks like :

Fabelio/UriPrefix/etc/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">
    <preference for="Magento\Framework\App\RouterInterface" type="Fabelio\UriPrefix\Controller\Router"/>
</config>

As you can see from above di.xml I'm overriding the interface RouterInterface which implemented in the Base class.

Fabelio/UriPrefix/etc/module.xml :

<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Fabelio_UriPrefix" setup_version="1.0.0">
    </module>
</config>

Fabelio/UriPrefix/Controller/Router :

<?php

namespace Fabelio\UriPrefix\Controller;

use Magento\Framework\App\RequestInterface;
use Magento\Framework\App\Router\Base as BaseRouter;
use Magento\Framework\App\ActionFactory;
use Magento\Framework\App\Action\Forward;
use Magento\Framework\App\Action\Redirect;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\App\State;
use Magento\Framework\DataObject;
use Magento\Framework\Event\ManagerInterface;
use Magento\Framework\Url;
use Magento\Framework\UrlInterface;
use Magento\Store\Model\ScopeInterface;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Framework\Controller\ResultFactory;

class Router extends BaseRouter
{
    // I remove all the variables here for simplicity so that you can read the code
    /**
     * @param \Magento\Framework\App\Router\ActionList $actionList
     * @param \Magento\Framework\App\ActionFactory $actionFactory
     * @param \Magento\Framework\App\DefaultPathInterface $defaultPath
     * @param \Magento\Framework\App\ResponseFactory $responseFactory
     * @param \Magento\Framework\App\Route\ConfigInterface $routeConfig
     * @param \Magento\Framework\UrlInterface $url
     * @param string $routerId
     * @param \Magento\Framework\Code\NameBuilder $nameBuilder
     * @param \Magento\Framework\App\Router\PathConfigInterface $pathConfig
     *
     * @throws \InvalidArgumentException
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function __construct(
        \Magento\Framework\App\Router\ActionList $actionList,
        \Magento\Framework\App\ActionFactory $actionFactory,
        \Magento\Framework\App\DefaultPathInterface $defaultPath,
        \Magento\Framework\App\ResponseFactory $responseFactory,
        \Magento\Framework\App\Route\ConfigInterface $routeConfig,
        \Magento\Framework\UrlInterface $url,
        $routerId,
        \Magento\Framework\Code\NameBuilder $nameBuilder,
        \Magento\Framework\App\Router\PathConfigInterface $pathConfig
    ) {
        $this->actionList = $actionList;
        $this->actionFactory = $actionFactory;
        $this->_responseFactory = $responseFactory;
        $this->_defaultPath = $defaultPath;
        $this->_routeConfig = $routeConfig;
        $this->_url = $url;
        $this->nameBuilder = $nameBuilder;
        $this->pathConfig = $pathConfig;
    }

    /**
     * Match provided request and if matched - return corresponding controller
     *
     * @param \Magento\Framework\App\RequestInterface $request
     * @return \Magento\Framework\App\ActionInterface|null
     */
    public function match(\Magento\Framework\App\RequestInterface $request) {
        $urlKey = trim($request->getPathInfo(), '/');
        $origUrlKey = $urlKey;
        var_dump($urlKey);
        var_dump($origUrlKey);
        die();
    }
}

As you can see in the above Router.php code in the match function, I print some variable and use die to stop execution.

But magento 2.1.8 still work when I go to the category page or product page.

2

This is not how you need to approach here. Magento's core routers and classes have more precedence over your module and thus the request flow won't reach your router class.

Background Theory

In Magento 2, there are routers and they are grouped inside router list. Now Magento's front controller will loop through the router list and look for a router which is able to process the requested URL. Once it finds a match, then the job will be handed over to that router which will find the controller and action responsible to handle the request.

But through you module, you are trying to give preference to the router interface which is not going to work. Instead what you need to do is, define your own router, add that router to router list and then finally make your router precedence higher than core routers so that Magento finds your router first as a match winner and hand over the rest of the works to your router.

1. Define your router.

Well, you already did this job and your router is Fabelio/UriPrefix/Controller/Router.

2. Add the router to router list.

File : app\code\Fabelio\UriPrefix\etc\frontend\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\Framework\App\RouterList">
        <arguments>
            <argument name="routerList" xsi:type="array">
                <item name="fabelio_uriprefix" xsi:type="array">
                    <item name="class" xsi:type="string">Fabelio\UriPrefix\Controller\Router</item>
                    <item name="disable" xsi:type="boolean">false</item>
                    <item name="sortOrder" xsi:type="string">5</item>
                </item>
            </argument>
        </arguments>
    </type>
</config>

Here you are adding a new router fabelio_uriprefix into the router list via di.xml file. This will get affected only in frontend since the di.xml file comes under the area frontend. This way Magento will consider your router in the "router matching game".

3. Give precedence to Module's router

This step is already done in step 2. See the sort order sortOrder parameter. We put there 5. Hopefully that will consider your router first in the "game". In a quick look, I find Magento's standard router has a sort order of 10.

PS: I am not sure whether this will work in your case since I didn't test the code. But I think you got the idea.

  • did you try this? – Rajeev K Tomy Sep 12 '17 at 9:45
  • Ya I'm trying it now, but I got the idea how the router works and how to add new Router from your answer, the xml and other things will come later :D – Gujarat Santana Sep 12 '17 at 9:48
  • sorry this doesnt work like what I expected. What I want is the router will accept all the request so that I can change the request_path – Gujarat Santana Sep 12 '17 at 10:38
  • somehow your answer lead me to a solution so thank you – Gujarat Santana Sep 13 '17 at 4:40

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.