Skip to end of metadata
Go to start of metadata

<ac:macro ac:name="toc"><ac:parameter ac:name="style">disc</ac:parameter><ac:parameter ac:name="indent">20px</ac:parameter></ac:macro>

<h1>Introduction</h1>
<p>This example shows how to implement Zend_Acl with a database backend. Roles, Resources and Users are stored in a database and can easily be queried. This ACL implementation uses 5 basic roles and uses Zend_Acl inheritance.</p>

<p>Firstly, the database tables and initial roles and resources need to be built.</p>

<h1>Ini files</h1>

<p>I have chosen to use .ini files for the initial setup for ease of use and customization.</p>

<h3>roles.ini</h3>

<p>This .ini defines the roles to be used in the ACL.</p>

<ac:macro ac:name="code"><ac:parameter ac:name="title">roles.ini</ac:parameter><ac:parameter ac:name="borderStyle">solid</ac:parameter><ac:plain-text-body><![CDATA[
role[] = Implementor
role[] = Administrator
role[] = Operator
role[] = User
role[] = Everyone
]]></ac:plain-text-body></ac:macro>

<h3>users.ini</h3>

<p>This .ini file simply maps users to roles for the initial build.</p>

<ac:macro ac:name="code"><ac:parameter ac:name="title">users.ini</ac:parameter><ac:plain-text-body><![CDATA[
fred = Implementor
barney = Administrator
wilma = Operator
betty = User
; DO NOT CHANGE ANYTHING BELOW THIS LINE!
Guest = Everyone
]]></ac:plain-text-body></ac:macro>

<h3>resources.ini</h3>

<p>This .ini file maps resources to roles for the initial build. The resources will be stored in the database as 'group:resource'. In the example .ini file below this would mean that the 'Load' resource would be stored as 'Applications:Load'.</p>

<ac:macro ac:name="code"><ac:parameter ac:name="title">resources.ini</ac:parameter><ac:plain-text-body><![CDATA[
[mainMenu]
login = Everyone
applications = Everyone
preferences = User
administration = Implementor

[userPreferences]
details = User
params = User
themes = User
]]></ac:plain-text-body></ac:macro>

<h1>Database Initialisation:</h1>

<p>The following code uses the above .ini files to build the initial database tables. </p>

<h3>BuildRoles.php</h3>

<ac:macro ac:name="code"><ac:parameter ac:name="title">BuildRoles.php</ac:parameter><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$params = array ('dbname' => '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'myDB.db3');

$db = Zend_Db::factory('PDO_SQLITE', $params);

$roles = new Zend_Config_Ini('roles.ini');

try {
echo "\n>>> Delete acl_roles table\n";
$db->query('DROP TABLE [acl_roles]');
} catch (Exception $e) {
echo $e->getMessage();
}

try {
echo "\n>>> Re-creating acl_roles table\n";
$db->query('CREATE TABLE `acl_roles` (
`role_id` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`role_name` VARCHAR(64) NOT NULL UNIQUE ON CONFLICT IGNORE);
');

foreach ($roles->role as $key=>$value)

Unknown macro: { $db->query('INSERT INTO acl_roles (role_name) VALUES ("' . $value . '")'); }

echo "\n>>> acl_roles table rebuild complete\n\n";
} catch (Exception $e) {
echo $e->getMessage();
}
]]></ac:plain-text-body></ac:macro>

<h3>BuildUsers.php</h3>

