Desde hace algún tiempo he comprobado que hay muchos desarrolladores que al tratar de implementar un sistema de autenticación en CakePHP con AuthComponent tienen problemas y no funciona como debería. Sea por motivos de versión del framework o, simplemente, porque no está bien implementado el código, la cuestión es que la aplicación no funciona.
Vamos entonces a ver a continuación cómo programar un sistema de autenticación sin la necesidad del AuthComponent.
Partimos de que tenemos una base de datos conectada correctamente a través de la configuración de nuestro archivo database.php y, además, suponemos que tenemos ya una aplicación en CakePHP que debemos proteger de usuarios no autenticados.
Con lo primero que debemos contar es con una tabla en nuestra base de datos que yo he llamado users. Esta tabla cuenta a su vez con tres campos: id, username y password. El campo id será nuestra clave primaria autoincremental y los otros dos campos de tipo varchar.
Una vez hecho esto, vamos con el código. Abrimos nuestro archivo AppController que se encuentra en la ruta CarpetaAplicacion/app/Controller donde CarpetaAplicacion es el nombre de la carpeta donde guardas tu proyecto. Escribimos el siguiente código:

<?php

App::uses('Controller','Controller');

class AppController extends Controller {

public$components=array('Session');

    // Comprobar si el usuario está logueado
    function authenticate()
    {
        // Comprobamos si la variable de sesión existe. Si es así quiere decir que el usuario se ha logueado
       //correctamente y se le redirecciona a la aplicación.
      //Si no existe se le devuelve al login.
        if(!$this->Session->check('User'))
        {
            $this->redirect(array('controller'=>'users','action'=>'autenticar'));
            exit();
        }

    }
 
    //Autenticación obligatoria si se quiere entrar a cualquier parte de la aplicación
    function afterFilter()
    {
        if($this->action!='autenticar')
        {
            $this->authenticate();
        }
    }
}

La función afterFilter va a permitirnos controlar cuándo un usuario intenta entrar en una zona donde se ejecuta una acción distinta a ‘autenticar’. Inmediatamente llama a la función authenticate que nos va a permitir saber si se ha creado ya una sesión de usuario. Si es así significará que el usuario esta autenticado, con lo que automáticamente será redireccionado al index de la aplicación. Si no es así se le redireccionará de nuevo a la acción autenticar del controlador users (lo veremos a continuación) que, por supuesto, contará con una vista que contendrá el formulario de login. Sigamos.
Ahora vamos a crear, dentro de la carpeta de nuestros modelos, un archivo con el nombre User.php. La ruta será CarpetaAplicacion/app/Model/User.php. Escribimos lo siguiente:

<?php
App::uses('AppModel','Model');
/**
 * User Model
 *
 */
class User extends AppModel {

   var$name='User';

/**
 * Display field
 *
 * @var string
 */

   public$displayField='username';

   var$validate=array(
       'username'=>array(
                    'rule'=>array('minLength',1),
                    'required'=>true,
                    'allowEmpty'=>false,
                    'message'=>'Por favor, introduce un nombre'
                    ),
       'password'=>array(
                    'rule'=>array('minLength',1),
                    'required'=>true,
                    'allowEmpty'=>false,
                    'message'=>'Por favor, introduce la contraseña'
                    ),

   );

}

Lo que hemos hecho es crear nuestra clase modelo que conectará con nuestra tabla users de la BD. También usamos la validación de los campos username y password del formulario que posteriormente crearemos en nuestra View.
Continuamos. Volvemos a nuestra carpeta de controladores y creamos un archivo llamado UsersController.php. La ruta será CarpetaAplicacion/app/Controller/UsersController.php. Aquí escribimos ahora el siguiente código:

<?php
App::uses('AppController','Controller');
/**
 * Users Controller
 *
 * @property User $User
 * @property PaginatorComponent $Paginator
 */
class UsersController extends AppController {

/**
 * Components
 *
 * @var array
 */
    public$components=array('Session');
 
    publicfunction autenticar(){
        // Aunque los campos username y password tienen validación para que no estén vacíos,
// volvemos a asegurarnos con el condicional que el campo username del formulario tiene
        //algún valor
        if(empty($this->data['User']['username'])==false)
        {
    	 //Consulta SQL para buscar al usuario con sus credenciales en la BD
$user=$this->User->find('all',array('conditions'=>array(
                'User.username'=>$this->data['User']['username'],
                'User.password'=>$this->data['User']['password'])));
         //Si se ha encontrado al usuario en la consulta
         if($user!=false)
         {
          //Si existe se redirecciona al usuario a la aplicación creando una variable de sesión 
          $this->Session->setFlash(__('Gracias por loguearse!'));
          $this->Session->write('User',$user);
          $this->Redirect(array('controller'=>'ControllerDeTuAplicacion','action'=>'index'));
          exit();
         }
         else
         {
//Si los datos no son correctos se comunica al usuario y se le devuelve al mismo
          //formulario de login
          $this->Session->setFlash(__('Nombre de usuario y/o password incorrectos'));
          $this->Redirect(array('action'=>'autenticar'));
          exit();
         }
        }
    }
}

