Using the same Magento route frontname for frontend and admin routers - magento

I discovered an issue with Magento routing logic and I would like to see if anyone can confirm this.
Magento stacks routers admin, standard, then default and processes them one at a time. Magento gets the current module name based on the URL (see Mage_Core_Controller_Varien_Router_Standard::match()), then checks if the module should be handled by this router, based on a match to a frontName in the Magento config. If a match is found, it routes it. If not, it continues to the next router.
Config 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 frontend router as your admin router, the admin router will always be matched first, even on frontend pages. Your frontend page will now route as is if were an admin page, using the admin base_url, which may be different from your store's URL causing a broken redirect.
Note that this issue is not apparent in Magento instances where the admin base URL is the same as the frontend base URL.
Can anyone confirm that my assesment of the router logic is correct here?

You may want to look over Varien/Router/Standard.php as well 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 within the method match(Zend_Controller_Request_Http $request) as well as collectRoutes($configArea, $useRouterName) as $useRouterName will sometimes return admin and will also return standard for frontend requests. The assumption sounds correct as it all depends on how magento builds and stacks the _routes and _modules private array in this same class: Mage_Core_Controller_Varien_Router_Standard.
I believe in this case you would want to specify the <use> node as standard for frontend and admin for admin, or rewrite the controller action in the <global> node.
I think your best bet is to read over:
http://alanstorm.com/magento_dispatch_admin_cms_default_routers
and/or step through the logic with X-debug.
Even Alan Storm in his article writes how the same routers used for frontend and backend shouldn't be the same.
So it looks like this method is here to ensure the Standard router object bails if, for some reason, the store model object thinks its in admin 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 being focused on the frontend application first, and then tacking on an admin console later and having to back-port changes.
The store object is a model that really only applies to the frontend/cart application. However, because so much code in Magento assumes the store object exists, it needs to be available to the admin console application. This, in turn, creates trouble at the router level, which is what leads to a check like this. Many layers of abstraction, no defined contracts between classes/modules, and the fear of refactoring created by the lack of tests will always lead to these sorts of situations.

This is not a Magento bug, but is something to be aware of when writing modules or working with third party code. I have clarified the issue and resolution here. Essentially, the existing adminhtml route should always be used rather than creating new admin routes. This makes urls in the admin consistent and avoids conflicts. Thank you Alan and Jared for helping me understand Magento routing better.

Just to throw my 2 cents into this; I certainly noticed this issue tonight! I'm building a custom module and my config.xml routers are defined like so:
<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 on the frontend while the backend routers worked just fine. I changed the frontend 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>
Makes sense to use a unique name I guess!

Related

Magento - Override other Route of another Module

I'm using the clever cms module to manage some basic cms pages. Now I want to add some custom behaviour to one of the routes the clever cms is using. An Example:
example.com/cms/page // <- a normale cms page
example.com/cms/category // <- another module should do it's stuff here
When I make a new module, I can only override the whole cms route, and not plug myself in the cms/category only.
Is there a way to do this?
If you are creating a new controller, this is easy; just make use of the native ability to map multiple controller directories to a frontname. In your module config:
<frontend>
<routers>
<cms>
<args>
<modules>
<your_module after="Mage_Cms">Your_Module</your_module>
</modules>
</args>
</cms>
</routers>
This will allow requests to map to Your/Module/controllers/CategoryController.php.

Magento Module with Frontend and Admin functionality

