domingo, 28 de febrero de 2010

Validación: comparar con otro campo

En la validación de datos de formularios, muchas veces nos gustaría comprobar que dos campos coinciden, como pueden ser los casos de contraseñas, emails, etc.

Para ello, en los formularios ponemos un segundo campo similar al que queremos comparar a fin de que el usuario introduzca dos veces el valor. Así, por ejemplo, tendríamos el campo User.password y el campo User.confirm_password, o bien User.emal y User.confirm_email.

Yo recomendaría que en el formulario usaras los campos de confirmación como si fuesen campos del modelo. A la hora de guardar (save), CakePHP los va a ignorar pues no están en el schema del modelo y nos resulta bastante fácil manipularlos.

No hay una regla de validación por defecto para esto, así que me he escrito mi propio método match para hacerlo.

La comparación de contraseñas

Una de las cuestiones problemáticas tiene que ver si usas campos de contraseñas y el AuthComponent, ya que éste intercepta los datos del formulario antes de que lleguen al sistema de validación por lo que el campo de contraseña original vendrá transformado por un hash, mientras que el campo de confirmación no (normalmente). En consecuencia, es imposible que coincidan ambos campos.

Es decir, los campos van a llegar más o menos así:

['User']['password'] = 'a3f9b5c4....'
['User']['confirm_password'] = 'miclave'

Por eso, he añadido al método soporte para obtener el hash deseado del campo de confirmación antes de comparar los campos. Si no indicas nada, los campos serán comparados en bruto.

Uso

Para comparar un campo con otro:

'campo' => array('rule' => array('match', 'otro_campo')

Para comparar un campo transformado por un hash, indicamos el tipo de hash.

'password' => array('rule' => array('match', 'confirm_password', 'sha1'))

Si se usa AuthComponent no hay que olvidar que se debe añadir el valor de Salt, lo que indicamos así


'password' => array('rule' => array('match', 'confirm_password', 'sha1', true))

Aquí un ejemplo con otro tipo de hash, en este caso md5

'password' => array('rule' => array('match', 'confirm_password', 'md5', true))

No hay comentarios: