• No se han encontrado resultados

The Definitive Guide to Yii

N/A
N/A
Protected

Academic year: 2021

Share "The Definitive Guide to Yii"

Copied!
118
0
0

Texto completo

(1)

THE DEFINITIVE GUIDE TO YII – Algunas partes en español – Instalación

Para instalar Yii solo debe seguir los siguientes 2 pasos: 1. Descargar el framework Yii de yiiframework.com.

2. Descomprimir el archivo a un directorio accesible por el servicio Web. Tip: Yii no necesita ser instalado en un directorio accesible via web. La aplicacion Yii tiene un script de entrada la cual usualmente es el único archivo que debe ser expuesto a los usuarios Web. Otros scripts PHP , incluidos los de Yii, pueden (y se recomienda) estar protegidos del acceso Web ya que esos pueden intentar ser explotado para Hackeo.

1. Requerimiento ¶

Luego de instalar Yii, ustede puede verificar si su server satisface todos los requerimientos para utilizar Yii. Para hacerlo debe hacer accesible el script de verificación de requerimientos para utilizar Yii. Usted puede acceder al script de verificación de requerimientos en la siguiente URL en un explorador Web:

http://hostname/path/to/yii/requirements/index.php

El requerimiento mínimo de Yii es que su server soporte PHP 5.1.0 o superior. Yii ha sido testeado con Apache HTTP server en los sistemas operativos Windows y Linux. También puede funcionar en otras plataformas que soporten PHP 5.

Creando primera aplicación Yii

Para ingresar al mundo de Yii, en esta scción le indicamos como crear nuestra primera aplicación Yii. Usaremos la poderosa herramientayiic que puede ser utilizadapara automatizar la creación del códgo de ciertas tareas. Por conveniencia asumimos que YiiRoot es el directorio donde Yii se encuentra instalado y WebRoot es la ruta del documento de tu Web Server.

Ejecute yiic en la linea de comandos de la siguiente manera: % YiiRoot/framework/yiic webapp WebRoot/testdrive

Nota: Cuando ejecuta yiic en Mac OS, Linux o Unix, usted deberá modificar los permisos del archivo yiic para poder ejecutarlo. Alternativamente puede correr la herramienta de la siguiente manera,

% cd WebRoot/testdrive

% php YiiRoot/framework/yiic.php webapp WebRoot/testdrive

Esto creará una aplicación Yii esqueleto en el directorio WebRoot/testdrive. Esta aplicación contiene la estructura de directorios requerida por la mayoría de las aplicaciones Yii.

Sin escribir ni una sola linea de código, nosotros podemos probar nuestra primera aplicación Yii ingresando a la siguiente URL en un explorador Web:

http://hostname/testdrive/index.php

Como vemos, la aplicación contiene tres páginas: homepage (la página inicial), contact (página de contacto) y login (página de login de usuario). La página inicial muestra información de la aplicación y del estado del usuario logueado, la página de contacto contiene un formulario para rellenar y enviar sus consultas y la página de login de usuario permite a los mismos autenticarse para acceder a contenidos que necesitan privilegios de acceso. Mire las siguientes pantallas para más detalles.

(2)
(3)
(4)
(5)

Login page

El siguiente diagrama muestra la estructura de directorios de nuestra aplicación. Por favor mire Convencionespara una explicación detallada acerca de esta estructura.

testdrive/

index.php archivo de entrada de la aplicación Web assets/ contiene archivos de recursos públicos css/ contiene archivos CSS

images/ contiene archivos de imágenes themes/ contiene temas de la aplicación

protected/ contiene los archivos protegidos de la aplicación yiic script de linea de comandos yiic

(6)

commands/ contiene comandos 'yiic' personalizados shell/ contiene comandos 'yiic shell' personalizados components/ contiene componentes reusables

MainMenu.php clase de widget 'MainMenu'

Identity.php clase 'Identity' utilizada para autenticación views/ contiene los archivos de vistas para los widgets mainMenu.php el archivo vista para el widget 'MainMenu' config/ contiene archivos de configuración

console.php configuración aplicación consola main.php configuración de la aplicación Web

controllers/ contiene los archivos de clase de controladores SiteController.php la clase controlador predeterminada

extensions/ contiene extensiones de terceros messages/ contiene mensajes traducidos

models/ contiene archivos clase de modeloscontaining model class files

LoginForm.php el formulario modelo para la acción 'login' ContactForm.php el formulario modelo para la acción 'contact' runtime/ contiene archivos temporarios generados

views/ contiene archivos de vista de controladores y de diseño layouts/ contiene archivos de diseño

main.php el diseño default para todas las vistas

site/ contiene archivos vista para el controlador 'site' contact.php contiene la vista para la acción 'contact' index.php contiene la vista para la acción 'index' login.php contiene la vista para la acción 'login' system/ contiene archivos de vista del sistema 1. Conectandose a Base de Datos

La mayoría de las aplicaciónes Web utilizan bases de datos. Nuestra aplicación test-drive no es una excepción. Para utilizar una base de datos, primero se debe decir a la aplicación como conectarse a la misma. Esto se realiza modificando el

archivo de configuración de

aplicaciónWebRoot/testdrive/protected/config/main.php como se muestra a continuación. return array( ... 'components'=>array( ... 'db'=>array( 'connectionString'=>'sqlite:protected/data/source.db', ), ), ... );

En el ejemplo anterior agregamos la entrada db al arreglo de components (componentes) el cual indica a la aplicación que se conecte a la base de datos WebRoot/testdrive/protected/data/source.db cuando sea necesario.

Nota: Para utilizar la característica de base de datos de Yii necesitamos habilitar la extensión PHP PDO y el driver especifico de la extensión PDO. Para la

(7)

aplicación test-drive se necesitará habilitar las extensiones php_pdo y php_pdo_sqlite.

En este momento tenemos que preparar una base de datos SQLite para que la configuración anterior sea correcta. Usando alguna herramienta de administración SQLite podemos crear la base de datos con la siguiente definición de tablas:

CREATE TABLE User (

id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, username VARCHAR(128) NOT NULL,

password VARCHAR(128) NOT NULL, email VARCHAR(128) NOT NULL );

Para simplificar el ejemplo solo creamos la tabla User en nuestra base de datos. El archivo de base de datos SQLite debe ser salvado como WebRoot/testdrive/protected/data/source.db. Nota: tanto el archivo como el directorio deben tener permisos de escritura para el proceso de servidor Web como lo requiere SQLite.

2. Implementando operaciones CRUD

Ahora comienza la parte divertida. Queremos implementar las operaciones CRUD para la tabla User que acabamos de crear. Esto es una práctica común en aplicaciónes prácticas.

En vez de estar lidiando con escribir el codigo actual podemos utilizar la poderosa herramienta yiicnuevamente para automaticar la generación de codigo por nosotros. Este proceso es tambien conocido comoscaffolding. Abre una ventana de linea de comandos y executa los comando listados a continuación: % cd WebRoot/testdrive

% protected/yiic shell Yii Interactive Tool v1.0

Please type 'help' for help. Type 'exit' to quit. >> model User

generate User.php

