Get your FREE 30 page Developing SOLID Applications guide!

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.

This Series: Zend Navigation

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:

$this->navigation()->setAcl($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:


if($this->navigation()->accept($page))
    $this->navigation()->htmlify($page);

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.

Conclusions
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.

Write better object oriented PHP today.

Object oriented programming always leaves you with a headache. What if you could master it instead?

Get the book now! »

Kevin Bruce (@kevinbruce) wrote at 4/2/2010 7:56 am:

Thanks Brandon! That’s very useful series. I’m going to try out ZF on my next fun project, and this series will be MOST helpful :)

Sanders (@sandersjj) wrote at 4/2/2010 11:16 am:

Hi Brandon,

Just discovered your blog. You have nice and useful articles. I am also in the middle of integrating zend_navigation into my project. I am still in the process of finding out how it works the best together with zend_acl.
Does the privilege you describe in your article correspond to the Zend_Role?

Gary (@garyj) wrote at 4/2/2010 3:04 pm:

I’d love to see small (say, 3-part again), mini-series on various different aspects of ZF – Zend_Acl would be one for a start, Routes would be another, etc.

Thanks for sharing Brandon.

Jose Perales (@joseperales) wrote at 4/3/2010 5:30 am:

Brando for President of PHP, Thanks for Your time Helping and Growing the community!!

Nikolai Petkov wrote at 4/4/2010 1:30 pm:

Hi Brandon,
this was indeed a very useful tutorial, keep up the good work. But can i point a bug :) The link “This Series: Zend Navigation” points to “http://www.brandonsavage.netseries/zend-navigation/”