Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Pages: 1
j'ai creer un plugin de zend auth grace a un tuto:
class My_Plugin_PluginAuth extends Zend_Controller_Plugin_Abstract { private $_auth; private $_acl; private $_noauth = array('module' => 'login', 'controller' => 'index', 'action' => 'login'); private $_noacl = array('module' => 'default', 'controller' => 'error', 'action' => 'privileges'); public function __construct($auth, $acl) { $this->_auth = $auth; $this->_acl = $acl; } public function preDispatch(Zend_Controller_Request_Abstract $request) { if ($this->_auth->hasIdentity()) { $role = $this->_auth->getIdentity()->role_acl; } else { $role = 'guest'; } $controller = $request->controller; $action = $request->action; $module = $request->module; $resource = $module.'/'.$controller; if (!$this->_acl->has($resource)) { $resource = null; } if (!$this->_acl->isAllowed($role, $resource, $action)) { if (!$this->_auth->hasIdentity()) { $module = $this->_noauth['module']; $controller = $this->_noauth['controller']; $action = $this->_noauth['action']; } else { $module = $this->_noacl['module']; $controller = $this->_noacl['controller']; $action = $this->_noacl['action']; } } $request->setModuleName($module); $request->setControllerName($controller); $request->setActionName($action); } }
Mon problème est que l'utilisateur est toujours rediriger sur la page de login, que la page existe ou pas, ce qui est normal mais j'aimerai faire un test et savoir si la route existe et récuperer l'erreur pour le rediriger vers une erreur 404.
mais je ne sais pas du tout comment faire.
j'ai dans mon bootstrap :
try {
$frontController->dispatch();
} catch (Exception $e) {
// A faire
}
j'utilisai $e mais c'est lors du dispatch.
Dernière modification par baboune (05-12-2008 17:05:25)
Hors ligne
j'ai comencé par mettre en place un plugin d'errorhandler (en predispatch ), il marche trés bien.
public function preDispatch()
{
$this->_exception = $this->_getParam('error_handler');
$this->_response->clearBody(); // on vide le contenu de la réponse
$this->_response->append('error',null); // on ajoute un segment 'error' dans la réponse
if (isset($this->_exception->type)) { //Ajout du test sur appel direct du contrôleur
switch ($this->_exception->type) {
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
self::$httpCode = 404;
self::$errorMessage = 'Page introuvable';
break;
case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER:
switch (get_class($this->_exception->exception)) {
case 'Zend_View_Exception' :
self::$httpCode = 500;
self::$errorMessage = 'Erreur de traitement d\'une vue';
break;
case 'Zend_Db_Exception' :
self::$httpCode = 503;
self::$errorMessage = 'Erreur de traitement dans la base de données';
break;
case 'Metier_Exception' :
self::$httpCode = 200;
self::$errorMessage = $this->_exception->exception->getMessage();
break;
case 'Autre_Exception' :
self::$httpCode = 500;
self::$errorMessage = 'Exemple avec une "autre exception"';
break;
default:
self::$httpCode = 500;
self::$errorMessage = 'Erreur inconnue';
break;
}
break;
}
}else{ //si on a eu un appel manuel on retourne ok et le paramètre passé qui n'a pas forcément le bon type
self::$httpCode = 200;
self::$errorMessage = $this->_exception;
}
}
mais du coup il y a une 'interférence' avec mon plugin auth mais qui est prioritaire.
Par le biais d'une fonction dans mon plugin auth j'ai solutionner mon problème mais je ne récupère pas mes exceptions.
personne ne peut m'aider je deviens fou !
Dernière modification par baboune (05-12-2008 03:12:04)
Hors ligne
Tu as un plugin dédié à la gestion des erreurs
Tu initialises ton front comme ca :
$frontController->registerPlugin( new Zend_Controller_Plugin_ErrorHandler(array( 'module' => 'monModule' 'controller' => 'monController', 'action' => 'monAction' )) );
Ensuite, il te suffit de coder une action 'ErrorAction()' dans le controller que tu passes en paramètre ci-dessus.
Regarde la doc concernant errorHandler.
Ainsi, lorsque le ZF ne trouve pas le controller/l'action a exécuter, il lance une exception, et la c'est le controller que tu as paramètrer avec errorHandler qui s'en charge.
Par exemple :
public function errorAction() { $errors = $this->_getParam('error_handler'); switch ($errors->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: // 404 error -- controller or action not found $this->getResponse()->setRawHeader('HTTP/1.1 404 Not Found'); $this->view->errorType = 404; $this->view->exception = $errors->exception; Zend_Registry::get('logger')-»error($errors->exception); // firebug et autres... break; default: throw $errors->exception; break; } }
Hors ligne
merci nORKy, mais c'est axactement ce que j'avais fait mais le problème c'est en faite un conflits de plugins.
déja ce matin (appache du coup à redémarrer), et il ma capte mes erreurs exception (content et dégouté a la fois) et enfin en cherchant mon problème était :
Que se passe-t-il si ce contrôleur là, n'est pas trouvé , ou aussi, si le contrôleur d'echec ACL n'est pas trouvé ?
Il faut faire attention car "en dessous" de notre plugin auth, il y a le plugin ErrorHandler, activé par défaut, et peut-être encore d'autres. Le rôle de celui-ci est de traiter justement les cas où le contrôleur, le module ou l'action sont introuvables (entres autres cas).
Si il agit, il redémarre toute la boucle de dispatching pour dispatcher vers un contrôleur d'erreur. Et notre plugin auth va ré-intervenir .... Il va donc à nouveau rechanger la requête, vers un contrôleur toujours invalide.
ErrorHandler va repasser une fois de plus derrière, mais vu qu'il a été prévu pour gérer ce genre de conflit, il va envoyer une exception au FC.
Il faut donc vérifier dans notre plugin si le ErrorHandler n'est pas déja passé par là.
}elseif (is_null($this->_request->getParam('error_handler'))) { vérifie ceci, car ce plugin "marque" la requête.
et du coup j'ai rajouté une condition lors du test if isAllow dans mon plugin auth :
&& (is_null($this->_request->getParam('error_handler')))
et enfin quand je reroute mes utilisateurs avec setModuleName, setControllerName...
try { $request->setModuleName($module); $request->setControllerName($controller); $request->setActionName($action); } catch(Zend_Acl_Exception $exception) { // l'ACL ne trouve pas la ressource, probablement contrôleur ou action incorrects : non répertoriés dans l'ACL //exit($exception->getMessage()); return; }
ça fonctionne maintenant, mais faut que je personalise maintenant les exceptions, j'ai toujours
"Erreur inconnue", j'ai essayé de personnalisé avec
]throw new Zend_Controller_Exception('Page n\'exite pas');
mais ça fonctionne pas. merci encore.
Hors ligne
bon j'ai ecrit n'importe quoi sur mon message au dessus désolé comme vous avez pu le comprendre je suis nouveau dans le monde de ZF et de PDO (voir même de la POO)
pour tous ce ceux que ça interesse et pour savoir si mon code et juste :
Mon Bootstrap
// setup controller $frontController = Zend_Controller_Front::getInstance(); $frontController->throwExceptions(false); $plugin = new Zend_Controller_Plugin_ErrorHandler(); $plugin->setErrorHandlerModule('default') ->setErrorHandlerController('error') ->setErrorHandlerAction('error'); $frontController->registerPlugin($plugin); $frontController->registerPlugin(new My_Plugin_PluginAuth($auth, $acl));
Mon ErrorControler :
public function preDispatch() { //$this->_helper->viewRenderer->setNoRender(true); // ne rend aucune vue automatiquement $this->_exception = $this->_getParam('error_handler'); $this->_response->clearBody(); // on vide le contenu de la réponse $this->_response->append('error',null); // on ajoute un segment 'error' dans la réponse if (isset($this->_exception->type)) { //Ajout du test sur appel direct du contrôleur switch ($this->_exception->type) { case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER: case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION: self::$httpCode = 404; self::$errorMessage = 'Page introuvable'; break; case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER: switch (get_class($this->_exception->exception)) { case 'Zend_View_Exception' : self::$httpCode = 500; self::$errorMessage = 'Erreur de traitement d\'une vue'; break; case 'Zend_Db_Exception' : self::$httpCode = 503; self::$errorMessage = 'Erreur de traitement dans la base de données'; break; case 'Metier_Exception' : self::$httpCode = 200; self::$errorMessage = $this->_exception->exception->getMessage(); break; case 'Zend_Acl_Exception' : self::$httpCode = 403; self::$errorMessage = $this->_exception->exception->getMessage(); break; default: self::$httpCode = 500; self::$errorMessage = 'Erreur inconnue'; break; } break; } }else{ //si on a eu un appel manuel on retourne ok et le paramètre passé qui n'a pas forcément le bon type self::$httpCode = 200; self::$errorMessage = $this->_exception; } }
et enfin mon PluginAuth
class My_Plugin_PluginAuth extends Zend_Controller_Plugin_Abstract { private $_auth; private $_acl; private $_noroute = array('module' => 'default', 'controller' => 'error', 'action' => 'index'); private $_noauth = array('module' => 'login', 'controller' => 'index', 'action' => 'login'); private $_noacl = array('module' => 'default', 'controller' => 'error', 'action' => 'privileges'); public function __construct($auth, $acl) { $this->_auth = $auth; $this->_acl = $acl; } public function preDispatch(Zend_Controller_Request_Abstract $request) { $dispatcher = Zend_Controller_Front::getInstance(); if ($this->_auth->hasIdentity()) { $role = $this->_auth->getIdentity()->role_acl; } else { $role = 'guest'; } $controller = $request->getControllerName(); $action = $request->getActionName(); $module = $request->getModuleName(); $resource = $module.'/'.$controller; if (!$this->_actionExists($request)) { $module = $this->_noroute['module']; $controller = $this->_noroute['controller']; $action = $this->_noroute['action']; } else { if (!$this->_acl->has($resource)) { $resource = null; } if ((!$this->_acl->isAllowed($role, $resource, $action)) && (is_null($this->_request->getParam('error_handler')))) { if (!$this->_auth->hasIdentity()) { $module = $this->_noauth['module']; $controller = $this->_noauth['controller']; $action = $this->_noauth['action']; throw new Zend_Acl_Exception('Vous n\'êtes pas authentifier !'); } else { $module = $this->_noacl['module']; $controller = $this->_noacl['controller']; $action = $this->_noacl['action']; throw new Zend_Acl_Exception('Vous n\'avez pas l\'autorisation ! Veuillez contacter votre Webmaster ou vous identifier de nouveau'); } } } try { $request->setModuleName($module); $request->setControllerName($controller); $request->setActionName($action); } catch(Zend_Acl_Exception $exception) { // l'ACL ne trouve pas la ressource, probablement contrôleur ou action incorrects : non répertoriés dans l'ACL //exit($exception->getMessage()); return; } } private function _actionExists($request) { $dispatcher = Zend_Controller_Front::getInstance()->getDispatcher(); // Check controller if (!$dispatcher->isDispatchable($request)) { throw new Zend_Acl_Exception('Page introuvable !'); return false; } // Check action $controllerClassName = $dispatcher->formatControllerName( $request->getControllerName() ); $controllerClassFile = $controllerClassName . '.php'; if ($request->getModuleName() != $dispatcher->getDefaultModule()) { $controllerClassName = ucfirst($request->getModuleName()) . '_' . $controllerClassName; } try { Zend_Loader::loadFile($controllerClassFile, $dispatcher->getControllerDirectory($request->getModuleName())); $actionMethodName = $dispatcher->formatActionName($request->getActionName()); if (@in_array($actionMethodName, get_class_methods($controllerClassName))) { return true; } return false; } catch(Exception $exception) { return false; } } }
tout marche comme je veux (c'est déja pas mal) après je sais pas si c'est la bonne méthode.
je sais pas si je doit laisser :
$module = $this->_noauth['module']; $controller = $this->_noauth['controller']; $action = $this->_noauth['action'];
étant donné que juste aprés il y a une exception.
merci Norky !
Dernière modification par baboune (05-12-2008 14:16:59)
Hors ligne
Pages: 1