Veamos qué hace nuestra clase controller. Es imprescindible, como en el archivo AppController, tener cargado el componente Session. Como podemos ver lo tenemos en nuestra variable pública $components. Lo primero que va a hacer la clase es comprobar que se han pasado datos en el campo username desde el formulario. Es cierto que los campos ya están validados desde nuestro Model, pero siempre es interesante comprobarlo también aquí. Si no es correcto, es decir, si el campo está vacío, entonces se redirecciona de nuevo al mismo formulario. De esto se encarga nuestro Model como sabemos, ya que al no haber ninguna variable Session creada reaccionará en consecuencia. Si, por el contrario, hay datos, se ejecuta una consulta en la BD para comprobar que, efectivamente, el usuario y password existen. Si no existen, entonces se le redireccciona al usuario de nuevo a la acción autenticar que hará que nuestro afterFilter del archivo AppController (¿Recuerdas?) compruebe que exista una variable de sesión. Como no es así se le reenvía automáticamente de nuevo al formulario con un mensaje flash indicando que uno o los dos campos no son correctos. Si existe el usuario, entonces se le redirecciona a la página index de la aplicación, no sin antes crear la variable de sesión que nos permitirá superar con éxito el método authenticate de nuestro AppController que es llamado automáticamente desde nuestro vigilante afterFilter.
Ya lo único que nos queda es crear nuestra View que mostrará el formulario para poder loguearse. Vamos a la ruta CarpetaAplicacion/app/View y creamos la carpeta Users. Despues, dentro de ella, creamos el archivo autenticar.ctp con el siguiente código:

<div>
<?php echo $this->Form->create('User'); ?>
	<fieldset>
		<legend><?php echo __('Login aplicación'); ?></legend>
	<?php
		echo $this->Form->input('username');
		echo $this->Form->input('password');
	?>
	</fieldset>
<?php echo $this->Form->end(__('Continuar')); ?>
</div>

Como se puede observar se trata de un simple formulario muy sencillo donde no creo que haya nada que explicar. Pues ya está, con esto hemos terminado. Ahora tenemos un sistema que permite proteger el acceso a nuestra aplicación de todos aquellos usuarios que, previamente, no estén en la base de datos. Obviamente, para poder probarlo, necesitamos entonces tener al menos un usuario en nuestra tabla users. Este ejemplo no contempla la posibilidad de registrarse pero creo que, con este punto de partida, no es nada complicado implementarlo. Pero eso lo dejo para vosotros 🙂 Un saludo.-

Anuncios

He decidido compartir con vosotros un ejercicio que suelo poner a mis alumnos de JavaScript. Se trata de implementar el típico mensaje de autosugerencia cuando escribimos algo en una entrada de texto destinada a tal fin. Vamos a comenzar creando un archivo HTML que puedes llamar como quieras, aunque en mi caso le he llamado index.html para seguir la costumbre ya que se trata del punto de entrada. Si estás usando un IDE como Aptana, Dreamweaver o cualquier otro, crea un nuevo proyecto y añade este archivo. Si eres de los que prefiere hacer las cosas “a pelo”, pues crea el archivo en el mismo escritorio y solucionado.
Bien, vamos allá. Escribimos en el susodicho archivo lo siguiente:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Autosugerencia</title>
</head>

<body>

Escribe una palabra: <input type="text" id="palabra"/>

<ul id="suggest"></ul>

</body>

<script type="text/javascript" src="js/autosugerencia.js"></script>

</html>

Simplemente, como podemos ver, este archivo contiene un campo de entrada de texto con el id palabra, y una lista desordenada vacía con el id suggest. Al final, antes del cierre de la etiqueta HTML, cargamos el JavaScript que se encargará de todo dentro de una carpeta llamada js. Al archivo le he llamado autosugerencia.js, tú puedes llamarle como quieras, siempre y cuando en el paso siguiente crees ese archivo con el mismo nombre. Con solo esto en el HTML es con lo que vamos a trabajar.
Ahora creamos una carpeta llamada js y dentro un archivo llamado autogerencia.js en mi caso o, como ya he advertido, con el nombre que hayas decidido ponerle en el HTML. Entonces, una vez creado, escribimos el siguiente código:

