2010-11-11 2 views
0
$this->add (new Zend_Acl_Resource ('index')); 
$this->addRole (new Zend_Acl_Role ('guest')); 
$this->allow('guest', 'index','view'); 

и у меня есть проблемы в этом состоянииZend Framework-как обнаружить не extisting действие с Zend_Acl

if (! $this->_acl->isAllowed ($role, $resource, $action)){ 
    ... redirect to access denied 
} 
  • Гость разрешен доступ к индекс регулятора, и действие вид.
  • Но когда он печатает в URL/индекса/View2 он должен перенаправить его на страницу ошибки, потому что действие view2 оленья кожа существовать
  • Но это условие саис, что ему разрешено Olny для вида действия. Таким образом, это не перенаправляет его на страницу с ошибкой, а на отказ от отказа

Как решить эту проблему?

+0

Может быть, некоторые классы использование Reflection поможет !! http://www.php.net/manual/en/class.reflectionmethod.php – tawfekov

ответ

3

Вы можете проверить для ресурса (действия), чтобы существовать в ACL:

if(!$this->_acl->has($resource) || $this->_acl->isAllowed($role, $resource, $action)) 

Else может просто отказать по умолчанию. Если вы затем проверите несуществующее действие, acl вернет false по умолчанию.
Если вы просто хотите обнаружить, что из вашего контроллера вызывается не существующее действие, вы можете использовать метод __call контроллера.

Для более конкретного решения вы должны предоставить больше информации, как, где вы выполняете аКЛ-чек, как вы настроите свой ACL, ....

Примера поймать не существовавшие действия в контроллере:

My_Controller extends Zend_Controller_Action 
{ 
    __call($method, $args) 
    { 
     throw new Exception("Action does not exist"); // This is done by default 
     // Just do whatever you want to do in this function (like redirecting) 
    } 
} 

В любом случае это может быть сделано с помощью ErrorhandlerPlugin даже без магической функции. Поскольку вы только хотите перенаправить на страницу с ошибкой, вам просто нужно позаботиться о том, чтобы проверка acl не выдавала никаких исключений, потому что ресурс (или действие) не найден. В зависимости от того, где вы делаете свой чек, у вас есть несколько возможностей сделать это, но при условии, что каждый контроллер является одним ресурсом, и вы все добавляете их, это не должно быть проблемой.

+0

Я отправил свой код ниже, iam, вызывающий acl из плагина frontcontroller. Не могли бы вы предоставить некоторый код, как использовать метод __call - из плагина frontcontroller – Tom

+0

@tom: обновлено. Но я думаю, что это не путь (как для решения проблемы, так и для «правильного» способа). – Fge

+0

Да, метод __call - это именно то, что я хочу, Thx – Tom

0

Я бы сделал это, выбросив NotAllowed исключение.

if (! $this->_acl->isAllowed ($role, $resource, $action)){ 
    throw new YourNotAllowedException('some error message'); 
} 

Затем контроллер ошибок я бы обработать это исключение:

if ($error->exception instanceof NotAllowed) { 
    // manual forward setting request params 
    // (url remains the same, but user sees the login page) 
} 

Стандартные исключения будут обрабатываться как обычно.

+0

вы misundersnad меня, я знаю, как перенаправление, но я не знаю, ho обнаруживает не существующее действие – Tom

1

Я называю ACL в predispatch из FrontController плагин

public function preDispatch(Zend_Controller_Request_Abstract $request) { 
    if ($this->_auth->hasIdentity()) { 
     $rights = $this->_auth->getIdentity()->rights; 
     if ($rights == 2) { 
      $role = 'admin'; 
     } elseif ($rights == 1) { 
      $role = 'user'; 
     } else { 
      $role = 'guest'; 
     } 
    } else { 
     $role = 'guest'; 
    } 
    $controller = $request->controller; 
    $action = $request->action; 
    $module = $request->module; 
    $resource = $controller; 
    if ($this->_acl->has ($resource)) { 
     if (! $this->_acl->isAllowed ($role, $resource, $action)) { 
      if (! $this->_auth->hasIdentity()) { 
       //redirect to login 
       $module = $this->_noauth ['module']; 
       $controller = $this->_noauth ['controller']; 
       $action = $this->_noauth ['action'];    
      } else { 
       //redirect to access denied 
       $module = $this->_noacl ['module']; 
       $controller = $this->_noacl ['controller']; 
       $action = $this->_noacl ['action']; 
      } 
      $request->setModuleName ($module); 
      $request->setControllerName ($controller); 
      $request->setActionName ($action); 
     } 
    } else { 
     //controller not found 
     $module = ('default'); 
     $controller = ('error'); 
     $action = ('not-found'); 
     $request->setModuleName ($module); 
     $request->setControllerName ($controller); 
     $request->setActionName ($action); 
    }   
}