<?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>Racó tècnic</title>
	<atom:link href="http://racotecnic.underave.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://racotecnic.underave.net</link>
	<description>Punt de trobada de coneixements</description>
	<lastBuildDate>Tue, 09 Mar 2010 19:10:06 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Validar datos duplicados en CakePHP</title>
		<link>http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/</link>
		<comments>http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 20:28:51 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Cake PHP 1.2]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[Codi]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1406</guid>
		<description><![CDATA[Hoy mismo he necesitado de una validación para verificar si un dato ya existe en la base de datos. Dado que CakePHP no lleva una validación en su núcleo para estos menesteres he tenido que crearla y ahora la comparto con vosotros:
/**
 * Verifica si un campo existe en la base de datos
 * Si [...]]]></description>
			<content:encoded><![CDATA[<p>Hoy mismo he necesitado de una validación para verificar si un dato ya existe en la base de datos. Dado que CakePHP no lleva una validación en su núcleo para estos menesteres he tenido que crearla y ahora la comparto con vosotros:</p>
<pre class="brush: php;">/**
 * Verifica si un campo existe en la base de datos
 * Si estamos editando se excluye el valor guardado en la validación
 * @param array $data
 * @param string $field Nom de la cel·la a verificar
 * @return
 */

public function checkUnique($data)
{
	$field = array_pop(array_keys($data));
	$data = array_pop(array_values($data));

	// Si estem editant...
	if(isset($this-&gt;data[$this-&gt;name]['id']))
	{
		if ($field == $this-&gt;field($field, array($this-&gt;name . '.id' =&gt; $this-&gt;data[$this-&gt;name]['id'])))
		{
			return true;
		}
	}
	// Si no estem editant...
	if($this-&gt;hasField($field)) {
		return $this-&gt;isUnique(array($field =&gt; $data));
	}
}</pre>
<p>Para utilizarlo no tenéis más que añadir el trozo de código en el modelo deseado (normalmente en AppModel, para poder utilizarlo desde cualquier modelo) y añadir la validación en el modelo que queráis:</p>
<pre class="brush: php;">var $validate = array('NOMBRE DE LA CELDA A VALIDAR' =&gt; array(
	'rule'		=&gt; 'checkUnique',
	'message' 	=&gt; 'Blahblahblah'));</pre>
<p>Un ejemplo muy común:</p>
<pre class="brush: php;">var $validate = array('username' =&gt; array(
	'rule'		=&gt; 'checkUnique',
	'message' 	=&gt; 'Ya existe un usuario registrado con este nombre!'));</pre>
<p>Que lo disfrutéis <img class="dtse-img dtse-post-1406" src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>Edición:</strong> Se me olvidó comentar que, a diferencia del método de validación <i>checkUnique</i> que se utiliza en el post <a href="http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/">Inegrando CakePHP y PhpBB 3.x</a>, este método sirve también a la hora de editar un ítem ya que, en ese caso, retorna <code>true</code> si el valor de la celda coincide con el ya guardado en la base de datos.</p>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1406_permalink = 'http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/';
			dtsv.dtse_post_1406_title = 'Validar datos duplicados en CakePHP';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/11/instalacion-de-cakephp-sin-base-de-datos/' rel='bookmark' title='Permanent Link: Instalación de CakePHP sin base de datos'>Instalación de CakePHP sin base de datos</a></li>
<li><a href='http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/' rel='bookmark' title='Permanent Link: CakePHP Auth Component ajaxLogin'>CakePHP Auth Component ajaxLogin</a></li>
<li><a href='http://racotecnic.underave.net/2009/05/obtener-informacion-post-de-manera-rapida-y-sencilla-con-php/' rel='bookmark' title='Permanent Link: Obtener datos POST de manera rápida y sencilla con PHP'>Obtener datos POST de manera rápida y sencilla con PHP</a></li>
<li><a href='http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/' rel='bookmark' title='Permanent Link: Integrando CakePHP y phpBB 3.x'>Integrando CakePHP y phpBB 3.x</a></li>
<li><a href='http://racotecnic.underave.net/2009/11/implementar-plugin-jquery-de-advertencias-tipo-growl-en-cakephp/' rel='bookmark' title='Permanent Link: Implementar plugin jQuery de advertencias tipo Growl en CakePHP'>Implementar plugin jQuery de advertencias tipo Growl en CakePHP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>MyJDB, un sistema de base de datos en JavaScript</title>
		<link>http://racotecnic.underave.net/2010/02/myjdb-un-sistema-de-base-de-datos-en-javascript/</link>
		<comments>http://racotecnic.underave.net/2010/02/myjdb-un-sistema-de-base-de-datos-en-javascript/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 19:47:40 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Bases de dades]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JavaScriptDB]]></category>
		<category><![CDATA[MyJDB]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1401</guid>
		<description><![CDATA[El próximo lunes 1 de marzo (de 2010) verá la luz la primera versión de MyJDB, un sistema de bases de datos inspirado en JavaScriptDB (muerto hacia el 2005..) resucitado por Luis García.
Lo mas destacado de esta versión (beta 1.1.0), que es más un puente hacia lo que se quiere llegar, es la optimización del [...]]]></description>
			<content:encoded><![CDATA[<p>El próximo lunes 1 de marzo (de 2010) verá la luz la primera versión de <a title="Web oficial de MyJDB" href="http://www.myjdb.org/" target="_blank">MyJDB</a>, un sistema de bases de datos inspirado en JavaScriptDB (muerto hacia el 2005..) resucitado por Luis García.</p>
<p>Lo mas destacado de esta versión (beta 1.1.0), que es más un puente hacia lo que se quiere llegar, es la optimización del código, aunque es la primera optimización los resultados han sido cuanto menos sorprendentes. Entre sus cambios destacan los siguientes:</p>
<ul>
<li>Relicenciamiento a GPL 3.</li>
<li>Documentación interna completa y en Ingles, así como las variables que pasan del catalán al ingles para internacionalizar el proyecto.</li>
<li>Reestructuración completa del código.</li>
<li>Nuevo analizador sintactico del Select sobre un 40% más rápido.</li>
<li>Tipado de datos de los campos de las tablas, lo que nos ayuda a evaluar correctamente números, cadenas y sobre todo fechas.</li>
<li>El algoritmo para realizar JOIN entre dos tablas es alrededor de 640 veces más rápido.</li>
<li>Se ha añadido el uso de between, el uso de parentesis, reconocimiento de &#8216;&lt;=&gt;&#8217;.</li>
<li>Implementación de la clausula limit.</li>
<li>Reconocimiento de is, is not, is null, is not null y unknown.</li>
<li>Realización de un select con sólo contando el tiempo de la clausula where alrededor de un 40 veces más rápido.</li>
<li>Evaluación de la clausula where alrededor de un 94% más rápido.</li>
<li>La evaluación de una condición LIKE es alrededor de 8 veces más rápida.</li>
<li>La clausula Order by es alrededor de 2 veces más rápido.</li>
</ul>
<p>Los tiempos han sido medidos con Firefox y el prerfilador de Firebug, con lo que aun queda probarlo en el resto de navegadores, y este es el objetivo de lanzar la beta, probarla y hacerla compatibles con el resto de navegadores (no van a incluir IE6, sólo versiones de IE7 hacia arriba).</p>
<p>Yo personalmente me pregunto cómo será todo el tema de la seguridad&#8230; ya que siendo una base de datos mediante JavaScript lo primero en lo que pienso es la manipulación que se puede hacer de código gracias a aplicaciones como firebug.</p>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1401_permalink = 'http://racotecnic.underave.net/2010/02/myjdb-un-sistema-de-base-de-datos-en-javascript/';
			dtsv.dtse_post_1401_title = 'MyJDB, un sistema de base de datos en JavaScript';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/11/instalacion-de-cakephp-sin-base-de-datos/' rel='bookmark' title='Permanent Link: Instalación de CakePHP sin base de datos'>Instalación de CakePHP sin base de datos</a></li>
<li><a href='http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/' rel='bookmark' title='Permanent Link: Validar datos duplicados en CakePHP'>Validar datos duplicados en CakePHP</a></li>
<li><a href='http://racotecnic.underave.net/2009/05/obtener-informacion-post-de-manera-rapida-y-sencilla-con-php/' rel='bookmark' title='Permanent Link: Obtener datos POST de manera rápida y sencilla con PHP'>Obtener datos POST de manera rápida y sencilla con PHP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/02/myjdb-un-sistema-de-base-de-datos-en-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Smashing magazine: Diferencias entre IE6, IE7 e IE8</title>
		<link>http://racotecnic.underave.net/2010/02/smashing-magazine-diferencias-entre-ie6-ie7-e-ie8/</link>
		<comments>http://racotecnic.underave.net/2010/02/smashing-magazine-diferencias-entre-ie6-ie7-e-ie8/#comments</comments>
		<pubDate>Thu, 11 Feb 2010 14:13:48 +0000</pubDate>
		<dc:creator>DPAM23</dc:creator>
				<category><![CDATA[Disseny]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[IE7]]></category>
		<category><![CDATA[IE8]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[MSIE6]]></category>
		<category><![CDATA[MSIE7]]></category>
		<category><![CDATA[MSIE8]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1385</guid>
		<description><![CDATA[
Hablando de CSS, hoy he encontrado (como siempre por casualidad, buscando otra cosa XD) una guia con las diferencias entre MSIE6, MSIE7 y MSIE8. Que propiedades soportan cada uno en función de la versión.
Muchas de ellas las hemos aprendido a base de cabezazos contra la pantalla, pero la verdad es que esta guia está realmente [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.smashingmagazine.com/2009/10/14/css-differences-in-internet-explorer-6-7-and-8/" rel="nofollow" target="_blank"><img class="aligncenter size-full wp-image-1386 dtse-img dtse-post-1385" title="smashing" src="http://racotecnic.underave.net/wp-content/uploads/2010/02/smashing.jpg" alt="Smashing magazine: diferencias CSS entre IE6, IE7, IE8" width="504" height="249" /></a></p>
<p>Hablando de CSS, hoy he encontrado (como siempre por casualidad, buscando otra cosa XD) una <a rel="nofollow" href="http://www.smashingmagazine.com/2009/10/14/css-differences-in-internet-explorer-6-7-and-8/" target="blank">guia con las diferencias entre MSIE6, MSIE7 y MSIE8</a>. Que propiedades soportan cada uno en función de la versión.</p>
<p>Muchas de ellas las hemos aprendido a base de cabezazos contra la pantalla, pero la verdad es que esta guia está realmente bien, siempre hay alguna cosilla que no conoces.</p>
<p>Recomiendo especialmente el apartado donde hablan de &#8220;Significant Bugs and Incompatibilities&#8221; , donde detallan todos los errores que nos encontramos al maquetar en los diferentes navegadores de microsoft.</p>
<p>y por supuesto para el que no la conozca, visitad smashing magazine, es genial.</p>
<blockquote>
<ul>
<li> smashing magazine: <a rel="nofollow" href="http://www.smashingmagazine.com/" target="_blank">http://www.smashingmagazine.com/</a></li>
<li>Articulo referenciado:  <a rel="nofollow" href="http://www.smashingmagazine.com/2009/10/14/css-differences-in-internet-explorer-6-7-and-8/" target="_blank">CSS diferences in Internet Explorer 6, 7 and 8</a></li>
</ul>
</blockquote>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1385_permalink = 'http://racotecnic.underave.net/2010/02/smashing-magazine-diferencias-entre-ie6-ie7-e-ie8/';
			dtsv.dtse_post_1385_title = 'Smashing magazine: Diferencias entre IE6, IE7 e IE8';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">No hi ha cap entrada relacionada</p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/02/smashing-magazine-diferencias-entre-ie6-ie7-e-ie8/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CSS hacks para Firefox, Internet Explorer, Chrome, Opera, Safari&#8230;</title>
		<link>http://racotecnic.underave.net/2010/02/css-hacks-para-firefox-internet-explorer-chrome-opera-safari/</link>
		<comments>http://racotecnic.underave.net/2010/02/css-hacks-para-firefox-internet-explorer-chrome-opera-safari/#comments</comments>
		<pubDate>Mon, 08 Feb 2010 22:38:44 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Gecko]]></category>
		<category><![CDATA[Google Chrome]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Opera]]></category>
		<category><![CDATA[Safari]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1369</guid>
		<description><![CDATA[Todos sabemos lo divertido y emocionante que es hacer la compatibilidad crossbrowser de nuestras páginas web.
Por suerte para nosotros, existen un gran número de hacks CSS que podemos utilizar en cada una de las versiones de cada navegador para ayudarnos a poder mostrar por igual los contenidos de una web en todos los navegadores.
Partiré de [...]]]></description>
			<content:encoded><![CDATA[<p>Todos sabemos lo <em>divertido</em> y <em>emocionante</em> que es hacer la compatibilidad crossbrowser de nuestras páginas web.</p>
<p>Por suerte para nosotros, existen un gran número de hacks CSS que podemos utilizar en cada una de las versiones de cada navegador para ayudarnos a poder mostrar por igual los contenidos de una web en todos los navegadores.</p>
<p>Partiré de este estilo:</p>
<pre class="brush: css;">.selector {
	color: #CCCCCC;
}</pre>
<p>Empezaré por Internet Explorer, dado que es para el que usualmente se necesitan más hacks:</p>
<h5>Internet Explorer 6</h5>
<pre class="brush: css;">.selector {
	_color: #CCCCCC;
}</pre>
<p>Recordad que IE6 no interpreta la propiedad (o palabra clave..) de CSS &#8220;!important&#8221; por lo que podéis jugar con ello (aunque no es lo más recomendable):</p>
<h5>Internet Explorer 6 (!important)</h5>
<pre class="brush: css;">.selector {
	color: #CCCCCC !important;
	color: #000000; /* Éste estilo sólo se aplicará a Internet Explorer 6 */
}</pre>
<h5>Internet Explorer 7 y anteriores:</h5>
<pre class="brush: css;">.selector {
	*color: #CCCCCC;
}</pre>
<h5>Internet Explorer 8</h5>
<p>Este es un poco <em>putilla</em>, ya que el mismo hack de IE8 a veces lo interpreta IE7&#8230; así que, si nos interesa, primero habrá que poner algo que interprete únicamente IE7 y después hay que poner el hack de IE8:</p>
<pre class="brush: css;">/* Interpretado únicamente por IE7 (actúa como un !important) */
*:first-child+html .selector {
	color: #CCCCCC;
}
.selector {
	color /*\**/: #CCCCCC\9   /* Sin punto y coma!! */
}</pre>
<h5>Todas las versiones de Internet Explorer</h5>
<pre class="brush: css;">.selector {
	color: #CCCCCC\9   /* Sin punto y coma!! */
}</pre>
<h5>Internet Explorer 7 y demás navegadores modernos (incluido IE8)</h5>
<pre class="brush: css;">html&gt;body .selector {
	color: #CCCCCC;
}</pre>
<h5>Todos los navegadores modernos (incluido IE8)</h5>
<pre class="brush: css;">html&gt;/**/body .selector {
	color: #CCCCCC;
}</pre>
<h5>Opera 9.27 y anteriores</h5>
<pre class="brush: css;">html:first-child .selector {
	color: #CCCCCC;
}</pre>
<h5>Safari</h5>
<pre class="brush: css;">html[xmlns*=&quot;&quot;] body:last-child .selector {
	color: #CCCCCC;
}</pre>
<h5>Safari 3+, Opera 9+, Firefox 3.5+ y Chrome 1+</h5>
<pre class="brush: css;">body:nth-of-type(1) .selector {
	color: #CCCCCC;
}
/* Otra opción... */
body:first-of-type .selector {
	color: #CCCCCC;
}

/* Y otra más... */
@media screen and (-webkit-min-device-pixel-ratio:0) {
	.selector {
		color: #CCCCCC;
	}
}</pre>
<h5>Safari 3+ y Chrome 1+</h5>
<pre class="brush: css;">@media screen and (-webkit-min-device-pixel-ratio:0) {
	.selector {
		color: #CCCCCC;
	}
}

/* Otra opción... */
body:nth-of-type(1) .selector{
   color: #CCCCCC;
}
</pre>
<h5>Todas las versiones de Firefox</h5>
<pre class="brush: css;">@-moz-document url-prefix() {
	.selector {
		color: #CCCCCC;
	}
 } </pre>
<h5>Cualquier Gecko (incluido Firefox)</h5>
<pre class="brush: css;">*&gt;.selector {
	color: #CCCCCC;
}</pre>
<h5>Firefox 1.5+</h5>
<pre class="brush: css;">.selector, x:-moz-any-link, x:only-child {
	color: #CCCCCC;
}</pre>
<h5>Firefox 2 y versiones anteriores</h5>
<pre class="brush: css;">body:empty .selector {
	color: #CCCCCC;
}

/* Otra opción... */
html&gt;/**/body .selector, x:-moz-any-link {
	color: #CCCCCC;
}</pre>
<h5>Firefox 3 (y quizás más nuevos)</h5>
<pre class="brush: css;">html&gt;/**/body .selector, x:-moz-any-link, x:default {
	color: #CCCCCC;
}</pre>
<p>No he probado todos ellos así que si veis alguno que no funciona, por favor, hacédmelo saber para que pueda buscar alguna alternativa (o eliminarlo&#8230;).</p>
<p>Además os invito a que añadáis cualquier hack de CSS que no haya puesto comentando esta entrada <img class="dtse-img dtse-post-1369" src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<blockquote><p><strong>Páginas de referencia:</strong></p>
<ul>
<li><a rel="nofollow" href="http://www.anieto2k.com/2008/01/23/otro-css-hack-para-safari/" target="_blank">Otro hack CSS para Safari @ Anieto</a></li>
<li><a rel="nofollow" href="http://perishablepress.com/press/2009/06/28/css-hacks-for-different-versions-of-firefox/" target="_blank">CSS hacks for differents versions of Firefox @ Perishable Press</a></li>
<li><a rel="nofollow" href="http://www.evotech.net/blog/2008/09/css-hack-for-google-chrome-and-safari-31/" target="_blank">CSS hack for Google Chrome and Safari 3.1 @ Evotech</a></li>
<li><a rel="nofollow" href="http://acidmartin.wordpress.com/2009/06/04/css-hack-for-internet-explorer-8/" target="_blank">CSS hack for Internet Explorer 8 @ Acid Martin</a></li>
<li><a rel="nofollow" href="http://www.drauta.com/articulos/hacks-css-para-todos-los-navegadores-incluido-explorer-8/" target="_blank">Hacks CSS para todos los navegadores&#8230; @ Drauta</a></li>
</ul>
</blockquote>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1369_permalink = 'http://racotecnic.underave.net/2010/02/css-hacks-para-firefox-internet-explorer-chrome-opera-safari/';
			dtsv.dtse_post_1369_title = 'CSS hacks para Firefox, Internet Explorer, Chrome, Opera, Safari…';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/05/color-explorer/' rel='bookmark' title='Permanent Link: Color Explorer'>Color Explorer</a></li>
<li><a href='http://racotecnic.underave.net/2009/10/spoon-app-studio-cuelga-tus-aplicaciones-en-internet-para-usarlas-con-el-navegador/' rel='bookmark' title='Permanent Link: Spoon App Studio: Cuelga tus aplicaciones en internet para usarlas con el navegador'>Spoon App Studio: Cuelga tus aplicaciones en internet para usarlas con el navegador</a></li>
<li><a href='http://racotecnic.underave.net/2009/03/cracking-cuenta-premium-de-megaupload-via-firefox/' rel='bookmark' title='Permanent Link: Cracking cuenta premium de Megaupload vía Firefox'>Cracking cuenta premium de Megaupload vía Firefox</a></li>
<li><a href='http://racotecnic.underave.net/2010/02/smashing-magazine-diferencias-entre-ie6-ie7-e-ie8/' rel='bookmark' title='Permanent Link: Smashing magazine: Diferencias entre IE6, IE7 e IE8'>Smashing magazine: Diferencias entre IE6, IE7 e IE8</a></li>
<li><a href='http://racotecnic.underave.net/2009/04/crear-transicion-de-imagenes-para-gallery2-con-jquery/' rel='bookmark' title='Permanent Link: Crear transición de imágenes para Gallery2 con jQuery'>Crear transición de imágenes para Gallery2 con jQuery</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/02/css-hacks-para-firefox-internet-explorer-chrome-opera-safari/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Integrando CakePHP y phpBB 3.x</title>
		<link>http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/</link>
		<comments>http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/#comments</comments>
		<pubDate>Sat, 23 Jan 2010 14:32:41 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Administració usuaris]]></category>
		<category><![CDATA[Cake PHP 1.2]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpBB]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1224</guid>
		<description><![CDATA[
// 

	.amunt {
		float: right;
		font-size: .8em;
	}
	#registre-phpbb {
		width: 300px;
		-moz-border-radius: 7px;
		border: 1px solid #cccccc;
		float: left;
		background-color: #f7f7f7;
		margin: 20px 0;
	}
	#imatge-cakephp {
		float: right;
	}


Ocultar

Antes de empezar
Primeros pasos
Creando el componente phpBB3
Registro de usuarios
Errores fatales :s
Login de usuarios
Cambio de datos del usuario
Modificando vuestra plantilla de phpBB



Antes de empezar&#8230;
Más o menos al empezar con este blog expliqué cómo podíais hacer un registro de usuarios externo [...]]]></description>
			<content:encoded><![CDATA[<p><script type="text/javascript">
// <![CDATA[
	jQuery(function(){
		jQuery("#registre-phpbb legend").css('cursor', 'pointer').click(function(){
			jQuery(this).next().slideToggle();
			if(jQuery(this).text() == 'Ocultar')
			{
				jQuery(this).text('Mostrar');
			}
			else
			{
				jQuery(this).text('Ocultar');
			}
		});
		jQuery(".amunt").click(function(){
			MGJS.goTop();
			return false;
		});
	});
// ]]&gt;
</script></p>
<style type="text/css">
	.amunt {
		float: right;
		font-size: .8em;
	}
	#registre-phpbb {
		width: 300px;
		-moz-border-radius: 7px;
		border: 1px solid #cccccc;
		float: left;
		background-color: #f7f7f7;
		margin: 20px 0;
	}
	#imatge-cakephp {
		float: right;
	}
</style>
<fieldset id="registre-phpbb">
<legend style="padding: 0 5px;">Ocultar</legend>
<ul>
<li><a href="#phpbb-zero">Antes de empezar</a></li>
<li><a href="#phpbb-primer">Primeros pasos</a></li>
<li><a href="#phpbb-segon">Creando el componente phpBB3</a></li>
<li><a href="#phpbb-tercer">Registro de usuarios</a></li>
<li><a href="#phpbb-quart">Errores fatales :s</a></li>
<li><a href="#phpbb-cinque">Login de usuarios</a></li>
<li><a href="#phpbb-sise">Cambio de datos del usuario</a></li>
<li><a href="#phpbb-sete">Modificando vuestra plantilla de phpBB</a></li>
</ul>
</fieldset>
<p><a href="http://racotecnic.underave.net/wp-content/uploads/2010/01/hot-features.png" id="imatge-cakephp" rel="lightbox[1224]"><img class="alignnone size-full wp-image-1348 dtse-img dtse-post-1224" title="hot-features" src="http://racotecnic.underave.net/wp-content/uploads/2010/01/hot-features.png" alt="" width="260" height="260" /></a></p>
<h4 id="phpbb-zero">Antes de empezar&#8230;</h4>
<p>Más o menos al empezar con este blog expliqué cómo podíais <a title="Leer tutorial" href="http://racotecnic.underave.net/2009/01/registro-de-usuarios-externo-a-phpbb-3x/" target="_self">hacer un registro de usuarios externo a phpBB3 con PHP</a>. Hoy voy a contaros cómo hacer para <strong>implementar el registro y login de usuarios de phpBB3 en CakePHP</strong>.</p>
<p>Podéis ver, como ejemplo, la página de <a href="http://www.underave.net">underave</a>. Pero os pido por favor que no os registréis si no vais a utilizar la cuenta.</p>
<p><strong>Antes de empezar</strong> con el tutorial, por favor, <strong>leeros el tutorial anterior</strong> sobre el <a title="Leer tutorial" href="http://racotecnic.underave.net/2009/01/registro-de-usuarios-externo-a-phpbb-3x/" target="_self">registro de usuarios externo a phpBB3</a>, ya que habrá ciertos aspectos que pasaré por alto por estar explicados en ese tutorial.</p>
<p>Además de miraros ese tutorial deberíais echar un vistazo a la documentación del componente Auth, ya que sin él el registro de usuarios sería otra cosa&#8230;</p>
<ul>
<li><a rel="nofollow" href="http://book.cakephp.org/view/172/authentication" target="_blank">CakePHP Authentication</a></li>
</ul>
<p>Como siempre, empiezo con lo que he utilizado para llevar a cabo el tutorial&#8230;</p>
<ul>
<li><a rel="nofollow" href="http://www.cakephp.org/" target="_blank">CakePHP</a> (v. 1.2.4.8284 [1.2.5 stable])</li>
<li>phpBB 3.0.2</li>
<li>Componente de integración de phpBB3 (que ahora crearemos)</li>
</ul>
<p>Aunque yo haya utilizado la versión 3.0.2 de phpBB, debéis saber que <strong>este sistema debe funcionar igual de bien en cualquier versión de phpBB 3</strong> <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Parto de la base de que tenéis creado un modelo y un controlador encargados de gestionar los usuarios de vuestra aplicación Cake. En mi caso los he llamado &#8220;<em>users</em>&#8220;, aunque podéis llamarlos &#8220;usuarios&#8221;, &#8220;<em>members</em>&#8220;, o como os dé la gana.</p>
<p>Es decir, <strong>doy por supuesto que ya tenéis un sistema de usuarios funcionando en vuestra aplicación CakePHP</strong>. En este tutorial sólo os explicaré cómo integrar el registro y login de phpBB3, así que todo lo demás (validaciones de datos, creación de formularios, funcionamiento de la clase Auth&#8230;) quedará por supuesto (lo cual no quiere decir que no vaya a haber código al respecto <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ).</p>
<h4 id="phpbb-primer">Primeros pasos<a class="amunt" href="#amunt">arriba</a></h4>
<p>Además de la parte encargada de la gestión de usuarios vamos a tener que crear un modelo para el foro. Este sólo debe contener el nombre del modelo y debemos indicarle que no va a utilizar base de datos:</p>
<pre class="brush: php;">&lt;?php // /app/models/forum.php
class Forum extends AppModel
{
	var $name = 'Forum';
	var $useDbConfig = 'forums';
	var $useTable = false;
}</pre>
<p>Como podéis ver, además de haber indicado el nombre del modelo y haber desactivado el uso de base de datos en éste, he indicado que utilice la configuración de base de datos <em>forums</em>. Con esto indicamos al modelo que, en caso de utilizar la base de datos, la configuración que utilizaremos será la <em>forums</em>.</p>
<p>Podéis añadir tantas configuraciones de conexión a la base de datos como queráis, simplemente cread una variable con el nombre que queráis de conexión conteniendo los datos necesarios en el fichero <em>/app/config/database.php</em>:</p>
<pre class="brush: php;">&lt;?php // /app/config/database.php
class DATABASE_CONFIG {
	var $default = array(
		'driver' =&gt; 'mysql',
		'persistent' =&gt; false,
		'host' =&gt; 'localhost',
		'login' =&gt; 'USUARIO',
		'password' =&gt; 'CONTRASEÑA',
		'database' =&gt; 'BASE_DE_DATOS'
	);
	var $forums = array(
		'driver' =&gt; 'mysql',
		'persistent' =&gt; false,
		'host' =&gt; 'localhost',
		'login' =&gt; 'USUARIO',
		'password' =&gt; 'CONTRASEÑA',
		'database' =&gt; 'BASE_DE_DATOS',
		'prefix' =&gt; 'phpbb_'
	);
}</pre>
<p>Si vuestras tablas del foro tienen un prefijo (como es mi caso) aseguraros de especificar la opción &#8220;prefix&#8221; en el array de conexión a la base de datos.</p>
<h4 id="phpbb-segon">Creando el componente phpBB3<a class="amunt" href="#amunt">arriba</a></h4>
<p>Vamos a por la creación del componente PhpBB3 que nos permitirá el login de usuarios. El componente es una modificación de uno llamado <a rel="nofollow" href="http://bakery.cakephp.org/articles/view/phpbb3-api-bridge" target="_blank">PhpBB3 Api Bridge</a>, del <a rel="nofollow" href="http://bakery.cakephp.org" target="_blank">Bakery</a> the Cake.</p>
<p>He modificado el componente porque tal y como lo presenta <em>Wilson Sheldon</em> (el autor del componente), al iniciar sesión en el foro y si el usuario no existe, se le registra en el sistema.</p>
<p>Esto está muy bien cuando añadimos el foro <strong>después</strong> de haber creado nuestra aplicación CakePHP. Sin embargo, si en lugar de añadir el foro estamos creando un portal con CakePHP y con phpBB desde cero, lo más seguro es que no os interese hacer esa verificación.</p>
<p>Cread, pues, el componente <em>php_b_b3.php</em> con el siguiente contenido:</p>
<pre class="brush: php; highlight: [11];">&lt;?php // /app/controllers/components/php_b_b3.php
/**
* Created by Willson Sheldon =&gt; http://bakery.cakephp.org/articles/view/phpbb3-api-bridge
* Modified by Òscar Casajuana a.k.a. elboletaire =&gt; http://www.underave.net
*/
class PhpBB3Component extends Object
{

	var $controller;
	var $model;
	var $phpBBpath = '/ruta/a/tu/instalacion/de/phpBB3/';

	/**
	 * Inicia la sesión en phpBB3
	 * @param string $username
	 * @param string $password
	 * @param bool $remember [optional] Recordar entre sesiones
	 */
	public function login($username, $password, $remember = false)
	{
		$this-&gt;auth-&gt;login($username, $password, $remember);
	}

	/**
	 * Cierra la sesión en phpBB
	 */
	public function logout()
	{
		$this-&gt;user-&gt;session_kill();
		$this-&gt;user-&gt;session_begin();
	}

	/**
	 * Registra un usuario en el sistema
	 * @param array $data Datos del usuario
	 * @return id del usuario en caso de éxito; falso en caso contrario
	 */
	public function register($data)
	{
		// Paràmetres per defecte
		// Grup usuaris registrats
		if(!isset($data['group_id']) || empty($data['group_id'])) $data['group_id'] = 5;
		// Franja horària GMT+01
		if(!isset($data['user_timezone']) || empty($data['user_timezone'])) $data['user_timezone'] = 1;
		// Horari d'estiu desactivat
		if(!isset($data['user_dst']) || empty($data['user_dst'])) $data['user_dst'] = 0;
		if(!isset($data['user_lang']) || empty($data['user_lang'])) $data['user_lang'] = 'es';
		// Usuari inactiu per defecte
		if(!isset($data['user_type']) || empty($data['user_type'])) $data['user_type'] = 1;
		// Això millor no tocar-ho
		if(!isset($data['user_style']) || empty($data['user_style'])) $data['user_style'] = 2;
		$userData = array(
            'username' =&gt; $data['username'],
			'username_clean' =&gt; strtolower($data['username']),
            'user_password' =&gt; $this-&gt;phpbb_hash($data['user_password']),
            'user_email' =&gt; $data['user_email'],
			'user_ip'=&gt;$_SERVER['REMOTE_ADDR'],
            'group_id' =&gt; $data['group_id'], //Registered users group
            'user_timezone' =&gt; $data['user_timezone'],
            'user_dst' =&gt; $data['user_dst'],
            'user_lang' =&gt; $data['user_lang'],
            'user_type' =&gt; $data['user_type'],
            'user_actkey' =&gt; '',
            'user_dateformat' =&gt; 'D d M Y, g:i a',
            'user_style' =&gt; 2,
            'user_regdate' =&gt; time(),
        );
 		$userId = user_add($userData);
		if(empty($userId)) return false;
		else
		{
			// Actualitzem darrer usuari registrat al phpBB
			update_last_username();
			return $userId;
		}
	}

	/**
	 * Encripta una contraseña utilizando el
	 * método de encriptación de phpBB3
	 * @param string $password
	 * @return contraseña encriptada
	 */
	public function phpbb_hash($password)
	{

		$itoa64 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
		$random_state = $this-&gt;unique_id();
		$random = '';
		$count = 6;

		if (($fh = @fopen ( '/dev/urandom', 'rb' )))
		{
			$random = fread ($fh, $count);
			fclose ($fh);
		}

		if (strlen($random) &lt; $count)
		{
			$random = '';
			for($i=0;$i&lt;$count;$i+=16)
			{
				$random_state = md5($this-&gt;unique_id () . $random_state);
				$random .= pack('H*', md5($random_state));
			}
			$random = substr($random, 0, $count);
		}

		$hash = $this-&gt;_hash_crypt_private($password, $this-&gt;_hash_gensalt_private($random, $itoa64 ), $itoa64);

		if (strlen($hash) == 34)
		{
			return $hash;
		}

		return md5($password);
	}

	/**
	 * Verifica la existencia de un usuario
	 * @param string $username
	 * @return
	 */
	public function userExists($username)
	{
		if (user_get_id_name(false, $username) == 'NO_USERS')
		{
			return false;
		}
		else
		{
			return true;
		}
	}

	/**
	 * Carga los ficheros necesarios de phpBB3
	 */
	function startup(&amp;$controller)
	{
        	$this-&gt;controller = &amp;$controller;
		define('IN_PHPBB', true);

		global $phpbb_root_path, $phpEx, $db, $config, $user, $auth, $cache, $template;

		$phpbb_root_path = $this-&gt;phpBBpath;
		$phpEx = substr(strrchr(__FILE__, '.'), 1);
		require_once($phpbb_root_path . 'common.' . $phpEx);

		$this-&gt;table_prefix = $table_prefix;
		$this-&gt;auth = $auth;
		$this-&gt;user = $user;

		// Start session management
		$this-&gt;user-&gt;session_begin();
		$this-&gt;auth-&gt;acl($user-&gt;data);
		this-&gt;user-&gt;setup();

		require_once($phpbb_root_path .'includes/functions_user.php');
	}

	private function unique_id($extra = 'c')
	{
		static $dss_seeded = false;
		global $config;

		$val = $config ['rand_seed'] . microtime ();
		$val = md5 ( $val );
		$config ['rand_seed'] = md5 ( $config ['rand_seed'] . $val . $extra );

		$dss_seeded = true;
		return substr ( $val, 4, 16 );
	}

	/**
	 * Generate salt for hash generation
	 */
	private function _hash_gensalt_private($input,&amp;$itoa64,$iteration_count_log2 = 6)
	{
		if ($iteration_count_log2 &lt; 4 || $iteration_count_log2 &gt; 31)
		{
			$iteration_count_log2 = 8;
		}

		$output = '$H$';
		$output .= $itoa64 [min($iteration_count_log2 + ((PHP_VERSION &gt;= 5) ? 5 : 3), 30)];
		$output .= $this-&gt;_hash_encode64($input, 6, $itoa64);

		return $output;
	}

	/**
	 * Encode hash
	 */
	private function _hash_encode64($input,$count,&amp;$itoa64)
	{
		$output = '';
		$i = 0;
		do
		{
			$value = ord ( $input [$i ++] );
			$output .= $itoa64 [$value &amp; 0x3f];
			if ($i &lt; $count)
			{
				$value |= ord ( $input [$i] ) &lt;&lt; 8;
			}
			$output .= $itoa64 [($value &gt;&gt; 6) &amp; 0x3f];
			if ($i ++ &gt;= $count)
			{
				break;
			}
			if ($i &lt; $count)
			{
				$value |= ord ( $input [$i] ) &lt;&lt; 16;
			}
			$output .= $itoa64 [($value &gt;&gt; 12) &amp; 0x3f];
			if ($i ++ &gt;= $count)
			{
				break;
			}
			$output .= $itoa64 [($value &gt;&gt; 18) &amp; 0x3f];
		} while ( $i &lt; $count );

		return $output;
	}

	/**
	 * The crypt function/replacement
	 */
	private function _hash_crypt_private($password,$setting,&amp;$itoa64)
	{
		$output = '*';

		// Check for correct hash
		if (substr ( $setting, 0, 3 ) != '$H$')
		{
			return $output;
		}
		$count_log2 = strpos ( $itoa64, $setting [3] );
		if ($count_log2 &lt; 7 || $count_log2 &gt; 30)
		{
			return $output;
		}
		$count = 1 &lt;&lt; $count_log2;
		$salt = substr ( $setting, 4, 8 );

		if (strlen ( $salt ) != <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' />
		{
			return $output;
		}
		/**
		 * We're kind of forced to use MD5 here since it's the only
		 * cryptographic primitive available in all versions of PHP
		 * currently in use.  To implement our own low-level crypto
		 * in PHP would result in much worse performance and
		 * consequently in lower iteration counts and hashes that are
		 * quicker to crack (by non-PHP code).
		 */
		if (PHP_VERSION &gt;= 5)
		{
			$hash = md5 ( $salt . $password, true );
			do
			{
				$hash = md5 ( $hash . $password, true );
			} while ( -- $count );
		}
		else
		{
			$hash = pack ( 'H*', md5 ( $salt . $password ) );
			do
			{
				$hash = pack ( 'H*', md5 ( $hash . $password ) );
			} while ( -- $count );
		}
		$output = substr ( $setting, 0, 12 );
		$output .= $this-&gt;_hash_encode64 ( $hash, 16, $itoa64 );

		return $output;
	}
}</pre>
<p>Aunque veáis mucho código, no os asustéis. La mayoría de estos métodos son para encriptar la contraseña. Los métodos que nosotros utilizaremos serán <strong>login</strong>, <strong>logout</strong>, <strong>register</strong> y <strong>userExists</strong>.</p>
<p>Lo primero que debéis hacer es substituir la ruta hacia vuestra instalación de phpBB3, en la <strong>línea 11</strong> (subrayada en azul, como no).</p>
<h4 id="phpbb-tercer">Registro de usuarios<a class="amunt" href="#amunt">arriba</a></h4>
<p>Ahora que ya tenemos el componente vamos a empezar a desarrollar el registro de usuarios. En esta parte editaremos / crearemos tres ficheros: el modelo de usuarios, para añadir las validaciones correspondientes; el controlador de usuarios, para añadir el método de registro y la vista del registro de usuarios.</p>
<p>Los usuarios los registraremos activados para ahorrarnos complicaciones. Dejo en vuestras manos la creación de un método para la activación de la cuenta del usuario en caso de que registréis a vuestros usuarios con la cuenta inhabilitada.</p>
<p>Empecemos con la vista <strong>register.ctp</strong>:</p>
<pre class="brush: php;">&lt;?= $form-&gt;create('User',array('action'=&gt;'register')) ?&gt;
&lt;?= $form-&gt;input('User.username', array('label'=&gt;__(&quot;Nombre de usuario&quot;,true))) ?&gt;
&lt;!-- Indicamos value = '' a la contraseña para que no se rellene el campo automáticamente en caso de haber algún error en los datos --&gt;
&lt;?= $form-&gt;input('User.password', array('label'=&gt;__('Contraseña',true),'type'=&gt;'password','value'=&gt;'')) ?&gt;
&lt;?= $form-&gt;input('User.confirm_passwd', array('label'=&gt;__('Confirma la contraseña',true),'type'=&gt;'password','value'=&gt;'')) ?&gt;
&lt;?= $form-&gt;input('User.email', array('label'=&gt;__('E-mail',true))) ?&gt;
&lt;?= $form-&gt;end(__('Registrarse',true)) ?&gt;</pre>
<p>Sencillo, ¿no?</p>
<p>Creemos las validaciones que nos interesen en nuestro modelo <strong>user</strong>:</p>
<pre class="brush: php;">&lt;?php // /app/models/user.php
class User extends AppModel {
	var $name = 'User';
	var $validate = array(
		'username'	=&gt;	array(
						'length'		=&gt;	array(
											'rule'		=&gt; array('between', 3, 23),
											'message'	=&gt;&quot;El nombre debe contener entre 3 y 23 caracteres&quot;
											),
						'exists'		=&gt;	array(
											'rule'		=&gt; array('checkUnique','username'),
											'message'	=&gt; &quot;El nombre de usuario ya existe&quot;
											)
						),
		'email'		=&gt;	array(
							&quot;El e-mail introducido no es válido&quot; =&gt; VALID_EMAIL,
							&quot;El e-mail es obligatorio&quot; =&gt; VALID_NOT_EMPTY,
							&quot;exists&quot;		=&gt; array(
												'rule'		=&gt; array('checkUnique','email'),
												'message'	=&gt; &quot;Ya hay un usuario registrado con este e-mail&quot;
												)
  							),
		'confirm_passwd' =&gt; array('identicalFieldValues'	=&gt; array(
													'rule'=&gt;array('identicalFieldValues','password'),
													'message'=&gt;'Las contraseñas introducidas no coinciden'
													)
							),
		'password'	=&gt;	array('length'		=&gt;	array(
											'rule'		=&gt; array('minLength', 6),
											'message'	=&gt;&quot;La contraseña debe contener al menos 6 caracteres&quot;
											)
						)
		);
	/**
	* Verifica si dos campos son iguales
	*/
	function identicalFieldValues( $field = array(), $compare_field = null )
	{
		foreach( $field as $key =&gt; $value )
		{
			$v1 = $value;
			$v2 = $this-&gt;data[$this-&gt;name][$compare_field];
			if($v1 !== $v2)
			{
				return FALSE;
			}
			else
			{
				continue;
			}
		}
		return TRUE;
	}

	/**
	* Verifica si un dato existe en la base de datos
	* @param $data         Dato con el que comparar
	* @param $fieldName    Nombre de celda a verificar
	* @return bool
	*/
	function checkUnique($data, $fieldName )
	{
		$valid = false;
		if(isset($fieldName) &amp;&amp; $this-&gt;hasField($fieldName))
		{
			$valid = $this-&gt;isUnique(array($fieldName =&gt; $data));
		}
		return $valid;
	}
}
</pre>
<p>Los métodos <strong>identicalFieldValues</strong> y <strong>checkUnique</strong> son los encargados de verificar si las dos contraseñas coinciden y si el usuario existe en la base de datos.</p>
<p>Si tenéis cualquier duda sobre la creación del modelo podéis dirigiros a la documentación de cake al respecto, ya que allí se explica todo con detalle:</p>
<ul>
<li><a rel="nofollow" href="http://book.cakephp.org/view/125/Data-Validation" target="_blank">CakePHP Data Validation</a></li>
<li><a rel="nofollow" href="http://book.cakephp.org/view/150/Custom-Validation-Rules" target="_blank">CakePHP Custom Validation Rules</a></li>
</ul>
<p>Vamos a por el método <strong>register</strong>. Este puede variar mucho según la aplicación que queráis hacer&#8230; por ejemplo, en el caso de <a href="http://www.underave.net">underave</a> verifico que el usuario no está registrado ni en el foro ni en la página principal, ya que cuando hicimos el cambio cometimos el error de hacerlo así. En el ejemplo doy por supuesto que si el usuario no existe en la base de datos principal, no existirá en el foro. De todos modos veréis cómo hacer para verificar la existencia de un usuario (todo el primer trozo comentado):</p>
<pre class="brush: php;">// /app/controllers/users_controller.php
class UsersController extends AppController
{
	var $name = 'Users';
	var $components = array('Auth','PhpBB3');

	function register()
	{
		$this-&gt;pageTitle = __(&quot;Registro&quot;,true) . &quot; | &quot; . __(&quot;Usuarios&quot;,true);
		if(!empty($this-&gt;data))
		{
			// Guardamos la contraseña sin encriptar para registrar al usuario en el foro
			$password = $this-&gt;data['User']['confirm_passwd'];
// 			Si nos interesa, verificamos la existencia del usuario en el foro
//			if($this-&gt;phpBB-&gt;userExists($this-&gt;data['User']['username']))
//				$this-&gt;User-&gt;invalidate('username','exists');
			// Cargamos los datos del usuario en el modelo
			$this-&gt;User-&gt;set($this-&gt;data);
			// En caso de pasar las validaciones...
			if($this-&gt;User-&gt;validates())
			{
				// Registramos el usuario en el foro
				$datos = array(
					'username'		=&gt; $this-&gt;data['User']['username'],
					'user_password'	=&gt; $password,
					'user_email'	=&gt; $this-&gt;data['User']['email']
				);
				if($userForumId = $this-&gt;PhpBB3-&gt;register($datos))
				{
					// En caso de haber registrado al usuario correctamente guardamos la variable con su id del foro
					$this-&gt;data['User']['forum_id'] = $userForumId;
					if($this-&gt;User-&gt;save($this-&gt;data,false))
					{
						$this-&gt;Session-&gt;setFlash(__(&quot;Usuario registrado correctamente&quot;,true));
						$this-&gt;redirect('/');
					}
					else
					{
						$this-&gt;Session-&gt;setFlash(__(&quot;Ha habido algún error al registrarte...&quot;,true));
					}
				}
				else
				{
					$this-&gt;Session-&gt;setFlash(__(&quot;Ha habido algún error al registrarte...&quot;,true));
				}
			}
		}
	}
}</pre>
<p>Como podéis ver en el ejemplo, una vez he registrado al usuario en el foro me quedo con la ID del usuario creado y es entonces cuando registro al usuario en el sistema, para poder disponer de esta ID.</p>
<p>Si no guardáis la ID del usuario en vuestra base de datos de Cake no podréis hacer nada una vez registrado el usuario. Es decir, no podréis hacer ni el login, ni un cambio de contraseña ni nada de nada. Así que es vital que guardéis su ID.</p>
<p>Bien, en principio esta parte ya la tenemos. Ahora mismo al registrarse alguien en vuestro sistema queda registrado en el foro y en la base de datos de CakePHP.</p>
<p>Ap!! Pero alto, si lo probáis no funcionará. Adelante, haced la prueba. Es necesaria para seguir adelante.</p>
<h4 id="phpbb-quart">Errores fatales :s<a class="amunt" href="#amunt">arriba</a></h4>
<p>Si estáis utilizando caché, lo más seguro es que el primer error que veáis sea este:</p>
<blockquote><p><strong>Fatal error:</strong> Cannot redeclare class cache in &#8230;</p></blockquote>
<p>Esto sucede porque el núcleo de Cake utiliza una classe que se llama igual que una del núcleo de phpBB3 (cache, en este caso). Estuve varios meses dándole vueltas a este asunto y la mejor solución que encontré fue modificar algunos ficheros de phpBB3, así que vamos a ello. No os preocupéis, tan solo modificaremos unos pocos ficheros:</p>
<p>Básicamente lo que hay que hacer es renombrar la clase <strong>cache</strong>. Primero modificaremos el nombre de la clase y luego pasaremos a cambiar aquellas líneas de código donde se instancíe la clase.</p>
<p>Abrid <em>phpBB3/includes/cache.php</em> y buscad lo siguiente (en la línea 23 aproximadamente):</p>
<pre class="brush: php;">class cache extends acm</pre>
<p>Substituidlo por:</p>
<pre class="brush: php;">class fcache extends acm</pre>
<p>Guardad el fichero y cerradlo. Ahora abrid estos ficheros:</p>
<ul>
<li><em>phpBB3/common.php</em></li>
<li><em>phpBB3/style.php</em></li>
<li><em>phpBB3/download/file.php</em></li>
</ul>
<p>Buscad esto en cada uno de ellos:</p>
<pre class="brush: php;">new cache();</pre>
<p>Y reemplazadlo por:</p>
<pre class="brush: php;">new fcache();</pre>
<p>Hecho esto (y una vez guardados los ficheros, por supuesto..) subís los ficheros al servidor y el foro debería seguir funcionando correctamente.</p>
<p>¡Aps! ¿Que no os funciona correctamente? Si, como yo, habéis creado el sistema de usuarios utilizando la palabra &#8220;users&#8221;, tendréis otro error fatal:</p>
<blockquote><p><strong>Fatal error:</strong> Cannot redeclare class user&#8230;</p></blockquote>
<p>Del mismo modo que con la caché, la mejor forma de solucionar esto es modificando phpBB3. Abrid el fichero phpBB3/includes/session.php y buscad lo siguiente (en la línea 1376 aproximadamente):</p>
<pre class="brush: php;">class user extends session</pre>
<p>Y reemplazadlo por&#8230;</p>
<pre class="brush: php;">class fuser extends session</pre>
<p>Ahora abrid el fichero <em>phpBB3/common.php</em> y buscad lo siguiente:</p>
<pre class="brush: php;">new user();</pre>
<p>Y reemplazadlo por:</p>
<pre class="brush: php;">new fuser();</pre>
<p>Ahora sí que sí <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /> . Vuestro registro de usuarios, así como vuestra instalación de phpBB, deberían funcionar perfectamente <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h4 id="phpbb-cinque">Login de usuarios<a class="amunt" href="#amunt">arriba</a></h4>
<p>Bien, ahora pasaremos a la creación de la vista <strong>login.ctp</strong>:</p>
<pre class="brush: php;">&lt;?php // /app/views/users/login.ctp
echo $form-&gt;create('User',array('action'=&gt;'login'));
echo $form-&gt;input('User.username', array('label'=&gt;__(&quot;Nombre&quot;,true)));
// Utilizamos 'pass' para que Auth no nos encripte la contraseña automáticamente
echo $form-&gt;input('User.pass', array('label'=&gt;__('Contraseña',true), 'type'=&gt;'password'));
// Guardamos el referer para saber si el usuario viene del foro y así poderle enviar de nuevo al finalizar el login
echo $form-&gt;hidden('User.referer',array('value'=&gt;@$_SERVER['HTTP_REFERER']));
// Nota: Recordar entre sesiones funciona en el foro. Si no tenéis algún componente o método para recordar sesiones en Cake, quizás os interese utilizar alguno.
echo $form-&gt;input(&quot;User.remember_me&quot;,array('type'=&gt;'checkbox','label'=&gt;__(&quot;Recordar entre sesiones&quot;,true)));
echo $form-&gt;end(__('Iniciar sesión',true));
?&gt;
</pre>
<p>Es importante que guardemos la contraseña con un nombre de campo distinto a <em>password</em> ya que necesitamos la contraseña sin encriptar para poder iniciar sesión en el foro.</p>
<p>Pasemos al método <em>login</em> de nuestro controlador de usuarios. Ya que estamos, también añadiremos el de <em>logout</em>:</p>
<pre class="brush: php; highlight: [13,14,15,16,17];">// /app/controllers/users_controller.php
function login()
{
	if (!empty($this-&gt;data))
	{
		// Guardamos la contraseña encriptada para iniciar sesión en Cake
		$this-&gt;data['User']['password'] = $this-&gt;Auth-&gt;password($this-&gt;data['User']['pass']);
		// Iniciamos sesión en Cake
		if ($this-&gt;Auth-&gt;login($this-&gt;data))
		{
			// Iniciamos sesión en PhpBB. Si tenemos el campo 'remember_me' se lo pasamos como tercer parámetro.
			$this-&gt;PhpBB3-&gt;login($this-&gt;data['User']['username'], $this-&gt;data['User']['pass'], $this-&gt;data['User']['remember_me']);
			$this-&gt;Session-&gt;setFlash('Sessió iniciada correctament','flash_info',array(),'auth');
			// Verifico si el usuario viene del dominio principal
			if(!preg_match('/^http:\/\/(www\.)?underave\.net/', $this-&gt;data['User']['referer']) &amp;&amp; !empty($this-&gt;data['User']['referer']))
			{
				// Limpio la URL de posibles ids de sesión del foro (para evitar que éste cierre la sesión por seguridad)
				$referer = preg_replace('/^(.+)sid=[0-9a-z]+/i', '$1', $this-&gt;data['User']['referer']);
			// Si viene del dominio principal lo redirigiremos con el método Auth-&gt;redirect()
			}
			else $referer = $this-&gt;Auth-&gt;redirect();

			$this-&gt;redirect($referer);
		}
	}
}

function logout()
{
	$this-&gt;PhpBB3-&gt;logout();
	$this-&gt;redirect($this-&gt;Auth-&gt;logout());
}
</pre>
<p>En las <strong>líneas 13 a 17</strong> lo que hago es verificar si el usuario viene de mi dominio principal. Lo hago así porque en mi caso tengo los foros en un subdominio. Si no es vuestro caso deberéis modificar la expresión regular para que se ajuste a vuestras necesidades.</p>
<p>Si, como yo, tenéis los foros en un subdominio debéis saber que necesitáis tener las cookies configuradas para que funcionen entre vuestros subdominios y vuestro dominio principal. Para hacerlo, primero de todo id a vuestro panel de control del foro. En la barra lateral de la pestaña &#8220;General&#8221; veréis un grupo de opciones: &#8220;Configuración del servidor&#8221;. Ahí dentro tenéis un enlace para acceder a la configuración de las cookies.</p>
<p>Dentro de esta configuración, debéis poner como dominio de las cookies un punto seguido de vuestro nombre de dominio. En mi caso <strong>.underave.net</strong>. El punto delante del dominio es importante porque algunos navegadores no reconocerían los subdominios sin él.</p>
<p>En directorio de la cookie aseguraros que apunta a la raíz del dominio: <strong>/</strong></p>
<p>Ahora debéis aseguraros que en vuestro php.ini tenéis las cookies también configuradas como en el foro:</p>
<pre class="brush: plain;">; The path for which the cookie is valid.
session.cookie_path = /
; The domain for which the cookie is valid.
session.cookie_domain = .underave.net</pre>
<p>Hecho esto y subido vuestro php.ini al servidor (antes de subirlo quizás os interese echar un ojo al resto de opciones para ver qué se cuece por ahí) el login de usuarios ya debe funcionar sin problema alguno <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<h4 id="phpbb-sise">Y si el usuario quisiera cambiar alguno de sus datos?<a class="amunt" href="#amunt">arriba</a></h4>
<p>A mi parecer, es importante que el usuario no tenga que actualizar sus datos varias veces. Es decir, si el usuario cambia su e-mail o su contraseña desde nuestra aplicación Cake, es importante que éste dato se actualice también en el foro.</p>
<p>Además, sería interesante modificar todos los enlaces de phpBB del perfil de usuario que tengan que ver con la edición de datos personales para que éstos enlacen hacia nuestra aplicación Cake.</p>
<p>Si antes he creado una conexión hacia nuestra base de datos de phpBB así como un modelo llamado <em>Forum</em> ha sido porque a partir de ahora trabajaremos con la base de datos en lugar de con el componente. ¿Porqué? Porque así veis que todo esto que hemos estado haciendo es posible hacerlo sin utilizar los métodos del núcleo de phpBB3. ¿Todo? Bueno no, todo no. Para el login de usuarios seguramente será necesario que utilicéis el componente (a no ser que intentéis crear a mano las cookies vosotros mismos).</p>
<p>El método que crearemos ahora será para cambiar la contraseña ya que el cambio de contraseña quizás sea de los datos del perfil más difíciles de modificar. Después de ver el ejemplo añadid tantos métodos como necesitéis (cambio de e-mail, de avatar &#8230;).</p>
<p>Para cambiar cualquier dato de los usuarios del foro sería interesante tener un método en nuestro modelo Forum:</p>
<pre class="brush: php;">	// /app/models/forum.php
/**
 * Actualiza un dato ($field) de un usuario a
 * partir de su $id en el foro con el valor $value
 *
 * @param integer $id of user
 * @param string $field to update
 * @param mixed $value
 * @return boolean true on success, false on failure
 */
function setUserField($id, $field, $value)
{
	$this-&gt;setSource('users');
	$this-&gt;primaryKey = 'user_id';
	$this-&gt;id = $id;
	return $this-&gt;saveField($field, $value);
}</pre>
<p>Añadamos una vista para el cambio de contraseña:</p>
<pre class="brush: php;">// /app/views/users/change_password.ctp
&lt;?php
echo $form-&gt;create('User',array('action'=&gt;'changePassword'));
echo $form-&gt;input('old_passwd',array('label'=&gt;__('Contraseña actual',true),'type'=&gt;'password','type','value'=&gt;''));
echo $form-&gt;input('password',array('label'=&gt;__('Contraseña',true),'type'=&gt;'password','value'=&gt;''));
echo $form-&gt;input('confirm_passwd',array('label'=&gt;__('Confirma la contraseña',true),'type'=&gt;'password','value'=&gt;''));
echo $form-&gt;end(__('Cambiar contraseña',true));
?&gt;</pre>
<p>Y aquí viene el método de cambiar contraseña (está creado en el controlador usuarios pero no estaría de más separarlo un poco entre modelo y controlador):</p>
<pre class="brush: php;">// /app/controllers/users_controller.php
function changePassword()
{
	if (!empty($this-&gt;data)){
		// Buscamos el usuario actual en la base de datos
		$user = $this-&gt;User-&gt;findById($this-&gt;Auth-&gt;user('id'));
		// Cargamos los datos en el modelo (para validarlos)
		$this-&gt;User-&gt;set($this-&gt;data);
		// Encriptamos la contraseña antigua para validarla
		$this-&gt;data['User']['old_passwd'] = $this-&gt;Auth-&gt;password($this-&gt;data['User']['old_passwd']);
		// Validamos y verificamos que la contraseña introducida coincide con la de la BDD
		if ($this-&gt;User-&gt;validates() &amp;&amp; $this-&gt;data['User']['old_passwd'] == $user['User']['password']) {
			$password = $this-&gt;data['User']['password'];
			// Actualizamos la contraseña del foro
			$this-&gt;Forum-&gt;setUserField($user['User']['forums_id'], 'user_password', $this-&gt;Auth-&gt;password($this-&gt;data['User']['password']));
			// Actualizamos la contraseña del sistema
			$this-&gt;User-&gt;updateAll(array('User.password'=&gt;&quot;'&quot;.$this-&gt;Auth-&gt;password($password).&quot;'&quot;),array('User.id'=&gt;$user['User']['id']));
			$this-&gt;Session-&gt;setFlash(__(&quot;Tu contraseña ha sido cambiada con éxito&quot;,true),'flash_info');
			$this-&gt;redirect(array('controller'=&gt;'users','action'=&gt;'profile'));
		}
		// Si la contraseña no coincide con la guardada en la BDD mostramos error.
		if($this-&gt;data['User']['old_passwd'] != $user['User']['password'])
		{
			$this-&gt;User-&gt;invalidate('old_passwd',__(&quot;La contraseña no es correcta&quot;,true));
		}
	}
}</pre>
<p>Con esto ya podéis cambiar la contraseña en todo el sistema y ya sabéis cómo hacer para modificar el resto de datos. Al actualizar la contraseña he utilizado <em>user_password</em> como nombre de celda. Consultad vuestra base de datos de phpBB para saber los nombres de las celdas a actualizar.</p>
<p>Si quisierais utilizar la vía del componente y así no tener que utilizar la base de datos y el modelo Forum tendríais que añadir un método en el componente PhpBB3 que actualizara la celda. Para crear dicho método podéis consultar la documentación de phpBB3:</p>
<blockquote>
<ul>
<li><a rel="nofollow" href="http://area51.phpbb.com/docs/code/" target="_blank">Especificaciones de métodos y clases de phpBB 3</a></li>
</ul>
<p><em><strong>Pista:</strong> Seguramente necesitaréis utilizar la clase &#8216;user&#8217; (cambiada por nosotros a fuser, recordad!!) y su método <a rel="nofollow" href="http://area51.phpbb.com/docs/code/phpBB3/user.html#optionset" target="_blank">optionset()</a>.</em></p></blockquote>
<h4 id="phpbb-sete">Modificando vuestra plantilla de phpBB<a class="amunt" href="#amunt">arriba</a></h4>
<p>Ahora sólo os faltaría modificar vuestra plantilla de phpBB para enlazar hacia vuestra aplicación Cake, con el registro de usuarios, el login y la edición de datos de vuestro perfil.</p>
<p>Podéis enlazar a ella o, en el caso de la edición de datos del perfil, tratar de modificar los formularios de phpBB para que envíen a la aplicación Cake y luego hacer algo como en el login con el referer para poder redirigir al usuario de nuevo al foro.</p>
<p>Esto lo dejo en vuestras manos dado que la solución es bastante abierta y ya llevo mucho rato <em>dándoos la tabarra</em>. Además, me parece que con las pistas que he dado ya tenéis más que suficiente para empezar <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Pues con esto creo que ya hemos terminado. Si veis cualquier fallo u os peta la aplicación por algún lado no dudéis en preguntar, comentar y despotricar sobre mí. Tened en cuenta que he modificado el código considerablemente (desde el propio Wordpress&#8230;) para tratar de simplificarlo y puede que me haya comido alguna línea o incluso hasta algún apartado entero (esperemos que no&#8230;).</p>
<p>En cuanto vea vuestros comentarios trataré de contestarlos <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1224_permalink = 'http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/';
			dtsv.dtse_post_1224_title = 'Integrando CakePHP y phpBB 3.x';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/' rel='bookmark' title='Permanent Link: Validar datos duplicados en CakePHP'>Validar datos duplicados en CakePHP</a></li>
<li><a href='http://racotecnic.underave.net/2009/01/registro-de-usuarios-externo-a-phpbb-3x/' rel='bookmark' title='Permanent Link: Registro de usuarios externo a phpBB 3.x'>Registro de usuarios externo a phpBB 3.x</a></li>
<li><a href='http://racotecnic.underave.net/2009/11/instalacion-de-cakephp-sin-base-de-datos/' rel='bookmark' title='Permanent Link: Instalación de CakePHP sin base de datos'>Instalación de CakePHP sin base de datos</a></li>
<li><a href='http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/' rel='bookmark' title='Permanent Link: CakePHP Auth Component ajaxLogin'>CakePHP Auth Component ajaxLogin</a></li>
<li><a href='http://racotecnic.underave.net/2009/11/implementar-plugin-jquery-de-advertencias-tipo-growl-en-cakephp/' rel='bookmark' title='Permanent Link: Implementar plugin jQuery de advertencias tipo Growl en CakePHP'>Implementar plugin jQuery de advertencias tipo Growl en CakePHP</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Adiós MultipleIE&#8230; Hola IETester!</title>
		<link>http://racotecnic.underave.net/2010/01/adios-multipleie-hola-ietester/</link>
		<comments>http://racotecnic.underave.net/2010/01/adios-multipleie-hola-ietester/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 15:20:19 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Windows]]></category>
		<category><![CDATA[IE6]]></category>
		<category><![CDATA[Internet Explorer]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1290</guid>
		<description><![CDATA[Acabo de descubrir IETester, una aplicación para Windows (compatible con todas sus versiones) con la que podéis comprobar cómo se ven vuestras webs desde Internet Explorer (desde la versión 5.5 hasta la 8).
Si habéis probado &#8216;MultipleIE&#8217; sabréis lo magníficamente bien que va y probablemente también sabréis que dejó de funcionar con Windows Vista.
No me enrollo [...]]]></description>
			<content:encoded><![CDATA[<p>Acabo de descubrir IETester, una aplicación para Windows (compatible con todas sus versiones) con la que podéis comprobar cómo se ven vuestras webs desde Internet Explorer (desde la versión 5.5 hasta la 8).</p>
<p>Si habéis probado &#8216;MultipleIE&#8217; sabréis lo <em>magníficamente bien</em> que va y probablemente también sabréis que dejó de funcionar con Windows Vista.</p>
<p>No me enrollo más, os dejo aquí una imagen y el enlace para que lo probéis ya mismo:</p>
<p style="text-align: center;"><a href="http://www.my-debugbar.com/wiki/uploads/IETester/ietester-0.3.png" target="_blank" rel="lightbox[1290]"><img class="aligncenter dtse-img dtse-post-1290" title="IETester" src="http://www.my-debugbar.com/wiki/uploads/IETester/ietester-0.3.png" alt="IETester" width="595" height="344" /></a></p>
<blockquote>
<ul>
<li>Web oficial: <a href="http://www.my-debugbar.com/wiki/IETester/HomePage" target="_blank" rel="nofollow">http://www.my-debugbar.com/wiki/IETester/HomePage</a></li>
</ul>
</blockquote>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1290_permalink = 'http://racotecnic.underave.net/2010/01/adios-multipleie-hola-ietester/';
			dtsv.dtse_post_1290_title = 'Adiós MultipleIE… Hola IETester!';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/04/atube-catcher-baja-video-y-musica-al-formato-que-quieras/' rel='bookmark' title='Permanent Link: aTube Catcher (baja vídeo y música al formato que quieras)'>aTube Catcher (baja vídeo y música al formato que quieras)</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/01/adios-multipleie-hola-ietester/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Grave vulnerabilidad en todas las versiones de Windows</title>
		<link>http://racotecnic.underave.net/2010/01/grave-vulnerabilidad-en-todas-las-versiones-de-windows/</link>
		<comments>http://racotecnic.underave.net/2010/01/grave-vulnerabilidad-en-todas-las-versiones-de-windows/#comments</comments>
		<pubDate>Wed, 20 Jan 2010 17:14:43 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Windows]]></category>
		<category><![CDATA[0-day]]></category>
		<category><![CDATA[Exploit]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1286</guid>
		<description><![CDATA[Fuente: GenBeta
¡Urgente! Se ha detectado una vulnerabilidad muy crítica en  todas las versiones de Windows desde 1993, un “0-day” en toda  regla, que permite escalar privilegios y ejecutar código con  permisos de sistema, equivalentes a efectos prácticos a los de  administrador.
Por ahora no existe parche, y el exploit es fácilmente  [...]]]></description>
			<content:encoded><![CDATA[<p><em><strong>Fuente: </strong><a href="http://www.genbeta.com/windows/vulnerabilidad-muy-critica-en-todas-las-versiones-de-windows" target="_blank">GenBeta</a></em></p>
<p>¡Urgente! Se ha detectado una <strong>vulnerabilidad muy crítica en  todas las versiones de Windows desde 1993</strong>, un “0-day” en toda  regla, que permite escalar privilegios y <strong>ejecutar código con  permisos de sistema</strong>, equivalentes a efectos prácticos a los de  administrador.</p>
<p>Por ahora <strong>no existe parche, y el exploit es fácilmente  aprovechable</strong> por cualquiera. La causa es un fallo de diseño que  persiste en todas las versiones de Windows de 32 bits desde 1993, por  lo que <strong>afecta a Windows 2000, 2003, 2008, XP, Vista y 7</strong>.</p>
<p>El fallo se encuentra en el soporte “legacy” que permite ejecutar  aplicaciones de 16 bits. Resulta que el sistema no valida correctamente  el cambio de contexto y pila que se efectúa al llamar al manejador  #GP trap. Windows comete varios fallos, toma como ciertas varias  suposiciones que son incorrectas y el resultado es una puerta abierta  al sistema con alfombra roja y luces de neón.</p>
<p>Con un código que va en contra de dichas suposiciones, un usuario  malicioso puede realizar un cambio de contexto y <strong>ejecutar código  con derechos de Sistema</strong>, que están por encima incluso del de  los administradores.</p>
<p><strong>Tavis Ormandy</strong>, el investigador que detectó el  fallo, <strong>notificó a Microsoft en junio de 2009</strong> de este  problema, y al poco le confirmaron que estaba en lo cierto. En todo este  tiempo, no se ha publicado parche al respecto, lo que ha motivado a  Ormandy el hacer pública la vulnerabilidad para forzar a que desde  Redmond se pongan las pilas.</p>
<p>Los principales afectados son aquellas empresas que mantienen los  sistemas de sus empleados con privilegios limitados. Para usuarios  domésticos, que habitualmente usan cuentas de administrador, la cosa no  afecta demasiado, porque escalar privilegios no es necesario para poner  en riesgo el sistema.</p>
<p>Aunque no hay parche, <strong>existe una sencilla vía de evitar la  vulnerabilidad</strong>. Tan sólo hay que deshabilitar el soporte para  aplicaciones de 16 bits, que en la mayor parte de los casos no supondrá  problema alguno. Para ello, hay que habilitar <strong>“Impedir el acceso  a aplicaciones de 16 bits”</strong> en la Consola de Políticas  (gpedit.msc), dentro de “Configuración de equipo – Plantillas  administrativas – Componentes de Windows – Compatibilidad de  aplicación”. Hay que forzar una actualización de las políticas en los  sistemas que dependan del controlador de dominio para que se aplique el  cambio.</p>
<p>¡Urgente! Se ha detectado una vulnerabilidad muy crítica en todas las versiones de Windows desde 1993, un “0-day” en toda regla, que permite escalar privilegios y ejecutar código con permisos de sistema, equivalentes a efectos prácticos a los de administrador.</p>
<p>Por ahora no existe parche, y el exploit es fácilmente aprovechable por cualquiera. La causa es un fallo de diseño que persiste en todas las versiones de Windows de 32 bits desde 1993, por lo que afecta a Windows 2000, 2003, 2008, XP, Vista y 7.</p>
<p>El fallo se encuentra en el soporte “legacy” que permite ejecutar aplicaciones de 16 bits. Resulta que el sistema no valida correctamente el cambio de contexto y pila que se efectúa al al llamar al manejador #GP trap. Windows comete varios fallos, toma como ciertas varias suposiciones que son incorrectas, y el resultado es una puerta abierta al sistema con alfombra roja y luces de neón.</p>
<p>Con un código que va en contra de dichas suposiciones, un usuario malicioso puede realizar un cambio de contexto y ejecutar código con derechos de Sistema, que están por encima incluso del de los administradores.</p>
<p>Tavis Ormandy, el investigador que detectó el fallo, notificó a Microsoft en junio de 2009 de este problema, y al poco le confirmaron que estaba en lo cierto. En todo este tiempo, no se ha publicado parche al respecto, lo que ha motivado a Ormandy el hacer pública la vulnerabilidad para forzar a que desde Redmond se pongan las pilas.</p>
<p>Los principales afectados son aquellas empresas que mantienen los sistemas de sus empleados con privilegios limitados. Para usuarios domésticos, que habitualmente usan cuentas de administrador, la cosa no afecta demasiado, porque escalar privilegios no es necesario para poner en riesgo el sistema.</p>
<p>Aunque no hay parche, existe una sencilla vía de evitar la vulnerabilidad. Tan sólo hay que deshabilitar el soporte para aplicaciones de 16 bits, que en la mayor parte de los casos no supondrá problema alguno. Para ello, hay que habilitar “Impedir el acceso a aplicaciones de 16 bits” en la Consola de Políticas (gpedit.msc), dentro de “Configuración de equipo – Plantillas administrativas – Componentes de Windows – Compatibilidad de aplicación”. Hay que forzar una actualización de las políticas en los sistemas que dependan del controlador de dominio para que se aplique el cambio.</p>
<p><em><strong>Fuente: </strong><a href="http://www.genbeta.com/windows/vulnerabilidad-muy-critica-en-todas-las-versiones-de-windows" target="_blank">GenBeta</a></em></p>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1286_permalink = 'http://racotecnic.underave.net/2010/01/grave-vulnerabilidad-en-todas-las-versiones-de-windows/';
			dtsv.dtse_post_1286_title = 'Grave vulnerabilidad en todas las versiones de Windows';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/03/eliminar-mensaje-de-copia-pirata-de-windows-genuine-advantage/' rel='bookmark' title='Permanent Link: Eliminar mensaje de copia pirata de Windows Genuine Advantage'>Eliminar mensaje de copia pirata de Windows Genuine Advantage</a></li>
<li><a href='http://racotecnic.underave.net/2009/07/evitar-mensaje-de-windows-office-genuine-advantage/' rel='bookmark' title='Permanent Link: Evitar mensaje de Windows &#038; Office Genuine Advantage'>Evitar mensaje de Windows &#038; Office Genuine Advantage</a></li>
<li><a href='http://racotecnic.underave.net/2009/07/gestores-de-descarga-para-linux-mac-y-windows/' rel='bookmark' title='Permanent Link: Gestores de descarga para Linux, Mac y Windows'>Gestores de descarga para Linux, Mac y Windows</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2010/01/grave-vulnerabilidad-en-todas-las-versiones-de-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Drag &amp; Share : Meebo Bar</title>
		<link>http://racotecnic.underave.net/2009/12/drag-share-meebo-bar/</link>
		<comments>http://racotecnic.underave.net/2009/12/drag-share-meebo-bar/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 13:41:43 +0000</pubDate>
		<dc:creator>DPAM23</dc:creator>
				<category><![CDATA[Aplicacions]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1275</guid>
		<description><![CDATA[El otro día descubrí la Meebo bar por casualidad al entrar a esta web:
http://abduzeedo.com/
(que por cierto, está bastante bien, echadle un vistazo  )
si pasáis el ratón por encima de las imágenes de las entradas, veréis que os aparece un texto que dice algo así como &#8220;arrastra para compartir&#8221;. Si arrastráis la imagen os aparecerá [...]]]></description>
			<content:encoded><![CDATA[<p>El otro día descubrí la <strong>Meebo bar</strong> por casualidad al entrar a esta web:</p>
<p><a rel="nofollow" href="http://abduzeedo.com/" target="_blank">http://abduzeedo.com/</a></p>
<p>(que por cierto, está bastante bien, echadle un vistazo <img src='http://racotecnic.underave.net/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' /> )</p>
<p>si pasáis el ratón por encima de las imágenes de las entradas, veréis que os aparece un texto que dice algo así como &#8220;arrastra para compartir&#8221;. Si arrastráis la imagen os aparecerá un selector, donde podéis escoger la imagen o el post en vuestra red social favorita.</p>
<p>Fantástico no?</p>
<p>Una herramienta para que los mismos usuarios puedan compartir nuestros trabajos.</p>
<p>¡Estupendo!</p>
<p style="text-align: center;"><img class="size-full wp-image-1276  aligncenter dtse-img dtse-post-1275" title="meebo_bar" src="http://racotecnic.underave.net/wp-content/uploads/2009/12/meebo_bar.png" alt="" width="451" height="124" /></p>
<p>Además tampoco os perdáis la Meebo Chat Bar , que emula la barra de chat del facebook. Parece muy muy potente y está también visible en la web anteriormente citada.</p>
<blockquote>
<ul>
<li>Drag and share Meebo bar: <a rel="nofollow" href="https://bar.meebo.com/" target="_blank">https://bar.meebo.com/</a></li>
<li>Más info sobre la barra de chat:  <a rel="nofollow" href="http://business.meebo.com/publishers/" target="_blank">http://business.meebo.com/publishers/</a></li>
</ul>
</blockquote>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1275_permalink = 'http://racotecnic.underave.net/2009/12/drag-share-meebo-bar/';
			dtsv.dtse_post_1275_title = 'Drag & Share : Meebo Bar';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">No hi ha cap entrada relacionada</p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2009/12/drag-share-meebo-bar/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>CakePHP Auth Component ajaxLogin</title>
		<link>http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/</link>
		<comments>http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/#comments</comments>
		<pubDate>Sun, 27 Dec 2009 14:10:01 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Programació]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Ajax]]></category>
		<category><![CDATA[CakePHP]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Snippet]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1269</guid>
		<description><![CDATA[Si habéis leído mi tutorial sobre la subida de ficheros con uploadify y validación Ajax en CakePHP recordaréis que separé los métodos add y ajax_add, ya que pensé que el único modo que había de mostrar un error de sesión al usuario era separando los métodos para, a uno de ellos darle permisos de acceso [...]]]></description>
			<content:encoded><![CDATA[<p>Si habéis leído mi tutorial sobre la <a href="http://racotecnic.underave.net/2009/10/subida-de-ficheros-con-uploadify-y-validacion-ajax-en-cakephp/">subida de ficheros con uploadify y validación Ajax en CakePHP</a> recordaréis que separé los métodos <em>add</em> y <em>ajax_add</em>, ya que pensé que el único modo que había de mostrar un error de sesión al usuario era separando los métodos para, a uno de ellos darle permisos de acceso y al otro no.</p>
<p>De este modo podía mostrar un error de &#8220;sesión expirada&#8221; al usuario, así:</p>
<pre class="brush: php;">$user = $this-&gt;Auth-&gt;user();
if(!empty($user)){
	// Código para añadir el elemento
}else{
	$message = &quot;&lt;b&gt;&quot; . __(&quot;Error&quot;,true) . &quot;:&lt;/b&gt; &quot; . __(&quot;Tu sesión ha expirado, vuelve a iniciarla por favor&quot;,true);
	$data = $this-&gt;data;
	$this-&gt;set('sessionTimeOut',compact('message','data'));
}</pre>
<p>Pues bien, acabo de descubrir que el componente <em>Auth</em> tiene una variable llamada <em>ajaxLogin</em> con la que podemos evitarnos todas estas líneas de código en cada uno de nuestros métodos tratados con ajax. Además esto nos permitirá poner ambos métodos (<em>add</em> y <em>ajax_add</em>) en un mismo método y utilizar el <em>RequestHandler</em> para distinguir los procesos a realizar de ambos.</p>
<p>Esta variable debéis configurarla en vuestro <em>beforeFilter</em> (probablemente del <em>AppController</em> aunque puede que prefiráis hacerlo en cada controlador por separado):</p>
<pre class="brush: php;">$this-&gt;Auth-&gt;ajaxLogin = '/ajax/ajax_login';</pre>
<p>Y después crear la vista correspondiente. La vista correspondiente al tutorial de subida de ficheros con uploadify y validación ajax sería así:</p>
<pre class="brush: php;">&lt;?php // /app/views/ajax/ajax_login.ctp
$message = __(&quot;La teva sessió ha expirat. Torna a iniciar-la siusplau&quot;,true);
$sessionTimeOut = compact('message');
echo json_encode(compact('sessionTimeOut'));</pre>
<p>El método <em>json_encode</em> es de PHP 5.2, así que si tenéis una versión anterior de PHP tendréis que utilizar el Helper de JavaScript para mostrar el resultado en JSON.</p>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1269_permalink = 'http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/';
			dtsv.dtse_post_1269_title = 'CakePHP Auth Component ajaxLogin';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/11/detectar-solicitud-ajax-con-php/' rel='bookmark' title='Permanent Link: Detectar solicitud AJAX con PHP'>Detectar solicitud AJAX con PHP</a></li>
<li><a href='http://racotecnic.underave.net/2009/10/subida-de-ficheros-con-uploadify-y-validacion-ajax-en-cakephp/' rel='bookmark' title='Permanent Link: Subida de ficheros con Uploadify y validación Ajax en CakePHP'>Subida de ficheros con Uploadify y validación Ajax en CakePHP</a></li>
<li><a href='http://racotecnic.underave.net/2010/02/validar-datos-duplicados-en-cakephp/' rel='bookmark' title='Permanent Link: Validar datos duplicados en CakePHP'>Validar datos duplicados en CakePHP</a></li>
<li><a href='http://racotecnic.underave.net/2009/11/leer-hilos-rss-en-cakephp-utilizando-jquery/' rel='bookmark' title='Permanent Link: Leer hilos RSS en CakePHP utilizando jQuery'>Leer hilos RSS en CakePHP utilizando jQuery</a></li>
<li><a href='http://racotecnic.underave.net/2010/01/integrando-cakephp-y-phpbb-3-x/' rel='bookmark' title='Permanent Link: Integrando CakePHP y phpBB 3.x'>Integrando CakePHP y phpBB 3.x</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2009/12/cakephp-auth-component-ajaxlogin/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Resultados y descarga del 2º concurso de producción de underave</title>
		<link>http://racotecnic.underave.net/2009/12/resultados-y-descarga-del-2%c2%ba-concurso-de-produccion-de-underave/</link>
		<comments>http://racotecnic.underave.net/2009/12/resultados-y-descarga-del-2%c2%ba-concurso-de-produccion-de-underave/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 01:28:12 +0000</pubDate>
		<dc:creator>Booletaire</dc:creator>
				<category><![CDATA[Audio]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Concursos]]></category>

		<guid isPermaLink="false">http://racotecnic.underave.net/?p=1255</guid>
		<description><![CDATA[Los ganadores del segundo concurso son&#8230;
13% [ 38 ] Fort (user therkore) &#8211; Kora&#8217;s Queen
9% [ 29 ] Fernival &#8211; Bastardos
9% [ 27 ] Hiry (user daniel jesus) &#8211; Le logement, un droit pas un privilège
8% [ 25 ] Pinyol &#8211; Disk-o-
Felicidades! Si no lo hemos hecho, pronto nos pondremos en contacto con vosotros para [...]]]></description>
			<content:encoded><![CDATA[<p>Los ganadores del segundo concurso son&#8230;</p>
<p>13% [ 38 ] <span style="font-weight: bold;"><span style="color: #ff8000;">Fort</span></span> (user <span style="font-style: italic;">therkore</span>) &#8211; Kora&#8217;s Queen<br />
9% [ 29 ] <span style="font-weight: bold;"><span style="color: #ff8000;">Fernival</span></span> &#8211; Bastardos<br />
9% [ 27 ] <span style="font-weight: bold;"><span style="color: #ff8000;">Hiry</span></span> (user <span style="font-style: italic;">daniel jesus</span>) &#8211; Le logement, un droit pas un privilège<br />
8% [ 25 ] <span style="font-weight: bold;"><span style="color: #ff8000;">Pinyol</span></span> &#8211; Disk-o-</p>
<p>Felicidades! Si no lo hemos hecho, pronto nos pondremos en contacto con vosotros para daros detalles sobre el vinilo.</p>
<p>Al resto de participantes, gracias por participar y sobretodo, no perdáis los ánimos! El siguiente concurso puede ser el vuestro!</p>
<p>Os dejamos el enlace de descarga del álbum de este segundo concurso. Con todos los nombres y etiquetas de los ficheros bien puestos y ordenados según valoración:</p>
<div style="margin: 0px; padding: 6px;">
<ol>
<li>Fort &#8211; Kora&#8217;s Queen.mp3</li>
<li>Fernival &#8211; Bastardos.mp3</li>
<li>Hiry &#8211; Le logement, un droit pas un privilège.mp3</li>
<li>Pinyol &#8211; Disk-o-.mp3</li>
<li>Icebreaker &#8211; Armored Armadillo.mp3</li>
<li>Naw Dj &#8211; That&#8217;s you really want.mp3</li>
<li>Freeson &#8211; Hipnosis.mp3</li>
<li>Pisu &#8211; Ocre.mp3</li>
<li>Dj Fane &#8211; Moskito.mp3</li>
<li>Esputo Social &#8211; Doctor Paranoius y su mala praxis.mp3</li>
<li>Ludovic &#8211; City creator.mp3</li>
<li>Dj Martk &#8211; MiMaDre.mp3</li>
<li>PaukNo6tem &#8211; DoubleMind.mp3</li>
<li>Aldricksound &#8211; Inside the sphinx.mp3</li>
<li>Dj Fatuin &#8211; Arrecife del pelícano.mp3</li>
<li>Nesttor_0 &#8211; Undersong.mp3</li>
<li>More Jaia &#8211; Txekeraut.mp3</li>
<li>Didi &#8211; House of fun.mp3</li>
<li>Dundrum &#8211; Eslaskusa.mp3</li>
<li>Madame &#8211; Lonely Place.mp3</li>
<li>Peggy &#8211; Futureofextasy.mp3</li>
<li>Dakore &#8211; Fumatta.mp3</li>
<li>Endre&#8217;k &#8211; Bäd Böy Style.mp3</li>
<li>Pakabrakdabra &#8211; PalabraKKore.mp3</li>
<li>Noize Corp &#8211; Mother&#8221;fucker.mp</li>
</ol>
<div style="text-align: center;"><a href="http://forums.underave.net/download.php?a=down&amp;id=2"><img class="aligncenter size-medium wp-image-966 dtse-img dtse-post-1255" title="cd" src="http://forums.underave.net/portada2onconcurs.png" alt="cd" width="500" height="500" /></a></div>
<div style="text-align: center;"><span style="font-size: 150%; line-height: normal;"><a href="http://forums.underave.net/download.php?a=down&amp;id=2"><span style="color: #ff8000;"> </span></a></span></div>
<div style="text-align: center;"><span style="font-size: 150%; line-height: normal;"><a href="http://forums.underave.net/download.php?a=down&amp;id=2"><span style="color: #ff8000;">Descargar!! (192 MB)</span></a></span></div>
<div style="text-align: center;">(Tracklist, lista de reproducción y portada también en el fichero)</div>
</div>



		<!-- Added by WP-DragToShare-eXtended Plugin -->
		<script type="text/javascript">
			dtsv.dtse_post_1255_permalink = 'http://racotecnic.underave.net/2009/12/resultados-y-descarga-del-2%c2%ba-concurso-de-produccion-de-underave/';
			dtsv.dtse_post_1255_title = 'Resultados y descarga del 2º concurso de producción de underave';
		</script>
		<!-- End of WP-DragToShare-eXtended Plugin -->

<p style="font-weight:bold">Entrades relacionades:<ol><li><a href='http://racotecnic.underave.net/2009/08/2o-concurso-de-produccion-musical-de-underave/' rel='bookmark' title='Permanent Link: 2o concurso de producción musical de underave'>2o concurso de producción musical de underave</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://racotecnic.underave.net/2009/12/resultados-y-descarga-del-2%c2%ba-concurso-de-produccion-de-underave/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
