Search code examples
phpoopzend-frameworkzend-acl

How to merge few ACLs in Zend Framework?


I have few instances of Zend_Acl objects, like this one (one for each module):

class My_Acl_Module1 extends My_Base_Acl
{
    public function __construct()
    {
        parent::__construct();
        $this->addResource('News_Model_Entry');
        $this->deny('guest', 'News_Model_Entry', 'index', new News_Model_Acl_Assert_CategoryPrivate());
    }       
}

class My_Base_Acl extends Zend_Acl 
{
    public function __construct()
    {
              $this->addRole('guest');
    }
}

How to merge them into one ACL object to use in navigation container?

Edit

Some more info:

  • I don't use controller resources in favor of model based resources (models, forms implement Zend_Acl_Resource_Interface). All of them have method isAllowed()
  • I use modular directory and reusable modules (separate models, configs, routes etc.)
  • My application knows all installed modules, controllers, action (structure already parsed, not in real time)

So I'm looking the way to follow this scheme, and separate the ACL for each module. I don't want to use application resource, because it is a waste - acl is not needed always.

I have an action helper which instantiates module specific ACL only when it is really needed. But sometimes I'd like to have global application ACL available too (eg. when I'd like to pass it to the navigation view helper or controller plugin).

My module ACL classes have all just one method: init().
Dirty solution I see, is to parse the source classes and merge the files into one method for new class.

Any suggestions?


Solution

  • I think this is almost impossible without the application knowing a bit more about itself. I had a similiar problem a while ago too and didn't find any satisfying solution. When merging you'll loose some information (the module) which you need later on in your navigation.

    The first solution I had back there, was to iterate over all acl-files in each module and create a custom ACL-merge function to merge them all. This actually did work but I didn't like the idea of a file-scan over my complete application (even if the results were cached).

    My last approach was to add more data to my application: For every linkable action I defined the corresponding acl-file. This wasn't as much work as it may sound. Mainly because my controllers/models do match almost exactly. So I have a model 'News' and a controller 'News' which handles the access to it and maps every action of the model to the frontend. So I only had to specify the acl/controller relations. (I used a custom element in each navigation container to save this).