I'm currently working on a custom module for Magento. I understand the basics of Packages, Modules and Routers, and I have built the front end part of my module.
However I am now moving on to the admin side of things. However I'm a little bit confused by how I add the admin part to my routers and get it to call the relevant controller.
Let's imagine I have created these routers...
<frontend>
<routers>
<slider>
<use>standard</use>
<args>
<module>Mypackage_Myodule</module>
<frontName>Mymodule</frontName>
</args>
</slider>
</routers>
</frontend>
<admin>
<routers>
<mymoduleadmin>
<use>admin</use>
<args>
<module>Mypackage_Myodule</module>
<frontName>Mymodule</frontName>
</args>
</mymoduleadmin>
</routers>
</admin>
I presume that both these routers will attempt to call controllers/IndexController.php and therefore the same functionality? Is it possible to set things up so my routers call different controllers depending on whether they are front end or admin? Is this even possible or do I need to set up a front end module and an admin module?
I apologise if this is a School Boy question, but this has me a bit confused and in reality I just want to know the most efficient way to set up a custom module with front end and admin functionality.
Depending upon the area(frontend or adminhtml), frontend or adminhtml router are dispatched.
So you need not need to worry about getting it messed up as long as you are using different controller files for frontend and adminhtml, frontend controller extending from Mage_Core_Controller_Front_Action & adminhtml extending from Mage_Adminhtml_Controller_Action.
Frontend / Adminhtml routers can be defined as (just a syntax):
<frontend>
<routers>
<[module]>
<use>standard</use>
<args>
<module>[Namespace]_[Module]</module>
<frontName>[module]</frontName>
</args>
</[module]>
</routers>
</frontend>
<admin>
<routers>
<[module]>
<use>admin</use>
<args>
<module>[Namespace]_[Module]</module>
<frontName>[module]</frontName>
</args>
</[module]>
</routers>
</admin>
And you can create frontend controllers under: app/code/[codePool]/[Namespace]/[Module]/controllers/
For example:
<?php
//file: app/code/local/MagePsycho/Testmodule/controllers/IndexController.php
class MagePsycho_Testmodule_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction(){
}
}
In order to access it from url: http://your-magento-url/testmodule/index/index
and adminhtml controllers under:
app/code/[codePool]/[Namespace]/[Module]/controllers/Adminhtml/
For example:
<?php
//file: app/code/local/MagePsycho/Testmodule/controllers/Adminhtml/IndexController.php
class MagePsycho_Testmodule_Adminhtml_IndexController extends Mage_Adminhtml_Controller_Action
{
public function indexAction(){
}
}
In order to access it from url: http://your-magento-url/testmodule/adminhtml_index/index
(You can see the Adminhtml folder for separating adminhtml controllers)
Hope this gave you some info.
Thanks
Have a look at my similar question: Admin route in custom modules
I also would recommend using
<admin>
 <routers>
   <adminhtml>
     <args>
       <modules>
         <modulename before="Mage_Adminhtml">Namespace_Module_Adminhtml</modulename>
       </modules>
     </args>
   </adminhtml>
 </routers>
</admin>
This will allow you to avoid using adminhtml part in the routes, so your module backend url will have simple and clean url like core modules e.g. admin/mymodule

Magento - Custom admin router but with no menu item

I want to create an admin controller - without having any menu items associated with it.
Ideally I want to have my controller accessible via /index.php/admin/my_controller/.
So far I have rewritten the adminhtml controller as follows but i simnply get a 404 inside the admin console (i.e. not the main 404 page):
<admin>
<routers>
<my_module>
<use>admin</use>
<args>
<module>Me_Mymodule</module>
<frontName>my_controller</frontName>
</args>
</my_module>
<adminhtml>
<args>
<modules>
<my_module after="Mage_Adminhtml">Me_Mymodule</my_module>
</modules>
</args>
</adminhtml>
</routers>
</admin>
Your current config technique has been obsolete since version 1.4. Instead it is more convenient to structure it like this.
<admin>
<routers>
<adminhtml>
<args>
<modules>
<my_module before="Mage_Adminhtml">Me_Mymodule_Adminhtml</my_module>
</modules>
</args>
</adminhtml>
</routers>
</admin>
Then to get the /index.php/admin/mymodule/ path create the class Me_Mymodule_Adminhtml_MymoduleController extends Mage_Adminhtml_Controller_Action in Me/Mymodule/controllers/Adminhtml/MymoduleController.php. In your example you used an underscore in the controller name, be careful of that as it will be used as a directory separator when searching for the correct class.
Remember to generate URLs for your controller like Mage::getUrl('adminhtml/mymodule') so that it adds the secret key to paths, this is necessary when making an admin controller or it will refuse the page.
If there are no menu items then it will not be possible to add them to the ACL. You do not need an adminhtml.xml file in this case.
For you goal xml config is redundant.
Use following to add your controller to /admin frontname
Company_Module_Adminhtml
Now every controller that will be created in controller/Adminhtml folder will accessed through admin like
/admin/yourfilename/index
The class name of controller should be Module_Module_Adminhtml_YourfilenameController and should extend Mage_Adminhtml_Controller_Action
That's the trick.
Even if you do not add your controller to menu, you still have to add acl section for your controller adminhtml.xml. Do not forget to relog to admin after that.

