title: Practical Zend_ACL + Zend_Auth implementation and best practices
body: <p><strong>Context:</strong></p>
  
  <p>My questions pertain to a forum I'm developing pretty much exactly like SO, where there are:</p>
  
  <ol>
  <li>guests who have access to view threads but can't reply or vote</li>
  <li>members who, with enough rep, can edit/vote others threads, and by default they can reply and have the same privileges as guests</li>
  <li>admins who can pretty much do anything</li>
  </ol>
  
  <p>I would want this ACL to be applied site-wide, and by default deny all resources.</p>
  
  <p>I read the basics of using Zend_Acl - in that you basically create roles ( guest, member, admin ) and either deny or allow resources ( controllers, methods ) to those roles. The documentation isn't very specific on how you should actually implement the acl code in your application, so I went looking on SO..<br><br></p>
  
  <p>Came across a pretty useful stackoverflow <a href="https://stackoverflow.com/questions/545702/help-with-zend-acl/545824#545824">answer from marek</a> which sheds some light on the issue, however due to my unfamiliarity I still can't fully grok how to properly implement this with best practices in mind.</p>
  
  <p>The poster has a static file <code>configAcl.php</code> in the application root which initializes the acl object, adds roles, creates a resource out of every controller, gives <code>admin</code> access to everything, gives <code>normal</code> access to everything but the admin and stores the acl object in the registry for later use.</p>
  
  <pre><code>$acl = new Zend_Acl();
  
  $roles  = array('admin', 'normal');
  
  // Controller script names. You have to add all of them if credential check
  // is global to your application.
  $controllers = array('auth', 'index', 'news', 'admin');
  
  foreach ($roles as $role) {
      $acl-&gt;addRole(new Zend_Acl_Role($role));
  }
  foreach ($controllers as $controller) {
      $acl-&gt;add(new Zend_Acl_Resource($controller));
  }
  
  // Here comes credential definiton for admin user.
  $acl-&gt;allow('admin'); // Has access to everything.
  
  // Here comes credential definition for normal user.
  $acl-&gt;allow('normal'); // Has access to everything...
  $acl-&gt;deny('normal', 'admin'); // ... except the admin controller.
  
  // Finally I store whole ACL definition to registry for use
  // in AuthPlugin plugin.
  $registry = Zend_Registry::getInstance();
  $registry-&gt;set('acl', $acl);
  </code></pre>
  
  <p><strong>Question #1</strong> - Should this code be in the bootstrap, or in a standalone file such as this? If so would it be better if it was inside say, the library directory?</p>
  
  <p>The second part of it is a new class extending the Zend Controller Plugin Abstract class which allows it to be hooked into <code>auth/login</code>, the logic is basically if the login fails, it redirects.. otherwise it grabs the acl object from the registry, grabs the identity, and determines if the user is allowed to view this resource.</p>
  
  <pre><code>$identity = $auth-&gt;getIdentity();
  
  $frontController-&gt;registerPlugin(new AuthPlugin());
  </code></pre>
  
  <p><strong>Question #2</strong> - How exactly would I code the auth plugin part that actually returns the identity of the user? I realize that he had some code below that generated a Auth adapter db table object which would query a database table's column by user id and credential ( hashed pass check ).. I'm confused on where this fits in with the getIdentity part.</p>
  
  <p>Let's say my users table was composed of this data:</p>
  
  <pre><code>user_id    user_name    level
  1          superadmin   3
  2          john         2
  3          example.com  1
  </code></pre>
  
  <p>Where level 3 = admin, 2 = member, 1 = guest.</p>
  
  <p><strong>Question #3</strong> - where exactly is a good place to put the above auth code in? Inside of the login controller?</p>
  
  <p><strong>Question #4</strong> - another poster <a href="http://www.aviblock.com/blog/2009/03/19/acl-in-zend-framework/" rel="nofollow noreferrer">replies</a> with his article on how the acl logic should be done inside models, yet the specific method which he uses is not natively supported and requires a workaround, is this feasible? And is this really how it ideally should be done?</p>