The 'User' class has been successfully created in the following file: D:\wwwroot\testdrive\protected\models\User.php

If you have a 'db' database connection, you can test it now with: $model=User::model()->find(); print_r($model); >> crud User generate UserController.php generate create.php mkdir D:/wwwroot/testdrive/protected/views/user generate update.php generate list.php generate show.php

Crud 'user' has been successfully created. You may access it via: http://hostname/path/to/index.php?r=user

(8)

En el código anterior utilizamos el comando yiic shell para interactuar con la aplicación esqueleto. Hemos ejecutado dos comandos: model User y crud User. El primero genera la clase Modelo para la tabla Usermientras que el segundo lee el modelo User y genera el código necesario para las operaciones CRUD.

Nota: Usted se puede encontrar con errores del estilo "...could not find driver", a pesar de que el script de verificación de requerimientos le haya indicado que tiene habilitado PDO y el driver PD correspondiente. Si esto ocurre puede intentar correr la herramienta yiic de la siguiente manera:

% php -c path/to/php.ini protected/yiic.php shell

donde path/to/php.ini representa el archivo PHP ini correcto.

Vamos a disfrutar de nuestro trabajo navegando a la siguiente URL: http://hostname/testdrive/index.php?r=user

Esto nos mostrará una listado de usuarios que se encuentran como entradas de la tabla User. Como nuestra tabla se encuentra vacía en este momento no verá ningún dato.

Haga click en el enlace New User de la página. Si no estamos logueados con anterioridad se nos redireccionará a la página de login de usuario. Luego de loguearse usted verá un formulario de entrada que nos permitirá agregar un nuevo usuario a nuestra tabla. Complete el formulario y haga click en el botónCreate. Si tiene algún tipo de error de ingreso, un bonito error se le mostrará que previene que grabemos nuestro usuario hasta que no sea correcto. Volviendo a la lista de usuarios podremos ver el nuevo usuario agregado en la lista.

Repita el paso anterior para agregar más usuarios. Fijese que la lista de usuarios contiene paginación automática de los datos de usuario si agrega muchos para ser mostrados en una sola página.

Si nos logueamos como administrador utilizando admin/admin podremos ver la página de administración en la siguiente URL:

http://hostname/testdrive/index.php?r=user/admin

Esto nos mostrará una tabla de entradas de usuarios. Podemos clickear en las celdas de los titulos para ordenar los datos de acuerdo a esa columna. Este cuadro también contiene paginación en caso de que la cantidad de entradas de usuarios sea mayor a las que se muestran en una página.

Todas estas bellas características han sido creadas sin que tengamos que escribir ni una sola linea de código!

(9)
(10)

$Id: quickstart.first-app.txt 723 2009-02-21 18:14:05Z sebathi $ Modelo-Vista-Controlador (Model-View-Controller MVC)

Yii implementa el diseño de patron modelo-vista controlador (model-view-controller MVC) el cual es adoptado ampliamente en la programación Web. MVC tiene por objeto separar la lógica del negocio de las consideraciones de la interfaz de usuario para que los desarrolladores puedan modificar cada parte más fácilmente sin afectar a la otra. En MVC el modelo representa la información (los datos) y las reglas del negocio; la vista contiene elementos de la interfaz de usuario como textos, formularios de entrada; y el controlador administra la comunicación entre la vista y el modelo.

Más alla del MVC, Yii tambien introduce un front-controller llamado aplicación el cual representa el contexto de ejecución del procesamiento del pedido. La aplicación resuelve el pedido del usuario y la dispara al controlador apropiado para tratamiento futuro.

El siguiente diagrama muestra la estructura estática de una aplicación Yii" Estructura estática de aplicación Yii

(11)

1. Un flujo de tareas típico

El siguiente diagrama muestra un típico flujo de tareas de una aplicación Yii cuando resuelve un pedido de usuario:

(12)

1. Un usuario realiza un pedido con la siguiente URL http://www.example.com/index.php?r=post/show&id=1 y el servidor Web se encarga de la solicitud mediante la ejecución del script de arranque en index.php.

2. El script de entrada crea una instancia de applicación y la ejecuta.

3. La aplicación obtiene la información detallada del pedido del usuario del componente de aplicaciónrequest.

4. El controlador determina le controlador y la acción pedido con ayuda del componente de aplicación llamado urlManager. Para este ejemplo el controlador es post que refiere a la clase PostController y la acción es show que su significado es determinado por el controlador.

5. La aplicación crea una instancia del controlador pedido para resolver el pedido del usuario. El controlador determina que la acción show refiere al nombre de método actionShow en la clase controlador. Entonces crea y ejecuta los filtros asociados con esta acción (ejemplo: control de acceso, benchmarking). La acción es ejecutado si los filtros lo permiten.

6. La acción lee el modelo Post cuyo ID es 1 de la base de datos. 7. La acción realiza la vista llamada show con el modelo Post 8. La vista lee y muestra los atributos del modelo Post. 9. La vista ejecuta algunos widgets.

(13)

10.El resultado realizado es embebido en un esquema (layout). 11.La acción completa la vista realizada y se la muestra al usuario.

12.

Script de entrada

13. El script de entrada es el script de inicio y es el que se ocupa de procesar el pedido del usuario inicialmente. Es el único script PHP que el usuario puede pedir directamente para ejecutarse.

14. En la mayoría de los casos, el escript de entrada de una aplicación Yii contiene un código tán simple como el siguiente,

15. // remove the following line when in production mode 16.defined('YII_DEBUG')ordefine('YII_DEBUG',true);

17. // include Yii bootstrap file

18.require_once('path/to/yii/framework/yii.php');

19. // create application instance and run 20.$configFile='path/to/config/file.php';

21.Yii::createWebApplication($configFile)->run();

22.Este script incluye el archivo principal de Yii framework yii.php, crea la instancia de aplicación web con la configuración especificada y inicia su ejecución.

23.

1. Modo Debug

24.Una aplicación Yii puede correr en modo debug o modo producción según el valor de la constante YII_DEBUG. Por predeterminado el valor de esta constante es false lo que significa modo producción. Para correr su aplicación en modo debug defina esta constante con el valor true antes de incluir el archivo yii.php. Ejecutar aplicaciones en modo debug es menos eficienta ya que debe mantener los logs internamente. Por otro lado el modo debug es de mucha ayuda durante la etapa de desarrollo ya que provee información de debug rica cuando ocurre el error.

Aplicación (Application)

Aplicación (Application) representa la el contexto de ejecución de cada pedido a la aplicación. Su principal tarea es resolver el pedido del usuario y dispararlo al controlador apropiado para procesamiento futuro. También se utiliza como el lugar principal para configuraciones que deben estar en el nivel de aplicación. Por esta razón application es también llamado front-controller (controlador principal).

Application es creado como un singleton por el script de entrada. El singleton Application puede ser accedido en cualquier lugar mediante Yii::app().

1. Configuración de Aplicación

Por predeterminado, application es una instancia de CWebApplication. Para customizarlo normalmente se provee un archivo de configuración (o un arreglo) para inicializar los valores de sus propiedades cuando la instancia application es

(14)

creada. Una alternativa de personalizar la aplicación es extender CWebApplication.

