Defining ACL resources & Custom Admin Menu in Magento

POSTED ON Oct 28, 2010 IN in How To

Sometimes you need to give ability for limiting access to a particular Magento Admin page and sometimes your customization goes out of just modifying some administrative page layout. In this case creation of adminhtml.xml file in your module etc folder helps you. You can define custom ACL rules and custom menu items or modify behavior of existing menu items, because adminhtml.xml files are merged into one file from different modules.

So lets try to create a custom menu with ACL resources for it. For these purpose you need to create adminhtml.xml file in your module etc directory with the following content:

<?xml version="1.0" ?>
<config>
    <menu>
        <mycustom_menu translate="title" module="[module_name]">
            <title>My Custom Menu Item</title>
            <sort_order>300</sort_order>
            <children>
                <!-- child items go here -->
                <subitem translate="title" module="[module_name]">
                    <title>Subitem</title>
                    <sort_order>10</sort_order>
                    <action>adminhtml/mycustom_controller/</action>
                </subitem>
            </children>
        </mycustom_menu>
    </menu>
    <acl>
        <resources>
            <admin>
                <children>
                    <mycustom_menu translate="title" module="[module_name]">
                        <title>My Custom Menu Item</title>
                        <sort_order>300</sort_order>
                        <children>
                            <!-- child items go here -->
                            <subitem translate="title" module="[module_name]">
                                <title>Subitem</title>
                                <sort_order>10</sort_order>
                            </subitem>
                        </children>
                    </mycustom_menu>
                </children>
            </admin>
        </resources>
    </acl>
</config>

Then you will be able to see the new menu item in Magento Admin menu block:

And you can see your custom ACL resources in “System -> Permissions -> Roles -> Add / Edit Role” in “Role Resources” tab:

adminhtml.xml file is used only to define ACL resources and menu items in Magento. Definition of menu items is placed in config/menu node path and definition of acl resources is placed in config/acl/resources.

Both menu items and ACL resources are hierarchically structured data, so in both of them you can define children node where you can pass the same structure of child nodes as in parent ones.

Let look closer on menu item structure

&lt;subitem translate=&quot;title&quot; module=&quot;[module_name]&quot;&gt;
      &lt;title&gt;Subitem&lt;/title&gt;
      &lt;sort_order&gt;10&lt;/sort_order&gt;
      &lt;action&gt;adminhtml/mycustom_controller/&lt;/action&gt;
&lt;/subitem&gt;

The node name identifies internal a menu item code, that can be used then for selection of current menu items in controller action via $this->_setActiveMenu(‘[parent_menu_item]/[child_menu_item]‘) or for defining of ACL resource for this menu item. Module attribute used to specify what module will be used for translations and translate attribute is used for specifying which nodes to translate (multiple values are separated by space or comma). If your menu item has parent, you can omit specifying of module attribute, then the parent menu item attribute will be used.

Each menu item node may contain such children:

  • title – the menu item label
  • sort_order – the menu item position between the other menu items on the same level
  • action – the menu item controller action, used in Mage_Core_Model_Url::getUrl($route, $params = array()) as first parameter. Specifies actually to what controller action menu item will send the admin user. If this node will not be specified, than your menu item will be not clickable, what is very useful if you want to group some items into some menu item, but do not want to provide separate page for grouped items
  • resource – a ACL resource path to check for checking of the admin user permissions to access this menu item. If you will not specify this node, then Magento will use path of menu item for ACL resource retrieval. For example if your menu item path is “menu_item1/submenu_item1″, then the ACL resource will be “admin/menu_item1/submenu_item1″
  • disabled – the boolean value that is used to indicate is this menu item visible or not. Can be used for purpose of hiding of the menu item of another module by adding this node to the same menu item path
  • depends- this node is used for checking menu items dependencies on another module activity or a configuration field value. To specify dependencies use the following child nodes:
    • module – this node should contain module name, Mage_Catalog for example. If the module specified in this node is not active, then this menu item will not be displayed.
    • config – this node should contain the path to the value of a configuration field. If the configuration field value is 0, then this menu item will not be displayed.

    Let review few examples of depends definitions:
    Example with a module:

    <depends>
          <module>Mage_Wishlist</module>
    </depends>
    

    In this case Magento will not display your menu item if Mage_Wishlist module is not active.

    Example with a configuration field:

    <depends>
          <module>payment/checkmo/active</module>
    </depends>
    

    In this case Magento will not display your menu item if “Check / Money Order” payment method is not enabled.

    Also you can combine a module with a configuration field, then the menu item will not be displayed if at least one of them equals to false.

The structure of ACL resources is similar to menu items. Let review it:

<resourcename translate="title" module="[module_name]">
       <title>Resource Name</title>
       <sort_order>10</sort_order>
</resourcename>

