Validación en CakePHP 1.2
Este fin de semana empecé a jugar con la versión alpha de cakePHP (1.2.x.x). Esta trae consigo una clase que se encarga de la validación de los datos (la labor más importante del desarrollo de software) que nos llegan desde el navegador de los usuarios. Esta nueva clase viene a sustituir las soluciones que habían surgido [...]
Este fin de semana empecé a jugar con la versión alpha de cakePHP (1.2.x.x). Esta trae consigo una clase que se encarga de la validación de los datos (la labor más importante del desarrollo de software) que nos llegan desde el navegador de los usuarios.
Esta nueva clase viene a sustituir las soluciones que habían surgido para suplir la deficiencia que tenía en esta área cakePHP 1.1, las reglas de validación de cakePHP se definen en cada modelo. Acá estaré dando un ejemplo de cómo implementé la validación sobre un modelo Usuario.
La base de datos
La base de datos se puede crear con el siguiente script:
[sql]
CREATE TABLE `users` (
`id` int(10) unsigned NOT NULL auto_increment,
`alias` varchar(255) NOT NULL COMMENT ‘Login’,
`email` varchar(255) NOT NULL,
`name` varchar(255) NOT NULL,
`salt` char(15) NOT NULL,
`password` varchar(40) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `email` (`email`),
UNIQUE KEY `alias` (`alias`)
)
[/sql]
Tenemos:
- id: clave primaria autonumérica.
- alias: nombre de usuario.
- email: correo electrónico.
- name: nombre del usuario.
- salt: una sal que se usa para aumentar la seguridad del sistema (http://phpsec.org/articles/2005/password-hashing.html)
- password: la clave del usuario.
El Modelo
Ahora pasamos a crear el modelo user.php, he comentado un poco el código para que se explique lo que hace:
[php]
class User extends AppModel {
var $name = ‘User’;
//The Associations below have been created with all possible keys, those that are not needed can be removed
var $hasAndBelongsToMany = array (
‘Feed’ => array (
‘className’ => ‘Feed’,
‘joinTable’ => ‘users_feeds’,
‘foreignKey’ => ‘user_id’,
‘associationForeignKey’ => ‘feed_id’,
‘conditions’ => ”,
‘fields’ => ”,
‘order’ => ”,
‘limit’ => ”,
‘offset’ => ”,
‘unique’ => ”,
‘finderQuery’ => ”,
‘deleteQuery’ => ”,
‘insertQuery’ => ”
)
);
function passwordConfirm() {
if ($this->data["User"]["password"] === $this->data["User"]["password_confirm"]) {
return true;
}
return false;
}
function isUnique() {
$args = func_get_args();
$field = $args[1];
$exists = $this->hasAny(”$field=’”.$this->data["User"][$field].”‘”);
return $exists===false;
}
var $validate = array (
‘alias’ => array (
‘required’ => array (
‘rule’ => array(’minLength’, 1)
),
‘unique’ => array(
‘rule’ => array(’isUnique’, ‘alias’)
)
),
‘name’ => array (
‘required’ => array (
‘rule’ => array(’minLength’, 1)
)
),
‘email’ => array (
‘valid’ => array(
‘rule’ => array(’email’)
),
‘required’ => array (
‘rule’ => array(’minLength’, 1)
),
‘unique’ => array(
‘rule’ => array(’isUnique’, ‘email’)
)
)
,
‘password’ => array(
‘required’ => array (
‘rule’ => array(’minLength’, 1)
)
),
‘password_confirm’ => array (
‘required’ => array (
‘rule’ => array(’minLength’, 1)
),
‘confirm’ => array (
‘rule’ => array (’passwordConfirm’)
),
)
);
}
[/php]
Las reglas minLength (usada acá para que el campo no sea dejado vacío) y email son métodos por defecto de cake 1.2.
Esta clase aún no está completada por lo que fue necesario definir métodos para la validación de otros parámetros, estos son:
- passwordConfirm: permite chequear que al crear un nuevo usuario clave y su confirmación coincidan.
Se encarga de revisar que el campo password sea igual al campo password_confirm. - isUnique: chequea que el campo no se encuentre repetido en la base de datos. Este método recibe un parámetro que es el campo que se desea estudiar.
El Controlador
En el controlador implementaremos sólo el método de agregar:
[php]
function add() {
if(!empty($this->data)) {
$this->cleanUpFields();
$this->User->create();
$this->User->set($this->data);
if($this->User->validates()) {
$salt = substr(md5(uniqid(rand(), true)), 0, 15);
$this->data["User"]["salt"] = $salt;
$this->data["User"]["password"] =
$this->data["User"]["password_confirm"] =
sha1($salt.$this->data["User"]["password"]);
$this->User->save($this->data);
$this->Session->setFlash(’The User has been saved’);
$this->redirect(array(’action’=>’index’), null, true);
} else {
$this->Session->setFlash(’The User could not be saved. Please, try again.’);
}
unset($this->data["User"]["password"]);
unset($this->data["User"]["password_confirm"]);
}
/** Possible recommended feeds =) */
$feeds = $this->User->Feed->generateList();
$this->set(compact(’feeds’));
}
[/php]
En el método, referente a la validación la única línea de interés es esta:
[php]if($this->User->validates()) {[/php]
Lo demás se encarga de encriptar y ponerle la sal al password.
La vista
CakePHP 1.2 tiene un nuevo FormHelper que se encarga de dibujar los formularios, sus campos y los mensajes de error:
[php]
New User
< ?php echo $form->create(’User’);?>
< ?php
echo $form->input(’name’, array (
‘error’ => array (
‘required’ => Configure :: read(’User.name_required’
)
)));
?>
< ?php
echo $form->input(’email’, array (
‘error’ => array (
‘required’ => Configure :: read(’User.email_required’),
‘valid’ => Configure :: read(’User.email_valid’),
‘unique’ => Configure::read(’User.email_unique’)
)
));
?>
< ?php
echo $form->input(’password’, array(
‘error’ => array(
‘required’ => Configure::read(”User.password_required”)
)
));
?>
< ?php
echo $form->input(’password_confirm’,
array(
“type” => “password”,
“error” => array(
‘required’ => Configure::read(’User.password_confirm_required’),
‘confirm’ => Configure::read(’User.password_confirm’)
)
));
?>
< ?php echo $form->submit(’Add’);?>
[/php]
El segundo parámetro de $form->input se encarga de indicarle a CakePHP qué mensaje de error debe imprimir en cada caso.
Configure::read
En la vista en vez de colocar los mensajes de error directamente he optado por colocarlos en un archivo de configuración app/config/messages.php para manejarlos de una manera más centralizada.
La estructura de este archivo es la siguiente:
[php]
$config['User.name_required'] = ‘You have to write your Name.’;
$config['User.alias_required'] = ‘The alias is required.’;
$config['User.alias_unique'] = ‘This alias is already taken, try another one.’;
$config['User.email_required'] = ‘You have to write your Email.’;
$config['User.email_valid'] = “The email you set doesn’t have the right format.”;
$config['User.email_unique'] = “The email you set is allready registered.”;
$config['User.password_required'] = “You have to write your password.”;
$config['User.password_confirm_required'] = “Please confirm you password.”;
$config['User.password_confirm'] = “The password and it’s confirmation don’t match.”;
[/php]
Lo cual se parece mucho a los ResourceBundle de Java. Para cargar estos datos es necesario colocar en el controlador (o en el app_controller.php):
[php]
function beforeRender() {
Configure :: load(’messages’);
}
[/php]
Posibles problemas
Puede que esta no sea la manera recomendada para la creación de métodos adicionales para la validación, existe en la clase de validación una función llamada userDefined que debería encargarse de hacer la llamada a funciones definidas por el desarrollador pasando los parámetros de manera correcta. Luego de varios intentos teminé encontrando el método que expuse aquí.
Otras capacidades de la clase validation
Esta clase tiene otros métodos de validación:
- alphaNumeric: chequea que el campo sea alfanumérico.
- between: chequea que el valor del campo se encuentre entre un mínimo y un máximo (incluidos)
- blank: chequea que el campo haya sido deajado en banco o sea sólo caracteres en blanco (espacio, tab, etc).
- cc: chequea formatos de tarjeta de crédito de varias marcas (Amex, Via, Maestro, etc).
- comparison: compara dos números
- custom: permite especificar una expresión regular.
- date: revisa que un texto tenga un formato de fecha correcto
- decimal: revisa que el un texto represente un número decimal
- email: revisa que un texto sea un correo electrónico correcto.
- ip: detecta direcciones IPv4
- minLength y maxLength: revisan que la longitud del texto cumpla una longitud mínima y máxima respectivamente.
- money: parece detectar un texto que representa una cantidad monetaria.
- multiple y number: no están implementadas aún.
- numeric: simplemete llama a la función de php is_numeric
- phone: número telefónico, al parecer tendrá soporte para distintos países (por ahora sólo estados unidos).
- postal: código postal, también tendrá soporte para códigos de otros países (por ahora sólo estados unidos, canadá y reino unido).
- nns: número del seguro social.
- url: chequea en busca de una dirección URL, con distintos protocolos.
Resumen
La clase que permite automatizar la validación en CakePHP 1.2 es muy poderosa comparandola con la que se usaba CakePHP 1.1 (que sólo tenía 4 métodos), ofreciando una metodología simple y extensible para definir nuevas reglas dependiendo de los requerimientos de cada aplicación. Es importante recordar que esto es un trabajo en curso, la versión actual es 1.2.0.5137alpha y aún la clase no está terminada (mucho menos documentada) pero lo que hay hasta ahora es muy usable y prometedor.
Recibe otros artículos como este automáticamente
Suscríbete vía RSS a aikon.com.ve ||
¿Qué es RSS?