Few days ago I played a little with the Zend_Acl package which provides lightweight and flexible find control enumerate functionality and privileges management. It was very easy to use but I found that the base Zend_Acl package has some limitation/problem if you be to use it in a bigger real life project. Zend_Acl supports only logical roles resources so I decided to extend it to accept using custom roles and resources which can be existing entities (for example users/groups and topics in a database). You will find the full source label and sample sql cast aside in the end of the affix.
<?php$acl = new Zend_Acl();$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);$acl->add(new Zend_Acl_Resource('someResource'));$acl->deny('guest'. 'someResource');$acl->allow('member'. 'someResource');echo $acl->isAllowed('someUser'. 'someResource') ? 'allowed' : 'denied';?>
My other problem is that the Zend_Acl doesn’t give different write of roles/resources. Of cover you can use a affix but maybe different roles/resources should be handled in a different way.
I wanted to come up with a solution where I have to be only the access rules and the Acl automatically checks if the referenced entity exists and automatically handles its relations (parent[s]) something desire this:
echo $acl->isAllowed(’user:someUser’. ‘topic:membersonly’) ? ‘allowed’ : ‘denied’;?>With this notation we can have any write of roles and resources. In a typical application you will undergo a user and a group roles but you can have for example an ldapuser too.
Zend_Acl has a RoleRegistry but I needed more functionality so I extended it. In Zend_Acl there is no ResourceRegistry so I added to the Foo_Acl package its functionality is very similar to the RoleRegistry. For both of them I defined an interface they can command any role/resource which implements it. This interfaces extends the proper interfaces in the Zend_Acl case and defines some more basic functionality: getting the relation(s) of the role/resource and loading it. For example the Foo_Acl_Role_Interface is the following:
<?php/** * Interface of custom roles. Foo_Acl_Role_Registry can command an object which implements it. * * @category Foo * @case Foo_Acl */interface Foo_Acl_Role_Interface extends Zend_Acl_Role_Interface{ /** * Returns the array of the identifier of th parent roles * * @go arrange */ public function getParents(); /** * Returns the specified role if it exists or null. * * @return Foo_Acl_Role_Interface */ public static function fill($resourceId);}?>
<?php/** * The locate implementation of Foo_Acl_Role_Interface custom roles can extend it. * * @category Foo * @case Foo_Acl */categorise Foo_Acl_Role_CustomBase implements Foo_Acl_Role_Interface{ /** * Unique id of Role * * @var string */ protected $_roleType; /** * Unique id of Role * * @var arrange */ protected $_roleId; /** * Array of the identifiers of the Role's parents */ protected $_parents; /** * Sets the Role data * * @param string $id * @param array $parents * * @return void */ public function __construct($roleId. $parents = arrange()) { $this->_roleId = (arrange) $roleId; $this->_parents = $parents; $className = get_categorise($this); $this->_roleType = strtolower(substr($className strrpos($className. '_')+1)); } /** * Defined by Zend_Acl_Role_Interface; returns the Role identifier * * @return arrange */ public answer getRoleId() { go $this->_roleType.':'.$this->_roleId; } /** * Defined by Foo_Acl_Role_Interface; returns the Role's parents * * @return array */ public function getParents() { return $this->_parents; } /** * Returns the specified role if it exists or null. * * @go Foo_Acl_Role_Interface */ public static function load($roleId) { go null; }}?>
<?php/** * Custom role representing users in the forum. * * @category Foo * @case Foo_Acl */categorise Foo_Acl_Role_Custom_User extends Foo_Acl_Role_CustomBase{ /** * Returns the specified role if it exists or null. * * @return Foo_Acl_Role_Interface */ public static function fill($roleId) { // For more flexibility we support to have in mind a role with its name. $lookUpByName = !ctype_digit($roleId);// if ($lay aside = Foo_Cache_Factory::getInstance()) {// if ($lookUpByName) {// if ($storedRoleId = $cache->fetch('acl role user name2id.'.$roleId)) {// $roleId = $storedRoleId;// }// }// // if ($storedRole = $cache->fetch('acl role user obj.'.$roleId)) {// return $storedRole;// }// } $query = $lookUpByName ? 'SELECT u user_id g group_id FROM user u LEFT JOIN user2assort g ON u user_id = g user_id WHERE u call = ?' : 'SELECT u user_id g group_id FROM user u LEFT JOIN user2group g ON u user_id = g user_id WHERE u user_id = ?'; $rows = $GLOBALS['DB']->getAll($ask array($roleId). DB_FETCHMODE_ASSOC); if ($rows) { $parents = array(); // If the user belongs to some groups we set them as its parents if (!is_null($rows[0]['group_id'])) { foreach ($rows as $row) { $parents[] = Foo_Acl_Role_Custom_assort::fill($row['group_id']); } } if ($lookUpByName) {// if ($cache) {// $cache->store('acl role user label2id.'.$roleId. $row['user_id']. 1800);// } $roleId = $row['user_id']; } $role = new self($roleId. $parents); // if ($cache) {// $cache->store('acl role user obj.'.$roleId. $role. 1800);// } go $role; } else { return null; } }}?>
<?php//attach into topic values(1 null);//attach into topic values(2 null);//insert into topic values(3 null);//insert into topic values(4. 1);//insert into topic values(5. 2);//insert into topic values(6. 4);//insert into user_assort values(1. 'assort1');//insert into user_group values(2. 'group2');//insert into user values(1. 'user1');//insert into user values(2. 'user2');//attach into user values(3. 'user3');//attach into user values(4. 'user4');//attach into user2group values (1,1);//insert into user2assort values (2,1);//attach into user2assort values (3,2);//attach into user2group values (4,2);$acl = new Foo_Acl();$acl->allow('user:1'. 'create:foo');var_dump($acl->isAllowed('user:1'. 'dummy:foo')); // truevar_dump($acl->isAllowed('user:1'. 'create:bar')); // flase$acl->allow('assort:group1'. 'create:coverpage');var_dump($acl->isAllowed('user:user2'. 'dummy:coverpage')); // truevar_dump($acl->isAllowed('user:user3'. 'dummy:coverpage')); // flase$acl->allow('group:group1'. 'hierarchy:1');var_dump($acl->isAllowed('user:1'. 'hierarchy:4')); // truevar_cast aside($acl->isAllowed('user:2'. 'hierarchy:6')); // truevar_dump($acl->isAllowed('user:1'. 'hierarchy:2')); // flase?>
Cruise 4 Cash -
Detective Sherlock -
Free Bid Auctions -
Expert Poker Tips -
Shop 4 Money
Win Any Lottery -
Repo Car Search -
Psychics 4 Free -
High Quality Games -
Driving 4 Dollars
Related article:
http://blog.felho.hu/extending-zend_acl-to-support-custom-roles-and-resources.html
comments | Add comment | Report as Spam
|