Facing redirection issues in custom module in magento 1.4.2.0

i have set secure url in magento and also set use secure url in front end variable. it is working perfect in default magento modules, we have made custom module wich is redirecting to secure url by 302 redirection. i want to redirect it to as default magento works.
Please help in this regards.
smart, the OP, already self-answered the question.
Quote:
it is resolved. i have an issue with ssl. its working fine now
Note: It's absolutely OK to self-answer your own question. Please just post it as an real answer, but not in a question or comment. Posting as real answer helps to keep the "Unanswered" list more clear (avoids making other people wasting their time).
You can add different "frontName" for <admin> and <frontend> routers in config.xml file of your module.
For example, you can see in the config.xml code below that admin and frontend routers have different name. Admin router name is frontName. Frontend router name is frontName1
<admin>
<routers>
<[ModuleName]>
<use>admin</use>
<args>
<module>[NameSpace_ModuleName]</module>
<frontName>[frontName]</frontName>
</args>
</[ModuleName]>
</routers>
</admin>
<frontend>
<routers>
<[ModuleName]>
<use>standard</use>
<args>
<module>[NameSpace_ModuleName]</module>
<frontName>[frontName1]</frontName>
</args>
</[ModuleName]>
</routers>
</frontend>
Source: https://magecracker.wordpress.com/2013/01/11/why-magento-custom-module-frontend-url-is-forced-to-https/

Magento config XML for adding a controller action to a core admin controller

I'm trying to add a custom action to a core controller by extending it in a local module. Below I have the class definition which resides in magento1_3_2_2/app/code/local/MyCompany/MyModule/controllers/Catalog/ProductController.php
class MyCompany_MyModule_Catalog_ProductController extends Mage_Adminhtml_Catalog_ProductController
{
public function massAttributeSetAction(){
...
}
}
Here is my config file at
magento1_3_2_2/app/code/local/MyCompany/MyModule/etc/config.xml:
...
<global>
<rewrite>
<mycompany_mymodule_catalog_product>
<from><![CDATA[#^/catalog_product/massAttributeSet/#]]></from>
<to>/mymodule/catalog_product/massAttributeSet/</to>
</mycompany_mymodule_catalog_product>
</rewrite>
<admin>
<routers>
<MyCompany_MyModule>
<use>admin</use>
<args>
<module>MyCompany_MyModule</module>
<frontName>MyModule</frontName>
</args>
</MyCompany_MyModule>
</routers>
</admin>
</global>
...
However, https://example.com/index.php/admin/catalog_product/massAttributeSet/ simply yields a admin 404 page. I know that the module is active - other code is executing fine. I feel it's simply a problem with my xml syntax. Am I going about this the write way? I'm hesitant because I'm not actually rewriting a controller method... I'm adding one entirely. However it does make sense in that, the original admin url won't respond to that action name and it will need to be redirected.
I'm using Magento 1.3.2.2
Thanks for any guidance.
I don't have access to my Magento installs at the moment, but two things pop out
First, your write rule
[#^/catalog_product/massAttributeSet/]
Is saying "match any URL that starts with /catalog_product" and your question indicates you want to match a URL that begins with /admin/catalog_product.
Second, if you're using 1.3+ consider skipping the URL rewrite method and trying a "real" controller override instead.

Resources