// JavaScript Document

var palabras = ["enero", "febrero", "marzo", "abril", "mayo", "junio",
				"julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"];

document.getElementById("palabra").addEventListener("keyup", autosugerir, false);

function autosugerir(){

	var contador = 0;

	var escribiendo = document.getElementById("palabra").value.toLowerCase();

	document.getElementById("suggest").innerHTML="";

		if (escribiendo != ""){

			var caracteres = escribiendo.length;

			for (x=0; x < palabras.length; x++){

				var pArray = new String(palabras[x]);

				var sugerencia = pArray.substring(0,caracteres);

				if (sugerencia == escribiendo){

					contador++;
					var ul = document.getElementById("suggest");
					var new_li = document.createElement('li');
					new_li.className = pArray;
					new_li.style.cursor = "pointer";
					new_li.innerHTML = "Quizás quiso decir " + pArray;
					ul.appendChild(new_li);
					new_li.addEventListener("click", aceptar, false);

				}

			}

			if (contador == 0){

				var ul = document.getElementById("suggest");
				var new_li = document.createElement('li');
				new_li.innerHTML = "No hay sugerencias";
				ul.appendChild(new_li);

			}

		}

		else {

			var ul = document.getElementById("suggest");
			var new_li = document.createElement('li');
			new_li.innerHTML = "No hay sugerencias";
			ul.appendChild(new_li);

		}

}

function aceptar(){

		document.getElementById("suggest").innerHTML="";
		var palabraSeleccionada = this.className;
		var cajaTexto = document.getElementById("palabra");
		cajaTexto.value = palabraSeleccionada;

}

Veamos el código paso a paso.
Lo lógico sería que toda la información que va a ser auto sugerida fuera suministrada por una base de datos pero, para no complicar el ejemplo, vamos a hacerlo desde un array. Eso es precisamente lo que hacemos al comienzo, declarar un array que contiene los meses del año. Acto seguido vinculamos un listener en tiempo de ejecución al campo de texto donde el usuario irá escribiendo. Como vemos, al método addEventListener encargado de ello, se le pasan tres argumentos. El primero es el tipo de evento, el segundo la función destino que se ejecutará cuando el evento se produzca, y el tercero es un argumento booleano opcional. Si es true, todos los eventos del tipo especificado serán lanzados al listener registrado antes de comenzar a ser controlados por algún EventTarget que esté por debajo en el arbol DOM del documento.
Como vemos, el evento que vamos a “escuchar” es el keyup, es decir, cuando el usuario termine de pulsar una tecla. La función de llamada será autosugerir, y el último argumento lo ponemos a false, ya que no queremos que reaccione como hemos explicado hace un momento.
Hasta ahora lo único que tenemos son los datos para sugerir y un escuchador de eventos que estará alerta vigilando cuándo se pulsa una tecla sobre el campo de texto de nuestro HTML.
Bien, veamos ahora qué hace la función autosugerir que es la que va a realizar todo el trabajo. Primero iniciamos una variable contador a cero, después guardamos en la variable escribiendo el resultado de capturar el contenido del campo de texto y convertirlo directamente a minúsculas con la función de JavaScript toLowerCase(). Para asegurarnos que la lista desordenada se encuentra vacía, lo hacemos en la siguiente línea. Ahora, con el condicional, comprobamos que la variable escribiendo no esté vacía, es decir, que haya algún dato en el campo de texto. Si lo hay, guardamos en la variable caracteres la longitud de caracteres, valga la redundancia, de lo que haya escrito en el campo de texto. Seguidamente, con el bucle for, vamos a iterarnos desde cero hasta el total de elementos contenidos en nuestro array. Dentro de este bucle es donde se haya el meollo de la cuestión. Veamos.
Lo primero es guardar en la variable pArray el elemento del array situado en la posición x (variable que, como sabemos, ira aumentando en cada iteración y que comienza por cero). Después, en la variable sugerencia, guardamos el resultado de substraer del contenido de nuestra variable pArray (que, recordemos, contendrá un elemento del array distinto en cada iteración) los caracteres que existan entre cero y el total de caracteres escritos por el usuario hasta ese momento, que ya guardamos anteriormente en la variable caracteres. En el condicional comprobamos si existe alguna coincidencia entre el trozo que hemos obtenido del elemento de nuestro array y lo que haya escrito el usuario. Si es así, aumentamos la variable contador en uno (ya veremos para qué), capturamos la lista desordenada de nuestro HTML en la variable ul y creamos en tiempo de ejecución una etiqueta HTML li en nuestra variable new_li. A continuación le añadimos un nombre de clase que hacemos igual a lo que contenga en ese momento nuestra variable pArray, le añadimos un estilo de cursor y un texto que mostrará la sugerencia obtenida. Para que la etiqueta li creada en tiempo de ejecución pueda aparecer en el HTML, debemos añadirla con appendChild a nuestra lista desordenada. Finalmente, añadimos un listener a la etiqueta li que controlará el evento click sobre cualquiera de ellas y disparará la función aceptar que veremos en un momento. Como ya he comentado, en este bucle for se encuentra la lógica más importante del programa y hará que se muestren todas y cada una de las coincidencias encontradas entre lo que escribamos y nuestro array.
Después del bucle for vemos otro condicional que comprueba si la variable contador es igual a cero. Si recordamos, esta variable la inicializamos así al comienzo de nuestra función. Esto nos sirve para controlar si se ha encontrado alguna sugerencia o no dentro del bucle for, ya que, como hemos visto, la variable va sumando uno cada vez que se encuentra con una coincidencia. Si no es así, la variable seguirá valiendo cero y, por lo tanto, mostramos un mensaje de ello al usuario a través de una etiqueta li creada en tiempo de ejecución y que añadimos a nuestra lista desordenada en el HTML. También, en el else del if contenedor, mostramos lo mismo si la variable escribiendo se encuentra vacía (esto ocurrirá si el usuario escribe algunos caracteres y, posteriormente, decide borrarlos todos). Con esto tenemos visto toda la función autosugerir completa.
Al final del archivo nos encontramos con la función aceptar vinculada a cada una de las etiquetas li que se creen en tiempo de ejecución. Con esto haremos que si un usuario desea aceptar cualquier sugerencia mostrada haciendo clic sobre ella, se muestre automáticamente en el campo de texto. Como vemos, vaciamos la lista desordenada, guardamos en la variable palabraSeleccionada el nombre de la clase que tenga la etiqueta y que, a su vez, será igual al elemento del array, capturamos en la variable cajaTexto el campo de texto de nuestro HTML y, finalmente, le asignamos el valor de la variable palabraSeleccionada.
Y con esto ya lo tenemos.
Ahora podemos probarlo y si, por ejemplo, escribimos solo la letra m en nuestra entrada de texto, veremos como mágicamente aparecen las sugerencias de los meses marzo y mayo.
Como dije al principio, lo suyo es que la fuente de datos se encuentre en una BD y que, además, obtengamos esos datos mediante Ajax. Teniendo este código como punto de partida no es demasiado complicado implementarlo.
Pero eso lo dejo para vosotros 🙂
Espero que os haya gustado y os sea de utilidad.

