title: Does Zend ACL suit my needs?
body: <p>I have based my application upon the Zend Framework.  I am using <code>Zend_Auth</code> for authentication, but I'm not sure if <code>Zend_Acl</code> will work for me because, frankly, the examples I've seen are either too simplistic for my needs or confuse me.</p>
  
  <p>I'm thinking of elements in my application as Resources and these Resources can have have Privileges.  Roles containing Resource Privileges are dynamically defined assigned to users.  I'm storing this information in normalized tables.</p>
  
  <ol>
  <li>Users have a Role</li>
  <li>A Role can have multiple Resources</li>
  <li>Resources can have multiple Privileges</li>
  </ol>
  
  <p>Roles are really just collections of Resource Privileges with no hierarchy.  An example of a Resource would be 'Page'.  Everyone can view the pages, but a authenticated user would need 'add', 'edit', or 'delete' privileges to do anything else with pages.</p>
  
  <p>Does this mesh with Zend ACL?  Am I thinking ACL in a way that's going to create problems for me?</p>
  
  <hr>
  
  <p><strong>My Solution</strong></p>
  
  <p>Typeonerror gets the credit, but here's my specific solution.</p>
  
  <p>I extended <code>Zend_Acl</code> to simplify my usage because I only load the role of the current user:</p>
  
  <pre><code>class My_Acl extends Zend_Acl
  {
      protected $_role_id;
  
      public function setRole($role_id)
      {
          $this-&gt;_role_id = $role_id;
          return $this-&gt;addRole($role_id);
      }
  
      public function getRole()
      {
          return $this-&gt;_role_id;
      }
  
      public function deny($resource, $privilege)
      {
          return parent::deny($this-&gt;_role_id, $resource, $privilege);
      }
  
      public function allow($resource, $privilege)
      {
          return parent::allow($this-&gt;_role_id, $resource, $privilege);
      }
  
      public function isAllowed($resource, $privilege)
      {
          return parent::isAllowed($this-&gt;_role_id, $resource, $privilege);
      }
  }
  </code></pre>
  
  <p>To populate the the ACL I execute a query which returns <code>resource</code>, <code>privilege</code>, and <code>role_id</code> columns.  The <code>role_id</code> column is null in the result set if the user's role does not have that privilege.</p>
  
  <pre><code>$acl = new My_Acl();
  
  $auth = Zend_Auth::getInstance();
  if ($auth-&gt;hasIdentity()) {
      $userInfo = $auth-&gt;getStorage()-&gt;read();
      $acl-&gt;setRole($userInfo-&gt;role_id);
  } else {
      $acl-&gt;setRole('');
  }
  
  // QUERY HERE
  
  foreach ($privileges as $privilege) {
      if (!$acl-&gt;has($privilege['resource'])) {
          $acl-&gt;addResource($privilege['resource']);
      }
      if (is_null($privilege['role_id'])) {
          $acl-&gt;deny($privilege['resource'], $privilege['privilege']);
      } else {
          $acl-&gt;allow($privilege['resource'], $privilege['privilege']);
      }
  }
  </code></pre>