<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>HiperGalaxia &#187; MVC</title>
	<atom:link href="http://www.hipergalaxia.org/blog/tag/mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.hipergalaxia.org/blog</link>
	<description>El conocimiento, la frontera final.</description>
	<lastBuildDate>Sun, 05 Feb 2012 03:52:47 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Los controladores en Yii</title>
		<link>http://blog.jorgeivanmeza.com/2010/01/los-controladores-en-yii-2/</link>
		<comments>http://blog.jorgeivanmeza.com/2010/01/los-controladores-en-yii-2/#comments</comments>
		<pubDate>Sat, 02 Jan 2010 05:45:56 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=2262</guid>
		<description><![CDATA[Introducción.
Estos se ubican entre el usuario y la aplicación.  Su función es la de controlar la comunicación entre los modelos y la vistas según la solicitud (requerimiento) que ha hecho usuario.
Su clase base es CController y en ellos se implementan Acciones (definen la lógica de la aplicación) y Filtros (establecen validaciones o controles antes y [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Estos se ubican entre el usuario y la aplicación.  Su función es la de controlar la comunicación entre los modelos y la vistas según la solicitud (requerimiento) que ha hecho usuario.</p>
<p>Su clase base es <span style="font-family: courier new,courier;">CController</span> y en ellos se implementan <strong>Acciones</strong> (definen la lógica de la aplicación) y <strong>Filtros</strong> (establecen validaciones o controles antes y después de la ejecución de las acciones).</p>
<p>El usuario invoca indirectamente a los controladores especificando un <strong>ruta</strong> a través del controlador frontal o <span style="font-family: courier new,courier;">Application</span>.</p>
<h2>La ruta del requerimiento.</h2>
<p>El URL solicitado determina que controlador y que acción se van a ejecutar para resolver el requerimiento del usuario.</p>
<p>Los URL tienen el siguiente formato.</p>
<p style="padding-left: 30px;">Sin <em>URL limpias</em> (por defecto).</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">http://servidor/index.php?r=ControladorId/AcciónId</span></p>
<p style="padding-left: 30px;">Con <em>URL limpias</em>.</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">http://servidor/ControladorId/AcciónId</span></p>
<p style="padding-left: 30px;">Si se utilizan módulos (y <em>URL limpias</em> para este ejemplo).</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">http://servidor/MóduloId/ControladorId/AcciónId</span></p>
<ul>
<li>El archivo fuente del controlador se ubica en <span style="font-family: courier new,courier;">protected/controllers/<strong>ControladorId</strong>Controller.php</span>.</li>
<li>El nombre de la clase allí contenida deberá ser <span style="font-family: courier new,courier;"><strong>ControladorId</strong>Controller</span>.</li>
<li>Se invoca a la acción (ver mas adelante) <span style="font-family: courier new,courier;">AcciónId</span>.  En caso de no haberse especificado una se considera la acción por defecto del controlador, comúnmente <span style="font-family: courier new,courier;">index</span>.</li>
</ul>
<h2>Las acciones.</h2>
<p>Pueden implementarse de dos maneras.</p>
<ul>
<li>Como métodos del mismo controlador.</li>
<li>Como clases que heredan de <span style="font-family: courier new,courier;">CAction</span>.</li>
</ul>
<h3>Acciones implementadas como métodos del controlador.</h3>
<ul>
<li>El nombre del método deberá ser <span style="font-family: courier new,courier;">action<strong>AcciónId</strong></span>.</li>
</ul>
<p>En el siguiente ejemplo se muestra al controlador <span style="font-family: courier new,courier;">User</span> que implementa la acción <span style="font-family: courier new,courier;">add</span> como un método suyo.</p>
<pre class="php">class UserController extends CController
{
    public function actionAdd()
    {
        // Implementación ...
    }
}</pre>
<h3>Acciones implementadas como clases independientes.</h3>
<ul>
<li>Los objetos acción heredan de <span style="font-family: courier new,courier;">CAction</span>.</li>
<li>El nombre de la clase es <span style="font-family: courier new,courier;"><strong>AcciónId</strong>Action</span> (por convención, no es obligatorio).</li>
<li>Se almacena en un archivo bajo la ruta <span style="font-family: courier new,courier;">protected/controllers/<strong>controladorId</strong>/<strong>AcciónId</strong>Action.php.</span></li>
<li>Su ubicación puede referenciarse mediante alias de esta manera: <span style="font-family: courier new,courier;">application.controllers.<strong>controladorId</strong>.<strong>AcciónId</strong>Action</span>.</li>
<li>Es obligatorio sobreescribir el método <span style="font-family: courier new,courier;">run()</span> de la acción para definir allí su implementación.</li>
</ul>
<p>En el siguiente código se muestra la acción <span style="font-family: courier new,courier;">remove</span> del controlador <span style="font-family: courier new,courier;">User</span> implementada como una clase independiente.</p>
<pre class="php">class RemoveAction extends CAction
{
    public function run()
    {
        // Implementación ...
    }
}</pre>
<p>Esta clase se almacena entonces en el archivo <span style="font-family: courier new,courier;">protected/controllers/user/RemoveAction.php</span>.</p>
<p>Como paso final de su implementación, es necesario indicarle al controlador de la existencia de la acción.  Para hacer esto es necesario sobreescribir el método <span style="font-family: courier new,courier;">actions</span> del controlador de la siguiente manera.</p>
<pre class="php">class UserController extends CController
{
   public function actions()
   {
       return array(
           'remove' =&gt; 'application.controllers.user.RemoveAction'
       );
   }
}</pre>
<h2>Los filtros.</h2>
<ul>
<li>Permiten realizar verificaciones y validaciones antes y después de la ejecución de las acciones.</li>
<li>Una acción puede tener asociados múltiples filtros.</li>
<li>Los filtros se ejecutan en el orden en que fueron especificados.</li>
<li>Un filtro puede abortar la ejecución de los demás filtros y de la acción misma.</li>
<li>De manera análoga a las acciones, los filtros pueden implementarse de dos maneras también.
<ul>
<li>Como métodos del mismo controlador.</li>
<li>Como clases que heredan de <span style="font-family: courier new,courier;">CFilter</span>.</li>
</ul>
</li>
</ul>
<h3>Filtros implementados como métodos del controlador.</h3>
<ul>
<li>El nombre del método debe empezar por la palabra <span style="font-family: courier new,courier;">filter</span>.</li>
<li>Deberá recibir como parámetro a <span style="font-family: courier new,courier;">$filterChain</span>.</li>
</ul>
<p>En el siguiente ejemplo se muestra al controlador <span style="font-family: courier new,courier;">User</span> que implementa al filtro <span style="font-family: courier new,courier;">checkUser</span> como un método suyo.</p>
<pre class='php'>class UserController extends CController
{
    public function filterCheckUser($filterChain)
    {
        // Implementación ... invocar $filterChain -&gt; run()
        // para continuar con el próximo filtro
    }
}</pre>
<h3>Filtros implementados como clases independientes.</h3>
<ul>
<li>Los objetos acción heredan de <span style="font-family: courier new,courier;">CFilter</span>.</li>
<li>El nombre de la clase es <span style="font-family: courier new,courier;"><strong>FiltroId</strong>Filter</span> (por convención, no es obligatorio).</li>
<li>Se almacena en un archivo bajo la ruta <span style="font-family: courier new,courier;">protected/filters/<strong>FiltroId</strong>Filter.php</span>.</li>
<li>Su ubicación puede referenciarse mediante alias de esta manera: <span style="font-family: courier new,courier;">application.filters.<strong>FiltroId</strong>Filter</span>.</li>
<li>Es obligatorio sobreescribir los métodos <span style="font-family: courier new,courier;">preFilter($filterChain)</span> y <span style="font-family: courier new,courier;">postFilter($filterChain)</span> del filtro para definir que hacer antes y después de ejecutar la acción.</li>
</ul>
<p>En el siguiente código se muestra al filtro <span style="font-family: courier new,courier;">isValid</span> del controlador <span style="font-family: courier new,courier;">User</span> implementado como una clase independiente.</p>
<pre class='php'>class IsValidFilter extends CFilter
{
    public $admin;

    public function preFilter($filterChain)
    {
        // Se aplica antes de ejecutarse la acción.
        // Si retorna true continúa el proceso, false lo
        // aborta y no se ejecuta la acción solicitada.

        return $exito;
    }

    public function postFilter($filterChain)
    {
        // Se aplica después de ejecutarse la acción.
    }
}</pre>
<p>Esta clase se almacena entonces en el archivo <span style="font-family: courier new,courier;">protected/filters/IsValidFilter.php</span>.</p>
<p>Como paso final de su implementación, es necesario indicarle al controlador de la existencia del filtro y determinar su alcance sobre las acciones del mismo.  Para hacer esto es necesario sobreescribir el método <span style="font-family: courier new,courier;">filters</span> del controlador de la siguiente manera.</p>
<pre class='php'>class UserController extends CController
{
   public function filters()
   {
       return array(
           'checkUser + add, remove',

           array(
               'application.filters.IsValidFilter - add, remove',
               'admin' =&gt; false
           )
       );
   }
}</pre>
<ul>
<li><span style="font-family: courier new,courier;">checkUser</span> es un filtro basado en un método del controlador.</li>
<li><span style="font-family: courier new,courier;">isValid</span> es un filtro basado en una clase externa.</li>
<li>Es posible especificar los filtros con una notación de arreglo para determinar valores específicos para los atributos del filtro.</li>
</ul>
<p>Los operadores <span style="font-family: courier new,courier;">+</span> y <span style="font-family: courier new,courier;">-</span> actúan como determinadores del alcance de los filtros sobre las acciones especificadas de la siguiente manera.</p>
<ul>
<li><span style="font-family: courier new,courier;">+</span> determina exactamente a cuales acciones se les debe aplicar el filtro.  De esta manera, el filtro <span style="font-family: courier new,courier;">checkUser</span> se aplicará a las acciones <span style="font-family: courier new,courier;">add</span> y <span style="font-family: courier new,courier;">remove</span> únicamente.</li>
<li><span style="font-family: courier new,courier;">-</span> determina a cuales acciones NO se les debe aplicar el filtro.  Así, el filtro <span style="font-family: courier new,courier;">isValid</span> se aplicará a todas las acciones EXCEPTO a <span style="font-family: courier new,courier;">add</span> y <span style="font-family: courier new,courier;">remove</span>.</li>
<li>Si no se especifica ninguno de los dos modificadores, el filtro aplicará a todas las acciones del controlador.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Documentation: controllers.<br />
<a href="http://www.yiiframework.com/doc/guide/basics.controller" >http://www.yiiframework.com/doc/guide/basics.controller</a></li>
<li>Yii PHP Framwork.<br />
<a href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2010/01/los-controladores-en-yii-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Experimentando con Yii y DAO: manipulando formularios y registros simples</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/experimentando-con-yii-y-dao-manipulando-formularios-y-registros-simples/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/experimentando-con-yii-y-dao-manipulando-formularios-y-registros-simples/#comments</comments>
		<pubDate>Tue, 21 Jul 2009 04:03:27 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Sqlite]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1923</guid>
		<description><![CDATA[Introducción.
El día de hoy amanecí con ganas de seguir experimentando con Yii.  Al ya tener documentado el acceso a la base de datos a través de DAO y todo el manejo de los formularios es hora de probar la teoría con algo un poco mas elaborado.
El experimento de hoy consiste en crear una tabla de [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>El día de hoy amanecí con ganas de seguir experimentando con Yii.  Al ya tener documentado el <a href="http://blog.jorgeivanmeza.com/2009/07/data-access-objects-dao-con-yii/" >acceso a la base de datos a través de DAO</a> y todo el <a href="http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-definicion-y-asignacion-de-atributos/" >manejo de los formularios</a> es hora de probar la teoría con algo un poco mas elaborado.</p>
<p>El experimento de hoy consiste en crear una tabla de Usuarios (nombre de usuario, contraseña y edad) y un formulario que permita su administración (agregar, editar, listar y remover), utilizando por supuesto formularios basados en <span style="font-family: courier new,courier;">CFormModel</span> y el acceso a la base de datos con <span style="font-family: courier new,courier;">CDbCommand</span>.</p>
<div id="attachment_1930" class="wp-caption aligncenter" style="width: 435px"><a href="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/07/Screenshot_0.1.png"><img class="size-full wp-image-1930" title="Screenshot_0.1" src="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/07/Screenshot_0.1.png" alt="Screenshot_0.1" width="425" height="476" /></a><p class="wp-caption-text">Vista del formulario de la versión 0.1</p></div>
<p style="text-align: center;">
<h2>Instalación preliminar.</h2>
</p><p>Mi equipo utiliza Linux Ubuntu 9.04 por lo que algunos procedimientos son particulares al estilo *nix, en especial los relacionados con la instalación de paquetes y el manejo de la línea de comando, y será necesario realizar ajustes específicos si se desea utilizarlos en Windows.</p>
<ul>
<li>Realicé la instalación de Apache y PHP (con soporte para SQLite 3.x) de acuerdo con los <a href="http://blog.jorgeivanmeza.com/2009/02/instalacion-de-apache-mysql-y-php-en-linux-ubuntu/" >pasos establecidos anteriormente</a>.</li>
<li>Realicé la instalación del framework de Yii versión 1.0.7 sin modificaciones significativas a lo <a href="http://blog.jorgeivanmeza.com/2009/03/instalacion-y-primera-prueba-de-yii/" >establecido anteriormente</a>.  La estructura inicial de directorios es la siguiente.</li>
</ul>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">/home/web              Directorio base de los archivos relacionados con web.<br />
</span></p>
<p style="padding-left: 60px;"><span style="font-family: courier new,courier;">/yii               Directorio de distribuciones de Yii.<br />
</span></p>
<p style="padding-left: 90px;"><span style="font-family: courier new,courier;">/1.0.7         Distribución 1.0.7 de Yii.<br />
</span></p>
<p style="padding-left: 90px;"><span style="font-family: courier new,courier;">/current       Enlace dinámico a la distribución mas reciente de Yii.<br />
</span>
</p>
<p style="padding-left: 60px;"><span style="font-family: courier new,courier;">/public </span><span style="font-family: courier new,courier;">Directorio público (<em>Document Root</em>).</span></p>
<p style="padding-left: 90px;"><span style="font-family: courier new,courier;">/YiiDaoDemo    Directorio base de la aplicación de prueba.<br />
</span></p>
<p>Para facilidad en el acceso de la aplicación <span style="font-family: courier new,courier;">yiic</span> se realizó también el siguiente ajuste al final <span style="font-family: courier new,courier;">~/.profile</span>.
</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">PATH=$PATH:/home/web/yii/current/framework<br />
export PATH</span></p>
<h2>Creación de los archivos base de la aplicación.</h2>
<p><span style="font-family: courier new,courier;">$ cd /home/web/public</span></p>
<p><span style="font-family: courier new,courier;">$ yiic webapp YiiDaoDemo</span>
</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">Create a Web application under '/home/web/public/YiiDaoDemo'? [Yes|No] <strong>Yes</strong><br />
mkdir /home/web/public/YiiDaoDemo<br />
mkdir /home/web/public/YiiDaoDemo/protected<br />
mkdir /home/web/public/YiiDaoDemo/protected/views<br />
mkdir /home/web/public/YiiDaoDemo/protected/views/system<br />
generate protected/views/system/.yii<br />
mkdir /home/web/public/YiiDaoDemo/protected/views/layouts<br />
generate protected/views/layouts/main.php<br />
mkdir /home/web/public/YiiDaoDemo/protected/views/site<br />
generate protected/views/site/login.php<br />
generate protected/views/site/contact.php<br />
generate protected/views/site/index.php<br />
generate protected/yiic.bat<br />
mkdir /home/web/public/YiiDaoDemo/protected/controllers<br />
generate protected/controllers/SiteController.php<br />
generate protected/yiic.php<br />
mkdir /home/web/public/YiiDaoDemo/protected/components<br />
mkdir /home/web/public/YiiDaoDemo/protected/components/views<br />
generate protected/components/views/mainMenu.php<br />
generate protected/components/UserIdentity.php<br />
generate protected/components/MainMenu.php<br />
mkdir /home/web/public/YiiDaoDemo/protected/runtime<br />
generate protected/runtime/.yii<br />
mkdir /home/web/public/YiiDaoDemo/protected/messages<br />
generate protected/messages/.yii<br />
mkdir /home/web/public/YiiDaoDemo/protected/config<br />
generate protected/config/main.php<br />
generate protected/config/console.php<br />
mkdir /home/web/public/YiiDaoDemo/protected/models<br />
generate protected/models/LoginForm.php<br />
generate protected/models/ContactForm.php<br />
mkdir /home/web/public/YiiDaoDemo/protected/extensions<br />
generate protected/extensions/.yii<br />
generate protected/.htaccess<br />
mkdir /home/web/public/YiiDaoDemo/protected/commands<br />
mkdir /home/web/public/YiiDaoDemo/protected/commands/shell<br />
generate protected/commands/shell/.yii<br />
generate protected/yiic<br />
mkdir /home/web/public/YiiDaoDemo/themes<br />
mkdir /home/web/public/YiiDaoDemo/themes/classic<br />
mkdir /home/web/public/YiiDaoDemo/themes/classic/views<br />
mkdir /home/web/public/YiiDaoDemo/themes/classic/views/system<br />
generate themes/classic/views/system/.yii<br />
mkdir /home/web/public/YiiDaoDemo/themes/classic/views/layouts<br />
generate themes/classic/views/layouts/.yii<br />
generate themes/classic/views/.htaccess<br />
mkdir /home/web/public/YiiDaoDemo/themes/classic/views/site<br />
generate themes/classic/views/site/.yii<br />
mkdir /home/web/public/YiiDaoDemo/css<br />
generate css/bg.gif<br />
generate css/form.css<br />
generate css/main.css<br />
mkdir /home/web/public/YiiDaoDemo/images<br />
generate images/.yii<br />
generate index.php<br />
mkdir /home/web/public/YiiDaoDemo/assets<br />
generate assets/.yii</span></p>
<p>Your application has been created successfully under /home/web/public/YiiDaoDemo.</p>
<h2>Creación y configuración de la base de datos.</h2>
<p><span style="font-family: courier new,courier;">$ mkdir -p YiiDaoDemo/protected/data</span></p>
<p><span style="font-family: courier new,courier;">$ cd YiiDaoDemo/protected</span></p>
<p><span style="font-family: courier new,courier;">$ vi data/script.sql</span></p>
<pre class="sql">CREATE TABLE usuario
(
 username        CHAR(16)        NOT NULL,
 contrasena      CHAR(32)        NOT NULL,
 edad            INT             ,

 PRIMARY KEY(username)
);</pre>
<p><span style="font-family: courier new,courier;">$ sqlite3 data/basededatos.db &lt; data/script.sql</span></p>
<p><span style="font-family: courier new,courier;">$ chown -R www-data data</span></p>
<p><span style="font-family: courier new,courier;">$ ls -l data<br />
</span>
</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">-rw-r--r-- 1 www-data jimezam 3072 2009-07-20 15:16 basededatos.db<br />
-rw-r--r-- 1 www-data jimezam  126 2009-07-20 15:16 script.sql</span></p>
<p><span style="font-family: courier new,courier;">$ vi config/main.php</span></p>
<pre class="php">return array(
    // ...
    // application components
    'components'=&gt;array(
        //...
        'db'=&gt;array(
            'connectionString'=&gt;'sqlite:protected/data/basededatos.db',
        ),
        //...</pre>
<h2>Creación del modelo para el formulario (<span style="font-family: courier new,courier;">UsuarioForm</span>).</h2>
<ul>
<li>Al ser un modelo para manejar la información proveniente de informulario, hereda de <span style="font-family: courier new,courier;">CFormModel</span>.
<pre class="php">class UsuarioForm extends CFormModel
{
    // ...
}</pre>
</li>
<li>Se almacena en el archivo <span style="font-family: courier new,courier;">YiiDaoDemo/protected/models/UsuarioForm.php</span>.</li>
<li>Incluye los siguientes atributos de acuerdo con su contenido.
<pre class="php">public $username;     /* Nombre de usuario */
public $contrasena;   /* Contraseña del usuario */
public $contrasena2;  /* Confirmación de la contraseña */
public $edad;         /* Edad del usuario */</pre>
</li>
<li>Se definen las siguientes etiquetas para cada uno de los atributos descritos anteriormente.
<pre class="php">public function attributeLabels()
{
    return array(
        'username'    =&gt; 'Nombre de usuario',
        'contrasena'  =&gt; 'Contraseña',
        'contrasena2' =&gt; 'Contraseña (repetir)',
        'edad'        =&gt; 'Edad'
    );
}</pre>
</li>
<li>Se establecen las restricciones de validación para cada uno de los atributos.
<pre class="php">public function rules()
{
    return array (
        array('username, contrasena, contrasena2, edad', 'required'),
        array('edad', 'numerical', 'integerOnly' =&gt; true),
        array('contrasena', 'compare', 'compareAttribute' =&gt; 'contrasena2'),
        array('username', 'length', 'max' =&gt; 16),
        array('contrasena', 'length', 'max' =&gt; 16),
        array('contrasena2', 'length', 'max' =&gt; 16)
    );
}</pre>
</li>
</ul>
<h2>Creación de la vista del formulario.</h2>
<ul>
<li>Será manejada por el modelo <span style="font-family: courier new,courier;">UsuarioForm</span>.</li>
<li>Contiene dos partes generales.
<ol>
<li>Un formulario que permite ingresar la información del Usuario para después agregarlo o editar su contenido de la base de datos.</li>
<li>Un listado de los usuarios registrados en la base de datos desde el cual es posible remover los usuarios marcados o editar la información del usuario elegido.</li>
</ol>
</li>
<li>Es la única vista de la aplicación así que será la vista de la acción <span style="font-family: courier new,courier;">index</span> del controlador (<span style="font-family: courier new,courier;">AdminUsuario</span>) a definirse próximamente.</li>
<li>Se almacena en el archivo <span style="font-family: courier new,courier;">YiiDaoDemo/protected/views/adminUsuario/index.php</span>.</li>
<li>En la parte superior se muestran los mensajes <em>flash</em> provenientes de otras acciones.  Esto es útil para mostrar mensajes de error o éxito como "registro insertado".
<pre class="php">&lt;h1&gt;Administración de usuarios&lt;/h1&gt;

&lt;?php if(Yii::app() -&gt; user -&gt; hasFlash('mensajeEstado')):?&gt;
&lt;div style="color: #0000FF"&gt;
 &lt;?php echo Yii::app() -&gt; user -&gt; getFlash('mensajeEstado'); ?&gt;
&lt;/div&gt;
&lt;?php endif; ?&gt;</pre>
</li>
<li>La primera parte del formulario permite manipular la información del Usuario.
<pre class="html">&lt;h2&gt;Datos del usuario&lt;/h2&gt;

&lt;!-- Abre el formulario especificando su ACTION y METHOD --&gt;
&lt;?php echo CHtml::beginForm(CHtml::normalizeUrl(array('adminUsuario/index')), 'post'); ?&gt;  

&lt;div class='formulario'&gt;  

 &lt;!-- Muestra los mensajes de error asociados al modelo UsuarioForm --&gt;
 &lt;!-- El objeto $usuarioForm es enviado desde el controlador --&gt;
 &lt;?php echo CHtml::errorSummary($usuarioForm); ?&gt;  

 &lt;!-- Se genera el formulario con las etiquetas y valores asociados al modelo UsuarioForm --&gt;
 &lt;table&gt;
 &lt;tr&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeLabel($usuarioForm, 'username'); ?&gt;&lt;/td&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeTextField($usuarioForm, 'username'); ?&gt; &lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeLabel($usuarioForm, 'contrasena'); ?&gt;&lt;/td&gt;
     &lt;td&gt;&lt;?php echo CHtml::activePasswordField($usuarioForm, 'contrasena'); ?&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeLabel($usuarioForm, 'contrasena2'); ?&gt;&lt;/td&gt;
     &lt;td&gt;&lt;?php echo CHtml::activePasswordField($usuarioForm, 'contrasena2'); ?&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;tr&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeLabel($usuarioForm, 'edad'); ?&gt;&lt;/td&gt;
     &lt;td&gt;&lt;?php echo CHtml::activeTextField($usuarioForm, 'edad'); ?&gt;&lt;/td&gt;
 &lt;/tr&gt;
 &lt;/table&gt;

 &lt;br /&gt;

 &lt;!-- Genera el botón de enviar el cual cumplirá funciones de Agregar y Editar --&gt;
 &lt;!-- según exista o no el registro en la base de datos --&gt;
 &lt;div class='acciones'&gt;
     &lt;?php echo CHtml::submitButton('Enviar', array('id' =&gt; 'enviar')); ?&gt;
 &lt;/div&gt;  

&lt;/div&gt;  

&lt;!-- Cierra el formulario --&gt;
&lt;?php echo CHtml::endForm(); ?&gt;</pre>
</li>
<li>La segunda parte muestra un listado de los usuarios registrados en la base de datos con botones para las siguientes acciones.
<ul>
<li>Remover: eliminar de la base de datos a los usuarios cuyos registros se encuentren señalados con la <em>marca</em>.</li>
<li>Editar: editar la información del usuario correspondiente a la fila elegida.
<pre class="html">&lt;h2&gt;Listado de usuarios registrados&lt;/h2&gt;

&lt;!-- Abre el formulario especificando su ACTION y METHOD --&gt;
&lt;?php echo CHtml::beginForm(CHtml::normalizeUrl(array('adminUsuario/editar')), 'post'); ?&gt;

&lt;!-- Crea un campo oculto para guardar el ID del registro a editarse --&gt;
&lt;?php echo CHtml::hiddenField('UsuarioForm[elemento]', '', array()); ?&gt;

&lt;!-- Genera el listado de los usuarios registrados --&gt;
&lt;table style='border: 1px solid #FF0000;'&gt;
&lt;tr style='background-color: pink; text-align: center; font-weight: bold;'&gt;
    &lt;td&gt;Marcas&lt;/td&gt;
    &lt;td&gt;Username&lt;/td&gt;
    &lt;td&gt;Edad&lt;/td&gt;
    &lt;td&gt;Opciones&lt;/td&gt;
&lt;/tr&gt;

&lt;!-- El listado de $usuarios es enviado por el controlador a la vista --&gt;
&lt;?php $i = 0; ?&gt;
&lt;?php foreach($usuarios as $usuario): ?&gt;
&lt;tr&gt;
    &lt;!-- Crea el checkbox marca[$i], no seleccionado y cuyo valor es el nombre del usuario asociado --&gt;
    &lt;td style='text-align: center;'&gt;
        &lt;?= CHtml::checkBox("UsuarioForm[marca][{$i}]", false, array('value' =&gt; $usuario['username'])); ?&gt;
    &lt;/td&gt;

    &lt;!-- Nombre del usuario --&gt;
    &lt;td&gt;&lt;?= $usuario['username']; ?&gt;&lt;/td&gt;

    &lt;!-- Edad del usuario --&gt;
    &lt;td style='text-align: center;'&gt;&lt;?= $usuario['edad']; ?&gt;&lt;/td&gt;

    &lt;!-- Botón de editar del usuario asociado --&gt;
    &lt;!-- Al presionarse actualiza el valor del campo oculto 'elemento' con el --&gt;
    &lt;!-- el nombre del usuario asociado para la edición --&gt;
    &lt;td&gt;&lt;?= CHtml::submitButton('Editar', array(
        'onClick' =&gt; "document.getElementById('UsuarioForm_elemento').value = '{$usuario['username']}'"
    )); ?&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;?php $i++; ?&gt;
&lt;?php endforeach; ?&gt;
&lt;/table&gt;

&lt;br /&gt;

&lt;!-- Botón para remover los usuarios seleccionados --&gt;
&lt;!-- Al presionarse actualiza el ACTION del formulario para ser manejado por la --&gt;
&lt;!-- acción correcta del controlador --&gt;
&lt;?= CHtml::submitButton('Remover', array(
    'onClick' =&gt; "document.getElementById('formListado').action = '" . CHtml::normalizeUrl(array('adminUsuario/remover')) . "'"
)); ?&gt;

&lt;!-- Cierra el formulario --&gt;
&lt;?php echo CHtml::endForm(); ?&gt;</pre>
</li>
</ul>
</li>
</ul>
<h2>Creación del modelo para el usuario.</h2>
<ul>
<li>Al ser un modelo para manejar la persistencia de los datos, hereda de <span style="font-family: courier new,courier;">CActiveRecord</span>.  Debe tenerse en cuenta que en este experimento en particular se utilizarán los métodos de  DAO en lugar de las facilidades que el <em>ActiveRecord</em> provee directamente.
<pre class="php">class Usuario extends CActiveRecord
{
    // ...
}</pre>
</li>
<li>Se almacena en el archivo <span style="font-family: courier new,courier;">YiiDaoDemo/protected/models/Usuario.php</span>.</li>
<li>Se definen cuales atributos pueden ser asignados de manera automática.
<pre class="php">public function safeAttributes()  
{  
    return 'username, contrasena, edad';  
}</pre>
</li>
<li>Se implementa el <em>agregar</em> el usuario a la base de datos mediante un INSERT de SQL.
<pre class="php">   	public function agregar()
	{
		$sql = "INSERT INTO Usuario(username, contrasena, edad) " .
		       "VALUES (:username, :contrasena, :edad)";

		$comando = Yii::app() -&gt; db -&gt; createCommand($sql);

		$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);
		$comando -&gt; bindParam(":contrasena", $this -&gt; contrasena, PDO::PARAM_STR);
		$comando -&gt; bindParam(":edad", $this -&gt; edad, PDO::PARAM_INT);

		$control = $comando -&gt; execute();

		return ($control &gt; 0);
	}</pre>
</li>
<li>Se implementa el <em>editar</em> el usuario de la base de datos mediante un UPDATE de SQL.
<pre class="php">	public function actualizar()
	{
		$sql = "UPDATE Usuario SET contrasena=:contrasena,edad=:edad " .
		       "WHERE username=:username";

		$comando = Yii::app() -&gt; db -&gt; createCommand($sql);

		$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);
		$comando -&gt; bindParam(":contrasena", md5($this -&gt; contrasena), PDO::PARAM_STR);
		$comando -&gt; bindParam(":edad", $this -&gt; edad, PDO::PARAM_INT);

		$control = $comando -&gt; execute();

		return ($control &gt; 0);
	}</pre>
</li>
<li>Se implementa el <em>remover</em> el usuario de la base de datos mediante un DELETE de SQL.
<pre class="php">	public function remover()
	{
		$sql = "DELETE FROM Usuario WHERE username=:username";

		$comando = Yii::app() -&gt; db -&gt; createCommand($sql);

		$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);

		$control = $comando -&gt; execute();

		return ($control &gt; 0);
	}</pre>
</li>
<li>Se implementa el <em>recuperar</em> el usuario de la base de datos mediante un SELECT de SQL.
<pre class="php">        public function recuperar()
	{
		$sql = "SELECT * FROM usuario WHERE username = :username";

		$comando = Yii::app() -&gt; db -&gt; createCommand($sql);

		$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);

		$fila = $comando -&gt; queryRow();

		if($fila === false)
			return false;

		$this -&gt; username   = $fila['username'];
		$this -&gt; contrasena = $fila['contrasena'];
		$this -&gt; edad       = $fila['edad'];

		return true;
       }</pre>
</li>
<li>De manera similar se implementa el <em>existe</em> que verifica si el usuario, identificado por su nombre de usuario, ya se encuentra registrado en la base de datos o no.
<pre class="php">	public function existe()
	{
		$sql = "SELECT username FROM usuario WHERE username = :username";

		$comando = Yii::app() -&gt; db -&gt; createCommand($sql);

		$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);

		return ($comando -&gt; queryScalar() == $this -&gt; username);
	}</pre>
</li>
<li>Se implementa el método estático <em>listarTodos</em> que retorna el listado completo de los usuarios registrados en la base de datos.
<pre class="php">	public static function listarTodos()
	{
		$sql = "SELECT * FROM usuario";

		return Yii::app() -&gt; db -&gt; createCommand($sql) -&gt;  query();
	}</pre>
</li>
</ul>
<h2>Creación del controlador.</h2>
<ul>
<li>Se almacena en el archivo <span style="font-family: courier new,courier;">YiiDaoDemo/protected/controllers/AdminUsuarioController.php</span>.</li>
<li>Se definen tres acciones diferentes.
<ul>
<li><span style="font-family: courier new,courier;">index</span>: maneja el <em>agregar</em> y <em>editar</em> registros (primer <span style="font-family: courier new,courier;">FORM</span>).</li>
<li><span style="font-family: courier new,courier;">editar</span>: maneja el presionar el botón de <em>editar</em> para mostrar la información del usuario en el formulario (segundo <span style="font-family: courier new,courier;">FORM</span>).</li>
<li><span style="font-family: courier new,courier;">remover</span>: maneja el presionar el botón de <em>remover</em> para eliminar de la base de datos a los usuarios seleccionados (segundo <span style="font-family: courier new,courier;">FORM</span>).
<pre class="php">class AdminUsuarioController extends CController
{
    // ...
}</pre>
</li>
</ul>
</li>
<li>Acción <em>editar</em>: sucede cuando el usuario presiona el botón Editar frente a uno de los registros de los usuarios.  El sistema debe responder mostrando los datos del usuario seleccionado en el primer formulario.
<pre class="php">	public function actionEditar()
	{
                /* Verificar que se cuente con información del usuario (request) */

		if(!isset($_POST['UsuarioForm']))
		{
			Yii::app() -&gt; request -&gt; redirect(CHtml::normalizeUrl(array('adminUsuario/index')));
			exit;
		}

                /* Se obtiene el valor del 'elemento' que deberá tener el nombre del usuario a editar */

		$elemento = $_POST['UsuarioForm']['elemento'];

                /* Se intenta recuperar el usuario solicitado */

		$usuario = new Usuario();
		$usuario -&gt; username = $elemento;
		$control = $usuario -&gt; recuperar();

		$usuarioForm = new UsuarioForm();

                /* Si se tiene éxito, se pasa la información del Usuario al UsuarioForm
                   para ser mostrado en la vista */

		if($control)
		{
			$usuarioForm -&gt; attributes = array(
				'username' =&gt; $usuario -&gt; username,
				'edad' =&gt; $usuario -&gt; edad
			);
		}
		else
		{
                        /* Si se fracasa, se muestra en la vista el nombre de usuario y un mensaje flash */

			$usuarioForm -&gt; username = $usuario -&gt; username;

			$usuarioForm -&gt; addError('username', 'El usuario elegido no existe en la base de datos');
		}

                /* Se muestra la vista del formulario con la información recuperada y el listado
                   de usuarios registrados */

		$this -&gt; render('index',
			array(
				'usuarioForm' =&gt; $usuarioForm,
				'usuarios' =&gt; Usuario::listarTodos()
			));
	}</pre>
</li>
<li>Acción <em>remover</em>: sucede cuando el usuario presiona el botón de remover usuarios en la parte inferior.  El sistema debe responder eliminando de la base de datos a los usuarios seleccionados.
<pre class="php">	public function actionRemover()
	{
                /* Verifica que se cuente con información del usuario (request),
                   de lo contrario, redirecciona a la página inicial */

		if(!isset($_POST['UsuarioForm']))
		{
			Yii::app() -&gt; request -&gt; redirect(CHtml::normalizeUrl(array('adminUsuario/index')));
			exit;
		}

                /* Obtiene las marcas del formulario, los valores de las marcas corresponden a los
                   los nombres de los usuarios a remover */

		$usuarios = array_values($_POST['UsuarioForm']['marca']);

		$total = 0;
		$borrados = 0;

		foreach($usuarios as $username)
		{
                        /* Crea un nuevo usuario con el nombre de usuario a remover */

			$usuario = new Usuario();
			$usuario -&gt; username = $username;

                        /* Ejecuta su remoción */

			if($usuario -&gt; remover())
				$borrados ++;

			$total ++;
		}

                /* Prepara un mensaje flash con el estado final de la remoción */

		Yii::app() -&gt; user -&gt; setFlash('mensajeEstado', "Se removieron {$borrados} de {$total} registros.");

                /* Redirecciona a la página inicial de la aplicación */

		Yii::app() -&gt; request -&gt; redirect(CHtml::normalizeUrl(array('adminUsuario/index')));
		exit;
	}</pre>
</li>
<li>Acción <em>index</em>: sucede cuando la aplicación es invocada por primera vez, el sistema debe responder mostrando el formulario vacío.  También es invocada cuando el usuario presiona el botón Enviar para editar o agregar un nuevo usuario a la base de datos, el sistema debe responder realizando la acción solicitada.
<pre class="php">	public function actionIndex()
	{
		$usuarioForm = new UsuarioForm();

                /* Si se cuenta con información del usuario (request) entonces
                   se agregará un nuevo usuario o se realizará una edición del mismo */

		if(isset($_POST['UsuarioForm']))
		{
                        /* Carga el modelo con la información del formulario */

			$usuarioForm -&gt; attributes = $_POST['UsuarioForm'];

                        /* Verifica que su información sea válida */

			if($usuarioForm -&gt; validate())
			{
                                /* Crea un Usuario con su información */

				$usuario = new Usuario();

				$usuario -&gt; attributes = $_POST['UsuarioForm'];

				try
				{
					$control = false;

                                        /* Si el usuario existe ... */

					if(!$usuario -&gt; existe())
					{
                                                /* Se intenta agregarlo */

						$control = $usuario -&gt; agregar();
					}
					else
					{
                                                /* De lo contrario, se intenta actualizar */

						$control = $usuario -&gt; actualizar();
					}

                                        /* Si la acción tuvo éxito ... */

					if($control)
					{
                                                /* Muestra un mensaje flash de éxito */

						Yii::app() -&gt; user -&gt; setFlash('mensajeEstado', 'El registro fue incorporado exitosamente ' .
						                                                'en la base de datos');

                                                /* Limpia los valores del formulario */

						$usuarioForm = new UsuarioForm();
					}
					else
					{
                                                /* Si falló ... muestra un mensaje flash de fracaso */

						$usuarioForm -&gt; addError('username', 'El registro no pudo ser incorporado en ' .
						                                     'la base de datos, inténtelo nuevamente');
					}
				}
				catch (Exception $e)
				{
                                        /* Si se lanzó una excepción durante el proceso, esta se muestra y
                                           considera como un error */

					$usuarioForm -&gt; addError('username', $e -&gt; getMessage());
				}
			}
		}

                /* Se muestra la vista del formulario con la información recuperada y el listado
                   de usuarios registrados */

		$this -&gt; render('index',
		                array(
					'usuarioForm' =&gt; $usuarioForm,
					'usuarios' =&gt; Usuario::listarTodos()
				));
	}</pre>
</li>
</ul>
<h2>Conclusiones.</h2>
<ul>
<li>A pesar de que Yii parece ser un <em>framework</em> muy interesante para el desarrollo con PHP aún no me siento cómodo con él.</li>
<li>Aún quedan varios temas para revisar y experimentar de Yii con los que espero se aclare un poco mas el panorama.</li>
<li>El acceso a la base de datos mediante los objetos DAO es muy claro y fácil de implementar.</li>
<li>Para la implementación del CRUD es mas conveniente utilizar el <em>ActiveRecord</em> que se estará analizando próximamente y utilizar el DAO para las consultas demasiado complejas.</li>
<li>En este, mi tercer programita en Yii, se aclararon varias dudas que tenía, sin embargo persisten otras, en particular esta: cómo limpio/filtro la información proveniente del usuario ?</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Descargar el código fuente de la aplicación, versión 0.1.<br />
<a href="http://demo.jorgeivanmeza.com/PHP/YiiDaoDemo/" >http://demo.jorgeivanmeza.com/PHP/YiiDaoDemo/</a></li>
</ul>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 5397px; width: 1px; height: 1px;">public function agregar()<br />
{<br />
$sql = "INSERT INTO Usuario(username, contrasena, edad) " .<br />
"VALUES (:username, :contrasena, :edad)";
<p>$comando = Yii::app() -&gt; db -&gt; createCommand($sql);</p>
<p>$comando -&gt; bindParam(":username", $this -&gt; username, PDO::PARAM_STR);<br />
$comando -&gt; bindParam(":contrasena", $this -&gt; contrasena, PDO::PARAM_STR);<br />
$comando -&gt; bindParam(":edad", $this -&gt; edad, PDO::PARAM_INT);</p>
<p>$control = $comando -&gt; execute();</p>
<p>return ($control &gt; 0);<br />
}</p></div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/experimentando-con-yii-y-dao-manipulando-formularios-y-registros-simples/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Data Access Objects (DAO) con Yii</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/data-access-objects-dao-con-yii/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/data-access-objects-dao-con-yii/#comments</comments>
		<pubDate>Fri, 17 Jul 2009 19:44:58 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1902</guid>
		<description><![CDATA[Introducción.

Los objetos de acceso a datos (DAO) permiten el acceso genérico a las bases de datos, permitiendo cambiar el motor de base de datos sin impactar el sistema.
Se basan en PHP Data Objects (PDO) por lo cual la instalación de PHP deberá tener presentes los módulos correspondientes.
Se incluye el soporte para los siguientes motores de [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<ul>
<li>Los objetos de acceso a datos (DAO) permiten el acceso genérico a las bases de datos, permitiendo cambiar el motor de base de datos sin impactar el sistema.</li>
<li>Se basan en <em><a href="http://www.php.net/manual/en/intro.pdo.php" >PHP Data Objects</a></em> (PDO) por lo cual la instalación de PHP deberá tener presentes los <a href="http://www.php.net/manual/en/pdo.drivers.php" >módulos correspondientes</a>.</li>
<li>Se incluye el soporte para los siguientes motores de base de datos.
<ul>
<li><a href="http://www.php.net/manual/en/ref.pdo-dblib.php">Microsoft SQL Server and Sybase Functions (PDO_DBLIB)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-firebird.php">Firebird/Interbase (PDO_FIREBIRD)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-ibm.php">IBM (PDO_IBM)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-informix.php">Informix (PDO_INFORMIX)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-mysql.php">MySQL (PDO_MYSQL)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-oci.php">Oracle (PDO_OCI)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-odbc.php">ODBC and DB2 (PDO_ODBC)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-pgsql.php">PostgreSQL (PDO_PGSQL)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-sqlite.php">SQLite (PDO_SQLITE)</a></li>
<li><a href="http://www.php.net/manual/en/ref.pdo-4d.php">Driver 4D for PDO (PDO_4D)</a></li>
</ul>
</li>
<li>La arquitectura se compone por cuatro clases.
<ol>
<li><span style="font-family: courier new,courier;">CDbConnection</span>: conexión a la base de datos.</li>
<li><span style="font-family: courier new,courier;">CDbCommand</span>: sentencias para ser ejecutadas en la base de datos.</li>
<li><span style="font-family: courier new,courier;">CDbDataReader</span>: lector unidireccional y de sólo lectura para resultados de consultas.</li>
<li><span style="font-family: courier new,courier;">CDbTransaction</span>: transacciones de la base de datos.</li>
</ol>
</li>
</ul>
<h2>Establecer la conexión.</h2>
<h3>De manera explícita.</h3>
<ul>
<li>Se basa en la creación de un objeto CDbConnection, la especificación de un <em>Data Source Name</em> (DSN) y la información de autenticación del usuario de conexión si es necesaria.
<pre class="php">$conexion = CDbConnection($DSN, $username, $password);
$conexion -&gt; active = true;        // Abrir la conexión, se lanzan excepciones en error.
// ...
$conexion -&gt; active = false;       // Cerrar la conexión.</pre>
</li>
<li>El formato del DSN depende del módulo de PDO utilizado.
<ol>
<li>SQLite: <span style="font-family: courier new,courier;">sqlite:/ruta/al/archivo/sqlite</span></li>
<li>MySQL: <span style="font-family: courier new,courier;">mysql:host=&lt;HOST&gt;;dbname=&lt;NAME&gt;</span></li>
<li>PostgreSQL: <span style="font-family: courier new,courier;">pgsql:host=&lt;HOST&gt;;port=&lt;PORT [5432]&gt;;dbname=&lt;NAME&gt;</span></li>
<li>MSSQL: <span style="font-family: courier new,courier;">mssql:host=&lt;HOST&gt;;dbname=&lt;NAME&gt;</span></li>
<li>Oracle: <span style="font-family: courier new,courier;">oci:dbname=//&lt;HOST&gt;:&lt;PORT [1521]&gt;/&lt;NAME&gt;</span></li>
</ol>
</li>
</ul>
<h3>De manera automática.</h3>
<ul>
<li>La clase <span style="font-family: courier new,courier;">CDbConnection</span> es un <span style="font-family: courier new,courier;">CApplicationComponent</span> por lo que puede ser configurado como un componente de aplicación.</li>
<li>Para hacer esto es necesario modificar la configuración de la aplicación (<span style="font-family: courier new,courier;">protected/config/main.php</span>) de la siguiente manera para agregar al componente <span style="font-family: courier new,courier;">db</span>.
<pre class="php">array (
    // ...
    'components' =&gt; array (
        'db' =&gt; array (
            'class' =&gt; 'CDbConnection',
            'connectionString' =&gt; 'mysql:host=database.server.com;dbname=demo_db',
            'username' =&gt; 'demo_user',
            'password' =&gt; 'demo_pass'
        )
    )
);</pre>
</li>
<li>De esta manera la conexión se realiza de manera automática y puede accederse mediante <span style="font-family: courier new,courier;">Yii::app() -&gt; db</span>.</li>
</ul>
<h2>Ejecutar sentencias.</h2>
<ul>
<li>Es necesario crear un <span style="font-family: courier new,courier;">CDbCommand</span> a través de <span style="font-family: courier new,courier;">CDbConnection::createCommand()</span>.
<pre class="php">$comando = $conexion -&gt; createCommand($sql);
// $comando -&gt; text = $nuevoSQL;              // Actualiza el SQL de un comando</pre>
</li>
<li>La sentencia puede ejecutarse de dos maneras.
<ol>
<li><span style="font-family: courier new,courier;">execute()</span> para sentencias de modificación como <span style="font-family: courier new,courier;">INSERT</span>, <span style="font-family: courier new,courier;">UPDATE</span> y <span style="font-family: courier new,courier;">DELETE</span>.  En éxito retorna el número de registros afectados.</li>
<li><span style="font-family: courier new,courier;">query()</span> para sentencias de consulta (<span style="font-family: courier new,courier;">SELECT</span>).  En éxito retorna un <span style="font-family: courier new,courier;">CDbDataReader</span>.</li>
</ol>
</li>
<li>Existen otros métodos mas específicos del estilo <span style="font-family: courier new,courier;">queryXXX()</span> que facilitan la obtención de los resultados.
<ol>
<li><span style="font-family: courier new,courier;">$filas = $comando -&gt; queryAll()</span>.   Consulta y retorna inmediatamente todas las filas del resultado.</li>
<li><span style="font-family: courier new,courier;">$fila = $comando -&gt; queryRow()</span>.   Consulta y retorna inmediatamente la primera fila del resultado.</li>
<li><span style="font-family: courier new,courier;">$columna = $comando -&gt; queryColumn()</span>.   Consulta y retorna inmediatamente la primera columna del resultado.</li>
<li><span style="font-family: courier new,courier;">$valor = $comando -&gt; queryScalar()</span>.   Consulta y retorna inmediatamente el valor de la primera fila y primera columna del resultado.</li>
</ol>
</li>
</ul>
<h2>Obtener los resultados.</h2>
<ul>
<li>Si se utilizó un método del estilo <span style="font-family: courier new,courier;">queryXXX()</span> el valor obtenido como resultado es retornado inmediatamente.</li>
<li>Si se utilizó el método <span style="font-family: courier new,courier;">query()</span>, los resultados pueden obtenerse de tres maneras.
<ol>
<li>Mediante múltiples llamados a <span style="font-family: courier new,courier;">CDataReader::read()</span>.
<pre class="php">$dataReader = $comando -&gt; query();
while(($fila = $dataReader -&gt; read()) !== false)
{
    // ...
}</pre>
</li>
<li>Mediante la construcción <span style="font-family: courier new,courier;">foreach</span> la cual extrae una fila por cada iteración.
<pre class="php">foreach($dataReader as $fila)
{
    // ...
}</pre>
</li>
<li>Obtiene inmediatamente un arreglo con todas las filas del resultado.
<pre class="php">$filas = $dataReader -&gt; readAll();</pre>
</li>
</ol>
</li>
</ul>
<h2>Utilizar transacciones.</h2>
<ul>
<li>Se basan en la manipulación de un objeto de clase <span style="font-family: courier new,courier;">CDbTransaction</span>.</li>
</ul>
<pre class="php">$transaccion = $conexion -&gt; beginTransaction();           // Inicio de la transacción.
try
{
    $conexion -&gt; createCommand($sql) -&gt; execute();        // Ejecuta las sentencias SQL.
    // ...
    $transaccion -&gt; commit();                             // Almacena los cambios realizados en los datos.
}
catch(Exception $e)                                       // Captura cualquier excepción sucedida.
{
    $transaccion -&gt; rollBack();                           // En error se cancela la transacción y deshacen sus cambios.
}</pre>
<h2>Parametrizar consultas.</h2>
<ul>
<li>Son útiles para evitar la inyección de SQL y para aumentar el rendimiento en la ejecución de consultas recurrentes.</li>
<li>Se basa en la ubicación de marcas en el código SQL que después son reemplazadas por valores dinámicamente.</li>
<li>Las marcas pueden tener un nombre (etiquetas únicas como <span style="font-family: courier new,courier;">:nombre</span> y <span style="font-family: courier new,courier;">:contrasena</span>) o ser anónimas (representadas por <span style="font-family: courier new,courier;">?</span>).</li>
<li>Para reemplazar las marcas por los valores finales pueden utilizarse los siguientes métodos.
<ol>
<li><span style="font-family: courier new,courier;">CDbCommand::bindParam()</span>.  Relaciona la marca con una referencia a la variable PHP.  Para valores grandes esta opción es preferible en términos de desempeño.</li>
<li><span style="font-family: courier new,courier;">CDbCommand::bindValue()</span>.  Relaciona la marca con el valor de una varible PHP.</li>
</ol>
</li>
<li>El reemplazo de las marcas debe hacerse antes de que la consulta sea ejecutada.</li>
</ul>
<pre class="php">$sql = "INSERT INTO usuario(nombre, contrasena) VALUES(:username, :password)";
$comando = $conexion -&gt; createCommand($sql);

// Agregar el primer usuario.
$comando -&gt; bindParam(":username", $nombre1, PDO::PARAM_STR);
$comando -&gt; bindParam(":password", $contrasena1, PDO::PARAM_STR);
$comando -&gt; execute();

// Agregar el segundo usuario.
$comando -&gt; bindParam(":username", $nombre2, PDO::PARAM_STR);
$comando -&gt; bindParam(":password", $contrasena2, PDO::PARAM_STR);
$comando -&gt; execute();

// ...</pre>
<p>Las constantes que determinan el tipo del valor a reemplazarse por la marca pueden consultarse en la sección de <a href="http://www.php.net/manual/en/pdo.constants.php" >Constantes Predefinidas de PDO</a> en el <a href="http://www.php.net/manual/en/book.pdo.php" >manual de PHP</a>.</p>
<h2>Asociar columnas.</h2>
<ul>
<li>Yii provee una facilidad adicional para la manipulación de resultados provenientes de la base de datos.</li>
<li>Consiste en relacionar variables con las columnas del resultado así se actualizarán de manera automática en cada iteración que obtenga una nueva fila de datos.</li>
</ul>
<pre class="php">$sql = "SELECT nombre, contrasena FROM usuario";
$dataReader = $conexion -&gt; createCommand($sql) -&gt; query();

// Asociar las variables $username y $password a las columnas uno y dos del resultado.
$dataReader -&gt; bindColumn(1, $username);
$dataReader -&gt; bindColumn(2, $password);

while($dataReader -&gt; read() !== false)
{
    // $username y $password tendrán el valor de cada fila
    // del resultado en cada una de las iteraciones.
}</pre>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/');" href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/doc/');" href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/data-access-objects-dao-con-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modelos de formularios con Yii (formulario y acción)</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-formulario-y-accion/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-formulario-y-accion/#comments</comments>
		<pubDate>Tue, 14 Jul 2009 22:04:28 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1890</guid>
		<description><![CDATA[Introducción.
Le etapa final de la implementación de la aplicación basada en formularios web corresponde con la implementación del formulario (vista) y de la acción del controlador que la va a procesar.
Definición de las etiquetas del formulario.

Permite definir desde el modelo las etiquetas que acompañarán a cada uno de los atributos del mismo.
Es preferible este método [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Le etapa final de la implementación de la aplicación basada en formularios web corresponde con la implementación del formulario (vista) y de la acción del controlador que la va a procesar.</p>
<h2>Definición de las etiquetas del formulario.</h2>
<ul>
<li>Permite definir desde el modelo las etiquetas que acompañarán a cada uno de los atributos del mismo.</li>
<li>Es preferible este método en lugar de escribirlos manualmente en la vista ya que permite modificarlos según sucedan ciertas situaciones.  Por ejemplo, resaltarlos en rojo (mediante CSS) cuando la validación arroja un valor en un campo específico.</li>
<li>Para definirlas es necesario sobreescribir el método <span style="font-family: courier new,courier;">attributeLabels()</span> del modelo.  Por defecto se retornan los mismos nombres de los atributos.</li>
</ul>
<pre class="php">public function attributeLabels()
{
    return array(
        'value1'   =&gt; 'Operando #1',
        'value2'   =&gt; 'Operando #2',
        'operator' =&gt; 'Operación'
    );
}</pre>
<h2>Creación del formulario.</h2>
<ul>
<li>Yii provee algunos ayudantes para la creación y estandarización de código HTML mediante la <a href="http://www.yiiframework.com/doc/api/CHtml" >clase CHtml</a> como <span style="font-family: courier new,courier;">CHtml::textField</span>, <span style="font-family: courier new,courier;">CHtml::dropDownList</span>, <span style="font-family: courier new,courier;">CHtml::beginForm</span> y <span style="font-family: courier new,courier;">CHtml::endForm</span>.</li>
</ul>
<pre class="php">&lt;div class='formulario'&gt;
    &lt;?php echo CHtml::beginForm(); ?&gt;
    &lt;?php echo CHtml::errorSummary($calc); /* $calc es una referencia al modelo */ ?&gt;

    &lt;div class='operacion'&gt;
        &lt;div class='operando'&gt;
            &lt;?php echo CHtml::activeLabel($calc, 'value1'); ?&gt;
            &lt;?php echo CHtml::activeTextField($calc, 'value1'); ?&gt;
        &lt;/div&gt;
        &lt;div class='operador'&gt;
            &lt;?php echo CHtml::activeLabel($calc, 'operator'); ?&gt;
            &lt;?php echo CHtml::activeTextField($calc, 'operator'); ?&gt;
        &lt;/div&gt;
        &lt;div class='operando'&gt;
            &lt;?php echo CHtml::activeLabel($calc, 'value2'); ?&gt;
            &lt;?php echo CHtml::activeTextField($calc, 'value2'); ?&gt;
        &lt;/div&gt;
&lt;/div&gt;
&lt;div class='acciones'&gt;
    &lt;?php echo CHtml::submitButton('Ejecutar'); ?&gt;
&lt;/div&gt;

&lt;?php echo CHtml::endForm(); ?&gt;
&lt;/div&gt;</pre>
<h2>Creación de la acción.</h2>
<ul>
<li>Contiene la lógica del controlador que manipula los modelos de acuerdo al requerimiento recibido por parte del usuario.</li>
</ul>
<pre class="php">public function actionCalculate()
{
    $calc = new CalculatorForm();

    if(isset($_POST['CalculatorForm']))                         /* If the form was submitted */
    {
        $calc -&gt; attributes = $_POST['CalculatorForm'];         /* Populate the form with POST data */

        if($calc -&gt; validate())                                 /* Validate the input data */
            // ...                                              /* On success do something */

        $this -&gt; render('result', array('calc' =&gt; $calc));      /* Render a view */
    }
}</pre>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/');" href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/doc/');" href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
<li>CHtml class reference.<br />
<a href="http://www.yiiframework.com/doc/api/CHtml" >http://www.yiiframework.com/doc/api/CHtml</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-formulario-y-accion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modelos de formularios con Yii (validación)</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-validacion/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-validacion/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 14:38:17 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1873</guid>
		<description><![CDATA[Introducción.
Después de poblado el modelo con la información proporcionada por el usuario a través del formulario, la validación verifica que la información del modelo sea correcta mediante la aplicación de un conjunto de reglas definidas específicamente para cada modelo.
Especificación de reglas.

Para especificar las reglas de validación de un modelo es necesario sobreescribir el método rules().
public [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>Después de poblado el modelo con la información proporcionada por el usuario a través del formulario, la validación verifica que la información del modelo sea correcta mediante la aplicación de un conjunto de reglas definidas específicamente para cada modelo.</p>
<h2>Especificación de reglas.</h2>
<ul>
<li>Para especificar las reglas de validación de un modelo es necesario sobreescribir el método <span style="font-family: courier new,courier;">rules()</span>.
<pre class="php">public function rules()
{
    return array(
        array('value1, value2, operator', 'required'),
        array('value1, value2', 'numerical')
    );
}</pre>
</li>
<li>El método <span style="font-family: courier new,courier;">rules()</span> retorna un arreglo cuyos elementos corresponden con la siguiente especificación.
<pre class="php">array('&lt;lista de atributos&gt;', '&lt;validador&gt;', 'on' =&gt; '&lt;lista de escenarios&gt;', ... &lt;opciones adicionales&gt;)</pre>
<ul>
<li>El <strong>listado de atributos</strong> corresponde con los nombres separados por comas de los atributos a los cuales se les aplica la regla de valildación.</li>
<li>El nombre del <strong>validador</strong> determina el tipo de verificación que se debe realizar sobre los <strong>atributos</strong>.</li>
<li>El parámetro <strong>on</strong> (opcional) permite especificar en cuales escenarios (lista separada por comas) aplica la regla.</li>
<li>Las <strong>opciones adicionales</strong> son parejas nombre/valor que permiten asignar valores iniciales a las propiedades del validador.</li>
</ul>
</li>
</ul>
<h2>Tipos de validadores.</h2>
<p>Existen tres tipos de formas como es posible especificar las reglas de validación.</p>
<ol>
<li>Como un método del modelo.</li>
</ol>
<blockquote>
<ul>
<li>La firma del método deberá corresponder con la siguiente.
<pre class="php">/**
 * @param string El nombre del atributo que será validado.
 * @param array Opciones adicionales especificadas en la regla de validación.
 */
public function NombreValidador($atributo, $parametros)</pre>
</li>
</ul>
</blockquote>
<ol>
<li>Como una clase que hereda de <span style="font-family: courier new,courier;">CValidator</span>.</li>
<li>Como un alias de un validador predefinido.</li>
</ol>
<h3>Validadores predefinidos.</h3>
<p>Corresponden a alias mas cortos y sencillos de los validadores mas utilizados sobre los atributos.</p>
<table style="border-color: #d6d6d6; border-width: 1px;" border="1" cellspacing="3" cellpadding="3" align="center">
<tbody>
<tr style="text-align: center; background-color: #f3da9a;">
<td><strong>Alias</strong></td>
<td><strong>Clase</strong></td>
<td><strong>Descripción</strong></td>
</tr>
<tr>
<td>captcha</td>
<td><a href="http://www.yiiframework.com/doc/api/CCaptchaValidator" >CCaptchaValidator</a></td>
<td>Debe ser igual al código de verificación mostrado en el CAPTCHA.</td>
</tr>
<tr>
<td>compare</td>
<td><a href="http://www.yiiframework.com/doc/api/CCompareValidator" >CCompareValidator</a></td>
<td>Es igual a otro o a una constante.</td>
</tr>
<tr>
<td>email</td>
<td><a href="http://www.yiiframework.com/doc/api/CEmailValidator" >CEmailValidator</a></td>
<td>Es una dirección de correo electrónico válida.</td>
</tr>
<tr>
<td>default</td>
<td><a href="http://www.yiiframework.com/doc/api/CDefaultValueValidator" >CDefaultValueValidator</a></td>
<td>Asigna un valor por defecto.</td>
</tr>
<tr>
<td>exist</td>
<td><a href="http://www.yiiframework.com/doc/api/CExistValidator" >CExistsValidator</a></td>
<td>Existe en una columna específica de la tabla.</td>
</tr>
<tr>
<td>file</td>
<td><a href="http://www.yiiframework.com/doc/api/CFileValidator" >CFileValidator</a></td>
<td>Contiene el nombre de un archivo subido al servidor.</td>
</tr>
<tr>
<td>filter</td>
<td><a href="http://www.yiiframework.com/doc/api/CFilterValidator" >CFilterValidator</a></td>
<td>Transforma al atributo con el filtro.</td>
</tr>
<tr>
<td>in</td>
<td><a href="http://www.yiiframework.com/doc/api/CRangeValidator" >CRangeValidator</a></td>
<td>Pertenece a una lista predefinida de valores.</td>
</tr>
<tr>
<td>length</td>
<td><a href="http://www.yiiframework.com/doc/api/CStringValidator" >CStringValidator</a></td>
<td>Su longitud se encuentra dentro de cierto rango específico.</td>
</tr>
<tr>
<td>match</td>
<td><a href="http://www.yiiframework.com/doc/api/CRegularExpressionValidator" >CRegularExpressionValidator</a></td>
<td>Coincide con la expresión regular especificada.</td>
</tr>
<tr>
<td>numerical</td>
<td><a href="http://www.yiiframework.com/doc/api/CNumberValidator" >CNumberValidator</a></td>
<td>Es un valor numérico.</td>
</tr>
<tr>
<td>required</td>
<td><a href="http://www.yiiframework.com/doc/api/CRequiredValidator" >CRequiredValidator</a></td>
<td>No permite valores vacíos.</td>
</tr>
<tr>
<td>type</td>
<td><a href="http://www.yiiframework.com/doc/api/CTypeValidator" >CTypeValidator</a></td>
<td>Verifica que sea del tipo especificado.</td>
</tr>
<tr>
<td>unique</td>
<td><a href="http://www.yiiframework.com/doc/api/CUniqueValidator" >CUniqueValidator</a></td>
<td>Es único en la columna de la tabla en la base de datos.</td>
</tr>
<tr>
<td>url</td>
<td><a href="http://www.yiiframework.com/doc/api/CUrlValidator" >CUrlValidator</a></td>
<td>Es una URL válida.</td>
</tr>
</tbody>
</table>
<p>A continuación se muestras algunos ejemplos de estos validadores.</p>
<pre class="php">/* Se requiere un valor Username, no puede dejarse vacío */
array('username', 'required'),

/* Username deberá tener entre 3 y 12 carácteres */
array('username', 'length', 'min' =&gt; 3, 'max' =&gt; 12),

/* En el escenario 'registro', password deberá coincidir con password2 */
array('password', 'compare', 'compareAttribute' =&gt; 'password2', 'on' =&gt; 'registro'),

/* En el escenario 'login', password deberá ser autenticado (validador de método [1] o de clase [2]) */
array('password', 'authenticate', 'on' =&gt; 'login')</pre>
<h2>Ejecución de la validación.</h2>
<ul>
<li>Es posible forzar a la validación manualmente mediante el llamado al método <span style="font-family: courier new,courier;">CModel::validate()</span>.  El llamado a métodos como <span style="font-family: courier new,courier;">CActiveRecord::save()</span> lanzan automáticamente la validación.</li>
<li>El retorno del método <span style="font-family: courier new,courier;">CModel::validate()</span> se utiliza para verificar si la validación fue exitosa o si falló alguna de las reglas.</li>
<li>Es posible (opcional) definir un escenario para la ejecución de la validación.  En caso de especificarse se tomarán en cuenta las reglas que NO tienen definido un escenario (parámetro <span style="font-family: courier new,courier;">on</span>) y aquellas cuyo escenario coincida con el definido para la ejecución de la validación.  En caso de no especificarse un escenario, se tomarán en cuenta únicamente las primeras reglas, las que NO tienen definido un escenario.</li>
</ul>
<pre class="php">$modelo -&gt; scenario = 'registro';

if($modelo -&gt; validate())
{
    // Éxito en la validación
}
else
{
    // Fracaso en la validación
}</pre>
<ul>
<li>Es posible obtener mayor información del validador mediante los siguientes métodos que pueden ser aplicados globalmente para todos los atributos o a uno en específico.
<ul>
<li><span style="font-family: courier new,courier;">CModel::hasErrors()</span>.  Verifica si hubo o no errores en la validación.</li>
<li><span style="font-family: courier new,courier;">CModel::getErrors()</span>.  Obtiene los mensajes de error generados durante la validación.</li>
</ul>
</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/');" href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/doc/');" href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-validacion/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Modelos de formularios con Yii (definición y asignación de atributos)</title>
		<link>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-definicion-y-asignacion-de-atributos/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-definicion-y-asignacion-de-atributos/#comments</comments>
		<pubDate>Mon, 13 Jul 2009 03:16:17 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1870</guid>
		<description><![CDATA[Introducción.
En Yii existen dos tipos de modelos: los basados en información que proviene de un formulario (form model) la cual se va obtener, manipular y desechar, y la proveniente de una base de datos (active record model) la cual provee las operaciones de CRUD sobre los datos.  En este artículo estaré haciendo referencia al primero [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<p>En Yii existen dos tipos de modelos: los basados en información que proviene de un formulario (<em>form model</em>) la cual se va obtener, manipular y desechar, y la proveniente de una base de datos (<em>active record model</em>) la cual provee las operaciones de <a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete" >CRUD</a> sobre los datos.  En este artículo estaré haciendo referencia al primero de los modelos, el relacionado con la manipulación de información proveniente del usuario a través de un formulario.</p>
<p>El procedimiento típico para el desarrollo de las aplicaciones basadas en formularios es el siguiente.</p>
<ol>
<li>Crear un <strong>modelo</strong> que represente en sus campos a los datos que van a ser manipulados.</li>
<li>Crear un <strong>controlador</strong> con sus respectivas acciones que respondan a los requerimientos del usuario.</li>
<li>Crear una <strong>vista</strong> con el/los formulario/s asociados a las acciones.</li>
</ol>
<p>Las acciones generales que es posible definir en un modelo basado en formularios son siguientes.</p>
<ul>
<li>Definición.</li>
<li>Asignación de atributos (datos).</li>
<li><a href="http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-validacion/" >Validación</a>.</li>
<li>Implementación de la acción.</li>
<li>Creación del formulario.</li>
</ul>
<h2>Definición.</h2>
<ul>
<li>Los modelos basados en formularios heredan de <span style="font-family: courier new,courier;">CFormModel</span>.</li>
<li>Sus atributos definen los datos que van a ser almacenados del formulario.</li>
<li>Si se especifican valores por defecto para los atributos su estado se reflejará en las vistas correspondientes a los formularios.</li>
</ul>
<pre class="php">class CalculatorForm extends CFormModel
{
    public $value1;
    public $value2;
    public $operator = '+';    // Default value.
}</pre>
<h2>Asignación de datos.</h2>
<p>Es posible especificar valores para los atributos del modelo de dos maneras.</p>
<ol>
<li>Asignación individual.</li>
<li>Asignación general.</li>
</ol>
<h3>Asignación individual.</h3>
<ul>
<li>Hace referencia al acceso directo de los atributos.</li>
<li>Se debe utilizar cuando es necesario realizar algún tipo de verificación o cálculo de la información proveniente del formulario.</li>
</ul>
<pre class="php">$model = new CalculatorForm();
$model -&gt; operator = '*';</pre>
<h3>Asignación general.</h3>
<ul>
<li>Asigna todos los atributos del modelo cuyos nombres coincidan con la información proporcionada, habitualmente en<span style="font-family: courier new,courier;"> $_POST</span>.</li>
<li>Se incluye un <em>escenario</em> que permite diferenciar cuales atributos si se deberán modificar durante la asignación general.</li>
</ul>
<pre class="php">$model = new CalculatorForm();
$model -&gt; scenario = 'calculate';
if(isset($_POST['CalcForm']))
    $model -&gt; attributes = $_POST['CalcForm'];</pre>
<ul>
<li>Es posible filtrar/asegurar cuales son los valores seguros para asignar masivamente por cada uno de los escenarios posibles.</li>
<li>Para hacer esto es necesario sobreescribir el método <span style="font-family: courier new,courier;">safeAttributes()</span> del modelo.</li>
</ul>
<pre class="php">public function safeAttributes()
{
    return array(
        parent::safeAttributes(),

        /* Atributos que pueden ser asignados en todos los scenarios */
        'atrib1, atrib2, ...',

        /* Atributos que sólo pueden ser asignados en el escenario X */
        'escenarioX' =&gt; 'atribA, atribB, ...'
    );
}</pre>
<ul>
<li>Si ninguno de los atributos del modelo será dependiente de un escenario es posible simplificar el retorno de <span style="font-family: courier new,courier;">safeAttributes()</span> en una cadena conteniendo el listado de los nombres de los atributos seguros para asignación general.</li>
</ul>
<pre class="php">public function safeAttributes()
{
    /* Asignación general sin dependencia de escenarios */
    return 'atrib1, atrib2, ...';
}</pre>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/');" href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a onclick="javascript:pageTracker._trackPageview('/http://www.yiiframework.com/doc/');" href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/07/modelos-de-formularios-con-yii-definicion-y-asignacion-de-atributos/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Los componentes en Yii</title>
		<link>http://blog.jorgeivanmeza.com/2009/06/los-componentes-en-yii/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/06/los-componentes-en-yii/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 21:30:11 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1835</guid>
		<description><![CDATA[Introducción.

Son objetos escritos basados en una especificación.
Heredan de la clase CComponent.
Es posible acceder y modificar sus propiedades así como lanzar y manejar sus eventos.

Propiedades.

Son atributos públicos de lectura y escritura.
Pueden definirse de dos maneras.

Declarando un atributo público en el componente.

En este caso el nombre de la propiedad es sensible a mayúsculas.


Definiendo los métodos setter y [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<ul>
<li>Son objetos escritos basados en una especificación.</li>
<li>Heredan de la clase <span style="font-family: courier new,courier;">CComponent</span>.</li>
<li>Es posible acceder y modificar sus propiedades así como lanzar y manejar sus eventos.</li>
</ul>
<h2>Propiedades.</h2>
<ul>
<li>Son atributos públicos de lectura y escritura.</li>
<li>Pueden definirse de dos maneras.
<ul>
<li>Declarando un atributo público en el componente.
<ul>
<li>En este caso el nombre de la propiedad <span style="text-decoration: underline;">es</span> sensible a mayúsculas.</li>
</ul>
</li>
<li>Definiendo los métodos <em>setter</em> y <em>getter</em> correspondientes.
<ul>
<li>En este caso el nombre de la propiedad <span style="text-decoration: underline;">no es</span> sensible a mayúsculas.</li>
<li>Para implementar la propiedad <span style="font-family: courier new,courier;">imageType</span> es necesario implementar los siguientes métodos.
<pre class="php">public function getImageType()
{
    return $this -&gt; _imageType;
}

public function setImageType($value)
{
    $this -&gt; _imageType = $value;
}</pre>
</li>
<li>Este método es mas flexible ya que permite definir una lógica del negocio que condicione el acceso a las propiedades.</li>
<li>De igual manera es posible implementar propiedades de sólo lectura (sin <em>setter</em>) o de sólo escritura (sin <em>getter</em>).</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Eventos.</h2>
<ul>
<li>Los eventos del componente son propiedades que toman referencias a métodos (<em>event handlers</em>) como valores.</li>
<li>Estos métodos son invocados automáticamente cuando sucede el evento asociado.</li>
<li>Un evento del componente es definido por la implementación de un método cuyo nombre empieza por <span style="font-family: courier new,courier;">on</span> y termina con el nombre del evento asociado (no es sensible a mayúsculas).
<ul>
<li>Para el evento <em>click</em> -&gt; el método deberá ser entonces: <span style="font-family: courier new,courier;">onClicked</span>.
<pre class="php">public function onClicked($event)
{
    // ...
}</pre>
</li>
</ul>
</li>
<li>Los eventos (<span style="font-family: courier new,courier;">$event</span>) son instancias de la clase <span style="font-family: courier new,courier;">CEvent</span>.</li>
<li>Los manejadores de evento se asginan de la siguiente manera.
<pre class="php">$component -&gt; onClicked = $callback;</pre>
<ul>
<li><span style="font-family: courier new,courier;">$callback</span> deberá ser una referencia válida en PHP según las siguientes opciones.
<ul>
<li>El nombre de una función global.</li>
<li>Un método de una clase, para este caso deberá ser de la forma <span style="font-family: courier new,courier;">array($objeto, 'nombreMétodo')</span>.</li>
</ul>
</li>
</ul>
</li>
<li>Varios manejadores de evento pueden asociarse a un mismo evento, estos se ejecutarán en el orden en que fueron creados.</li>
<li>Un manejador de eventos puede evitar que se invoquen los demás manejadores de eventos al realizar la siguiente modificación.
<pre class="php">$event -&gt; handled = true;</pre>
</li>
</ul>
<h2>Comportamientos.</h2>
<ul>
<li>Un comportamiento es un objeto cuyos métodos pueden ser <em>transferidos</em> a los componentes que se le agreguen.</li>
<li>Es decir, reune funcionalidades en lugar de realizar una especialización como lo hace la herencia convencional.</li>
<li>Es posible agregar múltiples comportamientos lo que se asemeja a la herencia múltiple.</li>
<li>Son análogos a los <a href="http://en.wikipedia.org/wiki/Mixin" ><em>mixins</em></a> que incluyen otros lenguajes orientados a objetos (como <a href="http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_modules.html" >Ruby</a>) o que implementan otros <em>frameworks</em> (como <a href="http://www.librosweb.es/symfony_1_0/capitulo17/mixins.html" >Symfony</a>).</li>
<li>Existen varias maneras de implementar un comportamiento.
<ul>
<li>Como una clase que implementa a la interfaz <span style="font-family: courier new,courier;">IBehaviour</span>.</li>
<li>Como una clase que hereda de <span style="font-family: courier new,courier;">CBehaviour</span>.</li>
<li>Si va a ser agregado a un modelo puede ser una clase que herede de <span style="font-family: courier new,courier;">CModelBehaviour</span> o <span style="font-family: courier new,courier;">CActiveRecordBehaviour</span> según corresponda.</li>
</ul>
</li>
<li>Para utilizar un comportamiento primero debe ser agregado a un componente.
<pre class="php">$comportamiento -&gt; attach($nombre, $componente);
$componente -&gt; métodoDelComportamiento();</pre>
</li>
<li>Los comportamientos pueden ser activados y desactivados según se desee en cada componente.
<pre class="php">$componente -&gt; enableBehaviour($nombre);
$componente -&gt; disableBehaviour($nombre);</pre>
</li>
<li>Si dos o mas comportamientos agregados a un componente entran en conflicto porque tienen métodos con igual nombre, la precedencia la tendrá el comportamiento que haya sido agregado primero.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/06/los-componentes-en-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Los módulos en Yii</title>
		<link>http://blog.jorgeivanmeza.com/2009/06/los-modulos-en-yii/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/06/los-modulos-en-yii/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 16:03:06 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1830</guid>
		<description><![CDATA[Introducción.

Son unidades autocontenidas de software.
Tienen sus propios modelos, vistas, controladores y demás componentes de soporte.
Se asemejan a una aplicación pero no pueden ser desplegados individualmente, deben residir como parte de  una aplicación.
Los usuarios acceeden a los controladores de los módulos de la misma forma como se acceden los controladores convencionales.
Son útiles para dividir el desarrollo [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<ul>
<li>Son unidades autocontenidas de software.</li>
<li>Tienen sus propios modelos, vistas, controladores y demás componentes de soporte.</li>
<li>Se asemejan a una aplicación pero no pueden ser desplegados individualmente, deben residir como parte de  una aplicación.</li>
<li>Los usuarios acceeden a los controladores de los módulos de la misma forma como se acceden los controladores convencionales.</li>
<li>Son útiles para dividir el desarrollo y mantenimiento de aplicaciones muy grandes en módulos independientes.</li>
<li>Facilitan la reutilización de código a alto nivel.</li>
<li>Se utilizan para implementar funcionalidades como autenticación, manejo de usuarios, manejo de comentarios, etc.</li>
</ul>
<h2>Estructura.</h2>
<ul>
<li>Cada módulo tiene una clase principal que hereda de <span style="font-family: courier new,courier;">CWebModule</span>.</li>
<li>El nombre de la clase se determina de la siguiente manera: <span style="font-family: courier new,courier;">ucfirst(IdentificadorMódulo) . 'Module'</span>.
<ul>
<li>Ejemplo, la clase del módulo <span style="font-family: courier new,courier;">gallery</span> debe llamarse <span style="font-family: courier new,courier;">GalleryModule</span>.</li>
</ul>
</li>
<li>Esta clase se utiliza para almacenar información y características que son comúnes a todo el módulo.
<ul>
<li><span style="font-family: courier new,courier;">CWebModule::params</span> almacena los parámetros del módulo.</li>
<li><span style="font-family: courier new,courier;">CWebModule:: components</span> comparte componentes de aplicación a nivel del módulo.</li>
</ul>
</li>
</ul>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;"></span></p>
<h2>Creación.</h2>
<h3>Utilizando <span style="font-family: courier new,courier;">yiic</span>.</h3>
<p><span style="font-family: courier new,courier;">yiic</span> permite crear fácilmente un esqueleto básico del módulo para empezar a trabajar sobre él.</p>
<p><span style="font-family: courier new,courier;">$ cd WebRoot/MiAplicacion<br />
$ protected/yiic shell</span></p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">Yii Interactive Tool v1.0<br />
Please type 'help' for help.  Type 'exito' to quit.</span>
</p>
<p style="padding-left: 30px;"><span style="font-family: courier new,courier;">&gt;&gt; module gallery</span></p>
<h2>Uso.</h2>
<ul>
<li>Copie el directorio del módulo en el directorio <span style="font-family: courier new,courier;">modules</span> de la aplicación.</li>
<li>Declare el módulo (con su identificador) en la propiedad <span style="font-family: courier new,courier;">modules</span> de la configuración de la aplicación de la siguiente manera.
<pre class="php">return array (
    // ...
    'modules' =&gt; array('gallery', /* ... */),
    // ...
);</pre>
</li>
</ul>
<ul>
<li>Es posible especificar valores iniciales para las propiedades del módulo de la siguiente manera.
<pre class="php">return array (
    // ...
    'modules' =&gt; array(
        'gallery' =&gt; array(
            'fileType' =&gt; 'png',
            'rows' =&gt; 10,
            'cols' =&gt; 3
        ),
        /* ... */
     ),
    // ...
);</pre>
</li>
<li class="php">La instancia del módulo puede ser accedida a través de la propiedad <span style="font-family: courier new,courier;">module</span> del controlador acrivo.
<pre class="php">$rows = Yii::app() -&gt; controller -&gt; module -&gt; rows;</pre>
</li>
<li>Los módulos se acceden con la ruta <span style="font-family: courier new,courier;">módulo/controlador/acción</span>.
<ul>
<li>Para el ejemplo, <span style="font-family: courier new,courier;">gallery/image/add</span> corresponderá entonces con el URL <span style="font-family: courier new,courier;">http://www.servidor.com/index.php?r=gallery/image/add</span>.</li>
</ul>
</li>
<li>Un módulo puede contener a su vez a otros módulos los cuales pueden ser accedidos de manera similar: <span style="font-family: courier new,courier;">móduloPadre/móduloHijo/controlador/acción</span>.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/06/los-modulos-en-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Las vistas en Yii</title>
		<link>http://blog.jorgeivanmeza.com/2009/06/las-vistas-en-yii/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/06/las-vistas-en-yii/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 05:25:57 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1798</guid>
		<description><![CDATA[Introducción.

Son archivos PHP convencionales.
Pueden incluír elementos de interfaz de usuario basados en Yii.
Se recomienda que las vistas accedan a la información de los modelos pero que no los modifiquen.
Deben permanecer lo mas simples posibles, lógicas complejas deberían llevarse hasta el controlador.
El nombre del archivo donde se almacena la vista corresponde con el identificador junto con [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<ul>
<li>Son archivos PHP convencionales.</li>
<li>Pueden incluír elementos de interfaz de usuario basados en Yii.</li>
<li>Se recomienda que las vistas accedan a la información de los modelos pero que no los modifiquen.</li>
<li>Deben permanecer lo mas simples posibles, lógicas complejas deberían llevarse hasta el controlador.</li>
<li>El nombre del archivo donde se almacena la vista corresponde con el identificador junto con la extensión <span>.php</span>.
<ul>
<li>La vista <span>edit</span> se almacenará en el archivo <span>edit.php</span>.</li>
</ul>
</li>
<li>Los archivos de las vistas se almacenan bajo la ruta <span>protected/views/&lt;Identificador del controlador&gt;</span>.</li>
<li>Desde la vista es posible acceder a los atributos del controlador a través del objeto <span>$this</span>.</li>
<li>Para procesar una vista se debe invocar el método <span>CController::render(&lt;Identificador de vista&gt;)</span>.</li>
<li>Es posible pasar explícitamente información desde el controlador a la vista en el momento de su generación.
<pre class="php">$this -&gt; render('edit', array (
    'variable1' =&gt; $valor1,
    'variable2' =&gt; $valor2
));</pre>
<ul>
<li>En la vista <span>edit</span> se podrá acceder a<span> $variable1</span> y <span>$variable2</span> como variables convencionales.</li>
</ul>
</li>
</ul>
<h2><em>Layouts</em> (diseños).</h2>
<ul>
<li>El <em>layout</em> permite especificar el diseño común y constante de la interfaz de usuario.</li>
<li>Evita la necesidad de agregar elementos comúnes (archivos javascript y css, título, subtítulo, menú izquierdo, pies, etc) a todas las páginas en cada una de ellas.</li>
<li>El <em>layout</em> aplica a todo el sitio web y se aplica automáticamente al invocar el método <span>render</span>.</li>
<li>Para generar una vista <span>sin</span> el <em>layout</em> es necesario utilizar el método <span>renderPartial</span>.</li>
<li>El <em>layout</em> utilizado por defecto se encuentra en <span>views/layouts/main.php</span>.
<ul>
<li>Es posible modificar esto alterando <span>CWebApplication::layout</span> para toda la aplicación o <span>CController::layout</span> para todas las acciones del controlador.</li>
</ul>
</li>
<li>En el <em>layout</em> se debe incluír la variable <span>$</span><span>content</span> para especificar la ubicación en la que se agregará el contenido de la vista específica al controlador/acción ejecutado (parte no constante de la interfaz de usuario).</li>
</ul>
<h2><em>Widgets</em>.</h2>
<ul>
<li>Los <em><a href="http://es.wikipedia.org/wiki/Widget" >widgets</a></em> son componentes predefinidos para la presentación de la interfaz de usuario.</li>
<li>Generalmente agregan una funcionalidad gráfica compleja, específica y autocontenida.</li>
<li>Heredan de <span>CWidget</span>.</li>
<li>Su forma de invocarlos depende de si tienen o no contenido en su cuerpo.
<ul>
<li>Sin contenido en su cuerpo.
<pre class="php">&lt;? php $this -&gt; widget('ruta.a.la.ClaseWidget'); ?&gt;</pre>
</li>
<li>Con contenido en su cuerpo.
<pre class="php">&lt;? php $this -&gt; beginWidget('ruta.a.la.ClaseWidget'); ?&gt;
... contenido del cuerpo del Widget ...
&lt;? php $this -&gt; endWidget(); ?&gt;</pre>
</li>
</ul>
</li>
<li>Es posible definir valores iniciales para los atributos del <em>Widget</em> durante su invocación con <span>widget</span> o <span>beginWidget</span>.
<pre class="php">$this -&gt; widget('CMaskedTextField', array (
    'mask' =&gt; '99/99/9999'
));</pre>
</li>
</ul>
<h3>Creación de nuevos <em>Widgets</em>.</h3>
<ul>
<li>El nuevo <em>widget</em> debe heredar de <span>CWidget</span> e implementar los métodos <span>init</span> y <span>run</span>.
<pre class="php">class NuevoWidget extends CWidget
{
    public function init()
    {
        // Invocado por CController::beginWidget().
    }

    public function run()
    {
        // Invocado por CController::endWidget().
    }
}</pre>
</li>
<li>Tienen sus propias vistas y se ubican por defecto en el directorio <span>views</span> bajo el directorio que contiene la clase del <em>widget</em>.</li>
<li>Estas vistas se generan invocando <span>CWidget::render()</span>.</li>
</ul>
<h2>Vistas del sistema.</h2>
<ul>
<li>Estas vistas se utilizan para mostrar errores del sistema o información de registro.</li>
<li>Las excepciones de HTTP (<span>CHTTPException</span>) se despliegan con las vistas <span>errorXXX</span> donde <span>XXX</span> es el código del error HTTP generado.</li>
<li>Las vistas por defecto provistas por Yii se ubican en <span>framework/views</span> y pueden personalizarse definiéndolas en <span>protected/views/system</span>.</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/06/las-vistas-en-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Los Controladores en Yii</title>
		<link>http://blog.jorgeivanmeza.com/2009/06/los-controladores-en-yii/</link>
		<comments>http://blog.jorgeivanmeza.com/2009/06/los-controladores-en-yii/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 04:19:58 +0000</pubDate>
		<dc:creator>jimezam</dc:creator>
				<category><![CDATA[Sindicados]]></category>
		<category><![CDATA[Desarrollo de software]]></category>
		<category><![CDATA[Hipergalaxia]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[yii]]></category>

		<guid isPermaLink="false">http://blog.jorgeivanmeza.com/?p=1790</guid>
		<description><![CDATA[Introducción.

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 [...]]]></description>
			<content:encoded><![CDATA[<h2>Introducción.</h2>
<div id="attachment_1482" class="wp-caption aligncenter" ><a href="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/03/structure.png"><img class="size-full wp-image-1482" title="structure" src="http://blog.jorgeivanmeza.com/wp-content/uploads/2009/03/structure.png" alt="Estructura de una aplicación Yii." width="400" height="300" /></a><p class="wp-caption-text">Estructura de una aplicación Yii.</p></div>
<ul>
<li>El <a href="http://es.wikipedia.org/wiki/Modelo_Vista_Controlador" >Modelo/Vista/Controlador</a> es un <a href="http://es.wikipedia.org/wiki/Patr%C3%B3n_de_dise%C3%B1o" >patrón de diseño</a>.</li>
<li>Su utilidad radica en separar la <strong>lógica del negocio</strong> de la <strong>interfaz de usuario</strong>.</li>
<li>El <strong>modelo</strong> representa la información y las reglas del negocio asociadas a ella.</li>
<li>La <strong>vista</strong> representa a los componentes de la interfaz de usuario y todo lo relacionado con su presentación.</li>
<li>El <strong>controlador</strong> recibe la solicitud del usuario (controlador, acción e información) e intermedia entre la vista y los modelos para elaborar la respuesta.</li>
<li>El <strong>controlador frontal</strong> (<span>index.php</span>) 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.</li>
<li>Consultar <a href="http://blog.jorgeivanmeza.com/2009/03/principales-flujos-en-yii/" >secuencia de procesamiento de un requerimiento</a>.</li>
</ul>
<h2>El controlador.</h2>
<ul>
<li>Hereda de <span>CController</span>.</li>
<li>Su identificador es de la forma <span>ruta/a/xyz</span> (ejemplo: <span>user</span>).</li>
<li>Corresponde con el archivo <span>protected/controllers/ruta/a/XyzController.php</span> (ejemplo: <span>protected/controllers/UserController.php</span>).</li>
<li>Si la aplicación utiliza módulos, su identificador se incluye en la ruta del identificador del controlador.</li>
<li>Incluye una o mas acciones.</li>
<li>Incluye cero o mas filtros para sus acciones.</li>
<li>La instanciación de un controlador puede realizarse de la siguientes maneras según el contexto.
<ul>
<li>Si se define <span>CWebApplication::catchAllRequest</span>, todas las solicitudes serán redireccionadas al controlador indicado ignorándose el solicitado.  Es útil para poner el sitio fuera de línea.</li>
<li>Si el identificador del controlador solicitado se encuentra en <span>CWebApplication::controllerMap</span> se utilizará el controlador asociado en la conversión.</li>
<li>Se busca el controlador en la ubicación específica según su ruta.</li>
<li>Si el controlador no existe se lanza una <span>CHttpException</span> 404.</li>
</ul>
</li>
</ul>
<h3>Las acciones.</h3>
<ul>
<li>Definen (implementan) que hacer ante el requerimiento específico de un usuario.</li>
<li>Si no se especifica una acción se utiliza la acción por defecto (<span>index</span>) que puede configurarse con <span>CController::defaultAction</span>.</li>
<li>Pueden implementarse de dos maneras.
<ul>
<li>Como un método del controlador cuyo nombre deberá ser <span>actionIdentificador</span>.
<ul>
<li>La acción <span>add</span> corresponderá con el método <span>add</span><span>View</span>.</li>
</ul>
</li>
<li>Como una nueva clase que hereda de <span>CAction</span> cuyo nombre deberá ser <span>IdentificadorAction</span> e implementa el método <span>run</span>.
<ul>
<li>La acción <span>add</span> en este caso corresponderá con una instancia de la clase <span>AddAction</span>.</li>
<li>Para que este caso funcione se debe sobreescribir el método <span>actions</span> del controlador estableciendo la relación entre identificador de la acción y clase que la implementa.
<pre class="php">...
public function actions()
{
    return array(
        'add' =&gt; 'application.controllers.post.AddAction'
    );
}
...</pre>
</li>
<li>Se recomienda almacenar las acciones bajo el alias de <span>application.controllers.&lt;identificador del controlador&gt;</span> que hace referencia a la ruta física <span>protected/controllers/</span><span>&lt;identificador del controlador&gt;.</span></li>
</ul>
</li>
</ul>
</li>
</ul>
<h3>Los filtros.</h3>
<ul>
<li>Permiten manipular el flujo de ejecución de la acción solicitada.</li>
<li>Se ejecutan antes y después de la acción solicitada permitiendo filtrar si esta es efectivamente invocada o no.</li>
<li>Ú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.).</li>
<li>Una acción puede tener cero o mas filtros.</li>
<li>Los filtros se ejecutan en el mismo orden en que fueron definidos.</li>
<li>Un filtro puede decidir si los demás filtros o la acción no deben ser ejecutados.</li>
<li>Al igual que las acciones, los filtros pueden implementarse de dos maneras.
<ul>
<li>Como un método del controlador cuyo nombre deberá ser <span>filterIdentificador</span>.
<ul>
<li>El filtro <span>editPassword</span> corresponderá con el método <span>filterEditPassword.</span>
<pre class="php">public function filterEditPassword($filterChain)
{
    // $filterChain -&gt; run() continúa la ejecución de los filtros.
}</pre>
</li>
</ul>
</li>
<li>Como una nueva clase que hereda de <span>CFilter</span> cuyo nombre deberá ser <span>IdentificadorFilter.</span>
<ul>
<li>Se deben implementar los métodos <span>preFilter</span> y <span>postFilter</span> que se ejecutarán antes y después de invocarse la acción.
<pre class="php">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.
    }
}</pre>
</li>
</ul>
</li>
</ul>
</li>
<li>Es necesario sobreescribir el <span>método CController::filters()</span> para asociar los filtros a las acciones.
<pre class="php">...
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' =&gt; 'usuario'
        )
    );
}
...</pre>
<ul>
<li>El filtro <span>editPassword</span> está implementado por un método del controlador mientras que el filtro <span>checkAuth</span> está basado en una clase que hereda de <span>CFilter</span>.</li>
<li>El alias <span>application.filters</span> hace referencia a la ruta física <span>protected/filters</span>.</li>
<li>Es posible especificar valores para los atributos del filtro utilizando un arreglo en la definición de los <span>filters </span>tal y como se le asigna un valor al atributo <span>tipo</span> del filtro <span>checkAuth</span>.</li>
<li>Los operadores + y - modifican el alcance de la relación entre filtros y acciones.
<ul>
<li><span>+</span>: el filtro se aplica a las acciones especificadas.  (incluye).
<ul>
<li>El filtro<span> editPassword</span> se aplica a las acciones <span>edit</span> y <span>create</span> únicamente.</li>
</ul>
</li>
<li><span>-</span>: el filtro se aplica a todas las acciones exceptuando las especificadas.  (excluye).
<ul>
<li>El filtro <span>checkAuth</span> se aplica a todas las acciones menos a <span>logout</span> e <span>index</span>.</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2>Enlaces.</h2>
<ul>
<li>Yii Web Programming Framework.<br />
<a href="http://www.yiiframework.com/" >http://www.yiiframework.com/</a></li>
<li>Yii Documentation.<br />
<a href="http://www.yiiframework.com/doc/" >http://www.yiiframework.com/doc/</a></li>
</ul>
<div id="_mcePaste" >
<pre>    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.
    }</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.jorgeivanmeza.com/2009/06/los-controladores-en-yii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

