Los Controladores en Yii

Introducción.

Estructura de una aplicación Yii.
Estructura de una aplicación Yii.
  • El Modelo/Vista/Controlador es un patrón de diseño.
  • Su utilidad radica en separar la lógica del negocio de la interfaz de usuario.
  • El modelo representa la información y las reglas del negocio asociadas a ella.
  • La vista representa a los componentes de la interfaz de usuario y todo lo relacionado con su presentación.
  • El controlador recibe la solicitud del usuario (controlador, acción e información) e intermedia entre la vista y los modelos para elaborar la respuesta.
  • El controlador frontal (index.php) recibe directamente la solicitud del usuario, es el único que interactúa directamente con él, y se encarga de enrrutar la solicitud al controlador y acción apropiados.
  • Consultar secuencia de procesamiento de un requerimiento.

El controlador.

  • Hereda de CController.
  • Su identificador es de la forma ruta/a/xyz (ejemplo: user).
  • Corresponde con el archivo protected/controllers/ruta/a/XyzController.php (ejemplo: protected/controllers/UserController.php).
  • Si la aplicación utiliza módulos, su identificador se incluye en la ruta del identificador del controlador.
  • Incluye una o mas acciones.
  • Incluye cero o mas filtros para sus acciones.
  • La instanciación de un controlador puede realizarse de la siguientes maneras según el contexto.
    • Si se define CWebApplication::catchAllRequest, todas las solicitudes serán redireccionadas al controlador indicado ignorándose el solicitado.  Es útil para poner el sitio fuera de línea.
    • Si el identificador del controlador solicitado se encuentra en CWebApplication::controllerMap se utilizará el controlador asociado en la conversión.
    • Se busca el controlador en la ubicación específica según su ruta.
    • Si el controlador no existe se lanza una CHttpException 404.

Las acciones.

  • Definen (implementan) que hacer ante el requerimiento específico de un usuario.
  • Si no se especifica una acción se utiliza la acción por defecto (index) que puede configurarse con CController::defaultAction.
  • Pueden implementarse de dos maneras.
    • Como un método del controlador cuyo nombre deberá ser actionIdentificador.
      • La acción add corresponderá con el método actionAdd.
    • Como una nueva clase que hereda de CAction cuyo nombre deberá ser IdentificadorAction e implementa el método run.
      • La acción add en este caso corresponderá con una instancia de la clase AddAction.
      • Para que este caso funcione se debe sobreescribir el método actions del controlador estableciendo la relación entre identificador de la acción y clase que la implementa.
        ...
        public function actions()
        {
            return array(
                'add' => 'application.controllers.post.AddAction'
            );
        }
        ...
      • Se recomienda almacenar las acciones bajo el alias de application.controllers.<identificador del controlador> que hace referencia a la ruta física protected/controllers/<identificador del controlador>.

Los filtros.

  • Permiten manipular el flujo de ejecución de la acción solicitada.
  • Se ejecutan antes y después de la acción solicitada permitiendo filtrar si esta es efectivamente invocada o no.
  • Útiles para realizar procesos previos de preparación (estadísticas, verificación de autenticación/autorización, etc.) y de limpieza (liberación de recursos, verificaciones finales, etc.).
  • Una acción puede tener cero o mas filtros.
  • Los filtros se ejecutan en el mismo orden en que fueron definidos.
  • Un filtro puede decidir si los demás filtros o la acción no deben ser ejecutados.
  • Al igual que las acciones, los filtros pueden implementarse de dos maneras.
    • Como un método del controlador cuyo nombre deberá ser filterIdentificador.
      • El filtro editPassword corresponderá con el método filterEditPassword.
        public function filterEditPassword($filterChain)
        {
            // $filterChain -> run() continúa la ejecución de los filtros.
        }
    • Como una nueva clase que hereda de CFilter cuyo nombre deberá ser IdentificadorFilter.
      • Se deben implementar los métodos preFilter y postFilter que se ejecutarán antes y después de invocarse la acción.
        class CheckAuthFilter extends CFilter
        {
            protected function preFilter($filterChain)
            {
                // Ejecutado antes de invocar la acción.
                return true;   // false si se debe abortar la ejecución de la acción.
            }
        
            protected function postFilter($filterChain)
            {
                // Ejecutado después de terminar la invocación de la acción.
            }
        }
  • Es necesario sobreescribir el método CController::filters() para asociar los filtros a las acciones.
    ...
    public function filters()
    {
        return array(
            'editPassword + edit, create',                               // filtro basado en un método
    
            array (
                 'application.filters.CheckAuthFilter - logout, index',  // filtro basado en una clase
                 'tipo' => 'usuario'
            )
        );
    }
    ...
    • El filtro editPassword está implementado por un método del controlador mientras que el filtro checkAuth está basado en una clase que hereda de CFilter.
    • El alias application.filters hace referencia a la ruta física protected/filters.
    • Es posible especificar valores para los atributos del filtro utilizando un arreglo en la definición de los filters tal y como se le asigna un valor al atributo tipo del filtro checkAuth.
    • Los operadores + y – modifican el alcance de la relación entre filtros y acciones.
      • +: el filtro se aplica a las acciones especificadas.  (incluye).
        • El filtro editPassword se aplica a las acciones edit y create únicamente.
      • : el filtro se aplica a todas las acciones exceptuando las especificadas.  (excluye).
        • El filtro checkAuth se aplica a todas las acciones menos a logout e index.

Enlaces.

    protected function preFilter($filterChain)
    {
        // Ejecutado antes de invocar la acción.
        return true;   // false si se debe abortar la ejecución de la acción.
    }

Leave a Reply

Your email address will not be published. Required fields are marked *