2014-04-22 4 views
0

Je suis à la recherche d'un moyen de avant le traitement des erreurs dans mon application Yii 1.1.14. Le scénario se présente comme suit:Yii: erreur personnalisée de traitement de transfert

En supposant que j'ai deux modules: ClientModule à/client /, AdminModule à/admin /. Si une URL est résolu d'appartenir à un contrôleur dans ce module, le contrôleur est chargé, et le errorHandler est réaffecté à un module de niveau erreur gestionnaire comme ceci:

public function beforeControllerAction($controller, $action) 
{ 
    Yii::app()->errorHandler->errorAction='admin/error'; 
    return parent::beforeControllerAction($controller, $action); 
} 

De cette façon, une action existe à ' admin/admin/erreur »(qui à son tour est spécifié manuellement à résoudre pour « admin/error »), qui gère l'erreur avec un passe-partout comme:

public function actionError() { 
    if($error=Yii::app()->errorHandler->error) 
    { 
     if(Yii::app()->request->isAjaxRequest) 
      echo $error['message']; 
     else 
      $this->render('application.views.error.index', $error); 
    } 
} 

pendant ce temps, le code analogue (pour les deux fonctions) existent dans l'autre module (Il y a aussi un ClientModule et un ClientController avec une actionError mappée automatiquement sur 'client/client/error', remappé sur 'client/error').

Je n'ai aucun problème avec ces segments de code. Mon problème commence maintenant:

Si je entrer une URL qui ne peut être résolu, même lorsque le préfixe est un préfixe de module (par exemple, « client/invalide/url » ou 'client/client/invalide), le contrôleur ne sera pas créé (puisqu'il n'existe pas - ou, comme dans le second exemple, le contrôleur existe mais pas l'action), et donc beforeController ne sera pas appelé, et donc le gestionnaire d'erreur personnalisé (dans cet exemple: le correspondant à ClientModule qui définit $ aClientController-> actionError) ne sera pas affecté. Résultat: le ErrorController par défaut gère l'erreur d'URL non résolue.

Ainsi, les questions :

  1. Est-il possible que je pourrais une erreur url non résolue (404) à certains modules, en fonction du préfixe? (il est prudent, dans mon cas, d'assumer des préfixes, puisque je n'ai défini aucun module par défaut). Alternativement: existe-t-il un moyen, étant dans le ErrorController-> actionIndex(), de transmettre le traitement des erreurs à l'un de ces contrôleurs (c'est-à-dire passer à admin/admin/error et client/client/error tout en gardant le Yii::app()->errorHandler->error état)?

Modifier - Note: Pourquoi devrais-je utiliser un autre contrôleur si le code de gestion des erreurs est le même? Parce que j'ai des données supplémentaires fournies par ces contrôleurs qui sont utilisés dans la mise en page (par exemple menu, menu principal).

Répondre

0

J'ai trouvé la réponse, encore une fois (mon juniority n'a pas de limites - et le nom de la méthode dont j'avais besoin avait le nom exact: forward !!). En utilisant le CController->forward('module/controller/action') à l'intérieur de la méthode ErrorController->actionError je pourrais expédier partout. J'ai également modifié une autre condition de logique métier et n'ai plus l'affectation de gestionnaire d'erreur personnalisée dans les constructeurs de modules, mais j'utilise toujours ces contrôleurs comme cibles d'erreur/index en fonction du type d'utilisateur connecté (une erreur est survenue et l'utilisateur était un client => transmettre au client/client/erreur, tout en étant admin conduit à admin/admin/error, et étant aucun utilisateur connecté effectué la gestion des erreurs avec erreur/index comme d'habitude).

public function actionIndex() { 
    if (Yii::app()->user->getState('client')) 
    { 
     $this->forward('client/client/error'); 
    } 
    if (Yii::app()->user->getState('staff')) 
    { 
     $this->forward('admin/admin/error'); 
    } 

    //usual boilerplate here 
    if($error=Yii::app()->errorHandler->error) 
    { 
     if(Yii::app()->request->isAjaxRequest) 
      echo $error['message']; 
     else 
      $this->render('index', $error); 
    } 
}