<ac:macro ac:name="code"><ac:parameter ac:name="title">BuildUsers.php</ac:parameter><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$params = array ('dbname' => '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'myDB.db3');

$db = Zend_Db::factory('PDO_SQLITE', $params);

$users = new Zend_Config_Ini('users.ini');

try {
echo "\n>>> Delete acl_users table\n";
$db->query('DROP TABLE [acl_users]');
} catch (Exception $e) {
echo $e->getMessage();
}

try {
echo "\n>>> Re-creating acl_users table\n";
$db->query('CREATE TABLE `acl_users` (
`uid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`role_id` INTEGER(4) NOT NULL,
`user_name` VARCHAR(64) NOT NULL UNIQUE ON CONFLICT IGNORE);
');

foreach ($users as $key => $value)

Unknown macro: { $sql = $db->query('SELECT `role_id` FROM `acl_roles` WHERE `role_name` = "' . $value . '"'); $role = $sql->fetchObject(); $db->query('INSERT INTO `acl_users` ("role_id", "user_name") VALUES (' . $role->role_id . ', "' . $key . '")'); }

echo "\n>>> ACL Users rebuild complete\n\n";
} catch (Exception $e) {
echo $e->getMessage();
}
]]></ac:plain-text-body></ac:macro>

<h3>BuildResources.php</h3>

<ac:macro ac:name="code"><ac:parameter ac:name="title">BuildResources.php</ac:parameter><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
$params = array ('dbname' => '..' . DIRECTORY_SEPARATOR . 'database' . DIRECTORY_SEPARATOR . 'myDB.db3');

$db = Zend_Db::factory('PDO_SQLITE', $params);

$resources = new Zend_Config_Ini('resources.ini');

try {
echo "\n>>> Delete acl_resources table\n";
$db->query('DROP TABLE [acl_resources]');
$db->query('DROP TABLE [acl_permissions]');
} catch (Exception $e) {
echo $e->getMessage();
}

try {
echo "\n>>> Re-creating acl_resouces table\n";
$db->query('CREATE TABLE `acl_resources` (
`uid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`resource` VARCHAR(64) NOT NULL UNIQUE ON CONFLICT IGNORE);
');

echo "\n>>> Re-creating acl_resouces table\n";
$db->query('CREATE TABLE `acl_permissions` (
`role_id` INTEGET(1) NOT NULL,
`resource_uid` INTEGER(4) NOT NULL,
`permission` VARCHAR(64) NOT NULL);
');

foreach ($resources as $key => $value) {

$db->query('INSERT INTO `acl_resources` ("resource") VALUES ("' . $key . '")');
$lastInsertId= $db->lastInsertId();

foreach ($value as $key2 => $value2) {

$sql = $db->query('SELECT `role_id` FROM `acl_roles` WHERE `role_name` = "' . $value2 . '"');
$role = $sql->fetchObject();
if ($role)

Unknown macro: { $db->query('INSERT INTO `acl_permissions` ("role_id", "resource_uid", "permission") VALUES ("'.$role->role_id.'", ' . $lastInsertId . ', "' . $key2 . '")'); }

else

Unknown macro: { echo "ERROR! resource " . $value2 . " not found!"; }

}
}

echo "\n>>> ACL Resources rebuild complete\n\n";
} catch (Exception $e) {
echo $e->getMessage();
}

]]></ac:plain-text-body></ac:macro>

<h1>Main ACL class:</h1>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class MyAcl extends Zend_Acl {

private $_db;

public $_getUserRoleName = null;

public $_getUserRoleId = null;

public $_user = null;

public function __construct($user)

Unknown macro: { $this->_user = $user ? $user }

private function initRoles()
{
$roles = $this->_db->fetchAll(
$this->_db->select()
->from('acl_roles')
->order(array('role_id DESC')));

$this->addRole(new Zend_Acl_Role($roles[0]['role_name']));

for ($i = 1; $i < count($roles); $i++)

Unknown macro: { $this->addRole(new Zend_Acl_Role($roles[$i]['role_name']), $roles[$i-1]['role_name']); }

}

private function initResources()
{
self::initRoles();

$resources = $this->_db->fetchAll(
$this->_db->select()
->from('acl_resources'));

foreach ($resources as $key=>$value){
if (!$this->has($value['resource']))

Unknown macro: { $this->add(new Zend_Acl_Resource($value['resource'])); }

}
}

private function roleResource()
{
self::initResources();

$acl = $this->_db->fetchAll(
$this->_db->select()
->from('acl_roles')
->from('acl_resources')
->from('acl_permissions')
->where('acl_roles.role_id = acl_permissions.role_id'));

foreach ($acl as $key=>$value)

Unknown macro: { $this->allow($value['role_name'], $value['resource'],$value['permission']); }

}

public function listRoles()

Unknown macro: { return $this->_db->fetchAll( $this->_db->select() ->from('acl_roles')); }

public function getRoleId($roleName)

Unknown macro: { return $this->_db->fetchRow( $this->_db->select() ->from('acl_roles', 'role_id') ->where('acl_roles.role_name = "' . $roleName . '"')); }

public function insertAclUser()

Unknown macro: { $data = array( 'role_id' => $this->_getUserRoleId, 'user_name' => $this->_user); return $this->_db->insert('acl_users',$data); }

public function listResources()

Unknown macro: { return $this->_db->fetchAll( $this->_db->select() ->from('acl_resources') ->from('acl_permissions') ->where('resource_uid = uid')); }

public function listResourcesByGroup($group)
{
$result = null;
$group = $this->_db->fetchAll($this->_db->select()
->from('acl_resources')
->from('acl_permissions')
->where('acl_resources.resource = "' . $group . '"')
->where('uid = resource_uid')
);

foreach ($group as $key=>$value) {
if($this->isAllowed($this->_user, $value['resource'], $value['permission']))

Unknown macro: { $result[] = $value['permission']; }

}

return $result;
}

public function isUserAllowed($resource, $permission)

Unknown macro: { return ($this->isAllowed($this->_user, $resource, $permission)); }

}

]]></ac:plain-text-body></ac:macro>

