Magento - Custom admin router but with no menu item - magento

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.

Related

How to change admin router?

How to change admin routing? For example:
My current url is "http://www.something.com/index.php/admin/Pos".
Now want to rewrite into "http://www.something.com/index.php/Pos".
Is it possible in Magento?
Are you sure admin/Pos is your admin url path? Usually it should be admin only.
Go to app/etc/local.xml file and you will see something like
<admin>
<routers>
<adminhtml>
<args>
<frontName><![CDATA[admin]]></frontName>
</args>
</adminhtml>
</routers>
</admin>
Change admin to Pos or whatever you want.

Magento OnepageController overwrite breaking checkout

In brief: Made overrides to one page cart controller and clicking on 'checkout' in front end no longer redirects you to checkout/onepage/
The details: I'm trying to override some of the OnepageController functionality - essentially so it will always go from the billing tab to the shipping tab, wherein I can ask for some extra shipping-related information that's used to calculate, well, shipping rates.
So, here's the config.xml bit:
<frontend>
<routers>
<checkout>
<args>
<modules>
<CodexMedia_SmartSend before="Mage_Checkout">
CodexMedia_SmartSend
</CodexMedia_SmartSend>
</modules>
</args>
</checkout>
</routers>
</frontend>
.. which uses a new OnepageController instance (located in CodexMedia/SmartSend/controllers/OnepageController.php) that extends Mage_Checkout_OnepageController) This controller only has the saveBillingAction() modded to always push out the shipping tab and not go straight to Payment Information (I will be adding custom saveShippingAction logic when I get this working properly).
My best guess is I've binked some kind of routing
Thanks for any help!
EDIT: Moved the controller to controllers/Checkout, changing the class to CodexMedia_SmartSend_Checkout_Onepagecontroller and changing config to:
<checkout>
<args>
<modules>
<CodexMedia_SmartSend_Checkout before="Mage_Checkout">CodexMedia_SmartSend_Checkout</CodexMedia_SmartSend_Checkout>
</modules>
</args>
</checkout>
Bingo! All good. Thanks for the help!
You need to remove the newline between CodexMedia_SmartSend tag.The config file should be as follows
<frontend>
<routers>
<checkout>
<args>
<modules>
<CodexMedia_SmartSend before="Mage_Checkout">CodexMedia_SmartSend</CodexMedia_SmartSend>
</modules>
</args>
</checkout>
</routers>
</frontend>

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

Using the same Magento route frontname for frontend and admin routers

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!

starting with Magento Backend

Since a couple of days I´m looking at the behaviour of the Magento backend. To comprehend I made a new grid to see a table of the bbdd. After finishing this grid I can see that I have a 404 error when try I to add a widget in a CMS page:
Debugging I can see that the error disappears if I comment this out of my custom module
<admin>
<routers>
<giftrouter>
<use>admin</use>
<args>
<module>Wpr_Giftproducts_Adminhtml</module>
<frontName>admin</frontName>
<modules>
<sintax after="Wpr_Giftproducts_Adminhtml">Mage_Adminhtml</sintax>
</modules>
</args>
</giftrouter>
</routers>
</admin>
Concretely I think that the error was caused by this:
<sintax after="Wpr_Giftproducts_Adminhtml">Mage_Adminhtml</sintax>
But I don´t understand how this config works.
How can I set a custom route to avoid conflict with the widget?
I think you have your routers in reverse.
<admin>
<routers>
<adminhtml>
<args>
<modules>
<sintax before="Mage_Adminhtml">Wpr_Giftproducts_Adminhtml</sintax>
</modules>
</args>
</adminhtml>
</routers>
</admin>
This way the Giftproducts controller is part of the adminhtml router, whereas the old way was reassigning admin controllers to giftrouter.

Resources