ZF-984: Zend_Acl : debug for inheritance of rules : get source from used rule



The Zend_Acl inheritance system of to be applied rules is powerful because it does allow inheriting rules from multiple parents. The drawback of this mechanic is that the Acl is like a black box returning the 'last inserted' rule.

When debugging an application, or even during normal usage, it can be very informative for the users to get informed what rules have been applied. Following a previous discussion with Darby Felton : Consider the following code:

<?php require_once 'Zend/Acl.php'; $acl = new Zend_Acl(); require_once 'Zend/Acl/Role.php'; $acl->addRole(new Zend_Acl_Role('guest')) ->addRole(new Zend_Acl_Role('member')) ->addRole(new Zend_Acl_Role('admin')); $parents = array('guest', 'member', 'admin'); $acl->addRole(new Zend_Acl_Role('someUser'), $parents); require_once 'Zend/Acl/Resource.php'; $acl->add(new Zend_Acl_Resource('someResource')); $acl->deny('guest', 'someResource'); $acl->allow('member', someResource'); echo $acl->isAllowed('guest', 'someResource') ? 'allowed' : 'denied'; ?>

So, the printed result should be 'Allowed' since the rules are checked as admin => no rule member =>allowed ===>exit (guest is not processed)

The problem is then to know that the 'allowed' result actually comes from the 'member' Role, not from 'Guest' nor 'Admin' My suggestion is then to allow a debug output (or whatever its name) that could return an array as:

0]function isAllowed on 'guest' 'someResource': check for specific rule: none [1]function isAllowed on 'guest' 'someResource': check for rule on parent 'admin' : none [2]function isAllowed on 'guest' 'someResource': check for rule on parent 'member' : 'allowed' returning this value [3]end of processing this would be very very helpful when debugging an application!!

The developers will benefit from this because they will be able to follow the complete logical commands operating their application The users will benefit because they can be informed why a resource is not available, and react accordingly (ask privileges to the admins, change the access rules, etc)

I belive this would be quite simple to achieve as this only reflects the way Acl did the processing (inside some kinds of loops,I guess)

Your comments are welcome.



I really like this idea! How better to illustrate the way inheritance works in Zend_Acl than by providing dynamic feedback from working with your own data? I also think it would be quite simple to build this into Zend_Acl.

Thanks, Vincent, for the suggestions!

This doesn't appear to have been fixed in 1.5.0. Please update if this is not correct.

Assigning to Ralph to get closure on this issues.

If we are to support this, it should be done by adding a Zend_Log instance to the $acl object.

I would support this if the API include a setLogger(Zend_Log $logger); method. And then if internal methods used a INFO level log to output about information within the ACL.


Ralph, Nice idea. That would create a cleaner and understandable API. Having attached logger instead of "debug" method should be a preferred solution.

While this is a worthwhile feature, the ZF team will not develop this feature, but if a community member would like to pick up and develop it, they may make an assignment of it.

This sounded like a great idea, so i whipped something up today. Following ralph's suggestion this adds a setLogger public method and changes the DFS searches to log to it.

See logtest.php for a quick demonstration.

Daniel, You provided Zend_Log - in place I suppose of Zend_Acl (that would actually send messages to assigned Zend_Log) instance. Or am I missing something?

Sorry about that Torio, wasn't paying enough attention last night. Here's the Acl.php that you actually need.

added a svn diff for the change.