<?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>CuatroXL</title>
	<atom:link href="http://www.cuatroxl.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.cuatroxl.com</link>
	<description>Desarrollo web - Cuatro XL</description>
	<lastBuildDate>Fri, 13 Jul 2012 16:50:11 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.4.1</generator>
		<item>
		<title>Remodelando la página</title>
		<link>http://www.cuatroxl.com/2012/07/remodelando-la-pagina/</link>
		<comments>http://www.cuatroxl.com/2012/07/remodelando-la-pagina/#comments</comments>
		<pubDate>Wed, 11 Jul 2012 18:03:24 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.cuatroxl.com/?p=639</guid>
		<description><![CDATA[Llevaba mucho tiempo queriendo remodelar un poco la página y por fin me he puesto manos a la obra! Por ahora se verán algunas cosas un poco raras; pero a ver si antes del fin de semana puedo dejarlo terminado!]]></description>
			<content:encoded><![CDATA[<p>Llevaba mucho tiempo queriendo remodelar un poco la página y por fin me he puesto manos a la obra!</p>
<p>Por ahora se verán algunas cosas un poco raras; pero a ver si antes del fin de semana puedo dejarlo terminado!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2012/07/remodelando-la-pagina/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Este blog ha sido violado!</title>
		<link>http://www.cuatroxl.com/2011/12/este-blog-ha-sido-violado/</link>
		<comments>http://www.cuatroxl.com/2011/12/este-blog-ha-sido-violado/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 12:21:02 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=496</guid>
		<description><![CDATA[Hace un par de semanas instalaron un troyanos en este blog; aprovecharon una vulnerabilidad de WordPress (yo tenía la versión sin actualizar) y unos permisos inadecuados en carpetas inadecuadas. La verdad es que no sé muy bien que es lo&#8230;]]></description>
			<content:encoded><![CDATA[<p>Hace un par de semanas instalaron un troyanos en este blog; aprovecharon una vulnerabilidad de WordPress (yo tenía la versión sin actualizar) y unos permisos inadecuados en carpetas inadecuadas.</p>
<p>La verdad es que no sé muy bien que es lo que hacía el troyano este; sólo sé que dejó trozos de código en todas las carpetas del servidor. Este código respondía si se le llamaba desde la url pesándole unos parámetros fijos.</p>
<p>Mi primera medida ha sido borrar toda la instalación de WP y hacer una nueva con la última versión. El mayor error que cometí fue no hacer copia de las imágenes que tenía en la carpeta de Uploads por lo que se han perdido casi todas las imágenes que había dentro de los post. Sorry!</p>
<p>Seguiré mirando a ver como puedo solucionar esto a ver si hay alguna manera de recuperarlas y pueda volver a subir imágenes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/12/este-blog-ha-sido-violado/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Metodos y Algoritmo para crear una URL corta (shorturl)</title>
		<link>http://www.cuatroxl.com/2011/09/metodos-algoritmo-crear-una-url-corta-shorturl/</link>
		<comments>http://www.cuatroxl.com/2011/09/metodos-algoritmo-crear-una-url-corta-shorturl/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 21:58:54 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[php]]></category>
		<category><![CDATA[tutoriales]]></category>
		<category><![CDATA[utilidades]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=480</guid>
		<description><![CDATA[Intro Hoy quería investigar sobre cómo crear un sistema de URL cortas; lo primero que hay que decir, es que hay cientos de servicios que te generan este tipo de URL, pero siempre es con el dominio de la herramienta,&#8230;]]></description>
			<content:encoded><![CDATA[<h2>Intro</h2>
<p>Hoy quería investigar sobre cómo crear un sistema de  URL cortas; lo primero que hay que decir, es que hay cientos de servicios que te generan este tipo de URL, pero siempre es con el dominio de la herramienta, cosa que no es muy recomendable.</p>
<p>De las librerías(resumidas más abajo) que he podido analizar; todas guardan en una base de datos la URL y un identificador que será el que se envía como parámetro. Dentro de estas librerías, <strong>se puede separar en tres grupo por la forma de generar ese identificador</strong>:</p>
<ol>
<li>Las que crean un indice numérico incremental y lo utilizan como identificador.</li>
<li>Las que crear un indice numérico incremental y luego encriptan este número y usan como identificador</li>
<li>Las que ecriptan de algún modo la URL de destino y utilizan (el resultado de la encriptación) como identificador.</li>
</ol>
<h2>YourURL</h2>
<p>Esta librería ha sido la primera en descartar; porque creo que usa la API de su web para realizar la tarea acortar la URL. Cabe destacar que es una aplicación bastante completa porque tiene una sección para ver el trafico que han tenido las URL generadas.</p>
<p>web: <a href="http://yourls.org">http://yourls.org</a></p>
<h2>Rick URL Shortening Service </h2>
<p>Esta librería (en .NET) es del primer grupo; que más o menos nos da una idea de como se monta el sistema. </p>
<p>El principal fallo que le veo; es que se pasa como identificador el ID (numérico) como parámetro y no queda demasiado estético.</p>
<p>En el siguiente screencast (del autor de esta librería) se puede ver bastante bien cómo se monta este sistema(es exactamente igual a como lo monta el segundo grupo):</p>
<p><iframe src="http://player.vimeo.com/video/2517727?title=0&amp;byline=0&amp;portrait=0" width="100%" height="302" frameborder="0"></iframe></p>
<p>web: <a href="http://www.stum.de/2008/12/14/rick-url-shortening-service-an-aspnet-mvc-learning-project/">http://www.stum.de/&#8230;url-shortening-service&#8230;-project/</a></p>
<h2>LilURL</h2>
<p>Esta librería es del 2 grupo; aunque hace una encriptación un tanto rara y bastante enrevesada. Hace una encriptación con caracteres alfabéticos en minúscula.</p>
<p>Lo curioso es que no usa el indice incremental; es él mismo quien va creando la secuencia de identificadores. Para que os hagáis una idea de cómo funciona, este es su código para generar el identificador:</p>
<pre class="brush: php;">
$id = $this-&gt;get_next_id($this-&gt;get_last_id());
</pre>
<p>Como podéis ver, genera el identificador a partir del último. Esto resultaría interesante si no fuese porque realiza una consulta a la base de datos para poder conocer el último identificador generado y a partir de ahí genera el siguiente.</p>
<p>web: <a href="http://lilurl.sourceforge.net/">http://lilurl.sourceforge.net/</a></p>
<h2>Loolu</h2>
<p>Este pertenece al segundo grupo y sin lugar a duda, para mi, es la mejor manera de encriptar la URL. Aquí directamente se descompone el número en una base (64) y se representa con caracteres numéricos, alfabéticos con minúsculas y mayúsculas. El algoritmo es más que sencillo (está en python):</p>
<pre class="brush: python">
codeset  = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
base = 62 # len(codeset)
#....
def encode(self, id):
        hash = ""
        while (id > 0):
            hash = self.codeset[int(id % self.base)] + hash
            id = math.floor(id / self.base)
        return hash
</pre>
<p>Poco más que añadir a lo genial que es esta solución, simple y eficaz.</p>
<p>web: <a href="http://code.google.com/p/loolu/">http://code.google.com/p/loolu/</a></p>
<h2>LessN</h2>
<p>Esta librería pertenece al tercer grupo; encripta la URL utilizando un CheckSum (de PHP y Mysql) y lo usa como identificador. Código que realiza la encriptación:</p>
<pre class="brush: php;">
$checksum 		= sprintf('%u', crc32($url));
$escaped_url 	= function_exists('mysql_real_escape_string') ? mysql_real_escape_string($url) : mysql_escape_string($url);
//...
mysql_query('INSERT INTO `'.DB_PREFIX.'urls` SET `url`="'.$escaped_url.'", `checksum`='.$checksum);
</pre>
<p><em>nota: Cómo podéis ver es muy importante escapar las URL, ya que corremos el peligro de que nos pongan javascript en la url y puede llegar a ejecutarse en el navegador.</em></p>
<p>web: <a href="http://www.shauninman.com/archive/2009/08/17/less_n">http://www.shauninman.com/archive/2009/08/17/less_n</a></p>
<h2>Resumen</h2>
<p>En este tipo de servicios, es muy importante tener muy en cuenta el rendimiento de nuestra aplicación, ya que una mala arquitectura te puede consumir demasiados recursos. Es por eso que personalmente me quedo con el algoritmo de Loolu que me parece de lo más sencillo y eficiente.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/09/metodos-algoritmo-crear-una-url-corta-shorturl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Añadiendo el servicio de &#8220;voz a texto&#8221; en campo Input y Textarea</title>
		<link>http://www.cuatroxl.com/2011/08/anadiendo-el-servicio-de-voz-a-texto/</link>
		<comments>http://www.cuatroxl.com/2011/08/anadiendo-el-servicio-de-voz-a-texto/#comments</comments>
		<pubDate>Sun, 07 Aug 2011 19:47:45 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=472</guid>
		<description><![CDATA[Navegando he descubierto una etiqueta de WebKit (sólo me funciona en Chrome) que te añade el servicio con vierte voz en texto, igual al que tiene Android. Es una herramienta bastante interesante si se quiere aportar algo de accesibilidad. Probarlo&#8230;]]></description>
			<content:encoded><![CDATA[<p>Navegando he descubierto una etiqueta de WebKit (sólo me funciona en  Chrome) que te añade el servicio con vierte voz en texto, igual al que  tiene Android.</p>
<p>Es una herramienta bastante interesante si se quiere aportar algo de accesibilidad.</p>
<p>Probarlo en vuestro html:</p>
<pre class="brush: html;">&lt;input x-webkit-speech /&gt;</pre>
<p><label for="demo">Ejemplo <i>(ver en Chrome)</i>: </label><input name="demo" value="" x-webkit-speech /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/08/anadiendo-el-servicio-de-voz-a-texto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework 2.0</title>
		<link>http://www.cuatroxl.com/2011/07/zend-framework-2-0/</link>
		<comments>http://www.cuatroxl.com/2011/07/zend-framework-2-0/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 19:16:01 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=465</guid>
		<description><![CDATA[Introducing Zend Framework 2.0 Zend Framework 2.0 Patterns Tutorial Para terminar: How to start with Zend Framework 2?]]></description>
			<content:encoded><![CDATA[<h2>Introducing Zend Framework 2.0</h2>
<p><a title="Introducing Zend Framework 2.0" href="http://www.slideshare.net/weierophinney/introducing-zend-framework-20" target="_blank"><br />
<img src="/wp-content/uploads/2011/07/Pantallazo-1.png" alt="Introducing Zend Framework 2.0" /><br />
</a></p>
<h2>Zend Framework 2.0 Patterns Tutorial</h2>
<p><img src="/wp-content/uploads/2011/07/Pantallazo-2.png" alt="Zend Framework 2.0 Patterns Tutorial" /></p>
<p>Para terminar: <a href="http://framework.zend.com/wiki/pages/viewpage.action?pageId=42303506" target="blank">How to start with Zend Framework 2?</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/07/zend-framework-2-0/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Invitaciones para Google Plus</title>
		<link>http://www.cuatroxl.com/2011/07/invitaciones-para-google-plus/</link>
		<comments>http://www.cuatroxl.com/2011/07/invitaciones-para-google-plus/#comments</comments>
		<pubDate>Wed, 27 Jul 2011 19:45:12 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=462</guid>
		<description><![CDATA[Últimamente ando poniendo links de interés y cosillas en Google+ ya que me parece una herramienta bastante interesante. Si alguno quiere invitaciones, no tiene más que pedirlas por aquí y os enviaré las invitaciones.]]></description>
			<content:encoded><![CDATA[<p>Últimamente ando poniendo links de interés y cosillas en Google+ ya que me parece una herramienta bastante interesante.</p>
<p>Si alguno quiere invitaciones, no tiene más que pedirlas por aquí y os enviaré las invitaciones.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/07/invitaciones-para-google-plus/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Instalando MongoDb en WampServer (Update:2011-03-15)</title>
		<link>http://www.cuatroxl.com/2011/03/instalando-mongodb-en-wampserver/</link>
		<comments>http://www.cuatroxl.com/2011/03/instalando-mongodb-en-wampserver/#comments</comments>
		<pubDate>Mon, 14 Mar 2011 18:34:07 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=447</guid>
		<description><![CDATA[Lo primero es descargar los ejecutables para correr MongoDb en windows:  http://www.mongodb.org/downloads (en mi caso es Windows 32-bit) Mientras descarga tenemos que crear dos directorios en la raíz: C:\&#62; mkdir \data C:\&#62; mkdir \data\db (lo podéis hacer desde el modo&#8230;]]></description>
			<content:encoded><![CDATA[<p>Lo primero es descargar los ejecutables para correr MongoDb en windows:  <a href="http://www.mongodb.org/downloads" target="_blank">http://www.mongodb.org/downloads</a> (en mi caso es Windows 32-bit)</p>
<p>Mientras descarga tenemos que crear dos directorios en la raíz:</p>
<pre>C:\&gt; mkdir \data
C:\&gt; mkdir \data\db
</pre>
<p>(lo podéis hacer desde el modo visual de la carpeta  <img src='http://www.cuatroxl.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Una vez lo tengamos descargado, lo vamos a guardar en la carpeta bin de Wamp:</p>
<p><img src="http://cuatroxl.com/blog/wp-content/uploads/2011/03/cap_3.gif" alt="" /></p>
<p>Ahora toca bajarse la DLL para que php pueda tener acceso:  <a href="http://www.php.net/manual/en/mongo.installation.php#mongo.installation.windows">http://www.php.net/&#8230;allation.windows</a> (en mi caso <a href="http://downloads.mongodb.org/mongo-latest-php5.2vc6ts.zip">PHP 5.2 VC6 Thread-Safe Mongo extension</a> pero al principio no lo reconocía, luego si). La instalamos en la carpeta de extensiones:</p>
<pre>C:\wamp\bin\php\php5.3.0\ext</pre>
<p>y ahora le tenemos que dar de alta en el php.ini:</p>
<pre>extension="C:\wamp\bin\php\php5.3.0\ext\php_mongo.dll"</pre>
<p>Para terminar; no nos tenemos que olvidar de arrancar el servidor de mongo, cada vez que se quiera usar ya que no se inicia automáticamente. Pero para facilitarnos la vida lo vamos a poner como un botón más del Wamp. Para ello hace falta editar &#8220;wampmanager.tpl&#8221; está justo en la carpeta de Wamp.</p>
<p>y ahora añadimos las siguiente línas:</p>
<pre>Type: separator; Caption: "Run MongoDB Server"
Type: item; Caption: "mongod"; Action: run; FileName: "C:\wamp\bin\mongo\mongod.exe"; Glyph: 5</pre>
<p>Ajunto una captura; lo añadido es lo verde:</p>
<p><img src="http://cuatroxl.com/blog/wp-content/uploads/2011/03/cap_2.gif" alt="" /></p>
<p>Resultado:</p>
<p><img src="http://cuatroxl.com/blog/wp-content/uploads/2011/03/cap_4.gif" alt="" /></p>
<p><span style="text-decoration: line-through;">Nota: voy a intentar ponerlo que arranque automáticamente, pero por ahora no lo he conseguido.</span></p>
<p>Update:</p>
<p>Ya he conseguido ponerlo para que arranque automáticamente con el inicio del Wamp; para ello hay que añadir la siguiente línea:</p>
<pre>Action: run; FileName: "C:\wamp\bin\mongo\mongod.exe"; Flags: waituntilterminated</pre>
<p>Dentro de la configuración de inicio ( [StartupAction] ), en el mismo archivo &#8220;wampmanager.tpl&#8221;, nos quedaría de la siguiente manera (en negrita lo nuevo que hemos puesto) :</p>
<pre>[StartupAction]
;WAMPSTARTUPACTIONSTART
Action: run; FileName: "${c_phpCli}";Parameters: "refresh.php";WorkingDir: "${c_installDir}/scripts"; Flags: waituntilterminated
Action: resetservices
Action: readconfig;
Action: service; Service: wampapache; ServiceAction: startresume; Flags: ignoreerrors
Action: service; Service: wampmysqld; ServiceAction: startresume; Flags: ignoreerrors
<strong>Action: run; FileName: "C:\wamp\bin\mongo\mongod.exe"; Flags: waituntilterminated</strong>
;WAMPSTARTUPACTIONEND</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/03/instalando-mongodb-en-wampserver/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Carga de productos en la tienda online de Zara</title>
		<link>http://www.cuatroxl.com/2011/03/carga-de-productos-tienda-zara/</link>
		<comments>http://www.cuatroxl.com/2011/03/carga-de-productos-tienda-zara/#comments</comments>
		<pubDate>Sat, 12 Mar 2011 21:04:15 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[html]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=427</guid>
		<description><![CDATA[feature-image]]></description>
			<content:encoded><![CDATA[<p>Zara va súper rápido; y uno de sus secretos es que no hace llamadas Ajax para saber como recargar sus productos.</p>
<p>Lo que hace, es definir un objeto dentro del HTML con el resultado total de la búsqueda de colección:</p>
<p><img class="alignleft size-medium wp-image-429" title="cap_zara-1" src="http://cuatroxl.com/blog/wp-content/uploads/2010/12/cap_zara-1.png" alt="" width="100%" /></p>
<p><img class="alignleft size-medium wp-image-430" title="cap_zara_2" src="http://cuatroxl.com/blog/wp-content/uploads/2010/12/cap_zara_2.png" alt="" /></p>
<p><img class="alignleft size-medium wp-image-431" title="cap_zara_3" src="http://cuatroxl.com/blog/wp-content/uploads/2010/12/cap_zara_3.png" alt="" /></p>
<p>Con esto ya no es necesario volver a hacer peticiones al servidor con paginado o que procese una nueva consulta; rápido y bonito con las transiciones.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2011/03/carga-de-productos-tienda-zara/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Esta noche vieja: Manifestación contra la ley Sinde</title>
		<link>http://www.cuatroxl.com/2010/12/esta-noche-vieja-manifestacion-contra-la-ley-sinde/</link>
		<comments>http://www.cuatroxl.com/2010/12/esta-noche-vieja-manifestacion-contra-la-ley-sinde/#comments</comments>
		<pubDate>Fri, 24 Dec 2010 18:40:14 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=437</guid>
		<description><![CDATA[31 Dic &#8211; 23:pm Puerta del Sol &#8211; Madrid Muchos están protestando por no aprobar una ley a su medida. Nuestro ministro dice que todos estamos a favor de la ley Sinde. Los medios (tv &#8211; radio) apoyan la ley&#8230;]]></description>
			<content:encoded><![CDATA[<p><strong>31 Dic &#8211; 23:pm<br />
Puerta del Sol &#8211; Madrid</strong></p>
<ul>
<li>Muchos están protestando por no aprobar una ley a su medida.</li>
<li>Nuestro ministro dice que todos estamos a favor de la ley Sinde.</li>
<li>Los medios (tv &#8211; radio) apoyan la ley  Sinde.</li>
<li>No paran de decir que somos unos delincuentes.</li>
<li><strong>Esta noche  vieja tendrán que abrir los ojos y escuchar que no apoyamos la ley Sinde</strong></li>
</ul>
<p><img title="sinde" src="http://cuatroxl.com/blog/wp-content/uploads/2010/12/sinde.gif" alt="Manifestación Contra la ley Sinde" /></p>
<p><em> Feliz navidad señora ministra de &#8220;cultura&#8221;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2010/12/esta-noche-vieja-manifestacion-contra-la-ley-sinde/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cuatroxl_Controller_Plugin_DataPage :: Un plugin para cargar datos multi-idioma (o no) con ZF</title>
		<link>http://www.cuatroxl.com/2010/08/cuatroxl_controller_plugin_datapage-un-plugin-para-cargar-datos-multi-idioma-o-no-con-zf/</link>
		<comments>http://www.cuatroxl.com/2010/08/cuatroxl_controller_plugin_datapage-un-plugin-para-cargar-datos-multi-idioma-o-no-con-zf/#comments</comments>
		<pubDate>Mon, 02 Aug 2010 12:12:08 +0000</pubDate>
		<dc:creator>acido69</dc:creator>
				<category><![CDATA[component]]></category>
		<category><![CDATA[componente_web]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[zend framework]]></category>
		<category><![CDATA[cuatroxl source]]></category>
		<category><![CDATA[zend_controller plugin]]></category>

		<guid isPermaLink="false">http://cuatroxl.com/?p=406</guid>
		<description><![CDATA[Este plugin viene bastante bien para tener todos los datos de texto en un XML. Por norma general se suele guardar en una base de datos; pero muchas veces el sitio no tiene un CMS o es muy pequeño para&#8230;]]></description>
			<content:encoded><![CDATA[<p>Este plugin viene bastante bien para tener todos los datos de texto en un XML. Por norma general se suele guardar en una base de datos; pero muchas veces el sitio no tiene un CMS o es muy pequeño para tener la información en una base de  datos.</p>
<p>Con este plugin cargamos un XML, pasandole unos parámetros de configuración para que automáticamente nos seleccione un nodo especifico del XML. Esta configuración utiliza comodines de Zend_Route (Module, Controller, Action, ParamX&#8230;.) para el nombre del archivo y el nodo por defecto:</p>
<pre class="brush: php;">
<?php
/*
 * Cuatroxl
 *
 * LICENSE
 *
 * This file is part of Cuatroxl ( http://code.google.com/p/cuatroxl/ ).
 *
 * Cuatroxl is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Cuatroxl is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Cuatroxl.  If not, see <http ://www.gnu.org/licenses/>.
 *
 *
 * @category   Cuatroxl
 * @package    Cuatroxl_Zf_Action_Helper
 * @autor      Jimmy Collazos <jimmy.collazos@gmail.com>
 * @license    http://www.gnu.org/licenses/gpl.html     GPLv3
 * @version    0.01
 */



/**
 * @see Zend_Controller_Plugin_Abstract
 */
require_once 'Zend/Controller/Plugin/Abstract.php';


/**
 * @category   Cuatroxl
 * @package    Cuatroxl_Controller
 * @subpackage Cuatroxl_Controller_Plugin
 * @license    http://www.gnu.org/licenses/gpl.html     GPLv3
 */
class Cuatroxl_Controller_Plugin_DataPage extends Zend_Controller_Plugin_Abstract
{

    /*
     * Variable de configuración
     *
     * @var Array
     */
    protected       $_config      = array('autoload'  => false
                            ,'filePath'     => 'public/:module/:controller/:action.xml'
                            ,'xpath'        => ''
                            ,'basePath'     => APPLICATION_PATH
                            // esta opción es solo para cuando NO usamos Zend_Application
                            ,'_keyPlugin'   => '');

    /*
     * Ruta del archivo XML a cargar
     *
     * @var string
     */
    protected       $_filePath = null;

    /*
     * Xpath query para poder obteenr el nodo por defecto del XML
     *
     * @var string
     */
    protected       $_xpath = null;

    

    /*
     * En esta variable se almacena el XML final con el que podemos trabajar
     * desde el controlador
     *
     * @var SimpleXMLElement
     */
    protected       $_data;


    /*
     * Nombre asignado en el archivo de configuración de al aplicación
     *
     * @var string
     */
    private         $_keyPlugin;

    /**
     * Constructor
     *
     * @param  Array
     * @return void
     */

    public function  __construct( array $options = array() ) {
        
        $this->_setConfig($options);
            
    }

    /*
     * routeShutdown() es como el constructor ya que se usa para setear el XML
     * en caso de estar activado el "autoload" y también setea la configuración del INI
     *
     * @param Zend_Controller_Request_Abstract
     * @return void
     */
    public function routeShutdown( Zend_Controller_Request_Abstract $request)
    {
        
        //@TODO cambiar esto por una funcion que setee todas las opciones
        $bootstrap = Zend_Controller_Front::getInstance()
                            ->getParam('bootstrap');
        if(! empty($bootstrap) ){
            $bootstrapOptions   = $bootstrap->getOptions();
            $this->_keyPlugin          = $this->_getKeyPlugin($bootstrapOptions['resources']['frontController']['plugins']);
            if($this->_keyPlugin){
                if(! empty($bootstrapOptions[$this->_keyPlugin]['config'])){
                    $this->_setConfig($bootstrapOptions[$this->_keyPlugin]['config']);
                }
            }
            //@TODO añadir una excepción
            $this->_parseFilePath();
            $this->_parseXPath();
            
            if( $this->_config['autoload'] ){
                $this->_loadXmlFile();
                $this->_setXPath();
            }
        }
    }

    /*
     * Setea los daots en la variable _data
     *
     * @param SimpleXMLElement
     * @return void
     */
    public function setData ( SimpleXMLElement $data )
    {
        $this->_data = $data;

        if(!empty ($this->_keyPlugin) ){
            Zend_Controller_Front::getInstance()
                    ->setParam($this->_keyPlugin, $this->_data);
        }
    }

    /*
     * Devueble el XML obtenido
     *
     * @return Cuatroxl_Controller_Plugin_DataPage $_data
     * 
     */
    public function getData ()
    {
        return $this->_data;
    }

    /*
     * Configura todas las opiones de la clase
     * 
     * @var array
     * @return Cuatroxl_Controller_Plugin_DataPage  Provides a fluent interface
     *
     */
    protected function _setConfig( array $config) {
        foreach ($config as $k => $v){
            if(!empty ($v)){
                $this->_config[$k] = $v;
            }
        }
        return $this;
    }

    /*
     * Carga el archivo XML
     *
     * @var string
     * @return Cuatroxl_Controller_Plugin_DataPage Provides a fluent interface
     *
     */
    protected function _loadXmlFile( string $fileName = NULL ) {
        if( $fileName === NULL ){
            $fileName = $this->_filePath;
        }
        if( file_exists( $fileName ) ){
            $data   = simplexml_load_file( $fileName );
            $this->setData( $data );
        }
        return $this;
    }

    /*
     * Ejecuta una query sobre el XML con xpath y devuelve TRUE o FALSE  según el exito de la consulta
     *
     * @var string
     * @return Boolean
     *
     */
    protected function _setXPath( string $path = NULL ) {
        if( $path === NULL){
            $path = $this->_xpath;
        }

        if( empty($this->_xpath) ){
            return false;
        }

        $data = $this->_data->xpath($this->_xpath);

        if( empty ($data[0]) ){
            return false;
        }else{
            $this->setData( array_shift( $data ) );
            return true;
        }

        
    }

    /*
     * remplaza los comodines en la ruta al XML y devuelve TRUE o FALSE
     * según el exito de la consulta
     *
     * @return Boolean
     *
     */
    private function _parseFilePath() {
        
        //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route
        if(! preg_match_all("/:[^\/\.]+/s", $this->_config['filePath'], $matches) ){
            return false;
        }
        $request        = $this->getRequest();
        $values         = array();
        $matches        = $matches[0];
        foreach($matches as $v){
            $values[] = $request->getParam(substr($v, 1));
        }
        $matches[]          = '/';
        $values[]           = DIRECTORY_SEPARATOR;
        $this->_filePath    = str_replace($matches, $values, $this->_config['basePath'].$this->_config['filePath']);
        
        return true;
    }

    /*
     * remplaza los comodines en la ruta al nodop por defecto del  XML
     * y devuelve TRUE o FALSE  según el exito de la consulta
     *
     * @return Boolean
     *
     */
    private function _parseXPath() {

        //@TODO indagar para hacer este proceso con con Zend_Controller_Router_Route
        if( empty ($this->_config['xpath']) ){
            return false;
        }
        if(! preg_match_all("/:[\d\w_]+/s", $this->_config['xpath'], $matches) ){
            $this->_xpath = $this->_config['xpath'];
            return true;
        }
        $request        = $this->getRequest();
        $values         = array();
        $matches        = $matches[0];
        foreach($matches as $v){
            $values[] = $request->getParam(substr($v, 1));
        }
        
        $this->_xpath    = str_replace($matches, $values, $this->_config['xpath']);

        return true;
    }


    /*
     * Devuelve el nombre que se designó en el archivo de configuración
     *
     * @return string o false
     */
    private function _getKeyPlugin(array $config)
    {
        foreach ($config as $k => $v){
            if($v === 'Cuatroxl_Controller_Plugin_DataPage'){
                return $k;
            }
        }
        return false;
    }
}
</pre>
<h1>Modo de uso con Zend_Application</h1>
<p>Configuracion:</p>
<pre class="brush: javascript;">
;definimos la clase, en este caso lo asociamos a "dataPage"
resources.frontController.plugins.dataPage = "Cuatroxl_Controller_Plugin_DataPage"
;le decimos que la carga es automática
dataPage.config.autoload = 1
;la ruta del XML utilizando como comodín el parámetro LANG, nombre del controlador y acción
dataPage.config.filePath = ":lang/:controller/:action.xml"
;el nodo, del XML, por defecto que tiene que cargar; también usando la variable PAGE
dataPage.config.xpath = "pages/page[@id=':page']"
;el directorio raíz de donde están los XML
dataPage.config.basePath = APPLICATION_PATH "/../public/data/"
</pre>
<p>Controller:</p>
<pre class="brush: php;">
public function indexAction()
{
    // El parámetro "dataPage" es el mismo nombre con que vinculamos en el archivo de configuración
    var_dump($this->getFrontController()->getParam('dataPage'));
}
</pre>
<p>pdt: tengo que subirlo a Google Code; por lo que pronto colgaré la dirección con un manual más sencillo</p>
]]></content:encoded>
			<wfw:commentRss>http://www.cuatroxl.com/2010/08/cuatroxl_controller_plugin_datapage-un-plugin-para-cargar-datos-multi-idioma-o-no-con-zf/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
