2012-01-27 15 views
8

He trabajado con CakePHP 1.3, pero esta es mi primera incursión en las excepciones de CakePHP 2.0 y PHP, así que tengan paciencia si mi pregunta parece prolija.CakePHP 2.0 - beforeFilter() no se ejecuta en cakeErrorController?

En mis AppController 's beforeFilter() puse un par de variables a través de $this->set() para su uso en mi plantilla de vista.

En mi UsersController tengo código que se ve más o menos así:

public function beforeFilter() { 
    parent::beforeFilter(); 
    if (userDeniedAccess()) { 
    throw new ForbiddenException(); 
    } 
} 

donde la función hipotética userDeniedAccess() encapsula mis comprobaciones de autorización.

Todo funciona bien, y obtengo el error 403 cuando lo espero. Sin embargo, cuando se lanza la excepción, las variables de vista que se establecieron en AppController::beforeFilter() ya no están configuradas, lo que provoca errores en mi plantilla de vista. Cuando se lanza la excepción no, las variables se establecen correctamente.

Puedo codificar las variables faltantes si es necesario, pero realmente me gustaría saber qué causa este comportamiento. Tanto mi UsersController como CakeErrorController extienden AppController. Naturalmente, espero que cuando se lanza la excepción y se instancia el CakeErrorController, genere las mismas variables de vista para mí.

Sin embargo, parece que el método Controller::startupProcess() (que incluye la llamada a beforeFilter()) nunca se llama en CakeErrorController. Según tengo entendido, el despachador lo hace para solicitudes regulares, pero el ciclo de vida del controlador de errores es diferente.

He visto descripciones (like this one) de comportamiento similar en CakePHP 1.3, pero por supuesto el código de manejo de error de CakePHP ha sido completamente revisado en 2.0.

Así que o bien:

  1. Esto es un error en el manejo de excepciones por defecto de CakePHP,
  2. el comportamiento es como se pretende y yo no lo entiendo, o
  3. Me estoy volviendo loco.

Sé que no puede ayudar con el caso 3, pero si aplica alguno de los dos primeros, agradecería la opinión de alguien que sabe más que yo.

Gracias!

EDITAR: Establecer las variables de vista en beforeRender() resuelve mi problema. Sin embargo, todavía me pregunto si es intencional que beforeFilter() nunca se llame en CakeErrorController.

+1

+1 para el autodiagnóstico "Yo podría estar loco". –

Respuesta

4

Ponga las llamadas a $this->set() en la devolución de llamada beforeRender(). De esa forma, siempre se establecerán incluso cuando arrojes una excepción.

Tuve el mismo problema con algunas variables de diseño personalizadas, ya que con DebugKit mi página estaría llena de advertencias variables no declaradas cada vez que hubiera algún tipo de error. El uso de beforeRender() en su lugar lo solucionó.

+0

+1 para obtener una respuesta intuitiva, pero no estoy seguro de que esto funcione para mí, ya que 'beforeRender()' se ejecuta después de la lógica de acción. Como estoy haciendo verificaciones de autorización, no quiero que la lógica de acción se ejecute si fallan. – eaj

+0

Pensándolo bien, eso no tiene sentido. Por supuesto, puedo lanzar mi excepción en 'beforeFilter()' y establecer las variables de vista en 'beforeRender()'. He aceptado esta respuesta porque soluciona mi problema inmediato, pero aún me gustaría saber si es un error que 'beforeFilter()' no se invoque en el controlador de errores. – eaj

3

puede sobrescribir CakeErrorController.php copiándolo en App/Controller/ y luego agregar parent :: beforeFilter() en el constructor.

+0

Gracias, eso es ciertamente una opción útil. Sin embargo, se siente un poco hackish. En este punto tengo mi código haciendo lo que tiene que hacer. Todavía me gustaría entender por qué el proceso de manejo de excepciones nunca llama a 'startupProcess()' en el 'CakeErrorController' de la misma manera que el despachador lo llama a otros controladores. – eaj

Cuestiones relacionadas