<?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>Blog cakephp en español por Hospedaxes &#187; cakephp-1.2</title>
	<atom:link href="http://cakephp.hospedaxes.com/category/cakephp-12/feed" rel="self" type="application/rss+xml" />
	<link>http://cakephp.hospedaxes.com</link>
	<description>Blog sobre desarrollo web con cakephp en español por Hospedaxes</description>
	<lastBuildDate>Mon, 26 Apr 2010 07:11:23 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Lanzamiento de la versión 1.2.7 de CakePHP</title>
		<link>http://cakephp.hospedaxes.com/lanzamiento-version-1-2-7-cakephp</link>
		<comments>http://cakephp.hospedaxes.com/lanzamiento-version-1-2-7-cakephp#comments</comments>
		<pubDate>Fri, 23 Apr 2010 07:25:48 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[1.2.7]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[lanzamiento]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=315</guid>
		<description><![CDATA[A la espera de que salga la versión 1.3 final de CakePHP (ya han lanzado la RC4), ayer han anunciado en su web la publicación de la versión 1.2.7. Como se puede ver en el changelog, en esta nueva versión han corregido varios bugs (en concreto han cerrado 36 tickets); uno de ellos se refiere [...]]]></description>
			<content:encoded><![CDATA[<p>A la espera de que salga la versión 1.3 final de CakePHP (ya han lanzado la RC4), ayer han anunciado en su web la <a title="Lanzamiento de CakePHP 1.2.7" href="http://bakery.cakephp.org/articles/view/cakephp-1-2-7-released">publicación de la versión 1.2.7</a>. Como se puede ver en el <a title="Changelog CakePHP 1.2.7" href="http://cakephp.lighthouseapp.com/projects/42648/changelog-1-2-7">changelog</a>, en esta nueva versión han corregido varios bugs (en concreto han cerrado 36 tickets); uno de ellos se refiere a un parche de seguridad en el test suite, no excesivamente importante porque sólo era un problema cuando el debug estaba activado, por lo que en producción no se produciría. Si queremos corregir este error en una versión previa de CakePHP sin actualizarla, podemos encontrar la solución en este <a title="Corrección bug de seguridad en TestSuite" href="http://bin.cakephp.org/view/1459556460">parche</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/lanzamiento-version-1-2-7-cakephp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP Queue Plugin</title>
		<link>http://cakephp.hospedaxes.com/cakephp-queue-plugin</link>
		<comments>http://cakephp.hospedaxes.com/cakephp-queue-plugin#comments</comments>
		<pubDate>Thu, 22 Apr 2010 07:50:33 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[cola de email]]></category>
		<category><![CDATA[cola de tareas]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[queue]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=308</guid>
		<description><![CDATA[Después de más tiempo del que nos gustaría sin poder escribir nada (por falta de tiempo, no porque no haya multitud de temas interesantes que tratar acerca de Cake), hemos encontrado un plugin que debemos explicar, pues resulta verdaderamente interesante en casi cualquier proyecto de desarrollo, ¿quién no estaría interesado en integrar en su web [...]]]></description>
			<content:encoded><![CDATA[<p>Después de más tiempo del que nos gustaría sin poder escribir nada (por falta de tiempo, no porque no haya multitud de temas interesantes que tratar acerca de <a title="CakePHP" href="http://cakephp.org/">Cake</a>), hemos encontrado un plugin que debemos explicar, pues resulta verdaderamente interesante en casi cualquier <a title="Hospedaxes" href="http://www.hospedaxes.com">proyecto de desarrollo</a>, ¿quién no estaría interesado en integrar en su web una cola de tareas que permita ir realizándolas de manera progresiva sin perjudicar el rendimiento del sitio? Este comportamiento nos lo proporciona el plugin <a title="CakePHP Queue Plugin" href="http://github.com/MSeven/cakephp_queue">CakePHP Queue Plugin</a> y resulta muy interesante, sobre todo, para tareas de envío de correo. Podríamos optar por utilizar un cron para realizar estas tareas, este plugin plantea prácticamente la misma idea con un desarrollo verdaderamente sencillo y múltiples opciones de configuración muy útiles.</p>
<p>Seguiremos la explicación que proporciona <a title="MSeven" href="http://github.com/MSeven">MSeven</a> en su web para ir comentando paso a paso cómo utilizar este plugin:</p>
<p><strong>1. Instalación</strong></p>
<p>* Copiamos los ficheros proporcionados en la carpeta plugins</p>
<p>* Ejecutamos el siguiente comando desde la consola de CakePHP (en <em>/cake/console</em>/):</p>
<pre class="prettyprint"><code>cake schema run create -path plugins/queue/config/sql -name queue</code></pre>
<p><strong>2. Configuración:</strong></p>
<p>El plugin nos permite añadir un archivo de configuración personalizado (<em>app/config/queue.php</em>), que tendrá el siguiente formato:</p>
<pre class="prettyprint"><code>// Tiempo de espera cuando no se encuentra una tarea que ejecutar
$config['queue']['sleeptime'] = 1;

// Probabilidad (en %) de que se limpie una tarea antigua
$config['queue']['gcprop'] = 5;

// Timeout por defecto en que el shell espera por la ejecución de un trabajo
$config['queue']['defaultworkertimeout'] = 120;

// Número de reintentos si el trabajo falla o se ha alcanzado el timeout
$config['queue']['defaultworkerretries'] = 4;

// Tiempo (en segundos) después de que el shell ha terminado (0 = ilimitado)
$config['queue']['workermaxruntime'] = 0;

// Tiempo (en segundos) después de que los trabajos completados se eliminen de la base de datos
$config['queue']['cleanuptimeout'] = 3600;</code></pre>
<p><strong>3. Uso</strong></p>
<p>Desde comando podemos utilizar el plugin para llevar a cabo determinadas acciones:</p>
<ul>
<li><strong>Help</strong>: para mostrar un mensaje de ayuda
<pre class="prettyprint"><code>cake queue help</code></pre>
</li>
<li><strong>Add</strong>: intenta llamar a la función add() de una tarea, pues podría pasar que las tareas no permitan esta posibilidad.
<pre class="prettyprint"><code>cake queue add &lt;taskname&gt;</code></pre>
</li>
<li><strong>Runworker</strong>: ejecuta un proceso  que comprueba la cola y ejecuta las tareas pendientes, eliminando las que hayan caducado.
<pre class="prettyprint"><code>cake queue runworker</code></pre>
</li>
</ul>
<p><strong>4. Tareas Instaladas</strong></p>
<ul>
<li><strong>QueueEmail</strong>: tarea para insertar en la cola un email que se enviará utilizando el <a title="CakePHP API: Email Component" href="http://api.cakephp.org/class/email-component">EmailComponent</a> de CakePHP.</li>
</ul>
<p>Podríamos crear nuestras propias tareas siguiendo la guía que se encuentra en el archivo <em>cakephp_queue/vendors/shells/tasks/queue_example.php</em>. Nosotros hemos adaptado, por ejemplo, la tarea <em>queue_email.php</em> para utilizar un componente distinto de envío de correo que mejora su funcionamiento y proporciona más opciones de configuración.</p>
<p><strong>5. Uso</strong></p>
<p>5.1 Añadir al modelo <em>Queue.QueuedTask</em> la lista de modelos que se van a utilizar</p>
<p>5.2 Crear los datos que se le van a pasar al email, será un array con la siguiente estructura:</p>
<p>* <em>Settings</em>: todas las opciones de configuración de envío del email.</p>
<p>* <em>Vars</em>: variables que se pasarán a la vista. La propia tarea se encargará de hacer un set, los sets realizados en la función del controlador no los tendrá en cuenta.</p>
<pre class="prettyprint"><code>array (
   'settings' =&gt;
      array (
        'to' =&gt; null,</code><code>        </code><code>'subject' =&gt; null,
        'charset' =&gt; 'UTF-8',
        'from' =&gt; null,
        'sendAs' =&gt; 'html',
        'template' =&gt; null,
        'debug' =&gt; false,
        'additionalParams' =&gt; '',
        'layout' =&gt; 'default'
),
'vars' =&gt;
   array (
   ),
);</code></pre>
<p><em>Ejemplo:</em></p>
<pre class="prettyprint"><code>$email_data = array (
   'settings' =&gt;
      array (
        'attachments' =&gt; [fichero_adjunto],
        'from' =&gt; [email_origen],
        'layout' =&gt; [layout],
        'subject' =&gt; [asunto],
        'template' =&gt; [template],
        'to' =&gt; [destinatario],
),
'vars' =&gt;
   array (
      'asunto' =&gt; [asunto],
      'contenido' =&gt; [contenido],
      ... // Podríamos incluir tantas variables como consideremos necesario
      'fullBaseUrl' =&gt; FULL_BASE_URL, // Utilizaremos esta variable pues si utilizamos la propia de Cake en el template nos devolverá la ruta de la consola, no la de la aplicación
   ),
);</code></pre>
<p>3. Llamamos a la función que añade la tarea a la cola</p>
<pre class="prettyprint"><code>$this-&gt;QueuedTask-&gt;createJob('email', $email_data);</code></pre>
<p>Ahora únicamente nos quedaría llamar al <em>Runkworker</em> como se comentó anteriormente y ya tendremos nuestra cola de tareas funcionando.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/cakephp-queue-plugin/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Containable Behavior</title>
		<link>http://cakephp.hospedaxes.com/containable-behavior</link>
		<comments>http://cakephp.hospedaxes.com/containable-behavior#comments</comments>
		<pubDate>Mon, 23 Nov 2009 09:57:54 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[cakephp-1.2]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=299</guid>
		<description><![CDATA[Hasta ahora, en el desarrollo de aplicaciones web nos hemos encontrado siempre con el problema de la cantidad de datos que genera CakePHP en las consultas a los modelos.
En nuestros desarrollos siempre definimos las relaciones en los modelos y al hacer consultas find tenemos el problema de que un nivel de recursividad demasiado elevado nos [...]]]></description>
			<content:encoded><![CDATA[<p>Hasta ahora, en el <a title="Hospedaxes" href="http://www.hospedaxes.com">desarrollo de aplicaciones web</a> nos hemos encontrado siempre con el problema de la cantidad de datos que genera CakePHP en las consultas a los modelos.</p>
<p>En nuestros desarrollos siempre definimos las relaciones en los modelos y al hacer consultas <em>find</em> tenemos el problema de que un nivel de recursividad demasiado elevado nos genera demasiada información, ralentizando la ejecución debido a los <em>joins </em>generados, y un nivel inferior no alcanza para obtener las relaciones que deseamos utilizar. Además, en ocasiones, queremos obtener únicamente un modelo de entre todas las relaciones que componen una determinada entidad.</p>
<p>Esto nos llevaba a tener que utilizar llamadas a la función <em>unbind</em> (o <em>bind</em>, si es el caso) del <a title="Modelo en CakePHP" href="http://api.cakephp.org/class/model">modelo</a> al vuelo, previamente a la utilización de un <em>find</em>, o bien a tener que dividir la consulta en dos llamadas anidadas en un bucle, reduciendo el nivel de recursividad en ambas. La primera de las soluciones quizás complica excesivamente el desarrollo y la segunda reduce el rendimiento de la aplicación.</p>
<p>El <a title="Containable Behavior de CakePHP" href="http://api.cakephp.org/class/containable-behavior">Containable Behavior de CakePHP</a> nos resuelve este problema, ya que nos permite filtrar y limitar los modelos que generan las consultas a los modelos, mejorando el rendimiento de la aplicación con un sencillo modo de empleo.</p>
<p>Para utilizar este comportamiento lo primero que tendremos que hacer es definirlo en el modelo, ya sea utilizando la variable <em>$actAs</em> en la clase modelo, o bien, definiéndolo al vuelo en el controlador:</p>
<ul>
<li>En el modelo:
<pre class="prettyprint"><code>class Noticia extends AppModel {
   var $actsAs = array('Containable');
}</code></pre>
</li>
<li>En el controlador:
<pre class="prettyprint"><code>$this-&gt;Noticia-&gt;Behaviors-&gt;attach('Containable');</code></pre>
</li>
</ul>
<p>Una vez definido el comportamiento, ya podemos utilizarlo.</p>
<p>Si queremos utilizar un find sin recursividad, es decir:</p>
<pre class="prettyprint"><code>$this-&gt;Noticia-&gt;recursive = -1;
$this-&gt;Noticia-&gt;find('all');
// o bien: $this-&gt;Noticia-&gt;find('all', array('recursive' =&gt; -1));</code></pre>
<p>podríamos utilizar lo siguiente:</p>
<pre class="prettyprint"><code>$this-&gt;Noticia-&gt;find('all', array('contain' =&gt; false));</code></pre>
<p>o bien, utilizando la siguiente sintaxis:</p>
<pre class="prettyprint"><code>$this-&gt;Noticia-&gt;contain();
$this-&gt;Noticia-&gt;find('all');</code></pre>
<p>A continuación veremos un ejemplo con múltiples opciones de utilización:</p>
<pre class="prettyprint"><code>/**
* Usuario-&gt;Perfil
* Usuario-&gt;Cuenta-&gt;ResumenCuenta
* Usuario-&gt;Noticia-&gt;AdjuntoNoticia-&gt;HistorialAdjuntoNoticia-&gt;NotasHistorial
* Usuario-&gt;Noticia-&gt;Tag
*/
$this-&gt;Usuario-&gt;find('all', array(
   'contain'=&gt;array(
      'Perfil',
      'Cuenta' =&gt; array(
         'ResumenCuenta'
      ),
      'Noticia' =&gt; array(
         'AdjuntoNoticia' =&gt; array(
            'fields' =&gt; array('id', 'nombre'),
            'HistorialAdjuntoNoticia' =&gt; array(
            'NotasHistorial' =&gt; array(
               'fields' =&gt; array('id', 'nota')
            )
         )
      ),
      'Tag' =&gt; array(
         'conditions' =&gt; array('Tag.nombre LIKE' =&gt; '%feliz%')
      )
    )
  )
));</code></pre>
<p>Utilizando esta configuración obtendremos todos los campos de los modelos Usuario, Perfil, Cuenta y ResumenCuenta; y también las Noticias, aunque de los Adjuntos y su Historial únicamente los campos id y nombre. Y, por último, aquellos Tags que incluyan en su nombre la cadena &#8220;feliz&#8221;. Las demás relaciones del modelo, si las tuviera, no serían resultado de la búsqueda si no se especifican explícitamente.</p>
<p>Es importante tener en cuenta que incluir una condición a este nivel (por ejemplo, al nivel de Tag) sólo afecta al modelo en el que se ha introducido. Por lo tanto, los usuarios seguirán mostrándose igual aunque el array de Tags esté vacío. Se podrían incluir condiciones al <em>find</em> por el procedimiento común para filtrar elementos, aunque deberemos tener en cuenta la recursividad del <em>find</em>, en el caso de que ésta se establezca, pues incluir un modelo en la variable <em>contain</em> no implica que se pueda establecer condiciones a ese nivel si la recursividad no llega hasta él. Además, debemos tener en cuenta que si no establecemos una recursividad adecuada, no podremos llegar a la obtención de los modelos establecidos. Es recomendable no especificar ningún nivel de recursividad al utilizar este behavior.</p>
<p>En el caso de consultas paginadas, se utilizará la variable <em>contain</em> dentro de la función <em>paginate</em> al igual que hemos hecho en el <em>find</em>.</p>
<p>Existen algunas opciones de configuración del comportamiento, que pueden consultarse en el <a title="Containable Behavior en el CookBook." href="http://book.cakephp.org/view/474/Containable">cookbook</a>, documento del que se ha obtenido la información para la publicación  de este post.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/containable-behavior/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mostrar videos con FlowPlayer</title>
		<link>http://cakephp.hospedaxes.com/mostrar-videos-con-flowplayer</link>
		<comments>http://cakephp.hospedaxes.com/mostrar-videos-con-flowplayer#comments</comments>
		<pubDate>Wed, 28 Oct 2009 11:02:56 +0000</pubDate>
		<dc:creator>david</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[cakephp-1.2]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=259</guid>
		<description><![CDATA[Primero descargamos el FlowPlayer. Para ello vamos a la página oficial de descarga de FlowPlayer y lo instalamos en la carpeta    /app/webroot/js.
En la vista donde queremos que se vea el video se añade
&#60;?php
// Librería necesaria para el Flowplayer
   echo $javascript-&#62;link('flowplayer/example/flowplayer-3.1.4.min');
?&#62;
&#60;?php
   echo $html-&#62;link('', '/files/ejemplo.flv' , array('id' =&#62; 'player1' , [...]]]></description>
			<content:encoded><![CDATA[<p>Primero descargamos el FlowPlayer. Para ello vamos a la página oficial de descarga de <a href="http://flowplayer.org/download/index.html" target="_blank">FlowPlayer</a> y lo instalamos en la carpeta    /app/webroot/js.</p>
<p>En la vista donde queremos que se vea el video se añade</p>
<pre class="prettyprint"><code>&lt;?php
// Librería necesaria para el Flowplayer
   echo $javascript-&gt;link('flowplayer/example/flowplayer-3.1.4.min');
?&gt;
&lt;?php
   echo $html-&gt;link('', '/files/ejemplo.flv' , array('id' =&gt; 'player1' , 'class' =&gt; 'video'));
?&gt;
&lt;script language="JavaScript"&gt;
   // Función para cargar el Flowplayer en la zona correspondiente
   flowplayer(
    "player1",
    "&lt;?php echo Router::url("/"); ?&gt;js/flowplayer/flowplayer-3.1.5.swf",
    {
      clip: {
               autoPlay: false,
	       autoBuffering: true
	     }
     }
    );
&lt;/script&gt;</code></pre>
<p>Hemos de tener en cuenta la versión de FlowPlayer que hemos descargado en estas dos líneas</p>
<pre class="prettyprint"><code>echo $javascript-&gt;link('flowplayer/example/flowplayer-3.1.4.min');</code></pre>
<p>y</p>
<pre class="prettyprint"><code>"&lt;?php echo Router::url("/"); ?&gt;js/flowplayer/flowplayer-3.1.5.swf"</code></pre>
<p>que en este caso se corresponden con la versión FlowPlayer 3.1.5</p>
<p>Lo de player1 es por si quieres meter varios videos en la misma página, con lo que el segundo pondría player2 y así sucesivamente (o lo que consideres oportuno)</p>
<p>Además hay que añadir al css</p>
<pre class="prettyprint"><code>.video{
	display:block;
	width:400px;
	height:300px;
}</code></pre>
<p>FlowPlayer muestra videos que estén en formato flv. Una buena herramienta para convertir nuestros videos avi, mpeg, &#8230; a este formato flv es <a href="http://ffmpeg.org/" target="_blank">ffmpeg</a>.<br />
Un ejemplo de uso :</p>
<pre class="prettyprint"><code>ffmpeg -i entrada.avi  salida.flv</code></pre>
<p>En este <a title="Demostración de funcionamiento de FlowPlayer" href="http://cakephp.hospedaxes.com/pruebas/mostrar_video">link</a> podéis ver una demostración.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/mostrar-videos-con-flowplayer/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Utilizar cakephp sin base de datos</title>
		<link>http://cakephp.hospedaxes.com/utilizar-cakephp-sin-base-de-datos</link>
		<comments>http://cakephp.hospedaxes.com/utilizar-cakephp-sin-base-de-datos#comments</comments>
		<pubDate>Tue, 28 Apr 2009 07:57:23 +0000</pubDate>
		<dc:creator>bernal</dc:creator>
				<category><![CDATA[base de datos]]></category>
		<category><![CDATA[cakephp-1.2]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=187</guid>
		<description><![CDATA[Hay ocasiones en las que se puede dar que nos enfrentemos a un proyecto que no necesita tener una base de datos asociada, bien porque es un proyecto sencillo, bien porque no requiere tener datos almacenados o simplemente porque el servidor en el que vamos a alojar la aplicación no dispone de una base de [...]]]></description>
			<content:encoded><![CDATA[<p>Hay ocasiones en las que se puede dar que nos enfrentemos a un proyecto que no necesita tener una base de datos asociada, bien porque es un proyecto sencillo, bien porque no requiere tener datos almacenados o simplemente porque el servidor en el que vamos a alojar la aplicación no dispone de una base de datos.<br />
Esta razón no deberá ser un impedimento para seguir utilizando cakephp, con unos pequeños cambios podremos seguir usándolo normalmente.</p>
<p>En primer lugar tendremos que crear un nuevo datasource, estos ficheros van almacenados en el directorio &#8220;/app/models/datasources/dbo/&#8221;, será un fichero php cuyo nombre comience por dbo_, en nuestro caso lo llamaremos &#8220;dbo_mi_dbo.php&#8221;.</p>
<p>Tendrá el siguiente contenido:</p>
<pre class="prettyprint">
class DboMiDbo extends DboSource
{
	function connect()
	{
		$this->connected = true;
		return $this->connected;
	}
	function disconnect()
	{
		$this->connected = false;
		return !$this->connected;
	}
}
</pre>
<p>Después de esto tendremos que cambiar el driver de la base de datos utilizada por nuestro proyecto cakephp, por defecto mysql. Para esto, en el archivo database.php que se encuentra en &#8220;/app/config/&#8221;, modificamos la variable $default, debería quedar así:</p>
<pre class="prettyprint">
var $default = array(
		'driver' => 'mi_dbo',
		'persistent' => false,
		'host' => '',
		'port' => '',
		'login' => '',
		'password' => '',
		'database' => '',
		'schema' => '',
		'prefix' => '',
		'encoding' => ''
	);
</pre>
<p>Por último, en todos los modelos que creemos, tendremos que añadir la línea &#8220;<strong><em>var $useTable = false;</em></strong>&#8220;, para indicarle que ese modelo no va a tener una tabla asociada.</p>
<p>A partir de aquí podremos utilizar toda la potencia de cakephp sin preocuparnos de tener una base de datos instalada.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/utilizar-cakephp-sin-base-de-datos/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Validación en CakePHP 1.2 (III): Internacionalización de mensajes en el modelo</title>
		<link>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-iii-internacionalizacion-de-mensajes-en-el-modelo</link>
		<comments>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-iii-internacionalizacion-de-mensajes-en-el-modelo#comments</comments>
		<pubDate>Thu, 16 Apr 2009 10:37:46 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Validación 1.2]]></category>
		<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[internacionalizacion]]></category>
		<category><![CDATA[mensajes de error]]></category>
		<category><![CDATA[modelo]]></category>
		<category><![CDATA[validacion]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=141</guid>
		<description><![CDATA[Continuando con los posts anteriores relativos a la validación y relacionado con el post en el que se trata la localización e internacionalización de nuestras aplicaciones, explicaremos en éste cómo realizar la internacionalización de los mensajes de error. Tenemos dos opciones para implementar este funcionamiento:

Utilizar la función error del FormHelper (realizando la llamada desde la [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando con los posts anteriores relativos a la <a title="Validación en CakePHP 1.2 (I)" href="http://cakephp.hospedaxes.com/validacion-en-cakephp-12">validación</a> y relacionado con el post en el que se trata la <a title="Localización e internacionalización" href="http://cakephp.hospedaxes.com/localizacion-e-internacionalizacion" target="_blank">localización e internacionalización</a> de nuestras aplicaciones, explicaremos en éste cómo realizar la internacionalización de los mensajes de error. Tenemos dos opciones para implementar este funcionamiento:</p>
<ol>
<li>Utilizar la función <a title="Función error del FormHelper de CakePHP" href="http://api.cakephp.org/class/form-helper#method-FormHelpererror" target="_blank">error</a> del <a title="Form Helper (API CakePHP)" href="http://api.cakephp.org/class/form-helper" target="_blank">FormHelper</a> (realizando la llamada desde la vista) o la función <a title="Función invalidate del modelo de CakePHP" href="http://api.cakephp.org/class/model#method-Modelinvalidate" target="_blank">invalidate</a> del <a title="Clase Modelo de CakePHP" href="http://api.cakephp.org/class/model" target="_blank">modelo</a> (si realizamos la validación manual desde el controlador).</li>
<li>Utilizar el propio modelo como fuente de estos mensajes de error.</li>
</ol>
<p>En el primero de los casos utilizaríamos el siguiente código para la vista y el controlador respectivamente:</p>
<pre class="prettyprint">$form->error('campo', __('MENSAJE_ERROR', true));
$this->Modelo->invalidate('campo', __('MENSAJE_ERROR', true));</pre>
<p>y de esta forma buscaría esa clave del mensaje en el fichero de idioma.</p>
<p>La ventaja de hacerlo desde el modelo y no desde las vistas es que nos permite unificar los mensajes de error en cada campo y evitar la repetición de este código cuando estemos en formularios distintos que incluyan los mismos campos. El inconveniente es que en el modelo no se permite la utilización de la función __() de <a title="CakePHP" href="http://cakephp.org/" target="_blank">CakePHP</a>.</p>
<p>Para solucionar este problema será necesario modificar la clase <a title="AppModel de CakePHP" href="http://api.cakephp.org/class/app-model" target="_blank">AppModel</a> de la que extienden todos los modelos y que a su vez extiende de <a title="Clase Model en CakePHP" href="http://api.cakephp.org/class/model" target="_blank">Model</a> para redefinir la función <a title="Función invalidate del modelo de CakePHP" href="http://api.cakephp.org/class/model#method-Modelinvalidate" target="_blank">invalidate</a> (podemos ver la definición original en el <a href="http://api.cakephp.org/view_source/model/#line-2466">api de CakePHP</a>). Así, el fichero cake/libs/model/app_model.php quedaría como se muestra a continuación:</p>
<pre class="prettyprint"><code>&lt;?php
class AppModel extends Model {
   function invalidate($field, $value = true) {
      if (!is_array($this-&gt;validationErrors)) {
         $this-&gt;validationErrors = array();
      }
      $this-&gt;validationErrors[$field] = <strong>__($value, true)</strong>;
   }
}
?&gt;</code></pre>
<p>Con este simple cambio, tenemos los mensajes de error del modelo internacionalizados.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-iii-internacionalizacion-de-mensajes-en-el-modelo/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Consultas complejas con cakephp</title>
		<link>http://cakephp.hospedaxes.com/consultas-complejas-con-cakephp</link>
		<comments>http://cakephp.hospedaxes.com/consultas-complejas-con-cakephp#comments</comments>
		<pubDate>Mon, 23 Mar 2009 13:07:43 +0000</pubDate>
		<dc:creator>bernal</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[between]]></category>
		<category><![CDATA[busquedas complejas]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[find]]></category>
		<category><![CDATA[in]]></category>
		<category><![CDATA[nor]]></category>
		<category><![CDATA[not]]></category>
		<category><![CDATA[or]]></category>
		<category><![CDATA[sql]]></category>
		<category><![CDATA[xor]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=151</guid>
		<description><![CDATA[El framework cakephp tiene una definición de los modelos muy potente, lo que hace que sea muy fácil acceder a los datos de la base de datos, realizando consultas todo lo complejas que se desee.
En esta entrada hablaremos de todas las posiblidades, que tal vez no conozcáis, de establecer las condiciones de una consulta en [...]]]></description>
			<content:encoded><![CDATA[<p>El framework cakephp tiene una definición de los modelos muy potente, lo que hace que sea muy fácil acceder a los datos de la base de datos, realizando consultas todo lo complejas que se desee.<br />
En esta entrada hablaremos de todas las posiblidades, que tal vez no conozcáis, de establecer las condiciones de una consulta en cakephp.</p>
<p><strong>Consulta sencilla</strong></p>
<p>Las consultas más simples, que afectan a una única columna son fáciles de realizar, se resuelven con un find y la condición pasada como un parámetro en la llamada a este método.</p>
<p>De esta manera:</p>
<pre class="prettyprint">$this->Modelo->find('all',array('conditions'=>'Modelo.columna = valor'))</pre>
<p>se generará un select con una condición </p>
<pre class="prettyprint">where Modelo.columna = valor</pre>
<p><strong>Consulta con varias condiciones separadas por AND</strong></p>
<p>Surge la duda de ¿qué sucede si deseamos realizar una consulta con varias condiciones?, se podría hacer poniendo como segundo parámetro del array conditions una cadena con todas las condiciones concatenadas con AND entre ellas, pero cakephp ya pensó en eso y hay una manera más sencilla y más limpia de hacerlo, que es pasar un array con todas las condiciones que deseamos que cumpla la consulta, con el formato Modelo.columna =&gt; valor :</p>
<p>De esta manera:</p>
<pre class="prettyprint">$this->Modelo->find('all',array('conditions'=>array('Modelo.columna' => 'valor','Modelo.columna2' => 'valor2')))</pre>
<p>Esta llamada generará una consulta con una condición</p>
<pre class="prettyprint">where Modelo.columna = valor1 AND Modelo.columna2 = valor2</pre>
<p><strong>Consulta utilizando <>, <=, >=, > o <</strong></p>
<p>Si en lugar de querer que todas las columnas coincidan con los valores que se les pasan en el array, queremos que alguna columna sea distinta del valor, la condición debería tener este formato</p>
<pre class="prettyprint">$this->Modelo->find('all',array('conditions'=>array('Modelo.columna <>' => 'valor','Modelo.columna2' => 'valor2')))</pre>
<p>Esta llamada generará una consulta con una condición </p>
<pre class="prettyprint">where Modelo.columna <> valor1 AND Modelo.columna2 = valor2</pre>
<p>Este formato también permitiría además de utilizar el distinto de (<>), utlizar mayor que (>) ,mayor o igual que (>=), menor que (<) o menor o igual que (<=).</p>
<p><strong>Consulta utilizando OR</strong></p>
<p>Una nueva duda surge cuando se nos plantea, ¿qué pasa si en lugar de realizar una consulta con condiciones separadas con AND queremos crear una consulta con las condiciones separada por OR?, pues cakephp también permite hacerlo de manera muy sencilla, creando un find con el siguiente formato:</p>
<pre class="prettyprint">$this->Modelo->find('all',array('conditions'=>array('OR'=>array('Modelo.columna' => 'valor','Modelo.columna2' => 'valor2'))))</pre>
<p>Esto creará una consulta con una condición </p>
<pre class="prettyprint">where Modelo.columna = valor OR Modelo.columna2 => valor2</pre>
<p>Esta opción se puede utilizar con cualquiera de los operadores booleanos AND, OR, NOT, XOR.</p>
<p>Cakephp también permite otras opciones más complejas:</p>
<p><strong>Consulta utilizando IN</strong></p>
<p>¿Qué sucede si queremos utilizar una consulta en la que queramos que una columna coincida con una serie de valores?. Para esto, lo más sencillo sería utilizar la sentencia sql in.<br />
Instintivamente la primera idea que podemos tener para crear una consulta de este tipo es generar una cadena con todos los valores que deseamos pasarle a la consulta y esto concatenarlo con Modelo.columna IN.<br />
Cakephp ya había pensado en esto y ha hecho que sea mucho más sencillo que todo esto, para realizar una consulta con un IN como condición habrá que pasarle un array con los valores que queramos que se compruebe la coincidencia, de este modo:</p>
<pre class="prettyprint">
$valores = array(1,2,3,4,5,6);
$this->Modelo->find('all',array('conditions'=>array('Modelo.columna' => $valores,'Modelo.columna2' => 'valor2')))</pre>
<pre class="prettyprint">where Modelo.columna in (1,2,3,4,5,6) AND Modelo.columna2 => valor2</pre>
<p><strong>Consulta utilizando NOT IN</strong></p>
<p>Si en lugar de que se compruebe la coincidencia con ciertos valores, se compruebe la no coincidencia <strong>(NOT IN)</strong>, haremos la llamada de esta manera:</p>
<pre class="prettyprint">
$valores = array(1,2,3,4,5,6);
$this->Modelo->find('all',array('conditions'=>array('NOT'=>array('Modelo.columna' => $valores),'Modelo.columna2' => 'valor2')))</pre>
<pre class="prettyprint">where Modelo.columna in (1,2,3,4,5,6) AND Modelo.columna2 => valor2</pre>
<p><strong>Consulta utilizando BETWEEN</strong></p>
<p>Podría darse la posibilidad de tener que comprobar si el valor de un campo está contenido entre dos valores dados (BETWEEN), para esto igual que para la expresión in se nos ocurriría crear una cadena concatenando los valores y la sentencia sql, pero cakephp permite una forma mucho más sencilla de crearlo:</p>
<pre class="prettyprint">
$this->Modelo->find('all',array('conditions'=>array(array('Modelo.columna BETWEEN ? AND ?' => array(1,8)))))</pre>
<p>Esta llamada al find crearía una consulta sql con la siguiente condición:</p>
<pre class="prettyprint">where Modelo.columna between 1 AND 8</pre>
<p>Con todas estas opciones se podrían crear consultas tan complejas como deseemos sin tener que preocuparnos de generar cadenas con el código sql para concatenar a las condiciones, de una manera muy sencilla e intuitiva.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/consultas-complejas-con-cakephp/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Validación en CakePHP 1.2 (II)</title>
		<link>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-ii</link>
		<comments>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-ii#comments</comments>
		<pubDate>Wed, 12 Nov 2008 14:22:20 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[Validación 1.2]]></category>
		<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[personalizada]]></category>
		<category><![CDATA[validacion]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=136</guid>
		<description><![CDATA[Continuando con el post Validación en CakePHP 1.2, explicaremos en esta ocasión cómo validar formatos de campos permitiendo que estén vacíos y cómo realizar una validación personalizada, introduciendo manualmente el código de validación.
Validaciones con campos vacíos
Hasta hoy, no habíamos encontrado la forma de validar formatos de campos, permitiendo que se encuentren vacíos, directamente en el [...]]]></description>
			<content:encoded><![CDATA[<p>Continuando con el post <a title="Validación en CakePHP 1.2" href="http://cakephp.hospedaxes.com/validacion-en-cakephp-12">Validación en CakePHP 1.2</a>, explicaremos en esta ocasión cómo validar formatos de campos permitiendo que estén vacíos y cómo realizar una validación personalizada, introduciendo manualmente el código de validación.</p>
<p><strong>Validaciones con campos vacíos</strong></p>
<p>Hasta hoy, no habíamos encontrado la forma de validar formatos de campos, permitiendo que se encuentren vacíos, directamente en el modelo. Lo que hacíamos era hacer este tipo de comprobaciones manualmente, rompiendo un poco la flexibilidad que nos ofrece CakePHP para hacer las validaciones directamente en el modelo y sin volver a preocuparnos de ellas.</p>
<p>Ahora ya descubrimos la manera de hacerlo. Es una cosa muy simple que habíamos pasado por alto. Simplemente tenemos que pasar un parámetro a la función de validación, de la manera siguiente:</p>
<pre class="prettyprint"><code>var $validate = array(
   'email' =&gt; array(
   'valid' =&gt; array( 'rule' =&gt; array('email'),
                             <strong>'allowEmpty' =&gt; true</strong>,
                             'message' =&gt; 'Formato email inválido')
                             )
              );</code></pre>
<p><strong>Validación a medida</strong></p>
<p>En el modelo introduciremos el siguiente código:</p>
<pre class="prettyprint"><code>var $validate = array(
    'campo' =&gt; array(
                  'valid' =&gt; array( 'rule' =&gt; 'reglaPropia',
                              'param1'=&gt;'valor',
                              'message' =&gt; 'Mensaje de salida')
                              )
                    );

function reglaPropia($value, $params)
{
   $valid = false;
   if (!condicion){
      // Asignamos el valor a $valid en función de la condición que queramos establecer
   }
   return $valid;
}</code></pre>
<p>A la función creada le hemos pasado dos argumentos, aunque el segundo podríamos no ponerlo si no es necesario. Ambos serán arrays, de manera que si queremos acceder al valor del campo a validar tendremos que leer <em>$value['campo']</em> y para acceder a los parámetros <em>$params['param1']</em> , pudiendo introducir tantos parámetros como sea necesario.</p>
<p>En esta función podemos utilizar también las funciones de validación de CakePHP. Por ejemplo:</p>
<pre class="prettyprint">$valid = Validation::custom($value['campo'], $params['param1']);</pre>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/validacion-en-cakephp-12-ii/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nueva versión de Cakephp 1.2</title>
		<link>http://cakephp.hospedaxes.com/nueva-version-de-cakephp-12-2</link>
		<comments>http://cakephp.hospedaxes.com/nueva-version-de-cakephp-12-2#comments</comments>
		<pubDate>Fri, 10 Oct 2008 09:27:48 +0000</pubDate>
		<dc:creator>bernal</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[cakephp-1.2]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=124</guid>
		<description><![CDATA[Hace unos días CakePHP lanzaba la tercera candidata de la beta de la versión 1.2 de su framework.
Todavía no sabemos si aporta algo nuevo. Como en versiones anteriores corrige bugs y por lo que se puede ver en la noticia del lanzamiento aumenta hasta 10 veces la velocidad de la anterior candidata.
Como siempre, iremos comentando [...]]]></description>
			<content:encoded><![CDATA[<p>Hace unos días CakePHP lanzaba la <a href="http://cakeforge.org/frs/?group_id=23&amp;release_id=426" target="_blank">tercera candidata</a> de la beta de la versión 1.2 de su framework.</p>
<p>Todavía no sabemos si aporta algo nuevo. Como en versiones anteriores corrige bugs y por lo que se puede ver en la <a href="http://bakery.cakephp.org/articles/view/release-cakephp-rc3-the-rc-of-triumph" target="_blank">noticia del lanzamiento</a> aumenta hasta 10 veces la velocidad de la anterior candidata.</p>
<p>Como siempre, iremos comentando las nuevas características e impresiones que tengamos en el <a href="http://www.hospedaxes.com" target="_blank">desarrollo páginas web</a>, con esta nueva versión candidata.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/nueva-version-de-cakephp-12-2/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Conexiones HTTP seguras (https) en CakePHP 1.2</title>
		<link>http://cakephp.hospedaxes.com/conexiones-http-seguras-https-en-cakephp-12</link>
		<comments>http://cakephp.hospedaxes.com/conexiones-http-seguras-https-en-cakephp-12#comments</comments>
		<pubDate>Thu, 09 Oct 2008 07:13:04 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[cakephp-1.2]]></category>
		<category><![CDATA[cakephp]]></category>
		<category><![CDATA[conexiones seguras]]></category>
		<category><![CDATA[http seguro]]></category>
		<category><![CDATA[https]]></category>
		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=65</guid>
		<description><![CDATA[Para el desarrollo de conexiones seguras de nuestra página web, vamos a utilizar un método que hemos visto en el weblog de Tanveer. Lo normal es que necesitemos que algunas de las páginas de la web sean seguras, como pueden ser formularios de contratación de servicios, y otras no lo sean, por ejemplo páginas simples [...]]]></description>
			<content:encoded><![CDATA[<p>Para el desarrollo de conexiones seguras de nuestra página web, vamos a utilizar un método que hemos visto en el <a title="Creatiing a route usage https ssl connection" href="http://neeocis.wordpress.com/2008/07/09/cakephp-creating-a-route-usage-https-ssl-connection/">weblog de Tanveer</a>. Lo normal es que necesitemos que algunas de las páginas de la web sean seguras, como pueden ser formularios de contratación de servicios, y otras no lo sean, por ejemplo páginas simples de información de dichos servicios. Por lo que desarrollaremos un sistema que nos permita hacer el cambio entre unas y otras.</p>
<p>Utilizamos para implementar este mecanismo el <a title="Componenete para forzar conexiones seguras" href="http://bakery.cakephp.org/articles/view/component-for-forcing-a-secure-connection">componente de la Bakery de CakePHP para forzar conexiones seguras</a>, y lo utilizaremos de la misma manera que se explica en este artículo, pero añadiéndole la funcionalidad inversa. Lo explicaremos paso a paso:</p>
<p>- Añadimos el componente ssl.php, en la carpeta app/controllers/components/ con el siguiente contenido:</p>
<pre class="prettyprint"><code>&lt;?php
class SslComponent extends Object {

   var $components = array('RequestHandler');

   var $Controller = null;

   function initialize(&amp;$Controller) {
      $this-&gt;Controller = $Controller;
   }

   function force() {
      if(!$this-&gt;RequestHandler-&gt;isSSL()) {
        $this-&gt;Controller-&gt;redirect('https://'.$this-&gt;__url());
      }
   }

   function unforce() {
      if($this-&gt;RequestHandler-&gt;isSSL()) {
         $this-&gt;Controller-&gt;redirect('http://'.$this-&gt;__urll());
      }
   }

   function __url() {
      $port = env('SERVER_PORT') == 80 ? '' : ':'.env('SERVER_PORT');
      return env('SERVER_NAME').$port.env('REQUEST_URI');
   }

   function __urll() {
      $port = env('SERVER_PORT') == 443 ? '' : ':'.env('SERVER_PORT');
      return env('SERVER_NAME').$port.env('REQUEST_URI');
   }

}
?&gt;</code></pre>
<p>- Añadimos en el app_controller (cake/libs/controlller/app_controller.php) la redirección a conexión segura para aquellas acciones que nos interese. Ésta es otra diferencia con el artículo de la Bakery, ya que en ésta se hace esa redirección desde cada acción de cada controlador.</p>
<pre class="prettyprint"><code>&lt;?php
class AppController extends Controller {

   var $components = array( 'Ssl' );

   public function beforeRender(){
      $action = array( 'action1', 'action2' );
      if( in_array( $this-&gt;params['action'] , $action ) ){
         $this-&gt;Ssl-&gt;force();
      }else{
         $this-&gt;Ssl-&gt;unforce();
      }
   }

}
?&gt;</code></pre>
<p>Podríamos cambiar en este punto la condición por la que nos interese para nuestro caso, por ejemplo, que sean controladores (todas las acciones de ese controlador) los que necesiten añadir este tipo de conexión.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/conexiones-http-seguras-https-en-cakephp-12/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

