我目前正在想办法解决上述问题。
我目前的申请结构如下:
/modules
/ modulename
/controllers
/ProjectController.php
该应用程序有3个不同的用户角色,每个角色都包含在这些模块中。我想防止在一个控制器中为每个用户角色执行多个操作,因为我认为它使我的代码不那么可读和丑陋。所以,我在考虑这样的结构:
/modules
/ modulename
/controllers
/ProjectController.php
/EmployeeProjectController.php
/ExecutiveProjectController.php
这应该如下工作:
当然,我可以比较容易地为每个用户角色提供不同的URL方案,但我不想要这个。我想要一个统一的URL方案。
然后,下一步是为每个控制器创建路由,将它们重写到另一个控制器。 我也想阻止它。
我想要一种全局告诉路由器根据用户角色为控制器添加“执行”或“员工”或其他内容的方法。
最好的方法是什么?
答案 0 :(得分:1)
听起来你可以使用front controller plugin和routeStartup()
方法检查Zend_Auth
实例并添加特定于角色的路由(例如,来自INI或XML文件)。 / p>
这样的事情:
class My_Controller_Plugin_RouteByAuth extends Zend_Controller_Plugin_Abstract
{
public function routeStartup()
{
$auth = Zend_Auth::getInstance();
if (!$auth->hasIdentity()){
return;
}
$identity = $auth->getIdentity();
if ($identity->isAdmin()){
$this->_addRoutes('routes_admin.ini');
} else if ($identity->isEmployee()){
$this->_addRoutes('routes_employee.ini');
} else if ($identity->isExecutive()){
$this->_addRoutes('routes_executive.ini');
} else {
return;
}
}
protected function _addRoutes($file)
{
$front = Zend_Controller_Front::getInstance();
$router = $front->getRouter();
$routes = new Zend_Config_Ini(APPLICATION_PATH . '/configs/ ' . $file);
$router->addConfig($routes);
}
}
未经测试,但我希望这传达了一个可行的想法的核心。
答案 1 :(得分:1)
我花了很多时间弄清楚如何使用Zend_Controller_Router_Route来做这件事,并提出了可行的解决方案:
class App_Controller_Router_Route_Rolebasedcontroller extends Zend_Controller_Router_Route_Module
{
/**
* Roles that should be rewritten automatically
*
* @var array
*/
protected $_rewriteRoles = array('employee', 'executive');
/**
* Matches a user submitted path. Assigns and returns an array of variables
* on a successful match.
*
* If a request object is registered, it uses its setModuleName(),
* setControllerName(), and setActionName() accessors to set those values.
* Always returns the values as an array.
*
* @param string $path Path used to match against this routing map
* @return array An array of assigned values or a false on a mismatch
*/
public function match($path, $partial = false)
{
$result = parent::match($path, $partial);
$role = Plano_Acl::getInstance()->getCurrentRole();
if (null !== $role && in_array($role, $this->_rewriteRoles))
{
if (isset($result[$this->_controllerKey]))
{
$result[$this->_controllerKey] = $role . ucfirst($result[$this->_controllerKey]);
}
}
return $result;
}
/**
* Assembles user submitted parameters forming a URL path defined by this route
* Removes fole prefixes when required
*
* @param array $data An array of variable and value pairs used as parameters
* @param bool $reset Weither to reset the current params
* @return string Route path with user submitted parameters
*/
public function assemble($data = array(), $reset = false, $encode = true, $partial = false)
{
if (!$this->_keysSet) {
$this->_setRequestKeys();
}
$params = (!$reset) ? $this->_values : array();
foreach ($data as $key => $value) {
if ($value !== null) {
$params[$key] = $value;
} elseif (isset($params[$key])) {
unset($params[$key]);
}
}
$params += $this->_defaults;
$url = '';
if ($this->_moduleValid || array_key_exists($this->_moduleKey, $data)) {
if ($params[$this->_moduleKey] != $this->_defaults[$this->_moduleKey]) {
$module = $params[$this->_moduleKey];
}
}
unset($params[$this->_moduleKey]);
$controller = $params[$this->_controllerKey];
// remove role prefix from url when required
$role = Plano_Acl::getInstance()->getCurrentRole();
if (null !== $role && in_array($role, $this->_rewriteRoles))
{
if (substr($params[$this->_controllerKey], 0, strlen($role)) == $role)
{
$controller = lcfirst(substr($params[$this->_controllerKey], strlen($role)));
}
}
unset($params[$this->_controllerKey]);
$action = $params[$this->_actionKey];
unset($params[$this->_actionKey]);
foreach ($params as $key => $value) {
$key = ($encode) ? urlencode($key) : $key;
if (is_array($value)) {
foreach ($value as $arrayValue) {
$arrayValue = ($encode) ? urlencode($arrayValue) : $arrayValue;
$url .= '/' . $key;
$url .= '/' . $arrayValue;
}
} else {
if ($encode) $value = urlencode($value);
$url .= '/' . $key;
$url .= '/' . $value;
}
}
if (!empty($url) || $action !== $this->_defaults[$this->_actionKey]) {
if ($encode) $action = urlencode($action);
$url = '/' . $action . $url;
}
if (!empty($url) || $controller !== $this->_defaults[$this->_controllerKey]) {
if ($encode) $controller = urlencode($controller);
$url = '/' . $controller . $url;
}
if (isset($module)) {
if ($encode) $module = urlencode($module);
$url = '/' . $module . $url;
}
return ltrim($url, self::URI_DELIMITER);
}
}