Using the same Magento route name for front-end and administrative routers

I found a problem with Magento's routing logic, and I would like to know if anyone can confirm this.

Magento installs the admin, standard, then default routers and processes them one at a time. Magento obtains the current module name based on the URL (see Mage_Core_Controller_Varien_Router_Standard::match()) , and then checks whether the module should be processed by this router based on the frontName match in the Magento configuration. If a match is found, it directs it. If not, it will continue to the next router.

Configuration Excerpt:

  <admin>
         <routers>
             <myroute>
                 <use> admin </use>
                 <args>
                     <module> MyNamespace_MyModule </module>
                     <frontName> myroute </frontName>
                 </args>
             </myroute>
         </routers>
     </admin>
     <frontend>
         <routers>
             <myroute>
                 <use> admin </use>
                 <args>
                     <module> MyNamespace_MyModule </module>
                     <frontName> myroute </frontName>
                 </args>
             </myroute>
         </routers>
     </frontend>
    

This means that if you use the same name for your external router as an administrator, the administrator router will always be negotiated first, even on the front-end pages. Now your front-end page will be routed as if it had an admin base_url using admin base_url , which may be different from your store URL, resulting in a broken redirect.

Note that this problem does not occur in instances of Magento, where the base URL of the administrator matches the base URL.

Can anyone confirm that my assessment of the router logic here is correct?

+6
source share
3 answers

This is not a Magento bug, but it is something you need to know about when writing modules or working with third-party code. I clarified the problem and the resolution here . Essentially, an existing adminhtml route should always be used, not create new admin routes. This leads to the fact that the URLs in the admin do not contradict each other and avoid conflicts. Thanks to Alan and Jared for helping me understand how Magento is developing better.

+3
source

You can also view Varien / Router / Standard.php, in particular:

 /** * checking if this admin if yes then we don't use this router * * @return bool */ protected function _beforeModuleMatch() { if (Mage::app()->getStore()->isAdmin()) { return false; } return true; } 

And this is called inside the match(Zend_Controller_Request_Http $request) method, as well as collectRoutes($configArea, $useRouterName) , since $useRouterName will sometimes return admin , as well as return standard for external requests. The assumption sounds correct, since it all depends on how magento builds and stacks the private array _routes and _modules in the same class: Mage_Core_Controller_Varien_Router_Standard .

In this case, I would like to specify the <use> node as standard for the interface and admin for the administrator, or rewrite the controller action in the <global> node.

I think it's best to read:

and / or follow the logic with X-debug .

Even Alan Storm writes in his article that the same routers used for the interface and backend should not be the same.

So, it looks like this method is designed to provide a standard router object if, for some reason, the store model object considers it in administrator mode. Like the Standard / Admin router relationship, the store object is another one of those things that points to certain parts of the Magento development process that focus on the frontend application first and then overlay on the admin console later and need to change the return port.

The store object is a model that really only applies to the frontend / cart application. However, since so much code in Magento assumes that the store object exists, it must be available for the admin console application. This, in turn, creates problems at the router level, which leads to such a check. Many levels of abstraction, undefined contracts between classes / modules and the fear of refactoring created by the lack of tests will always lead to such situations.

+4
source

Just throw me 2 cents on it; I definitely noticed this problem tonight! I am creating a custom module and my config.xml routers are defined as follows:

 <admin> <routers> <namespace_module> <use>admin</use> <args> <module>Namespace_Module</module> <frontName>namespace_module</frontName> </args> </namespace_module> </routers> </admin> <frontend> <routers> <namespace_module> <use>standard</use> <args> <module>Namespace_Module</module> <frontName>namespace_module</frontName> </args> </namespace_module> </routers> </frontend> 

I was getting a 404 error in the interface while the backend routers were working fine. I changed the interface name and voila:

 <admin> <routers> <namespace_module> <use>admin</use> <args> <module>Namespace_Module</module> <frontName>namespace_module</frontName> </args> </namespace_module> </routers> </admin> <frontend> <routers> <namespace_module> <use>standard</use> <args> <module>Namespace_Module</module> <frontName>namespace_module_front</frontName> </args> </namespace_module> </routers> </frontend> 

It makes sense to use a unique name that I think!

+1
source

Source: https://habr.com/ru/post/915125/


All Articles