2

I like the idea of binding ACL to models like described here:

But how can I combine this with Zend Navigation? When rendering the sitemap, I'd have to instantiate all the models.

Did someone actually used this approach on at least medium scale site and can share his experience on solving performance issues?

takeshin
  • 49,108
  • 32
  • 120
  • 164

2 Answers2

3

You can pass an acl instance straight to the navigation

$view->navigation ( $navContainer )
     ->setAcl ( $this->_acl )
     ->setRole ( Zend_Registry::get ( 'role' ) );

This is how I init the acl in my boostrap initAutoload method

$this->_acl = new Model_LibraryAcl ();
$fc = Zend_Controller_Front::getInstance ();
$fc->registerPlugin ( new Plugin_AccessCheck ( $this->_acl ) );

I use navigation xml code to define my navigation, e.g.

<all>
    <label>All</label>
    <resource>default:programme</resource>
    <module>default</module>
    <controller>programme</controller>
    <action>list</action>
    <privilege>index</privilege>
</all>

This defines the link for the list action. It can be accessed by all users, so

$this->allow('guests', 'default:programme', array('index','list'));

This is from my library acl file that is derived from Zend_Acl. For more detailed information go through this video tutorial Zend Framework 1.8 tutorial 8 zend_navigation and zend_acl

DarkLeafyGreen
  • 69,338
  • 131
  • 383
  • 601
  • Thank you. This is the obvious part, but how to add rules to the navigation ACL, when they are stored in models? – takeshin Jun 12 '11 at 21:21
  • Thanks for the edit, but looks like you don't quite understand what I'm asking about :) I'm asking about ACL in entities, not ACL *as* a model. – takeshin Jun 13 '11 at 18:51
  • I just added my own answer, do you still use this ACL approach in your applications btw? – Liyali Mar 02 '12 at 14:16
  • I would like to note that `setAcl()` and `setRole()` also work in ZF2. I was actually looking for this solution for ZF2 and this answer solved it, thanks! +1 – Yes Barry Nov 01 '12 at 07:15
1

I know you asked this question a while ago, but I thought it would be interesting to share my code since I've faced the same problem.

Basically, what I came up with, is a new parsing method for Xml file, so I can directly instantiate my models into my navigation Xml configuration file, so that my privileges are correctly added to my ACL tree.

Let's take a look at my Xml menu first:

<?xml version="1.0" encoding="UTF-8" ?>
<configdata>
    <nav>
        <dashboard>
            <label>Dashboard</label>
            <controller>index</controller>
            <action>index</action>
            <class>icon-dashboard</class>
                    <resource>Model_Dashboard_Dashboard</resource>
        </dashboard>
        <members>
            <label>Members</label>
            <controller>members</controller>
            <action>index</action>
                    <resource>Model_Members_Members</resource>
            <class>icon-members</class>
            <pages>
                <members-list>
                    <label>Members list</label>
                    <controller>members</controller>
                    <action>list</action>
                    <resource>Model_Members_List</resource>
                    <privilege>list</privilege>
                </members-list>
            </pages>
        </members>
        <charts>
            <label>Charts</label>
            <controller>charts</controller>
            <action>index</action>
                    <resource>Model_Charts_Charts</resource>
            <class>icon-charts</class>
        </charts>
        <documents>
            <label>Documents</label>
            <controller>documents</controller>
            <action>index</action>
                    <resource>Model_Documents_Documents</resource>
            <class>icon-documents</class>
        </documents>
    </nav>
</configdata>

What is interesting here is the resource attributes, all of them are actually classes that represent my models.

Now, you probably noticed in the Zend documentation:

Note: Return Type

Configuration data read into Zend_Config_Xml are always returned as strings. Conversion of data from strings to other types is left to developers to suit their particular needs.

which means that my models will be casted into string... bummer! To prevent this behavior, I used this function that transform resources string into objects:

public static function convertNavigationAclToObject($config)
{
    foreach ($config as $key => $value) {
        if (is_string($value) AND $key === "resource") {
            $config[$key] = new $value;
            break;
        } elseif (is_array($value)) {
            $config[$key] = self::convertNavigationAclToObject($value);
        }
    }
    return $config;
}

This function allow me to recursively converts all my values into object, and therefore set the privileges at the same time (allow, deny... in your models - setAcl()).

Finally, I instantiate my navigation in three steps:

  1. Get the config from a XML file
  2. Convert resource string into object
  3. Instantiate Zend_Navigation

In your bootstrap:

$config = new Zend_Config_Xml(APPLICATION_PATH . /modules/default/views/navigation/navigation.xml', 'nav');
$pages = My_Utils::convertNavigationAclToObject($config->toArray());
$container = new Zend_Navigation($pages);

Hope it can help ;)

Liyali
  • 5,643
  • 2
  • 26
  • 40