Zend FR

Consultez la FAQ sur le ZF avant de poster une question

Vous n'êtes pas identifié.

#1 04-12-2008 19:52:48

baboune
Membre
Date d'inscription: 29-11-2008
Messages: 103

[plugin Zend_Auth][1.7][résolu] redirection si la route n'existe pas

j'ai creer un plugin de zend auth grace a un tuto:

Code:

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

 

#2 05-12-2008 03:11:18

baboune
Membre
Date d'inscription: 29-11-2008
Messages: 103

Re: [plugin Zend_Auth][1.7][résolu] redirection si la route n'existe pas

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

 

#3 05-12-2008 09:31:42

nORKy
Membre
Date d'inscription: 06-03-2008
Messages: 1098

Re: [plugin Zend_Auth][1.7][résolu] redirection si la route n'existe pas

Tu as un plugin dédié à la gestion des erreurs

Tu initialises ton front comme ca :

Code:

$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 :

Code:

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;
    }
  }

----
Gruiiik !

Hors ligne

 

#4 05-12-2008 11:54:29

baboune
Membre
Date d'inscription: 29-11-2008
Messages: 103

Re: [plugin Zend_Auth][1.7][résolu] redirection si la route n'existe pas

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 :

Code:

 && (is_null($this->_request->getParam('error_handler')))

et enfin quand je reroute mes utilisateurs avec setModuleName, setControllerName...

Code:

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

Code:

]throw new Zend_Controller_Exception('Page n\'exite pas');

mais ça fonctionne pas. merci encore.

Hors ligne

 

#5 05-12-2008 14:13:13

baboune
Membre
Date d'inscription: 29-11-2008
Messages: 103

Re: [plugin Zend_Auth][1.7][résolu] redirection si la route n'existe pas

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

Code:

// 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 :

Code:

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

Code:

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 :

Code:

$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

 

Pied de page des forums

Propulsé par PunBB
© Copyright 2002–2005 Rickard Andersson
Traduction par punbb.fr

Graphisme réalisé par l'agence Rodolphe Eveilleau
Développement par Kitpages