想象一下,我有4个数据库表,以及一个界面,它在单个网页上呈现用于管理每个表中数据的表单(使用手风琴设计模式一次只显示一个表单)。每个表单都显示表格中的行列表,允许用户插入新行或选择要编辑或删除的行。然后使用AJAX将请求发送到服务器。
必须根据应用程序ACL向不同用户显示不同的表单集。
我的问题是:在控制器,操作,视图和布局方面,这个界面的最佳架构是什么?
例如,到目前为止,我有一个控制器,每个表都有添加,编辑和删除操作。每个都有一个indexAction,但它是一个空函数。我还为每个表扩展了Zend_Form。为了显示表单,我然后在IndexController中将Forms传递给它的视图,并回显每个表单。然后,Javascript负责填充表单并将请求发送到相应控制器的appropraite添加/编辑/删除操作。但是,这不允许ACL控制不同用户显示或不显示表单。
让indexAction实例化表单会更好,然后使用类似$ this-> render();在IndexController的indexAction视图中呈现每个视图?然后ACL会阻止呈现某些视图吗?
干杯。
答案 0 :(得分:1)
您可以在几个地方对ACL进行检查:
Zend_Form
扩展名的构造函数中扩展所有自定义Form对象(可能是最好的方法,因为它有助于减少代码重复)。请记住,如果您使用ZF执行更新的AJAXy解决方案,您的控制器也需要在其init()
方法中运行ACL检查,以防止对您的数据库进行未经授权的更改。
希望有所帮助。
答案 1 :(得分:0)
你有没有解决这个问题?
我正在构建一个大型数据库应用程序,其中包含许多嵌套子控制器作为父控制器上显示的仪表板上的面板。 简化的源代码如下:来自我的parentController-> indexAction()
$dashboardControllers = $this->_helper->model( 'User' )->getVisibleControllers();
foreach (array_reverse($dashboardControllers) as $controllerName) // lifo stack so put them on last first
{
if ($controllerName == 'header') continue; // always added last
// if you are wondering why a panel doesn't appear here even though the indexAction is called: it is probably because the panel is redirecting (eg if access denied). The view doesn't render on a redirect / forward
$this->_helper->actionStack( 'index', $this->parentControllerName . '_' . $controllerName );
}
$this->_helper->actionStack( 'index', $this->parentControllerName . '_header' );
如果你有更好的解决方案,我会热衷于听到它。 对于我的下一个技巧,我需要弄清楚如何根据用户偏好设置在一列,两列或三列中显示这些
答案 2 :(得分:-1)
我使用Manning Press的“Zend Framework in Action”一书中的修改版本(如果您现在需要,可以下载PDF格式)。我想你可以从本书的网站上下载附带的代码。您想查看第7章代码。
概述:
控制器是资源,操作是特权。 把你的允许和放在控制器的init方法中拒绝。 我也在使用他们的Controller_Action_Helper_Acl的自定义版本。
每个控制器都有一个公共静态getAcls方法:
public static function getAcls($actionName)
{
$acls = array();
$acls['roles'] = array('guest');
$acls['privileges'] = array('index','list','view');
return $acls;
}
这让其他控制器可以询问此控制器的权限。 每个控制器init方法调用$ this-> _initAcls(),它在我自己的基本控制器中定义:
public function init()
{
parent::init(); // sets up ACLs
}
父母看起来像这样:
public function init()
{
$this->_initAcls(); // init access control lists.
}
protected function _initAcls()
{
$to_call = array(get_class($this), 'getAcls');
$acls = call_user_func($to_call, $this->getRequest()->getActionName());
// i.e. PageController::getAcls($this->getRequest()->getActionName());
if(isset($acls['roles']) && is_array($acls['roles']))
{
if(count($acls['roles'])==0) { $acls['roles'] = null; }
if(count($acls['privileges'])==0){ $acls['privileges'] = null; }
$this->_helper->acl->allow($acls['roles'], $acls['privileges']);
}
}
然后我只有一个名为:
的函数aclink($link_text, $link_url, $module, $resource, $privilege);
它调用{$ resource} Controller :: getAcls()并对它们进行权限检查。 如果他们有权限,则返回链接,否则返回''。
function aclink($link_text, $link_url, $module, $resource, $privilege)
{
$auth = Zend_Auth::getInstance();
$acl = new Acl(); //wrapper for Zend_Acl
if(!$acl->has($resource))
{
$acl->add(new Zend_Acl_Resource($resource));
}
require_once ROOT.'/application/'.$module.'/controllers/'.ucwords($resource).'Controller.php';
$to_call = array(ucwords($resource).'Controller', 'getAcls');
$acls = call_user_func($to_call, $privilege);
if(isset($acls['roles']) && is_array($acls['roles']))
{
if(count($acls['roles'])==0) { $acls['roles'] = null; }
if(count($acls['privileges'])==0){ $acls['privileges'] = null; }
$acl->allow($acls['roles'], $resource, $acls['privileges']);
}
$result = $acl->isAllowed($auth, $resource, $privilege);
if($result)
{
return '<a href="'.$link_url.'" class="aclink">'.$link_text.'</a>';
}
else
{
return '';
}
}