开发者

Zend Framework: Can you do ACL without the plugins directory?

I am having trouble understanding the rules to ACL in ZF and the docs aren't clear. I am using a common Zend library for all websites. So开发者_C百科 far no problem but now every demo or example says that you should place the ACL class (acl.php) in the libraries directory as a plugin. Zend/Library/My/Controller/Plugin/.

I don't want to do this because it defeats the purpose for sharing a common framework directory.

Has anyone done or have any ideas about how to accomplish ACL using individual acl.php class files for each website/web application?

Thanks


You don't have to place the acl.php in the libraries directory as a plugin. The autoloader will load the class just fine, the trick to Zend_Acl is just priming an instance of the class with your roles and resources.

It's been a little while since I touched Zend Framwork but I'll try to steer you in the right direction.

  1. In your bootstrap, create the Zend_Acl object

    $acl = new Zend_Acl(); //see documentation on how to add roles and resources

  2. Now create a Plugin folder inside your Controller directory, this will allow you authenticate with your acl.

  3. Inside there create new class that extends Zend_Controller_Plugin_Abstract give it the correct class name to be picked up by the autoloader.

  4. Store the acl you create in the registry and in your plugin override the preDispatch method, from here you have access to the request and the acl (from the zend registry) you can validate as needed. (Some people have controller/action as resources others models. It's quite freeform.

  5. Register your plugin with the front controller.

    $frontController->registerPlugin(new My_Controller_Plugin_Acl());

This is probably what the other tutorials are suggesting (or variants of this), it can just be a little confusing sometimes.


You should never add files to your Zend library directory - do you have any links to tutorials recommending this? The files should either go in the library directory under your application's namespace, giving you a structure like:

application/
library/
    Zend/
        (ZF files)
    Foo/
        Controller/
            Plugin/
                ...

or in application/plugins, application/controller/helpers or somewhere else depending on the approach you are taking.

Edit: it sounds like a controller plugin is what the tutorial is recommending, in which case you'll want a class like Yourapp_Plugin_Acl (replace 'Yourapp' with your app's namespace) which would live at application/plugins/Acl.php.


Ultimately, you can place it anywhere you want as long as your autoloader is sufficiently configured to find it. And precisely how you use it depends upon what resources and privileges you are trying to protect.

But think you are confusing instantiating your ACL and querying your ACL.

You will most likely instantiate/populate your ACL object during bootstrap and store it in the Bootstrap registry or in the Zend_Registry singleton.

If your resources are controllers and your privileges are actions, then it is common to intercept the dispatch cycle with a preDispatch() plugin that queries your ACL object.

So, we are really looking at two different classes/objects:

  1. One is the ACL itself, extending Zend_Acl. This one could be named Application_Model_Acl and placed in the file application/models/Acl.php.

  2. The other is the front controller plugin. This one could be named Application_Plugin_Acl and stored in the file application/plugins/Acl.php

[Note that both of these presume that we are using an application namespace Application. Also, note that both of these are project-specific.]

Of course, the plugin as described needs to be given the ACL object in order to do its job, so your Bootstrap might have a method like this:

protected _initAclPlugin()
{
    $acl = new Application_Model_Acl();
    $plugin = new Application_Plugin_Acl($acl);
    Zend_Controller_Front::getInstance()->registerPlugin($plugin);
}

But remember, this is only one way to use your ACL. In some cases, your ACL might not be limited to just controllers/actions. In that case, you might need to pass your ACL object to other models/services that query it, as well. In that case, you might have a separate method in your Bootstrap to create your ACL object and store it in the Bootstrap registry. Then your controllers - or even a dependency injection system - can grab it from there and pass it through to whatever downstream models/services might need it.

[You know, looking at my answer, it's not really different from that of @linead. Same idea, different words, but he totally got in first.]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