Una vez presentadas las factorías, volvemos a la explicación del proceso que
despacha las peticiones. Tras la inicialización de sfContext
, se invoca el
método dispatch()
del controlador,
sfFrontWebController::dispatch()
.
En Symfony el proceso que despacha las peticiones es muy sencillo. De hecho,
sfFrontWebController::dispatch()
simplemente obtiene el nombre del módulo y
de la acción a partir de los parámetros de la petición y redirige la aplicación
mediante sfController::forward()
.
Nota En este punto, si el enrutamiento no puede encontrar ningún módulo o acción
a partir de la URL, se lanza una excepción de tipo
sfError404Exception
,
que redirige la petición al módulo encargado de procesar la respuesta del
error 404 (ver información sobre sf_error_404_module
y
sf_error_404_action
).
Si quieres mostrar un error de tipo 404 en cualquier punto de la aplicación,
tu también puedes lanzar esta excepción.
El método forward
realiza muchas comprobaciones previas a la ejecución, además
de preparar la configuración y los datos para la acción se que va a ejecutar.
En primer lugar el controlador comprueba si existe un archivo llamado
generator.yml
en el módulo actual. Esta comprobación es la primera que se realiza (después de
una limpieza básica del nombre del módulo y de la acción) porque el archivo de
configuración generator.yml
(si existe) se encarga de generar la clase base
de las acciones del módulo (mediante su
gestor de configuración, sfGeneratorConfigHandler
).
Esta comprobación es necesaria para el siguiente paso, que comprueba si existen
el módulo y la acción. La comprobación se delega en el controlador, a través
de su método
sfController::actionExists()
,
que después invoca el método
sfController::controllerExists()
.
Una vez más, si el método actionExists()
falla, se lanza una excepción de tipo
sfError404Exception
.
Nota El gestor de configuración
sfGeneratorConfigHandler
es un tipo especial de gestor que se encarga de instanciar la clase generadora
correcta para tu módulo y la ejecuta. Si quieres conocer más detalladamente los
gestores de configuración, puedes leer la sección anterior de este mismo
capítulo y también el
capítulo 6 de la Referencia de Symfony.
En este punto no hay mucho que hacer salvo redefinir el método
sfApplicationConfiguration::getControllerDirs()
en la clase de configuración de la aplicación. Este método devuelve un array
con los directorios en los que residen los controladores, además de un parámetro
adicional que le indica a Symfony si debe comprobar que los controladores estén
activados mediante la opción de configuración sf_enabled_modules
del archivo
settings.yml
. El método getControllerDirs()
podría tener por ejemplo el
siguiente aspecto:
/**
* Controllers in /tmp/myControllers won't need to be enabled
* to be detected
*/
public function getControllerDirs($moduleName)
{
return array_merge(parent::getControllerDirs($moduleName), array(
'/tmp/myControllers/'.$moduleName => false
));
}
Nota Si la acción no existe, se lanza una excepción de tipo sfError404Exception
.
El siguiente paso consiste en obtener una instancia del controlador que contiene
la acción. De ello se encarga el método
sfController::getAction()
,
que al igual que actionExists()
es un intermediario del método
sfController::getController()
.
Finalmente, la instancia del controlador se añade al conjunto de acciones o
action stack.
Nota El conjunto de acciones es una pila de tipo FIFO (First In First Out) que
contiene todas las acciones que se ejecutan durante la petición. Cada elemento
de la pila se representa con un objeto de tipo sfActionStackEntry
. La pila
siempre está accesible mediante sfContext::getInstance()->getActionStack()
o a través de $this->getController()->getActionStack()
dentro de una acción.
Después de cargar algo más de configuración, ya será posible ejecutar la acción.
De hecho, es necesario cargar la configuración específica del módulo, que se
puede encontrar en dos lugares diferentes. Primero Symfony busca el archivo
module.yml
(que se encuentra normalmente en apps/frontend/modules/miModulo/config/module.yml
),
que como es un archivo de configuración YAML, utiliza la cache de configuración.
Además, este archivo de configuración puede declarar el módulo como interno,
utilizando la opción mod_miModulo_is_internal
que hace que la petición produzca
in error, ya que los módulos internos no se pueden acceder públicamente.
Nota Los módulos internos se utilizaban antes para generar el contenido de los emails
(por ejemplo mediante getPresentationFor()
). Ahora se utilizan otras técnicas,
como los elementos parciales ($this->renderPartial()
).
Después de cargar el archivo module.yml
, se comprueba por segunda vez que el
módulo actual está activado. Efectivamente, puedes establecer la opción
mod_$moduleName_enabled
a false
si quieres deshabilitar el módulo en este
punto.
Nota Como se ha mencionado, existen dos formas diferentes de activar o desactivar
un módulo. La diferencia reside en lo que sucede cuando se deshabilita el
módulo. En el primer caso, cuando está activada la opción sf_enabled_modules
,
un módulo desactivado provoca que se lance una excepción de tipo
sfConfigurationException
.
Esta opción debería utilizarse cuando se deshabilita un módulo permanentemente.
En el segundo caso, mediante la opción mod_$moduleName_enabled
, el módulo
deshabilitado provocará que la aplicación se redirija al módulo deshabilitado
(ver las opciones sf_module_disabled_module
y
sf_module_disabled_action
).
Esta es la opción que debes utilizar cuando se deshabilita temporalmente un
módulo.
La última oportunidad para configurar un módulo se encuentra en el archivo
config.php
(apps/frontend/modules/yourModule/config/config.php
) donde puedes
incluir cualquier código PHP que quieras que se ejecute dentro del contexto del
método sfController::forward()
(es decir, que tienes acceso a la instancia de sfController
mediante la
variable $this
, ya que el código se ejecuta literalmente dentro de la clase
sfController
).
10.4.1. Resumen de cómo se despacha la petición
- Se invoca
sfFrontWebController::dispatch()
- Se invoca
sfController::forward()
- Se busca un archivo
generator.yml
- Se comprueba que el módulo y la acción existen
- Se obtiene la lista de directorios de los controladores
- Se obtiene una instancia de la acción
- Se carga la configuración del módulo mediante
module.yml
y/oconfig.php