我正在使用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,
关于这方面的优秀文档可能很难找到,但确实存在。在应用程序的引导中,你需要做的是两件事:- 初始化ACL的
- 链接到你的导航对象
在我的引导中,我使用类似于下面的函数来完成此操作。以下是关键方面的示例:
生成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);
}
希望对你有帮助