Zend навигация и Zend ACL - PullRequest
       19

Zend навигация и Zend ACL

5 голосов
/ 17 ноября 2011

Я работаю с 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 ]

15 голосов
/ 17 ноября 2011

Джои,

Хорошая документация по этому вопросу может быть трудно найти, но она существует.Что вам нужно сделать, в начальной загрузке вашего приложения есть две вещи:

  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>

Здесь мы создали раздел под названием администрация, требующий от пользователя права просмотра на ресурсе admin: copyright , который делает гость благодаря встроенному списку acl.

Теперь, когда вы вызываете $ this-> navigation () -> menu () -> render () и т. д., пункты меню будут основаны на доступе пользователя.

Хммм, я думаю, что я должен добавить пост к этому на моем сайте.Все лучшее с ним.

Мэтт

0 голосов
/ 25 ноября 2013

Попробуйте построить динамическую навигацию в 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);

          }

Я надеюсь, что это поможет вам

0 голосов
/ 23 марта 2013

Я думаю, что плагин контроллера лучше управлять с помощью 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);
        }
     }

}
0 голосов
/ 06 сентября 2012

Я предлагаю вам добавить еще один тег в свой XML-файл навигации, относящийся к ресурсу ACL, и отобразить его в своем INI-файле, где вы храните сопоставление ACL. Логика может быть наилучшим образом реализована на вашей начальной загрузке, чтобы ее можно было прочитать до того, как что-то произойдет. Не забудьте также внедрить его в свой вызов ajax, если он у вас есть.

...