Magento ACL: No More “Log Out And Back In” After Installing Extensions

In almost every Magento extension installation guide you find the step “Log out and log in again” which is necessary to gain access to new sections in the backend menu or system configuration. But why exactly do we put up with it? The problem is that the access control list (ACL) is loaded only on login and then cached in the session. Loading it on every request is no viable alternative because it would slow down the backend too much.

But with just a few lines of code we can make reloading the ACL a little more comfortable.

The Code

This controller action reloads the ACL by request:

class SSE_AclReload_Adminhtml_Permissions_AclReloadController
    extends Mage_Adminhtml_Controller_Action
{
    public function indexAction()
    {
        $session = Mage::getSingleton('admin/session');
        $session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());

        Mage::getSingleton('adminhtml/session')->addSuccess(
            $this->__('ACL reloaded'));
        $this->_redirectReferer();
    }
}

This template provides a button that links to the new controller:

<?php
$request = Mage::app()->getRequest();
?>
<a href="<?php echo $this->getUrl('adminhtml/permissions_aclReload/index'); ?>">
<?php echo $this->__('Reload ACL'); ?>
</a>

And this layout update adds the button to error 404 pages in the backend (those that you get when you don’t have access to a page):

    <adminhtml_noroute>
        <reference name="content">
            <block type="adminhtml/template" name="content.aclReload"
                after="content.noRoute" template="sse_aclreload/button.phtml" />
        </reference>
    </adminhtml_noroute>

The Result

Screenshot Magento Admin 404

I put it together as extension, available on GitHub:

https://github.com/schmengler/AclReload

It also adds a menu item to the “System” > “Permissions” submenu:

Screenshot Magento ACL Reload

Installation

The preferred way to install it is via composer, add these to your composer.json:

    "repositories": [
        {
            "type": "git",
            "url": "https://github.com/schmengler/AclReload.git"
        }
    }
    "require": {
        "sse/aclreload": ">=0.1.1"
    }

But you can also just download the repository and copy everything from src/app into the app directory of your Magento installation.

Acknowledgement

Thanks to Marius Strajeru for giving the idea in his answer on this StackExchange question.

James Anelay pushed the technique a little further with this snippet that you can use in your own extensions: Reload the ACL in an observer before dispatching the system configuration if the current section is not allowed (i.e. would normally show a 404 page). The same can be done in a preDispatch method in custom admin controllers.