Zend导航和Zend ACL

时间:2011-11-16 20:57:12

标签: php zend-navigation zend-acl zend-framework

我正在与Zend Acl和Zend Navigation合作。我在引导程序中设置导航。如果用户无权访问资源,我试图让链接不显示。我已阅读了几个教程,多次浏览了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角色和资源以及导航都来自数据库,以防重要

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

)

4 个答案:

答案 0 :(得分:15)

乔伊,

关于此的良好文档很难找到,但它存在。您需要做的是,在应用程序的引导程序中有两件事:

  1. 初始化您的ACL
  2. 将它们链接到导航对象
  3. 在我的引导中,我使用类似于以下的功能来执行此操作。以下是关键方面的示例:

    生成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>
    

    在这里,我们创建了一个名为管理的部分,要求用户在 admin:copyright 资源上拥有查看权限,该客户确实感谢pre - 建立的acl列表。

    现在,当您拨打$ this-&gt; navigation() - &gt; menu() - &gt; render()等时,菜单选项将基于用户的访问权限。

    嗯,我想我应该在我的网站上添加一个帖子。一切都很好。

    马特

答案 1 :(得分:0)

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

答案 2 :(得分:0)

我认为控制器插件更适合使用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);
        }
     }

}

答案 3 :(得分:0)

尝试在bootstrap中动态构建导航

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

          }

我希望它可以帮到你