11

Is it possible to create a module in Magento 2, using standard routing, that responds to a URL in the form of

http://magento.example.com/namespace_module/return/index

That is -- a URL where the second parameter is a PHP reserved keyword. The problem with the above is is create a PHP controller class name that's

Namespace\Module\Controller\Return\Index

and having Return in the namespace is illegal PHP. I know if the URL's final parameter (traditionally called the action) was a reserved keyword

http://magento.example.com/namespace_module/foo/return

that Magento would let me create a controller class named

Namespace\Module\Controller\Foo\ReturnAction

However, this does not work for the second parameter.

Is there a way to do this using standard Magento 2 routing techniques?

If not, is there a generally considered best practice for injecting a custom router object to get this behavior, or some other technique that would let me work around this? (an after plugin on Magento\Framework\App\Router\ActionList?)

1 Answer 1

7

I ended up adding a plugin for Magento\Framework\App\Router\ActionList

<!-- File: app/code/Package/Namespace/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">
    <type name="Magento\Framework\App\Router\ActionList">
        <plugin name="package_module_magento_framework_app_router_actionlist" type="Package\Module\Plugin\Magento\Framework\App\Router\ActionList"/>
    </type>
</config>

and then fiddled with the $namespace parameter of the get method

#File: app/code/Package/Module/Plugin/Magento/Framework/App/Router/ActionList.php
public function beforeGet($subject, $module, $area, $namespace, $action)
{
    if($namespace === 'return')
    {
        $namespace = 'returnaction';
    }
    return [$module, $area, $namespace, $action];
}

This gave me a class name of

Package\Module\Controller\ReturnAction\Index

Not sure how good an idea this is, so buyer beware, etc.

2
  • This looks nice and easy. Specially because it can be extended to all php reserved words in the same way the action names are mapped to action classes. An alternative would be to create a custom router but this requires way more code.
    – Marius
    Jun 7, 2017 at 6:12
  • 2
    Only a couple comments: 1) This will change the namespace for any module that tries to use the 'return' controller. Unless you're intentionally creating a 'catchall' it might be best to check the $module parameter to match your own module. 2) If we're going to try to preserve naming parity, the returned $namespace should probably be 'returnController' - which would then search for the ReturnController namespace/filepath. This would then load \Namespace\Module\Controller\ReturnController\Index - which is more accurate. Jul 5, 2017 at 23:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.