<h1>Example Usage</h1>

<h3>ExampleController.php</h3>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class ExampleController extends Zend_Controller_Action
{
private $_acl = array();

public function init()

Unknown macro: { $this->_acl = new MyAcl(Zend_Auth}

/**

  • Render Preferences dialog
    *
    */
    public function preferencesAction()
    Unknown macro: { $this->view->availablePrefs = $this->_acl->listResourcesByGroup('userPreferences'); }

    }
    ]]></ac:plain-text-body></ac:macro>

<h1>Testing</h1>

<h3>TestController.php</h3>

<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
class TestController extends Zend_Controller_Action
{
public function aclAction()
{
$params = new Zend_Controller_Request_Http();

$acl = new MyAcl($params->user);

$this->view->user = $acl->_user;

$this->view->role = $acl->_getUserRoleName;

foreach ($acl->listResources() as $key=>$r) {

try

Unknown macro: { $s[$r['resource'].' - '.$r['permission']] = $acl->isUserAllowed($r['resource'], $r['permission']) ? '<font color="green">allowed</font>' }

catch (Zend_Acl_Exception $e)

Unknown macro: { print_r ($e->getMessage()); }

}
}
]]></ac:plain-text-body></ac:macro>

<h3>/view/scripts/test/acl.phtml</h3>
<ac:macro ac:name="code"><ac:default-parameter>php</ac:default-parameter><ac:plain-text-body><![CDATA[
<p>User: <?php echo$this->user ?> - Role: <?php echo $this->role ?></p>

<?php foreach ($this->allowed as $resource => $access) : ?>
<div>User: <?php echo $this->user ?> is <?php echo $access ?> access to <?php echo $resource ?></div>
<?php endforeach; ?>
]]></ac:plain-text-body></ac:macro>

<h3>Example output from - <a class="external-link" href="http://localhost/MyApp/test/acl?user=dino">http://localhost/MyApp/test/acl?user=dino</a></h3>

<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
User: dino - Role: User
User: dino is allowed access to mainMenu - login
User: dino is allowed access to mainMenu - applications
User: dino is allowed access to mainMenu - preferences
User: dino is denied access to mainMenu - administration
User: dino is allowed access to userPreferences - details
User: dino is allowed access to userPreferences - params
User: dino is allowed access to userPreferences - themes
]]></ac:plain-text-body></ac:macro>

<h3>Example from - <a class="external-link" href="http://localhost/MyApp/test/acl?user=">http://localhost/MyApp/test/acl?user=</a></h3>

<ac:macro ac:name="code"><ac:plain-text-body><![CDATA[
User: Guest is allowed access to mainMenu - login
User: Guest is allowed access to mainMenu - applications
User: Guest is denied access to mainMenu - preferences
User: Guest is denied access to mainMenu - administration
User: Guest is denied access to userPreferences - details
User: Guest is denied access to userPreferences - params
User: Guest is denied access to userPreferences - themes
]]></ac:plain-text-body></ac:macro>

Labels:
acl acl Delete
zend_acl zend_acl Delete
database database Delete
example example Delete
Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.