La configuración es un arreglo de pares llave-valor (key-value). Cada par representa el nombre de una propiedad de la instancia de la aplicación y cada valor representa el valor inicial de la correspondiente propiedad. Por ejemplo, la siguiente configuración configura las propiedades name y defaultController de application.

array(

'name'=>'Yii Framework', 'defaultController'=>'site', )

Usualmente guardamos la configuración en un archivo de script PHP separado (ejemplo:protected/config/main.php). Dentro del script retornamos el arreglo de configuración como a continuación:

return array(...);

Para aplicar estas configuraciones pasamos el nombre del archivo de configuración como parametro al constructor de application o a Yii::createWebApplication() como en el siguiente ejemplo el cual es usualmente utilizado en el Script de entrada:

$app=Yii::createWebApplication($configFile);

Tip: Si la configuración de la aplicación es muy compleja, podemos dividirla en varios archivos en donde cada uno devuelve una parte del arreglo de configuración. Para eso, en el archivo de configuración llamamos a la funcion PHP include() para incluir el resto de los archivos de configuración y fusionarlos en un arreglo de configuración completo.

2. Directorio Base de Application

El directorio base de Application refiere a la ruta de directorio que contiene todos los scripts PHP sensibles de seguridad y datos de la misma. Por predeterminado es un subdirectorio llamado protected que se encuentra bajo el directorio que contiene el Script de Entrada. Puede ser modificado configurando la

propiedad basePathen la

configuración de application.

Las cosas que contiene el directorio base deben ser protegidas para que no sean accesibles por usuarios Web. Con el Apache HTTP server esto se realiza facilmente creando un archivo .htaccess dentro del directorio base. El contenido del archivo .htaccess debe ser el siguiente:

deny from all

3. Componentes de Application

Las funcionalidades de la aplicación pueden ser facilmente customizadas y enriquecidas con la arquitectura flexible de componentes. Application administra un juego de componentes de aplicación en los que cada uno implementa características específicas. Por ejemplo, appliction resuleve un pedido de usuario con la ayuda de los componentes CUrlManager y CHttpRequest.

Configurando la propiedad components de application, podemos personalizar la class y propiedades de cada uno de los componentes utilizados en application. Por ejemplo podemos configurara el componenteCMemCache para que utilice multiples servers memcache para realizar el cacheo,

array( ...

(15)

...

'cache'=>array(

'class'=>'CMemCache', 'servers'=>array(

array('host'=>'server1', 'port'=>11211, 'weight'=>60), array('host'=>'server2', 'port'=>11211, 'weight'=>40), ),

), ), )

En el ejemplo anterior agregamos el elemento cache en el arreglo components. El elemento cache define que la clase del componente será CMemCache y la propiedadservers` debe ser inicializada como lo indica.

Para acceder a un componente de application utilice Yii::app()->ComponentID, en donde ComponentIDindica el ID del componente que desea (ejemplo: Yii::app()->cache).

Un componente de aplicación puede ser deshabilitado mediante su configuración indicando la propiedadenabled con un valor false en su configuración. En el caso de intentar acceder a un componente deshabilitado, application le devolver Null. Tip: Por predeterminado, los componentes de application son creados cuando se necesitan. Esto quiere decir que los componentes no serán creados si estos no son utilizados durante el request del usuario. Como resultado de esto, la performance no se vera degradada aún si la aplicación es configuradad con muchos componentes. Algunos componentes de aplicación deben ser creados sin importar si ellos son accedidos o no. Para esto, liste los IDs en la propiedad preload de la aplicación.

4. Componentes del nucleo de Application

Yii predefine un juego de compoenentes de aplicación que proveen caracteristicas comunes en toda la aplicación Web. Por ejemplo, el componente request es usado para resolver pedidos de usuarios y proveer de información como URL, cookies. Configurando las propiedades de estos componentes podemos cambiar el comportamiento de casi todos los aspectos de Yii.

Abajo se encuentra la lista de componentes predeclarados por CWebApplication. • assetManager: CAssetManager - administra la publicación de archivos

privados.

• authManager: CAuthManager - Administra el control de acceso basado en roles (role-based access control - RBAC).

• cache: CCache - provee funcionalidad de cacheo de datos. Nota: se debe especificar la clase actual (ejemplo: CMemCache, CDbCache) o Null será retornado cuando se acceda a este componente.

• clientScript: CClientScript - Administra los scripts de cliente (javascripts y CSS).

• coreMessages: CPhpMessageSource - provee de los mensajes de nucleo traducidos utilizados por Yii framework.

• db : CDbConnection - provee la conexión a la base de datos. Nota: debe configurar la propiedadconnectionString para poder utilizar este componente.

• errorHandler: CErrorHandler - maneja los errores y excepciones PHP no advertidas.

(16)

• messages: CPhpMessageSource - Provee mensajes traducidos utilizados por la aplicación Yii.

• request: CHttpRequest - Provee información relacionada con el request. • securityManager: CSecurityManager - provee servicios relacionados con

seguridad como son hashing y encriptación.

• session: CHttpSession - provee funcionalidades relacionadas con la sesión. • statePersister: CStatePersister - provee métodos globles de persistencia

de estado.

• urlManager: CUrlManager - provee funcionalidad para parseo de URL y creación.

• user: CWebUser - representa la información de identidad del usuario actual.

• themeManager: CThemeManager - maneja temas (themes). 5. Ciclos de vida de la Aplicación

Cuando se maneja un un pedido de usuario, la aplicación realizará el siguiente ciclo de vida:

1. Configurará el autocargado de clases y el manejador de errores; 2. Registrará los componentes del nucleo de la aplicación;

3. Cargará la configuración de la aplicación;

4. Inicializará la aplicación mediante CApplication::init() • Carga de compoenentes de aplicación static; 5. Ejecuta el evento onBeginRequest;

6. Procesa el pedido de usuario:;

• Resuelve el pedido de usuario; • Crea el controlador

• Ejecuta el controlador; 7.Ejecuta el evento onEndRequest; Controlador (Controller)

Un controlador es una instancia de CController o una de las clases que lo heredan. Es creado por la aplicación cuando un usuario realiza un pedido para ese controlador. Cuando un controlador se ejecuta se realizar el pedido de la acción que utiliza los modelos necesarios y muestra la información a travez de la vista apropiada. Una acción, en su forma más simple, es un m;etodo de la clase controlador cuyo nombre comienza con action.

Un controlador tiene un a acción predeterminada. Cuando el usuario no especifica que acción se debe ejecutar, esta será la que se ejecute. Por predeterminado la acción default tiene el nombre de index. Puede ser personalizada modificando la configuración CController::defaultAction.

Abajo se encuentra el minimo código de una clase controlador. Dado que este controlador no tiene ninguna acción definida, pedirle resultará en una excepción. class SiteController extends CController

{ }

1. Ruta (Route)

Los controladores y acciones están definidas por IDs. El ID del controlador se encuentra en la forma depath/to/xyz el cual es interpretado como el archivo de clase controladorprotected/controllers/path/to/XyzController.php, donde xyz debe ser remplazada por el nombre de su controlador (ejemplo: post corresponde a protected/controllers/PostController.php). El ID de

(17)

acción es el nombre del metodo sin el prefijo action. Por ejemplo si el controlador contiene el métodoactionEdit el ID de la acción correspondiente será edit.

Nota: Antes de la versión 1.0.3, el formato del id del controlador era path.to.xyz en vez depath/to/xyz.

Los usuarios realizan pedidos por un controlador y acción en términos de ruta. Una ruta se encuentra formada por la concatenación de un ID de controlador y un ID de acción separados por una barra. Por ejemplo la rutapost/edit se refiere a PostController y a su acción edit. Por predeterminado la urlhttp://hostname/index.php?r=post/edit` realiza el pedido a el ese contlador y esa acción.

