Note: This applies to ZF1.
I’m working on a side-project of my own which uses Zend Framework. Part of what I’m trying is using the Zend_Navigation helper and Zend_Acl to render the navigation and control exactly what shows up.
I had the ACL side of things working, I’ve got my own users who have specific roles and can only see specific sections. But for some reason the menu would show everything (even to someone logged out).
To figure out the issue I spent ages going through the ACL object setup making sure it was correct. I also went though the Navigation setup and it was also correct.
It wasn’t until I trawled though pages of unrelated Google results I found the solution to my problem on Stacktrace!
I’m using Twitter’s Bootstrap theme, so there’s a specific menu layout I need. So when calling my navigation menu I pass in a custom partial name.
One thing I didn’t find in the documentation, the navigation menu doesn’t automatically remove pages that shouldn’t load. So if you don’t check for it yourself, it’ll show everything. It’s obvious now that I think about it, but it I’d assumed otherwise.
So now my menu.phtml includes the following line inside my loop.
<?php if(!$page->isVisible() || !$this->navigation()->accept($page)) continue; ?>
Ta da! The menu now listens to my ACL and hides the pages a user doesn’t have permission to see. The magic line is
$this->navigation()->accept($page) as this asks the navigation helper if the page is accepted. You can see the rules inside Zend_View_Helper_Navigation_HelperAbstract->accept method.
- If a page is not visible it is not accepted, unless RenderInvisible has been set to true.
- If helper has no ACL, page is accepted
- If helper has ACL, but no role, page is not accepted
- If helper has ACL and role:
- Page is accepted if it has no resource or privilege
- Page is accepted if ACL allows page’s resource or privilege
- If page is accepted by the rules above and $recursive is true, the page will not be accepted if it is the descendant of a non-accepted page.