<?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</title>
	<atom:link href="http://cakephp.hospedaxes.com/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>Lanzada la versión 1.3.0 estable de CakePHP</title>
		<link>http://cakephp.hospedaxes.com/lanzada-la-version-1-3-0-estable-de-cakephp</link>
		<comments>http://cakephp.hospedaxes.com/lanzada-la-version-1-3-0-estable-de-cakephp#comments</comments>
		<pubDate>Mon, 26 Apr 2010 07:11:23 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=319</guid>
		<description><![CDATA[Después de la publicación el viernes pasado del lanzamiento de la versión 1.2.7, el sábado los desarrolladores de CakePHP anunciaban la nueva y esperada versión estable 1.3.0. En el propio anuncio en la bakery tenéis enlaces para conocer cómo realizar la migración desde versiones 1.2 a la 1.3, las nuevas funcionalidades añadidas, el changelog y, [...]]]></description>
			<content:encoded><![CDATA[<p>Después de la publicación el viernes pasado del lanzamiento de la versión 1.2.7, el sábado los desarrolladores de CakePHP <a title="Anuncio oficial del lanzamiento de CakePHP 1.3.0 estable" href="http://bakery.cakephp.org/articles/view/announcing-cakephp-1-3-0-stable">anunciaban</a> la nueva y esperada versión estable 1.3.0. En el propio anuncio en la bakery tenéis enlaces para conocer cómo realizar la <a title="Migrar CakePHP desde versiones 1.2 a 1.3" href="http://book.cakephp.org/view/1561/Migrating-from-CakePHP-1-2-to-1-3">migración desde versiones 1.2 a la 1.3</a>, las <a title="Nuevas funcionalidades de CakePHP 1.3" href="http://book.cakephp.org/view/1572/New-features-in-CakePHP-1-3">nuevas funcionalidades</a> añadidas, el <a title="Changelog 1.3" href="http://cakephp.lighthouseapp.com/projects/42648/changelog-1-3-0">changelog</a> y, por supuesto, el <a title="Página de descarga de la versión 1.3 de CakePHP" href="http://github.com/cakephp/cakephp1x/downloads">enlace de descarga</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/lanzada-la-version-1-3-0-estable-de-cakephp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<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>CakePHP Questions</title>
		<link>http://cakephp.hospedaxes.com/cakephp-questions</link>
		<comments>http://cakephp.hospedaxes.com/cakephp-questions#comments</comments>
		<pubDate>Wed, 11 Nov 2009 08:31:24 +0000</pubDate>
		<dc:creator>bernal</dc:creator>
				<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=284</guid>
		<description><![CDATA[La Cake Software Foundation, nos sorprende con un nuevo producto pensado para ayudar a toda la comunidad de su framework.
Es una paǵina, llamada cakePHP Questions, en la que todos los usuarios que quieran, dejarán sus dudas para que el resto de la comunidad intenten resolverlas.
Es la misma idea que el grupo de google de cakephp, [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-full wp-image-285 alignleft" title="cakephp_questions_logo" src="http://cakephp.hospedaxes.com/wp-content/uploads/2009/11/cakephp_questions_logo.png" alt="cakephp_questions_logo" width="251" height="105" />La Cake Software Foundation, nos sorprende con un nuevo producto pensado para ayudar a toda la comunidad de su framework.</p>
<p>Es una paǵina, llamada <a href="http://cakeqs.org/">cakePHP Questions</a>, en la que todos los usuarios que quieran, dejarán sus dudas para que el resto de la comunidad intenten resolverlas.</p>
<p>Es la misma idea que el grupo de <a href="http://groups.google.com/group/cake-php">google de cakephp</a>, en funcionamiento desde hace mucho tiempo, pero adaptándolo a sus propias necesidades.</p>
<p>La mayor parte de las dudas, por no decir todas, están en inglés, un pequeño problema para los no acostumbrados a la lengua de shakespeare. La falta de documentación en español sigue siendo uno de los grandes problemas de este framework. Por ello, desde este blog intentamos aportar nuestro granito de arena para hacer más fácil el acceso acceso a este mundo, a todos los usuarios de cake.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/cakephp-questions/feed</wfw:commentRss>
		<slash:comments>0</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>Tree Behavior o cómo crear una estructura jerárquica</title>
		<link>http://cakephp.hospedaxes.com/tree-behavior-o-como-crear-una-estructura-jerarquica</link>
		<comments>http://cakephp.hospedaxes.com/tree-behavior-o-como-crear-una-estructura-jerarquica#comments</comments>
		<pubDate>Wed, 14 Oct 2009 08:42:33 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Noticias]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[árbol]]></category>
		<category><![CDATA[cakephp 1.2]]></category>
		<category><![CDATA[organización jerárquica]]></category>
		<category><![CDATA[tree behavior]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=237</guid>
		<description><![CDATA[En esta ocasión hablaremos de cómo crear una estructura jerárquica utilizando el Tree Behavior de CakePHP. Este comportamiento facilita muchísimo las cosas a la hora de manipular árboles jerárquicos de datos.
Utilizaremos también la librería de Javascript Ext JS para poder manipular el árbol gráficamente de manera sencilla, utilizando drag and drop.
Lo primero que tendremos que [...]]]></description>
			<content:encoded><![CDATA[<p>En esta ocasión hablaremos de cómo crear una estructura jerárquica utilizando el <a title="CakePHP: Tree Behavior" href="http://api.cakephp.org/class/tree-behavior">Tree Behavior</a> de CakePHP. Este comportamiento facilita muchísimo las cosas a la hora de manipular árboles jerárquicos de datos.</p>
<p>Utilizaremos también la librería de Javascript <a title="Ext JS" href="http://www.extjs.com/">Ext JS</a> para poder manipular el árbol gráficamente de manera sencilla, utilizando <a title="Wikipedia: Arrastrar y soltar" href="http://es.wikipedia.org/wiki/Arrastrar_y_soltar"><em>drag and drop</em></a>.</p>
<p>Lo primero que tendremos que hacer será añadir en la tabla de la base de datos de la entidad. Utilizando los nombres por defecto de Cake, serían los siguientes campos:</p>
<ul>
<li><em>parent_id</em>: hace referencia al padre del elemento.</li>
<li><em>lft</em>: almacena el identificador del elemento de la izquierda en el mismo nivel.</li>
<li><em>rght</em>: almacena el identificador del elemento de la derecha en el mismo nivel.</li>
</ul>
<p>Incluiremos también los campos <em>id</em> y <em>nombre</em>, en una entidad denominada, por ejemplo, Categoria.</p>
<p>El modelo lo haríamos de la siguiente manera:</p>
<p>Este comportamiento tiene funciones muy útiles para la manipulación del árbol. Las más utilizadas quizás sean las siguientes:</p>
<ul>
<li><strong><em>children</em></strong>: devuelve los hijos de un nodo concreto, pudiendo seleccionar si deseamos obtener sólo los hijos directos o todos los hijos en el árbol.</li>
<li><strong><em>generatetreelist</em></strong>: función muy útil para obtener los elementos a introducir en un select de HTML.</li>
<li><strong>getpath</strong>: devuelve todo el path hasta el nodo especificado en un array.</li>
<li><strong>movedown</strong> y <strong>moveup</strong>: sirven para bajar o subir un nivel de un nodo del árbol.</li>
<li><strong>removefromtree</strong>: elimina un nodo del árbol sin perder la estructura, es decir, modificando el padre de sus hijos.</li>
<li><strong>reorder</strong>: reordena un nodo (arrastrando también a sus hijos) en función de los parámetros especificados.</li>
</ul>
<p>Para realizar la manipulación visual del árbol de categorías crearemos las siguientes funciones en el controlador <em>app/controllers/categorias_controller.php</em> sería:</p>
<pre class="prettyprint"><code>&lt;?php

class CategoriasController extends AppController{

var $helpers = array( 'Javascript');

// Función para organizar las categorías
function organizar() {}

function getnodes() {
   Configure::write('debug', 0);
   // obtener el identificador del padre que se envío por POST vía Ajax
   $parent = intval($this-&gt;params['form']['node']);
   // encontrar los hijos directos del nodo anterior
   $nodes = $this-&gt;Categoria-&gt;children($parent, true, null, 'Categoria.lft ASC');

   $this-&gt;set(compact('nodes'));

   $this-&gt;render('getnodes', 'ajax');
}

function reorder()
{
   Configure::write('debug', 0);

   // delta es la diferencia en la posición (1 = nodo siguiente, -1 = nod anterior)
   $node = intval($this-&gt;params['form']['node']);
   $delta = intval($this-&gt;params['form']['delta']);

   if ($delta &gt; 0) {
      $this-&gt;Categoria-&gt;movedown($node, abs($delta));
   } elseif ($delta &lt; 0) {
      $this-&gt;Categoria-&gt;moveup($node, abs($delta));
   }

   exit('1');
}

function reparent()
{
   Configure::write('debug', 0);

   $node = intval($this-&gt;params['form']['node']);
   $parent = intval($this-&gt;params['form']['parent']);
   $position = intval($this-&gt;params['form']['position']);

   // guardamos el nuevo padre de la categoría
   $this-&gt;Categoria-&gt;id = $node;
   $this-&gt;Categoria-&gt;saveField('parent_id', $parent);

   // Si position == 0, nos movemos al inicio.
   // En otro caso, calculamos la distancia que nos moveremos ($delta).
   if ($position == 0) {
      $this-&gt;Categoria-&gt;moveup($node, true);
   } else {
      $count = $this-&gt;Categoria-&gt;childcount($parent, true);
      $delta = $count - $position - 1;
      if ($delta &gt; 0) {
         $this-&gt;Categoria-&gt;moveup($node, $delta);
      }
   }

   exit('1');
}
}
?&gt;</code></pre>
<p>Sólo nos quedaría hacer las vistas. En este caso, necesitamos crear 2 vistas: organizar.ctp y getnodes.ctp.</p>
<pre class="prettyprint"><code>// app/views/categorias/organizar.ctp

&lt;?php echo $html-&gt;css('/js/ext-2.0.1/resources/css/ext-custom.css'); ?&gt;
&lt;?php echo $javascript-&gt;link('/js/ext-2.0.1/ext-custom.js'); ?&gt;

&lt;script type="text/javascript"&gt;
Ext.BLANK_IMAGE_URL = '&lt;?php echo $html-&gt;url('/js/ext-2.0.1/resources/images/default/s.gif') ?&gt;';

Ext.onReady(function(){

   var getnodesUrl = '&lt;?php echo $html-&gt;url('/categorias/getnodes') ?&gt;';
   var reorderUrl = '&lt;?php echo $html-&gt;url('/categorias/reorder') ?&gt;';
   var reparentUrl = '&lt;?php echo $html-&gt;url('/categorias/reparent') ?&gt;';

   var Tree = Ext.tree;

   var tree = new Tree.TreePanel({
      el:'tree-div',
      autoScroll:true,
      animate:true,
      enableDD:true,
      containerScroll: true,
      rootVisible: true,
      loader: new Ext.tree.TreeLoader({
         dataUrl:getnodesUrl
      })
    });

   var root = new Tree.AsyncTreeNode({
      text:'Categorías',
      draggable:false,
      id:'root'
   });

   tree.setRootNode(root);
   tree.setHeight('auto');

   var oldPosition = null;
   var oldNextSibling = null;

   tree.on('startdrag', function(tree, node, event){
      oldPosition = node.parentNode.indexOf(node);
      oldNextSibling = node.nextSibling;
   });

   tree.on('movenode', function(tree, node, oldParent, newParent, position){

   if (oldParent == newParent){
      var url = reorderUrl;
      var params = {'node':node.id, 'delta':(position-oldPosition)};
   } else {
      var url = reparentUrl;
      var params = {'node':node.id, 'parent':newParent.id, 'position':position};
   }

tree.disable();

Ext.Ajax.request({
   url:url,
   params:params,
   success:function(response, request) {
      // if the first char of our response is zero, then we fail the operation,
      // otherwise we re-enable the tree
      if (response.responseText.charAt(0) != 1){
         request.failure();
      } else {
         tree.enable();
      }
   },
   failure:function() {
      // we move the node back to where it was beforehand and
      // we suspendEvents() so that we don't get stuck in a possible infinite loop
      tree.suspendEvents();
      oldParent.appendChild(node);
      if (oldNextSibling){
         oldParent.insertBefore(node, oldNextSibling);
      }
      tree.resumeEvents();
      tree.enable();
      alert("Oh no! Your changes could not be saved!");
   }
});
});

tree.render();
root.expand();
});
&lt;/script&gt;

&lt;div id="tree-div"&gt;&lt;/div&gt;</code></pre>
<p>Y la última vista:</p>
<pre class="prettyprint"><code>&lt;?php
// app/views/categorias/getnodes.ctp
$data = array();
foreach ($nodes as $node)
{</code>   <code>$data[] = array(</code>      <code>"text" =&gt; $node['Categoria']['nombre'],</code>      <code>"id" =&gt; $node['Categoria']['id']</code>   <code>);
}
echo $javascript-&gt;object($data);
?&gt;</code></pre>
<p>Ya sólo nos quedaría descargarnos la librería <a title="Ext JS" href="http://www.extjs.com/" target="_blank">ExtJS</a> y copiarla en la carpeta /app/webroot/js. En el <a title="Demostración de funcionamiento de Ext JS" href="http://cakephp.hospedaxes.com/pruebas/tree_behavior">ejemplo</a>, se ha utilizado la versión 2.0.1.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 289px; width: 1px; height: 1px;">
<pre style="display: block;">Categoria</pre>
</div>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/tree-behavior-o-como-crear-una-estructura-jerarquica/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nuevas versiones de CakePHP</title>
		<link>http://cakephp.hospedaxes.com/nuevas-versiones-de-cakephp</link>
		<comments>http://cakephp.hospedaxes.com/nuevas-versiones-de-cakephp#comments</comments>
		<pubDate>Wed, 05 Aug 2009 08:47:31 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=229</guid>
		<description><![CDATA[El lunes 3 de agosto se anunciaba en la página web de CakePHP el lanzamiento de dos nuevas versiones: la versión estable de la release 1.2.4.8284, podemos ver el changelog para conocer los bugs corregidos, y la versión 1.3.0, todavía en desarrollo.

Los cambios más importantes introducidos en la versión 1.3.0 son:

compatibilidad con PHP 5.3
nuevo helper [...]]]></description>
			<content:encoded><![CDATA[<p>El lunes 3 de agosto se anunciaba en la página web de <a title="Release: CakePHP 1.2.4.8284" href="http://bakery.cakephp.org/articles/view/release-cakephp-1-2-4-8284" target="_blank">CakePHP</a> el lanzamiento de dos nuevas versiones: la versión estable de la release 1.2.4.8284, podemos ver el <a title="Changelog 1.2.4.8284" href="https://trac.cakephp.org/wiki/changelog/1.2.x.x/8284" target="_blank">changelog</a> para conocer los bugs corregidos, y la versión 1.3.0, todavía en desarrollo.</p>
<p style="text-align: center;"><a href="http://www.cakephp.org"><img class="size-full wp-image-230 aligncenter" title="cakephp12" src="http://cakephp.hospedaxes.com/wp-content/uploads/2009/08/cakephp12.png" alt="CakePHP 1.2" width="238" height="240" /></a></p>
<p>Los cambios más importantes introducidos en la versión 1.3.0 son:</p>
<ul>
<li>compatibilidad con PHP 5.3</li>
<li>nuevo helper de javascript incluyendo soporte para múltiples librerías js</li>
<li>mejora de la generación de código automática con mejor soporte para plugins y templates.</li>
</ul>
<p>Ahora mismo estamos metidos de lleno en la utilización de plugins, así que nos alegramos mucho de que le den importancia a esta línea de desarrollo. En cuanto tengamos un poquito de tiempo y las ideas totalmente claras, escribiremos una entrada referente a este tema.</p>
<div id="_mcePaste" style="overflow: hidden; position: absolute; left: -10000px; top: 0px; width: 1px; height: 1px;">
<h3>1.2.4.8284</h3>
</div>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/nuevas-versiones-de-cakephp/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CakePHP debug kit</title>
		<link>http://cakephp.hospedaxes.com/cakephp-debug-kit</link>
		<comments>http://cakephp.hospedaxes.com/cakephp-debug-kit#comments</comments>
		<pubDate>Tue, 04 Aug 2009 10:13:34 +0000</pubDate>
		<dc:creator>nuria</dc:creator>
				<category><![CDATA[Noticias]]></category>

		<guid isPermaLink="false">http://cakephp.hospedaxes.com/?p=222</guid>
		<description><![CDATA[Nos han preguntado en varias ocasiones cómo hacemos para debuggear las aplicaciones desarrolladas con CakePHP. Hemos probado, sin meternos a fondo, la utilización de Eclipse+XDebug, pero todavía no hemos obtenido resultados satisfactorios, por lo que hasta ahora seguíamos utilizando el debug de CakePHP, al que estamos muy acostumbrados y que nos resulta fácil y cómodo.
Hemos [...]]]></description>
			<content:encoded><![CDATA[<p>Nos han preguntado en varias ocasiones cómo hacemos para debuggear las aplicaciones desarrolladas con <a href="http://cakephp.org/">CakePHP</a>. Hemos probado, sin meternos a fondo, la utilización de <a href="http://www.eclipse.org/">Eclipse</a>+<a href="http://xdebug.org/">XDebug</a>, pero todavía no hemos obtenido resultados satisfactorios, por lo que hasta ahora seguíamos utilizando el debug de CakePHP, al que estamos muy acostumbrados y que nos resulta fácil y cómodo.<br />
Hemos encontrado una herramienta de debug que se basa en esta idea, pero que nos muestra las variables de una manera más cómoda y visualmente más atractiva. Se trata del plugin <a href="http://www.ohloh.net/p/cakephp-debugkit">CakePHP debug kit</a>. Lo podéis bajar directamente de la web y, por tratarse de un plugin, su instalación es verdaderamente sencilla.<br />
Una vez instalado, en la esquina superior derecha de la aplicación se nos mostrará un botón que nos permite visualizar u ocultar el debug:</p>
<p><img class="aligncenter size-full wp-image-225" title="debugKit" src="http://cakephp.hospedaxes.com/wp-content/uploads/2009/08/debugKit.png" alt="debugKit" width="680" height="138" /><br />
Podemos observar el historial de peticiones anteriores, las variables de la sesión, de la request y de la vista, información de log y estadísticas de memoria utilizada y tiempo de petición.</p>
]]></content:encoded>
			<wfw:commentRss>http://cakephp.hospedaxes.com/cakephp-debug-kit/feed</wfw:commentRss>
		<slash:comments>2</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>
	</channel>
</rss>