Nota: Por predeterminado las rutas distinguen mayúsculas de minúsculas. Desde la versión 1.0.1 es posible utilizar rutas que no distingan mayúsculas de minúsculas modificando en la configuración de la aplicación la propiedad CUrlManager::caseSensitive en false. Cuando esta propiedad no está activada, asegurese de seguir las convencion de que los directorios que contienen controladores deben ser llamados con minúsculas y que ambos, controller map y action map usan claves en minúsculas.

Desde la versión 1.0.3 una aplicación puede contener modules. La ruta de una acción de controlador dentro de un módulo cumple es de la forma moduleID/controllerID/actionID. Para más información y detalle vea la sección acerca de módulos.

2. Instanciación de Controlador

Una instancia de controlador es creada cuando CWebApplication maneja un pedido de usuario. Dado el ID del controlador, la aplicación utilizará las siguientes reglas para determinar cual es la clase del controlador y cual la ruta al archivo de clase.

• Si CWebApplication::catchAllRequest se encuentra especificado, el controlador será creado basado en esta propiedad y se ignorará el ID de controlador especificado por el usuario. Esto es usado mayoritariamente para dejar la aplicación en un modo de mantenimiento y muestre una página con información estática.

• Si el ID se encuentra en CWebApplication::controllerMap, la configuración de controlador correspondiente se utilizará para crear la instancia del controlador.

• Si el ID se encuentra en el formato 'path/to/xyz', la clase de controlador assumida será XyzCOntroller y el archivo de clase correspondiente será protected/controllers/path/to/XyzController.php. Por ejemplo si el ID

del controlador es admin/user será resuelto por el

controlador UserController y el archivo de

clase protected/controllers/admin/UserController.php. En caso de que el archivo de clase no exista, un error 404 CHttpException será lanzado. En el caso que se utilizen modules (disponibles desde la versión 1.0.3), El proceso descripto anteriormente es ligeramente diferente. En particular, la aplicación verificará si el ID refiere a un controlador dentro de un módulo y si esto es así, el módulo será instanciado y luego se instanciará el controlador. 3. Accion (Action)

Como lo mencionamos anteriormente una acción puede ser definida mediante su nombre y comenzando con la palabra action. Una forma más avanzada de realizar esto es definir una clase acción y pedirle al controlador que la instancie

(18)

cuando es requerida. Esto permite que las acciones sean reusadas y genera más reusabilidad.

Para definir una nueva clase acción, realice lo siguiente: class UpdateAction extends CAction

