Zend navigation and Zend ACL



我正在使用Zend Acl和Zend导航。我在引导中设置导航。我试图有链接不显示,如果用户没有访问资源。我已经阅读了几个教程,浏览了几次zend参考手册,但是导航中的所有链接仍然为访客用户显示,尽管有些链接应该只显示给管理员用户

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);
}

所有ACL角色和资源以及导航都来自DB,如果重要的话

这是由$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
        )
)

Joey,

关于这方面的优秀文档可能很难找到,但确实存在。在应用程序的引导中,你需要做的是两件事:
  1. 初始化ACL的
  2. 链接到你的导航对象

在我的引导中,我使用类似于下面的函数来完成此操作。以下是关键方面的示例:

生成ACL:

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;
}

在这里,ACL是根据应用程序的需要设置的。资源方法返回它们,以便在其他地方需要时使用,它们也存储在注册中心中。

将导航链接到生成的ACL(也指定一个默认角色):

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;
}

资源方法从注册中心获取之前创建的acl,并使用setDefaultAcl方法将它们与默认角色一起分配给应用程序导航对象。

构建尊重acl的导航

<?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>

在这里,我们创建了一个名为administration的部分,它要求用户在admin:copyright资源上具有视图权限,这要归功于预构建的acl列表。

现在,当你调用$this->navigation()->menu()->render()等,菜单选项将基于用户的访问。

嗯,我想我应该在我的网站上添加一个帖子。祝你一切顺利。

马特

我建议您在导航xml文件中添加另一个标签,该标签属于ACL资源,并将其映射到存储ACL映射的ini文件中。最好在引导程序上实现逻辑,以便在事情发生之前读取它。如果有的话,也不要忘记在ajax调用中实现它。

我认为控制器插件更好地管理Zend_Nav和Zend_Acl,如:

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);
        }
     }
}

尝试在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);
          }

希望对你有帮助

最新更新