Más con Symfony

10.5. La cadena de filtros

Ahora que ya se ha realizado toda la configuración, es momento de empezar con el trabajo de verdad, que en este caso consiste en la ejecución de la cadena de filtros.

Nota La cadena de filtros de Symfony implementa un patrón de diseño llamado cadena de responsabilidad. Se trata de un patrón de diseño sencillo pero muy potente que permite encadenar varias acciones. Cada una de las partes de la cadena puede decidir si la cadena debe seguir ejecutándose o no. Cada parte de la cadena también puede ejecutarse antes o después del resto de partes de la cadena.

La configuración de la cadena de filtros se obtiene del archivo filters.yml del módulo actual, que es la razón por la que se necesita la instancia de la acción. En este punto es donde se puede modificar el conjunto de filtros ejecutados por la cadena. Simplemente se debe tener en cuenta que el filtro rendering siempre debe ser el primero de la lista (como se explicará más adelante). La configuración de los filtros por defecto es la siguiente:

Nota Recomendamos encarecidamente que añadas tus propios filtros entre el filtro security y el filtro cache.

10.5.1. El filtro security

Como el filtro rendering espera a que todos los demás filtros acaben antes de realizar su trabajo, el primer filtro que realmente se ejecuta es el filtro security. Este filtro asegura que se cumpla la configuración del archivo security.yml. En concreto, este filtro redirige a los usuarios sin autenticar al módulo y acción login y a los usuarios sin permisos suficientes al módulo y acción secure. Este filtro sólo se ejecuta si la seguridad está activada para esta acción.

10.5.2. El filtro cache

A continuación se ejecuta el filtro cache, que aprovecha su capacidad de evitar la ejecución del resto de filtros de la cadena. Efectivamente, si la cache está activada y si la página solicitada por el usuario está guardada en la cache, la acción ya no se ejecuta. Obviamente lo anterior sólo es válido para las páginas que se pueden guardar enteras en la cache, que no suele ser el caso para la mayoría de páginas.

Este filtro contiene además otra parte que se ejecuta después del filtro execution y justo antes del filtro rendering. Este código es responsable de establecer correctamente las cabeceras HTTP relacionadas con la cache, además de guardar si es necesario la página en la cache gracias al método sfViewCacheManager::setPageCache().

10.5.3. El filtro execution

El último filtro, pero no por eso menos importante, se denomina execution y se encarga de ejecutar la lógica de negocio y su vista asociada.

Todo comienza cuando el filtro comprueba la cache para la acción actual. Si se encuentra en la cache, la acción no se ejecuta y se pasa directamente a ejecutar la vista denominada Success.

Si no se encuentra la acción en la cache, se ejecuta el método preExecute() del controlador y después se ejecuta la propia acción. La ejecución se realiza invocando el método sfActions::execute() de la instancia de la acción. Este método simplemente comprueba que la acción se puede ejecutar y en caso afirmativo la ejecuta. Al volver al filtro, se ejecuta el método postExecute() de la acción.

Nota El valor devuelto por tu acción es muy importante, ya que determina la vista que se ejecuta. Por defecto, cuando no se devuelve ningún valor, se sobreentiende que el valor devuelto es sfView::SUCCESS (lo que se traduce en el valor Success y de ahí el nombre de las plantillas: indexSuccess.php).

Siguiendo con el proceso, ahora le toca el turno a la vista. El filtro comprueba si la acción ha devuelto alguno de los dos siguientes valores especiales: sfView::HEADER_ONLY y sfView::NONE. Cada uno de ellos hace lo que implica su nombre: devuelve solamente las cabeceras HTTP (mediante el método interno sfWebResponse::setHeaderOnly()) o no muestra ninguna página.

Nota Los nombres internos disponibles paras las vistas son: ALERT, ERROR, INPUT, NONE y SUCCESS. Además de estos valores preconfigurados, puedes utilizar cualquier otro valor propio.

Una vez que ya se ha determinado que la acción va a mostrar una página, se puede ejecutar el último paso del filtro: la ejecución de la vista seleccionada.

En primer lugar se obtiene un objeto de tipo sfView a través del método sfController::getView(). Este objeto se puede obtener de dos maneras diferentes. La primera es mediante un objeto propio de vista para esta acción específica, llamado actionSuccessView o module_actionSuccessView y disponible en el archivo apps/frontend/modules/module/view/actionSuccessView.class.php (suponiendo que la acción se llame action y el módulo se llame module). En cualquier otro caso se emplea la clase definida en la opción de configuración mod_module_view_class. El valor inicial de esta opción es sfPHPView.

Nota Si utilizas un clase propia para la vista es posible ejecutar lógica específica de la vista mediante el método sfView::execute(). De esta forma podrías por ejemplo instanciar tu propio motor de plantillas.

Existen tres modos diferentes de generar la vista:

  1. sfView::RENDER_NONE": equivalente a sfView::NONE, por lo que no se genera ninguna vista.
  2. sfView::RENDER_VAR: prepara la presentación de la acción, que después se puede acceder a través del método sfActionStackEntry::getPresentation().
  3. sfView::RENDER_CLIENT, genera la vista e incluye el contenido de la respuesta. Se trata del modo por defecto.

Nota En la práctica, el modo de generación de la vista sólo se utiliza a través del método sfController::getPresentationFor() que devuelve la vista generada para el módulo y acción indicados.

10.5.4. El filtro rendering

Aunque el proceso está prácticamente finalizado, todavía queda un último paso. La cadena de filtros se ha ejecutado en su totalidad pero el filtro rendering sigue esperando a que el resto de filtros terminen para poder hacer su trabajo. En concreto, el filtro rendering envía el contenido de la respuesta al navegador utilizando sfWebResponse::send().

10.5.5. Resumen de la ejecución de la cadena de filtros

  1. La cadena de filtros se instancia utilizando el archivo de configuración filters.yml
  2. El filtro security comprueba las credenciales y las autorizaciones
  3. El filtro cache gestiona la cache de la página actual
  4. El filtro execution ejecuta la acción
  5. El filtro rendering envía la respuesta mediante sfWebResponse