{

public function run() {

// place the action logic here }

}

Para que el controlador sepa que debe utilizar esta acción hacemos override del método actions() en nuestra clase controlador de la siguiente manera:

class PostController extends CController {

public function actions() { return array( 'edit'=>'application.controllers.post.UpdateAction', ); } }

En el ejemplo anterior usamos la ruta

alias application.controllers.post.UpdateAction para especificar que el archivo clase de la acción es protected/controllers/post/UpdateAction.php.

Escribiendo acciones basados en clases podemos organizar la applicación de manera modular. Por ejemplo, la siguiente estructura de directorios puede ser utilizada para organizar el código de los controladores:

protected/ controllers/ PostController.php UserController.php post/ CreateAction.php ReadAction.php UpdateAction.php user/ CreateAction.php ListAction.php ProfileAction.php UpdateAction.php 4. Filtros

Los filtros son una pieza de codigo que se configura para ser ejecutada antes y/o después de que una acción del controlador sea ejecutada. Por ejemplo, un filtro de control de acceso puede ser ejecutado para asegurarse de que el usuario ha sido autenticado con anterioridad antes de ejecutar cierta acción; un filtro de performance puede ser utilizado para medir el tiempo que tarda una acción en ejecutarse.

Una acción puede tener múltiples filtros. Los filtros son ejecutados en el orden en el que aparecen en la lista de filtros. Un filtro puede prevenir la ejecución de la acción y el resto de los filtros de la lista que no han sido ejecutados.

(19)

Un filtro puede ser definido como un método en la clase controlador. El nombre del método debe iniciar confilter. Por ejemplo, la existencia de un método filterAccessControl define un filtro llamado llamado `accessControl. El método de filtro debe ser definido de la siguiente manera:

public function filterAccessControl($filterChain) {

// call $filterChain->run() to continue filtering and action execution }

en donde $filterChain es una instancia de CFilterChain que representa la lista de filtro asociada con la accion pedida. Dentro del método del filtro podemos llamar a $filterChain->run() para continuar filtrando la ejecución de la acción.

A su vez, un filtro también puede ser un una instancia de CFilter o una clase que la herede. El siguiente código define una nueva clase filtro:

class PerformanceFilter extends CFilter {

protected function preFilter($filterChain) {

// logic being applied before the action is executed

return true; // false if the action should not be executed }

protected function postFilter($filterChain) {

// logic being applied after the action is executed }

}

Para aplicar filtro a acciones debemos realizar un override del método CController::filters(). El método debe devolver un arreglo de configuraciónes de filtros. Por ejemplo,

class PostController extends CController {

...

public function filters() {

return array(

'postOnly + edit, create', array(

'application.filters.PerformanceFilter - edit, create', 'unit'=>'second',

), ); } }

En el código del ejemplo anterior se especifican dos filtros: postOnly y PerformanceFilter. El filtropostOnly es un filtro basado en métodos (es decir, el filtro es un método predefinido en CController); mientras que el filtro PerformanceFilter especifica que el filtro es basado en clases y su archivo de clase filtro esprotected/filters/PerformanceFilter. Usamos un arreglo para configurar el filtro PerformanceFilterpara inicializar los valores de las

(20)

propiedades del objeto filtro. Aquí la propiedad unit delPerformanceFilter será inicializada como 'second'.

Utilizando el operador más y menos podemos especificar a qué acciones serán aplicadas y a cuales nó serán aplicadas el filtro. En el ejemplo anterior, el filtro postOnly debe ser aplicado a las acciones edit y create, mientras que el filtro PerformanceFilter debe ser aplicado a todas las acciones excepto a edit y create. Si los operadores mas y menos no aparecieran en la configuración del filtro el mismo se aplicaría a todas las acciones.

Modelo (Model)

Un modelo es una instancia de CModel y de las clases que lo heredan. Los modelos son utilizados para mantener los datos y sus reglas de negocio relevantes.

Un modelo representa un solo objeto de datos. El mismo puede ser una fila en una tabla de base de datos o un formulario de ingresos por usuario. Cada campo del objeto de datos esta representado por un atributo en el modelo. El atributo tiene una etiqueta y esta se puede validar contra un juego de reglas.

Yii implementa dos tipos de modelos: modelo de formulario y active record (registro activo). Ambos extienden de la misma clase base CModel.

Un modelo formulario es una instancia de CFormModel. El modelo formulario es utilizado para mantener la colección de datos de las entradas del usuario. Esos datos coleccionados, utilizados y descartados. Por ejemplo, en una página de login, nosotros podemos utilizar un modelo de formulario para representar la información del nombre de usuario y su contraseña que son provistas por un usuario final. Para más detalles por favor refierase a Trabajando con formularios Active Record (AR) es un patron de diseño utilizado para abstraer la base de datos de una forma orientada a objetos. Cada objeto AR es una instancia de CActiveRecord o una de las clases que lo heredan, representando una única fila de la tabla de base de datos. Los campos de la fila son representados por propiedades del objeto AR. Puede encontrar más información de AR en Active Record.

Vista (View)

Una vista es un script PHP que consiste basicamente en elementos de la interfaz de usuario (user interface - UI). La misma puede contener expresiones PHP, pero es recomendable que estas expresiones no modifiquen los datos del modelo y se mantengan relativamente simples. Para el mantener la separación de la lógica y la presentación se recomienda que la gran parte de la lógica se encuentre en el modelo y no en la vista.

Una vista tiene el mismo nombre que es utilizada para identificar un archivo script de vista cuando se presenta. El nombre de la vista es el mismo que el nombre del archivo de la vista. Por ejemplo, la vista editse refiere a el archivo script de vista llamado edit.php. Para presentar una vista llame a CController::render() con el nombre de la vista. Este método buscara la vista dentro del directorio protected/views/ControllerID.

Dentro del script de vista podemos acceder al controlador utilizando $this. De esta forma podemos pasmar cualquier propiedad del controlador en la vista evaluando $this->propertyName.

También podemos utilizar la siguiente forma de llamado a la función render del controlador para pasar datos a la vista.

$this->render('edit', array( 'var1'=>$value1,

(21)

'var2'=>$value2, ));

En el ejemplo anterior, el método render() extraera el segundo parametro array en el script de vista para que lo podamos acceder como variables locales $var1 y $var2.

1. Esquema (Layout)

El esquema o layout es un tipo de vista especial que es utilizado para decorar vistas. El mismo contiene usualmente porciones de la interfaz de usuario que son comunes a travez de muchas vistas. Por ejemplo, el esquema o layout puede contener la porción de header y footer y embeber dentro el contenido de la vista, ...header here...

<?php echo $content; ?> ...footer here...

en donde $content contiene el resultado de la presentación de la vista contenida.

El esquema o layout es aplicado implicitamente cuando se llama a la

funcion render(). Por predeterminado, el script de la

vista protected/views/layouts/main.php es utilizado como el esquema. Esto

puede ser personalizado

modificando CWebApplication::layout o CController::layout. Para presentar una vista sin aplicarle ningún esquema, llame a la funcion renderPartial() en vez de la función render().

2. Widget

Un widget es una instancia de CWidget o una clase que lo hereda. Es un componente con proposito presentacional principalmente. Los widgets son usualmente embebidos en los scripts de vista para generar interfaces de usuarios complejas y contenidas en los mismos widgets. Por ejemplo, un widget calendario puede ser utilizado para presentar una interfaz de usuario compleja de calendario. Los widgets nos ayudan a tener mayor reusabilidad de la interfaz de usuario.

Para utilizar un widget realize lo siguiente en un script de vista: <?php $this->beginWidget('path.to.WidgetClass'); ?>

...body content that may be captured by the widget... <?php $this->endWidget(); ?>

o

<?php $this->widget('path.to.WidgetClass'); ?>

El segundo se utiliza cuando el widget no necesita ninguno contenido es su cuerpo.

Los widgets pueden ser configurados para customizarse según su comportamiento. Esto es realizado mediante la configuración de sus valores de propiedades iniciales cuando se llama al métodoCBaseController::beginWidget o al método CBaseController::widget. Por ejemplo, cuando se utiliza el widgetCMaskedTextField, se puede identificar que máscara se desea utilizar. Podemos hacerlo pasandole un array con los valores de las propiedades incialmente de la siguiente forma, donde las claves del array son los nombres de las propiedades y los valores del array los vlores iniciales de las correspondientes propiedades del widget:

<?php

$this->widget('CMaskedTextField',array( 'mask'=>'99/99/9999'

(22)

)); ?>

Para definir un nuevo widget extienda CWidget y sobrecarge los métodos init() y run():

class MyWidget extends CWidget {

public function init() {

// this method is called by CController::beginWidget() }

public function run() {

// this method is called by CController::endWidget() }

}

Como un controlador el widget también puede tener sus propias vistas. Por predeterminado, los archivos de vista de un widget se encuentran dentro del subdirectorio views del directorio que contiene el archivo de clase widget. Estas vistas pueden ser presentadas llamando al método CWidget::render(), similarmente a como se realiza en un controlador. La única diferencia es que no se le aplicará ningún esquema o layout a la vista de un widget.

3. Vistas de sistema

Las vistas de sistema es la forma de referirse a las vistas utilizadas por Yii para mostrar los errores y la informaccion del logueo. Por ejemplo, cuando un se realiza un pedido de un controlador o una accion inexistente, Yii lanzará una excepción explicando el error. Yii mostrará el error utilizando la vista del sistema especifica para el mismo.

Los nombres de las vistas del sistema siguen ciertas reglas. Nombres como errorXXX refieren a vistas que muestran las CHttpException con código de error XXX. Por ejemplo, si CHttpException es lanzada con el código de error 404, la vista error404 será la que se mostrará.

Yii provee un conjunto de vistas de sistema predeterminados que se pueden localizar en framework/views. Las mismas pueden ser personalizadas creando las vistas con el mismo nombre de archivo dentro deprotected/views/system.

Component

Yii applications are built upon components which are objects written to a specification. A component is an instance of CComponent or its derived class. Using a component mainly involves accessing its properties and raising/handling its events. The base classCComponent specifies how to define properties and events.

1. Component Property

A component property is like an object's public member variable. We can read its value or assign a value to it. For example,

$width=$component->textWidth; // get the textWidth property

$component->enableCaching=true; // set the enableCaching property

To define a component property, we can simply declare a public member variable in the component class. A more flexible way, however, is by defining getter and setter methods like the following:

(23)

{

return $this->_textWidth; }

public function setTextWidth($value) {

$this->_textWidth=$value; }

The above code defines a writable property named textWidth (the name is case-insensitive). When reading the property, getTextWidth() is invoked and its returned value becomes the property value; Similarly, when writing the property, setTextWidth() is invoked. If the setter method is not defined, the property would be read-only and writing it would throw an exception. Using getter and setter methods to define a property has the benefit that additional logic (e.g. performing validation, raising events) can be executed when reading and writing the property.

Note: There is a slight difference between a property defined via getter/setter methods and a class member variable. The name of the former is case-insensitive while the latter is case-sensitive.

2. Component Event

Component events are special properties that take methods (called event handlers) as their values. Attaching (assigning) a method to an event will cause the method to be invoked automatically at the places where the event is raised. Therefore, the behavior of a component can be modified in a way that may not be foreseen during the development of the component.

A component event is defined by defining a method whose name starts with on. Like property names defined via getter/setter methods, event names are case-insensitive. The following code defines an onClicked event:

public function onClicked($event) {

$this->raiseEvent('onClicked', $event); }

where $event is an instance of CEvent or its child class representing the event parameter.

We can attach a method to this event as follows: $component->onClicked=$callback;

where $callback refers to a valid PHP callback. It can be a global function or a class method. If the latter, the callback must be given as an array: array($object,'methodName').

The signature of an event handler must be as follows: function methodName($event)

{ ... }

where $event is the parameter describing the event (it originates from the raiseEvent() call). The $eventparameter is an instance of CEvent or its derived class. At the minimum, it contains the information about who raises the event.

An event handler can also be an anonymous function which is supported by PHP 5.3 or above. For example,

(24)

$component->onClicked=function($event) { ...

}

If we call onClicked() now, the onClicked event will be raised (inside onClicked()), and the attached event handler will be invoked automatically.

An event can be attached with multiple handlers. When the event is raised, the handlers will be invoked in the order that they are attached to the event. If a handler decides to prevent the rest handlers from being invoked, it can set $event->handled to be true.

3. Component Behavior

A component supports the mixin pattern and can be attached with one or several behaviors. A behavior is an object whose methods can be 'inherited' by its attached component through the means of collecting functionality instead of specialization (i.e., normal class inheritance). A component can be attached with several behaviors and thus achieve 'multiple inheritance'.

Behavior classes must implement the IBehavior interface. Most behaviors can extend from the CBehavior base class. If a behavior needs to be attached to

a model, it may also extend

from CModelBehavior orCActiveRecordBehavior which implements additional features specifc for models.

To use a behavior, it must be attached to a component first by calling the behavior's attach() method. Then we can call a behavior method via the component:

// $name uniquely identifies the behavior in the component $component->attachBehavior($name,$behavior);

// test() is a method of $behavior $component->test();

An attached behavior can be accessed like a normal property of the component. For example, if a behavior named tree is attached to a component, we can obtain the reference to this behavior object using:

$behavior=$component->tree; // equivalent to the following:

// $behavior=$component->asa('tree');

A behavior can be temporarily disabled so that its methods are not available via the component. For example,

$component->disableBehavior($name);

// the following statement will throw an exception $component->test();

$component->enableBehavior($name); // it works now

$component->test();

It is possible that two behaviors attached to the same component have methods of the same name. In this case, the method of the first attached behavior will take precedence.

When used together with events, behaviors are even more powerful. A behavior, when being attached to a component, can attach some of its methods to some events of the component. By doing so, the behavior gets a chance to observe or change the normal execution flow of the component.

A behavior's properties can also be accessed via the component it is attached to. The properties include both the public member variables and the properties

(25)

defined via getters and/or setters of the behavior. For example, if a behavior has a property named xyz and the behavior is attached to a component $a. Then we can use the expression $a->xyz to access the behavior's property.

Module

A module is a self-contained software unit that consists of models,views, controllers and other supporting components. In many aspects, a module resembles to an application. The main difference is that a module cannot be deployed alone and it must reside inside of an application. Users can access the controllers in a module like they do with normal application controllers.

Modules are useful in several scenarios. For a large-scale application, we may divide it into several modules, each being developed and maintained separately. Some commonly used features, such as user management, comment management, may be developed in terms of modules so that they can be reused easily in future projects.

1. Creating Module

A module is organized as a directory whose name serves as its unique ID. The structure of the module directory is similar to that of the application base directory. The following shows the typical directory structure of a module named forum:

forum/

ForumModule.php the module class file

components/ containing reusable user components views/ containing view files for widgets

controllers/ containing controller class files DefaultController.php the default controller class file extensions/ containing third-party extensions models/ containing model class files

views/ containing controller view and layout files layouts/ containing layout view files

default/ containing view files for DefaultController index.php the index view file

A module must have a module class that extends from CWebModule. The class name is determined using the expression ucfirst($id).'Module', where $id refers to the module ID (or the module directory name). The module class serves as the central place for storing information shared among the module code. For example, we can use CWebModule::params to store module parameters, and use CWebModule::components to shareapplication components at the module level.

Tip: We can use the module generator in Gii to create the basic skeleton of a new module.

2. Using Module

To use a module, first place the module directory under modules of the application base directory. Then declare the module ID in the modules property of the application. For example, in order to use the above forummodule, we can use the following application configuration:

return array( ...

'modules'=>array('forum',...), ...

(26)

);

A module can also be configured with initial property values. The usage is very similar to configuring application components. For example, the forum module may have a property named postPerPage in its module class which can be configured in the application configuration as follows:

return array( ... 'modules'=>array( 'forum'=>array( 'postPerPage'=>20, ), ), ... );

The module instance may be accessed via the module property of the currently active controller. Through the module instance, we can then access information that are shared at the module level. For example, in order to access the above postPerPage information, we can use the following expression:

$postPerPage=Yii::app()->controller->module->postPerPage; // or the following if $this refers to the controller instance // $postPerPage=$this->module->postPerPage;

A controller action in a module can be accessed using the route moduleID/controllerID/actionID. For example, assuming the above forum module has a controller named PostController, we can use the routeforum/post/create to refer to the create action in this controller. The corresponding URL for this route would be http://www.example.com/index.php? r=forum/post/create.

Tip: If a controller is in a sub-directory of controllers, we can still use the

above route format. For example, assuming PostController is

under forum/controllers/admin, we can refer to thecreate action using forum/admin/post/create.

3. Nested Module

Modules can be nested in unlimited levels. That is, a module can contain another module which can contain yet another module. We call the former parent module while the latter child module. Child modules must be declared in the modules property of their parent module, like we declare modules in the application configuration shown as above.

To access a controller action in a child module, we should use the routeparentModuleID/childModuleID/controllerID/actionID.

Path Alias and Namespace

Yii uses path aliases extensively. A path alias is associated with a directory or file path. It is specified in dot syntax, similar to that of widely adopted namespace format:

RootAlias.path.to.target

where RootAlias is the alias of some existing directory.

By using YiiBase::getPathOfAlias(), an alias can be translated to its corresponding path. For example,system.web.CController would be translated as yii/framework/web/CController.

We can also use YiiBase::setPathOfAlias() to define new root path aliases. 1. Root Alias

(27)

For convenience, Yii predefines the following root aliases: • system: refers to the Yii framework directory; • zii: refers to the Zii library directory;

• application: refers to the application's base directory;

• webroot: refers to the directory containing the entry script file. • ext: refers to the directory containing all third-party extensions.

Additionally, if an application uses modules, each module will have a predefined root alias that has the same name as the module ID and refers to the module's base path. For example, if an application uses a module whose ID is users, a root alias named users will be predefined.

2. Importing Classes

Using aliases, it is very convenient to include the definition of a class. For example, if we want to include theCController class, we can call the following: Yii::import('system.web.CController');

The import method differs from include and require in that it is more efficient. The class definition being imported is actually not included until it is referenced for the first time (implemented via PHP autoloading mechanism). Importing the same namespace multiple times is also much faster than include_once andrequire_once.

Tip: When referring to a class defined by the Yii framework, we do not need to import or include it. All core Yii classes are pre-imported.

Using Class Map

Starting from version 1.1.5, Yii allows user classes to be pre-imported via a class mapping mechanism that is also used by core Yii classes. Pre-imported classes can be used anywhere in a Yii application without being explicitly imported or included. This feature is most useful for a framework or library that is built on top of Yii.

To pre-import a set of classes, the following code must be executed before CWebApplication::run() is invoked:

Yii::$classMap=array( 'ClassName1' => 'path/to/ClassName1.php', 'ClassName2' => 'path/to/ClassName2.php', ... ); 3. Importing Directories

We can also use the following syntax to import a whole directory so that the class files under the directory can be automatically included when needed.

Yii::import('system.web.*');

Besides import, aliases are also used in many other places to refer to classes. For example, an alias can be passed to Yii::createComponent() to create an instance of the corresponding class, even if the class file was not included previously. 4. Namespace

A namespace refers to a logical grouping of some class names so that they can be differentiated from other class names even if their names are the same. Do not confuse path alias with namespace. A path alias is merely a convenient way of naming a file or directory. It has nothing to do with a namespace.

Tip: Because PHP prior to 5.3.0 does not support namespace intrinsically, you cannot create instances of two classes who have the same name but with different definitions. For this reason, all Yii framework classes are prefixed with a letter 'C' (meaning 'class') so that they can be differentiated from user-defined

(28)

classes. It is recommended that the prefix 'C' be reserved for Yii framework use only, and user-defined classes be prefixed with other letters.

5. Namespaced Classes

A namespaced class refers to a class declared within a non-global namespace. For example, theapplication\components\GoogleMap class is declared within the namespace application\components. Using namespaced classes requires PHP 5.3.0 or above.

Starting from version 1.1.5, it is possible to use a namespaced class without including it explicitly. For example, we can create a new instance of application\components\GoogleMap without including the corresponding class file explicitly. This is made possible with the enhanced Yii class autoloading mechanism.

In order to be able to autoload a namespaced class, the namespace must be named in a way similar to naming a path alias. For example, the class application\components\GoogleMap must be stored in a file that can be aliased as application.components.GoogleMap.

Convenciones

Yii favorece convenciones sobre configuraciones. Siga las convencions y uno podrá crear aplicaciones Yii sofisticadas sin escribir y administrar configuraciones complejas. Obviamente Yii necesitara ser personalizado en casi cada aspecto con las configuraciones que son necesarias para su aplicación.

Abajo describimos las convenciones que recomendamos para programar en Yii. Por conveniencia asumimos que WebRoot es el directorio en el que se encuentra instalada la aplicación Yii.

1. URL

Por predeterminado Yii reconoce URLs con el siguiente formato: http://hostname/index.php?r=ControllerID/ActionID

La variable GET r refiere a la ruta que puede ser resuelta por Yii en controlador y acción. Si ActionID es omitido el controlador ejecutará la acción predeterminada (definida via CController::defaultAction); y siControllerID es omitida (o la variable r ausente), la aplicación usará el controlador predeterminado (definido via CWebApplication::defaultController).

Con la ayuda de [CUrlManager[ es posible crear y reconocer URLs mas amigables SEO comohttp://hostname/ControllerID/ActionID.html. Esta característica se cubre en detalle enAdministración URL.

2. Codigo

Yii recomienda nombrar variables, funciones y clases en camel Case lo que significa poner mayúscula en la primer letra de cada palabra y juntarlas sin espacios. Las variables y funciones deben tener su primer letra en minúscula y

para diferenciarla de los nombres de las clases

(ejemplo: $basePath, runController(),LinkPager). Para miembros de clase privado es recomendado ponerles de prefijo a sus nombres un guión bajo (underscore _) (ejemplo: $_actionsList).

Como los namespace no estan soportados por PHP anteriores a 5.3.0 es recomendado que las clases se llamen de forma única para evitar conflicto de nombres con clases de terceros. Por esta razón todas las clases de Yii framework tienen como prefijo la letra "C".

Una regla especial para las clases Controller es que deben finalizar con la palabra Controller. El ID del controlador será definido por el nombre de la clase con su primer letra en minúscula y la palabra Controllertruncada del mismo. Por

(29)

ejemplo la clase PageController tendra el ID page. Esta regla se aplica para hacer más segura la aplicación. Esta regla también hace que las URLs relacionada con los controladores sean más claras (ejemplo /index.php?r=page/index en vez de /index.php?r=PageController/index).

3. Configuración

La configuración es un arreglo de llave-valor (key-values). Cada llave (key) representa el nombre de una propiedod del objeto a configurar mientras que cada valor corresponde al valor inicial de sus propiedades. Por ejemplo: array('name'=>'My application', 'basePath'=>'./protected') incializa las propiedadesname y basePath a sis valores correspondientes del array.

Cualquier propiedad con permisos de escritura de un objeto puede ser configurada. Si no se configura las propiedades estarán inicializadas en su valor predeterminado. Cuando configuramos una propiedades recomendable leer la documentación correspondiente para darle los valores iniciales apropiadamente. 4. Archivo

Convenciones para el nombramineto y el uso de archivo dependiendo de su tipo. Archivos de clase deben ser llamados como la clase que contienen. Por ejemplo, la clase CController se encuentra en el archivo CController.php. Una clase pública es una clase que puede ser utilizada por otras clases. Cada archivo de clase debe contener al menos una clase pública. Las clases privadas (clases que solo son utilizadas por una única clase pública) deben residir en el mismo archivo que la clase pública.

Los archivos de vistas deben ser llamados con el nombre de la vista. Por ejemplo, la vista index debe encontrase en el archivo index.php. Un archivo de vista es un archivo script PHP que contiene HTML y codigo PHP principalmente con propositos de presentación.

Los archivos de configuración puede ser nombrados arbitrariamente. Un archivo de configuración es un script PHP con el solo proposito de devolver un arreglo representando la configuración.

5. Directorios

Yii asume un juego default de directorios que es utilizado para cumplir varios propositos. Cada uno de estos puede ser customizado en caso de necesitarse.

• WebRoot/protected: Este es el directorio base de aplicación el cual contiene todos los archivos de scripts PHP y de datos sensibles a la seguridad. Yii crea un alias predeterminado llamado applicationasociado con esta ruta. Este directorio y todo lo que se encuentra dentro de el debe ser protejido de poder ser accedido por los usuarios Web. Puede ser personalizado via CWebApplication::basePath.

• WebRoot/protected/runtime: Este direcotiro contiene archivos privados y temporarios generados durante el tiempo de ejecución de la aplicación. El proceso de servidor Web debe tener acceso de escritura en el mismo. Puede ser personalizado via CApplication::runtimePath.

• WebRoot/protected/extensions: Este directorio contiene todas las

extensiones de terceros. Puede ser personalizado

via CApplication::extensionPath.

• WebRoot/protected/modules: Este directorio contiene todos los módulos de la aplicación cada uno representado por un subdirectorio. • WebRoot/protected/controllers: este directorio contiene todos los archivos

de clase controlador. Puede ser personalizado

(30)

• WebRoot/protected/views: Este directorio contiene todos los archivos de vista de controladores, archivos de vista de esquema (layout) y de sistema (system). Puede ser personalizado viaCWebApplication::viewPath. • WebRoot/protected/views/ControllerID: Este directorio contiene los

archivos de vista de un solo controlador. Aquí ControllerID se modificará por el ID del controlador Puede ser personalizado viaCController::getViewPath.

• WebRoot/protected/views/layouts: Este directorio contiene todos los archivos de vista del esquema (layout). Puede ser personalizado via CWebApplication::layoutPath.

• WebRoot/protected/views/system: Este directorio contiene todos los archivos de vista de sistema (system). Los archivos de vista de sistema son templates utilizados para mostrar excepciones y errores. Puede ser personalizado via CWebApplication::systemViewPath.

• WebRoot/assets: este directorio contiene los archivos asset publicados. Un archivo asset es un archivo privado que puede ser publicado para convertirse en accesible para los usuarios Web. Este directorio debe tener permisos de escritura habilitados para el proceso de servidor Web. Puede ser modificado viaCAssetManager::basePath.

• WebRoot/themes: este directorio contiene varios temas (themes) que pueden ser aplicados a la aplicación. Cada subdirectorio representa a un solo tema (theme) cuyo nombre es el snombre de ese subdirectorio. Puede ser customizado via CThemeManager::basePath.

Development Workflow

Having described the fundamental concepts of Yii, we show the common workflow for developing a web application using Yii. The workflow assumes that we have done the requirement analysis as well as the necessary design analysis for the application.

1. Create the skeleton directory structure. The yiic tool described in Creating First Yii Application can be used to speed up this step.

2. Configure the application. This is done by modifying the application configuration file. This step may also require writing some application components (e.g. the user component).

3. Create a model class for each type of data to be managed. The Gii tool described in Creating First Yii Application and in Automatic Code Generation can be used to automatically generate the active recordclass for each interested database table.

4. Create a controller class for each type of user requests. How to classify user requests depends on the actual requirement. In general, if a model class needs to be accessed by users, it should have a corresponding controller class. The Gii tool can automate this step, too.

5. Implement actions and their corresponding views. This is where the real work needs to be done.

6. Configure necessary action filters in controller classes. 7. Create themes if the theming feature is required.

8. Create translated messages if internationalization is required.

9. Spot data and views that can be cached and apply appropriate caching techniques.

10.Final tune up and deployment.

(31)

Working with Form

Collecting user data via HTML forms is one of the major tasks in Web application development. Besides designing forms, developers need to populate the form with existing data or default values, validate user input, display appropriate error messages for invalid input, and save the input to persistent storage. Yii greatly simplifies this workflow with its MVC architecture.

The following steps are typically needed when dealing with forms in Yii: 1. Create a model class representing the data fields to be collected; 2. Create a controller action with code that responds to form submission. 3. Create a form in the view script file associated with the controller action. In the next subsections, we describe each of these steps in detail.

Creating Model

Before writing the HTML code needed by a form, we should decide what kind of data we are expecting from end users and what rules these data should comply with. A model class can be used to record these information. A model, as defined in the Model subsection, is the central place for keeping user inputs and validating them.

Depending on how we make use of the user input, we can create two types of model. If the user input is collected, used and then discarded, we would create a form model; if the user input is collected and saved into database, we would use an active record instead. Both types of model share the same base class CModel which defines the common interface needed by form.

Note: We are mainly using form models in the examples of this section. However, the same can also be applied to active record models.

1. Defining Model Class

Below we create a LoginForm model class used to collect user input on a login page. Because the login information is only used to authenticate the user and does not need to be saved, we create LoginForm as a form model.

class LoginForm extends CFormModel {

public $username; public $password;

public $rememberMe=false; }

Three attributes are declared

in LoginForm: $username, $password and $rememberMe. They are used to keep the user-entered username and password, and the option whether the user wants to remember his login. Because $rememberMe has a default value false, the corresponding option when initially displayed in the login form will be unchecked.

Info: Instead of calling these member variables properties, we use the name attributes to differentiate them from normal properties. An attribute is a property that is mainly used to store data coming from user input or database. 2. Declaring Validation Rules

Once a user submits his inputs and the model gets populated, we need to make sure the inputs are valid before using them. This is done by performing validation of the inputs against a set of rules. We specify the validation rules in the rules() method which should return an array of rule configurations.

class LoginForm extends CFormModel {

(32)

public $username; public $password;

public $rememberMe=false; private $_identity;

public function rules() {

return array(

array('username, password', 'required'), array('rememberMe', 'boolean'),

array('password', 'authenticate'), );

}

public function authenticate($attribute,$params) {

$this->_identity=new UserIdentity($this->username,$this->password); if(!$this->_identity->authenticate())

$this->addError('password','Incorrect username or password.'); }

}

The above code specifies that username and password are both required, password should be authenticated, and rememberMe should be a boolean.

Each rule returned by rules() must be of the following format:

array('AttributeList', 'Validator', 'on'=>'ScenarioList', ...additional options)

where AttributeList is a string of comma-separated attribute names which need to be validated according to the rule; Validator specifies what kind of validation should be performed; the on parameter is optional which specifies a list of scenarios where the rule should be applied; and additional options are name-value pairs which are used to initialize the corresponding validator's property values.

There are three ways to specify Validator in a validation rule. First, Validator can be the name of a method in the model class, like authenticate in the above example. The validator method must be of the following signature:

/**

* @param string $attribute the name of the attribute to be validated * @param array $params options specified in the validation rule */

public function ValidatorName($attribute,$params) { ... }

Second, Validator can be the name of a validator class. When the rule is applied, an instance of the validator class will be created to perform the actual validation. The additional options in the rule are used to initialize the instance's attribute values. A validator class must extend from CValidator.

Third, Validator can be a predefined alias to a validator class. In the above example, the name required is the alias to CRequiredValidator which ensures the attribute value being validated is not empty. Below is the complete list of predefined validator aliases:

Referencias

Documento similar

As defined in iJOIN, the NEO module is in charge of managing the energy savings that can be achieved in the over- all cellular network. Thus, the NEO module runs the

MD simulations in this and previous work has allowed us to propose a relation between the nature of the interactions at the interface and the observed properties of nanofluids:

In addition to traffic and noise exposure data, the calculation method requires the following inputs: noise costs per day per person exposed to road traffic

To delete mail messages, select the folder in which the messages are stored in, and in the top right display panel where the list of messages are displayed, select

Instrument Stability is a Key Challenge to measuring the Largest Angular Scales. White noise of photon limited detector

Foreground segmentation. This module does the foreground object extraction task. Foreground extraction is performed using an approach similar to the one of the semantic

On the road to the Preliminary Design Review of the MAORY.. adaptive optics module

The information stored in each input module is (i) the associated burst target output fiber, burst offset, burst length and QoS class, (ii) the information about burst allocation,