Controlling Access: Zend_Navigation and Zend_Acl
Out Of Date Warning
Languages change. Perspectives are different. Ideas move on. This article was published on April 2, 2010 which is more than two years ago. It may be out of date. You should verify that technical information in this article is still current before relying upon it for your own purposes.
In the last two entries, we examined creating a navigation structure with Zend_Navigation, and then we examined using that structure with the Zend Navigation View Helper. In both discussions, we focused on creating navigation items and menus, and inherently these items were available to all users regardless of access controls. But what happens when you have special areas of your site, say for subscribers or administrators? Controlling access is something that all web developers must do at some point. This is where integration between Zend_Navigation and Zend_Acl comes in.
Some important points about Zend_Acl
Zend_Acl doesn’t follow any particular paradigm with regards to implementation of access control. Instead, much like Zend_Navigation, it works as a standalone component, allowing you to determine when, where and how to implement access control. Personally, I implement access control at the module/controller/action level, but you can choose to do it any way you like.
This article works off the assumption that the reader knows, has used, and/or understands Zend_Acl and it’s behavior/functionality.
Setting Up Access Controls At The Navigation Level
Zend_Navigation provides built-in support for adding ACL controls, allowing you as a user to specify what, if any, access controls there are on particular pages. This is done when the objects are created, and you can either do it on the page object itself, or in the array you use to create the navigation structure. For the purposes of this example, we’re going to reuse our old array, but we’re also going to add an admin section that is access controlled.
$navArray = array( array( 'controller' => 'index', 'label' => 'Home', ), array( 'controller' => 'about', 'label' => 'About', 'pages' => array( array( 'controller' => 'about', 'action' => 'careers', 'label' => 'Careers', ), array( 'controller' => 'about', 'action' => 'mission', 'label' => 'Mission', ), ), ), array( 'controller' => 'tools', 'label' => 'Tools', 'pages' => array( array( 'controller' => 'tools', 'action' => 'free', 'label' => 'Free Tools', ), array( 'controller' => 'tools', 'action' => 'licenses', 'label' => 'New Licenses', ), array( 'controller' => 'tools', 'action' => 'products', 'label' => 'Products', ), ), ), array( 'module' => 'admin', 'label' => 'Administration', 'resource' => 'admin', 'privilege' => 'index', 'pages' => array( array( 'module' => 'admin', 'controller' => 'adduser', 'label' => 'Add User', 'resource' => 'admin', 'privilege' => 'adduser', ), array( 'module' => 'admin', 'controller' => 'addpage', 'label' => 'Add Page', 'resource' => 'admin', 'privilege' => 'addpage', ), ), ) );
If you compare the original array with this updated array, we’ve added the Administration section. We’ve also created some access controls on this section. First, we’ve created a resource called “admin” that grants us access to seeing the admin section. Next, we’ve created some actions that we can use to see the particular actions we can perform.
Of course, at the moment, if we were to use the functions in our previous article, we’d see the entire menu and we’d be able to see all the components (even if our ACL would restrict us from actually accessing them). Obviously we want to avoid this, so we need to give the view helper our ACL:
And with that, we’ve now limited the menu items we’re allowed to see.
Displaying Components Of Our Menu
Once we’ve set the access controls on our menu items, we want to output them somehow. The good news is that most of the commands in the previous article will obey the access control list. Using the menu renderer will only result in a menu of items the user can see. However, when outputting specific links, developers may need to check and see that the user is allowed to view that link. This is easy to do:
This will check the ACL to see if the page is permitted to be visited, and if so, will convert it into an HTML link.
The hope is that now you will be able to implement Zend_Navigation from start to finish, including the creation of navigation items that follow the rules of access control.