Aplicación Google Play

Aplicación Google Play – Mi lista de la compra

Os quiero presentar esta aplicación desarrollada para Android que programé hace algún tiempo. Se trata de una aplicación muy sencilla pero útil que nos permite crear nuestra lista de la compra y controlar el gasto en todo momento. Nos permite ir creando entradas de productos distribuidos en cinco categorías, modificarlas o eliminarlas. Podemos indicar el número de unidades a comprar y su precio, lo que nos mostrará automáticamente el precio total por producto. Si deseamos conocer cuál es el importe total de la compra lo tenemos disponible en cualquier momento. Además podemos ordenar nuestra lista alfabéticamente de mayor a menor o viceversa. En el momento de la compra podemos ir tachando los productos comprados pulsando sobre ellos para controlar aquellos que todavía no hemos adquirido de nuestra lista. En fin, como veis, una aplicación que nunca está de más llevar instalada en vuestro dispositivo móvil. Si estáis interesados visitar este enlace y descargarla gratuitamente: Mi lista de la compra

Aula Mentor

Aula Mentor

Si eres de ese tipo de seres inquietos que nunca pueden dejar de aprender y que, además, quieren ampliar su currículum profesional, te recomiendo visitar la página de Aula Mentor. Se trata de una iniciativa de formación online perteneciente al Ministerio de Educación, cultura y deporte. Por un precio módico puedes realizar un curso online de una calidad extraordinaria, donde además cuentas con la posibilidad de realizar un examen que te permita obtener un certificado del Ministerio avalando tus estudios. Los exámenes son presenciales, claro, y por ello deberás buscar tu aula mentor más cercana a tu residencia. No te preocupes que hay muchas. Toda la información al respecto de cursos, duración, matrícula y aulas la tenéis en la propia página web. Dado que este blog trata de programación os recomiendo ir al apartado correspondiente en la página web. Os sorprenderéis al encontraros con cursos como el de Symfony2, Java avanzado, Java web o el completísimo sobre aplicaciones Android, entre otros muchos.
Aquí va el enlace: Aula Mentor