Zend navigation and Zend ACL
Asked Answered
J

4

5

I am working with Zend Acl and Zend Navigation. I am setting up the navigation in the bootstrap. I am trying to have links not show if the user doesn't have access to the resource. I have read several tutorials, gone through the zend reference manual several times, but all of the links in the navigation are still appearing for the guest user even though some should only be shown to an admin user

protected function _initNavigationMenu()
{
    $this->bootstrap("layout");
    $layout = $this->getResource('layout');
    $view = $layout->getView();
    $navigation_model = new Core_Model_Navigation();
    $result = $navigation_model->getTopLevelNavigationLinksForDisplay();
    $sanitized = $navigation_model->sanatizeNavigationForDisplay($result);

    $config = new Zend_Config($sanitized);
    $nav = new Zend_Navigation($config);

    $view->navigation($nav)
            ->setAcl($this->_acl->acl())
            ->setRole((string)BW::user() -> role);
}

All ACL roles and resources and the navigation come from a DB in case that matters

here is teh array created by $sanitized

Array
(
    [0] => Array
        (
            [parent_id] => 0
            [label] => File Manager
            [order] => 1
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [module] => file
            [reset_params] => 1
            [id] => fileManagerLink
        )

    [1] => Array
        (
            [parent_id] => 0
            [label] => Upload
            [title] => Upload a file
            [order] => 2
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [controller] => upload
            [module] => file
            [reset_params] => 1
            [id] => fileManagerUploadLink
        )

    [2] => Array
        (
            [parent_id] => 0
            [label] => Files
            [title] => Manage your files
            [order] => 3
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [controller] => manage
            [module] => file
            [reset_params] => 1
            [id] => FileManagerFilesLink
        )   

    [3] => Array
        (
            [parent_id] => 0
            [label] => Contacts
            [order] => 4
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [controller] => contact
            [module] => file
            [reset_params] => 1
            [id] => Contacts
        )

    [4] => Array
        (
            [parent_id] => 0
            [label] => My Account
            [title] => Your Account
            [order] => 5
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => index
            [controller] => user
            [reset_params] => 1
            [id] => myAccountNavigationLink
        )

    [5] => Array
        (
            [parent_id] => 0
            [label] => Admin
            [title] => The administration panel
            [order] => 6
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [module] => admin
            [reset_params] => 1
            [id] => Administration
        )

    [6] => Array
        (
            [parent_id] => 0
            [label] => Test for ACL
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
         )   

     [7] => Array
        (  
            [parent_id] => 0
            [label] => Test for ACL
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [8] => Array
        (
            [parent_id] => 0
            [label] => Test for ACL
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [9] => Array
        (
            [parent_id] => 0
            [label] => Test for ACL
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [10] => Array
        (
            [parent_id] => 0
            [label] => ACL Test
            [order] => 0
            [resource] => 8
            [privilage] => index
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [11] => Array
        (
            [parent_id] => 0
            [label] => Joey
            [order] => 0
            [resource] => adminIndexIndex
            [privilage] => index
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        ) 

    [12] => Array
        (
            [parent_id] => 0
            [label] => another test
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [13] => Array
        (
            [parent_id] => 0
            [label] => another test
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [14] => Array
        (
            [parent_id] => 0
            [label] => another test
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
         )

    [15] => Array
        (
            [parent_id] => 0
            [label] => another stupid test
            [order] => 0
            [resource] => Admin Homepage
            [privilage] => index
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

    [16] => Array
        (
            [parent_id] => 0
            [label] => another stupid test
            [order] => 0
            [resource] => 9
            [active] => 1
            [visible] => 1
            [internal_page] => 1
            [action] => add-navigation
            [controller] => manage
            [module] => admin
            [reset_params] => 1
        )

)
Joeljoela answered 16/11, 2011 at 20:57 Comment(0)
C
14

Joey,

good documentation on this can be hard to find, but it exists. What you need to do, in your application's bootstrap is two things:

  1. Initialise your ACL's
  2. Link them to your navigation object

In my bootstraps, I use the functions similar to the following to do this. Here's examples of the key aspects:

Generating the ACL's:

protected function _buildAclList() 
{
    $acl = new Zend_Acl();

    // setup the roles for the application
    $acl->addRole(new Zend_Acl_Role('guest'));

    $moduleResource = new Zend_Acl_Resource('administration');

    $acl->add($moduleResource)
        ->add(new Zend_Acl_Resource('admin:copyright'), $moduleResource);

    $acl->allow(
        array('guest'), 
        array('admin:copyright'),
        array('view')
    );

    Zend_Registry::set('acl', $acl);
    return $acl;
}

Here, the ACL's are setup as needed for your application. The resource method returns them for use if needed elsewhere and they're also stored in the registry.

Linking the navigation to the generated ACL's (also specifies a default role):

protected function _buildNavigationList()
{
    $this->bootstrap('layout');
    $layout = $this->getResource('layout');
    $view = $layout->getView();
    $config = new Zend_Config_Xml(APPLICATION_PATH . '/configs/navigation.xml', 'nav');
    $acl = Zend_Registry::get('acl');
    $navigation = new Zend_Navigation($config);
    $view->navigation($navigation);
    Zend_View_Helper_Navigation_HelperAbstract::setDefaultAcl($acl);
    Zend_View_Helper_Navigation_HelperAbstract::setDefaultRole(
        Common_Controller_Plugin_Acl::DEFAULT_ROLE
    );
    return $navigation;
}

The resource method picks up the previously created acl's from the registry and uses the setDefaultAcl method to assign them to the application navigation object along with the default role.

Build navigation that respects ACLs

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <nav>
        <administration>
            <label>Administration</label>
            <uri></uri>
            <resource>reports:report</resource>
            <privilege>view</privilege>
            <pages>
                <page_admin_copyright>
                    <label>Copyright maintenance</label>
                    <uri>/admin/copyright</uri>
                    <resource>admin:copyright</resource>
                    <privilege>view</privilege>
                </page_admin_copyright>
            </pages>
        </administration>
    </nav>
</config>

Here, we've created a section called administration that requires the user to have the view privilege on the admin:copyright resource, which guest does thanks to the pre-built acl list.

Now, when you call $this->navigation()->menu()->render() etc, the menu options will be based on the access of the user.

Hmmm, I think I should add a post to this on my site. All the best with it.

Matt

Coen answered 17/11, 2011 at 10:24 Comment(0)
A
0

I suggest that you add another tag in your navigation xml file something that pertains to ACL resource and map it in your ini file where you store your ACL mapping. The logic can be best implemented on your bootstrap so that it can be read before things happen. Do not also forget to implement it to your ajax call in case you have one.

Aiken answered 6/9, 2012 at 14:34 Comment(0)
K
0

I think a controller plugin is better to manage with Zend_Nav and Zend_Acl like:

class App_Controller_Plugin_Layout extends Zend_Controller_Plugin_Abstract
{


    protected $_layout;
    protected $_view;

    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        $this->_layout = Zend_Controller_Action_HelperBroker::getStaticHelper('Layout');
        $this->_layout->disableLayout();
        $this->_view = $this->_layout->getView();
        $module = $request->getModuleName();
        if(null === $module){
            $module = 'default';
        }
        $this->_buildMenu($module,$request);
        $this->_layout->setLayout($module);
    }

    protected function _buildMenu($module,$request)
    {
        $configFilename = APPLICATION_PATH . '/modules/'.$module.'/configs/navigation.xml';
        if(file_exists($configFilename)){
            $role = null;
            $view= $this->_layout->getView();
            $config = new Zend_Config_Xml($configFilename, 'nav');
            $container = new Zend_Navigation($config);
            $view->navigation($container);
            $uri = $request->getPathInfo();
            $pages = $container->getPages();
            foreach($pages as $page){
                $page->setParams(array('ref'=>$request->getParam('ref')));
            }
            $activeNav = $view->navigation()->findByUri($uri);
            if ($activeNav == null){
                $activeNav = $view->navigation()->findOneByController($request->getControllerName());
            }
            if ($activeNav != null){
                $activeNav->active = true;
                $customCls = $activeNav->getClass();
                $activeNav->setClass('active'.!empty($customCls)?' '.$customCls:'');
            }
            $front = Zend_Controller_Front::getInstance();
            if ($front->hasPlugin('App_Controller_Plugin_Acl')) {
                $aclPlugin = $front->getPlugin('App_Controller_Plugin_Acl');
            }
            else{
                $front->registerPlugin(new App_Controller_Plugin_Acl());
                $aclPlugin = $this->getAclPlugin();
            }
            $auth = Zend_Auth::getInstance();
            if ($auth->hasIdentity()) {
                $role = is_object($auth->getIdentity())?$auth->getIdentity()->role:null;
            }
            $view->navigation()->setAcl($aclPlugin->getAcl())->setRole($role);
        }
     }

}
Kab answered 23/3, 2013 at 19:56 Comment(0)
I
0

Try this to build navigation dynamically in bootstarp

   protected function _initNavigation()
          {



            $this->bootstrap('layout');
            $layout = $this->getResource('layout');
            $view = $layout->getView();

            $config = $this->getOptions();

            $db = Zend_Db::factory($config['resources']['db']['adapter'], $config['resources']['db']['params']);

            if ($db) {
                $sql = "your query1 here";

                $result= $db->query($sql)->fetchAll();
                $configuration = array();
                if (count($result)){
                foreach($result as $key=>$row)
                {


                    $subsql = "your query 2 here";

                    $subMenu = $result= $db->query($subsql)->fetchAll();
                    if(count($subMenu)>0){
                       $pages = array();
                    foreach ($subMenu As $k=>$v){
                        $subcatpages = array();
                        $subcatgroup = array();
                        $group = array();
                        $page['label'] =$v['heading'];
                           if ($v['path']) == $row['path']){

                        $page['uri'] ='/'.$row['path'].'.html'; 
                        }elseif($row['id'] ==76){

                        $page['uri'] ='/'.$v['path'].'.html';
                          }else{

                        $page['uri'] ='/'.$row['path'].'/'.$v['path'].'.html';
                                                           }


                        $supersubsql = "Query 3";

                        $superSubMenu = $db->query($supersubsql)->fetchAll();
                            if(count($superSubMenu)>0){
                            if ($row['id'] != 76){
                        foreach ($superSubMenu as $menu=>$item){

                              $subpage['label'] =$item['heading'];
                              if ($v['path'] == $row['path']){


                              $subpage['uri'] ='/'.$row['path'].'/'.$item['path'].'.html';

                                }else{
                             $subpage['uri'] = '/'.$row['path'].'/'.$v['path'].'/'.$item['path'].'.html';

                                }

                              $subpage['params'] = array('action'=>'index',
                                    'category'=> $item['path']);

                         $group[] =$subpage;

                        }

                        }
                        $page['pages'] =$group;
                        foreach ($group as $k=>$v){
                            unset($group[$k]);
                        }    

                        }




                        $pages[] =$page;
                        foreach ($page as $k=>$v){
                            unset($page[$k]);
                        }   

                    }

                    }
                    $configuration[$row['name']] = array(
                            'label' => $row['name'],
                            'uri' => '/'.$row['path'].'.html', 


                            ),

                            'pages' =>  $pages,

                    );
                }

                    }
                  }

            $navigation = new Zend_Navigation($configuration);
            $view->navigation($navigation);

          }

I hope it help you

Indeciduous answered 25/11, 2013 at 13:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.