The node name identifies an internal ACL resource code. Module attribute used to specify what module will be used for translations and translate attribute is used for specifying which nodes to translate (multiple values are separated by space or comma). If your resource has parent one, you can omit specifying of module attribute, then the parent resource attribute will be used.

The resource definition contains only two child nodes, they are:

  • title – the label of the ACL resource in the resources tree
  • sort_order – the position of the ACL resource between the others on the same tree level

Checking for the user permission of your resource is pretty simple, just use this code statement:

Mage::getSingleton('admin/session')->isAllowed('[resource_item1_path]/[resource_item1_child_path]');

It will return the boolean value, that indicates the user permission existence.

All the Magento Admin resources are placed under the root resource that is called “admin”, so you need add “admin/children” into “config/acl/resources” node structure to define your ACL resource. But when you pass your resource name to isAllowed($resourcePath) method of the admin session model, you may not specify “admin” as prefix for resource path, because Magento then add it automatically.

Some examples of calling isAllowed method:

$adminSession = Mage::getSingleton('admin/session');
var_dump($adminSession->;isAllowed('admin/catalog/products')); // Checks the permission for managing of products
var_dump($adminSession->isAllowed('sales/order/create')); // Checks the permission for the order creation in Magento Admin
var_dump($adminSession->isAllowed('sales/order/view')); // Checks the permission for the order view in Magento Admin

Now you know how to create your custom menu items and your custom ACL resources.

Enjoy working with Magento!

Ivan Chepurnyi
Magento guru / System architect
Ivan started as Magento Core developer in early 2007, since that time he already has 6 years of experience in different areas of Magento development. During all that time he developed enormous amount of modules and customizations, so now almost every dark corner in Magento functionality is investigated by him. He can’t keep that knowledge in secret, that why he's sharing it with the community and helps finding the way out of Magento complexity maze.

18 Responses to “Defining ACL resources & Custom Admin Menu in Magento”

  1. Hi Ivan :),
    I normaly do this in the config.xml file: is there an advantage of doing it by adminhtml.xml? Or maybe it’s best practise?

    • Ivan Chepurnyi says:

      Hi osdave,
      Doing this in config.xml, is backward compatibility usage. It may be removed in future Magento releases, so better practice to use adminhtml.xml file. By the way it makes your config.xml file more readable, because there are less lines of code, those just define menu items in admin and ACL resources.

  2. Great article, Ivan. Didn’t know about ‘disable, depends’ for menu item node before. Thanks

  3. Very nice, thank you.
    Any way you could check if ANOTHER user isAllowed something though ?
    Suppose you want to retrieve a list of administrators enabled for the resource X.

    • Ivan Chepurnyi says:

      Magento uses Zend_Acl, so they are loading all users rights into one ACL object on each page load. For retrieving right of another user just use something like this (haven’t tested, but it should be possible):

      // Retrieving Zend_Acl object
      $acl = Mage::getSingleton('admin/session')->getAcl();
      // Checking the access
      $isAllowed = $acl->isAllowed($user->getAclRole(), $resource, $privilege);
      
  4. Hi,lvan: Thats all right, but i need to show my module menu item in other menu.. Like if i have multiple modules and i want to show all these module name list in one same menu, is this possible and how?

    Thanks and regards:
    imran.

  5. Hi Ivan

    In 1.6 – when I create a new user who only has access to the reports, the only report not showing is the bestsellers report – Ive tested this on 3 servers. Do you have any idea how to fix this?

    • @Chris, it is typo in Magento core :) They defined acl rule path as “report/products/ordered”, but the code of menu item is “report/products/bestsellers”. You can define additional acl rule with proper path and it should work.

  6. Thanks a lot Ivan for this crystal clear article about Magento ACL resources.

    This blog really helps me to follow Magento best practices and gives me a lot of insights about Magento !!!

    Wish you all the success for this fantastic blog and your powerful extensions (checkitout).

  7. Jean Paul says:

    Hi I need to provide a way to only set access for a specific role user to admin a specific category, whats the best way to limit the catalog product list and crud of the products already created.
    Regards,
    JP

  8. Hi Ivan, very nice article. Thanks to share.

    You suggest to move the acl section into adminhtml.xml file. So, is it the same for the section too ? I’m talking about the place where we define the .csv file for the locale.

    Regards,
    stéphan

  9. Ah, thank you very much! I also used to put this in the config.xml but now I understand a lot more what it does and where it goes! From now on I will use adminhtml.xml for this.

    kind regards,
    Isolde

  10. Hello,

    Thank you for suggestion..

    But still I am facing problem with this issue.

    I have developed new custom module.
    Now its working fin in only admin user.
    But when i am trying to give permission for other user then it is not working or save.
    So i can do this….pls help me…

  11. I have just spent some time with an issue where a permission would appear in the role creation page, but it just wouldn’t save.

    To fix it, i ended up using lowercase chars ONLY on the resource name. When using camelCase, magento just wouldn’t keep the resource active for a certain role.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>