Symfony: ¿cómo Implementar Un Validador Condicional?
posteado por Emiliano, categoría Symfony
20 abr2010
Implementamos un validador condicional para los formularios de Symfony.
Como ya sabemos, cuando utilizas el framework para formularios de Symfony, este nos da la gran utilidad de validadores para cada campo de un formulario, de este modo nosotros podemos validar los campos requeridos, el formato de los datos ingresados, etc. Ahora bien, también sabemos que cuando un validador es atado a un campo del formulario no tiene acceso a los valores ingresados en los otros campos.
Para poder realizar validaciones en casos que se necesiten validar requerimientos de las reglas de negocios y que no pueden ser validadas con los validadores de Symfony es necesario utilizar un post validator. Un post validator es ejecutado despues de todos los otros validadores y recibe un array con todos los valores ingresados al formulario.
Si tomamos un caso práctico, podriamos querer validar que el password ingresado en un formulario de login es igual al username ingresado. Para checkear esto, implementaremos un simple validador callback para asegurarnos que el password enviado es igual al username enviado. Obviamente este es un caso muy sencillo, pero tu puedes especializarlo tanto como quieras incluso llamando al Modelo de datos para validar reglas de negocio.
El formulario de login nos quedaría:
<?phpclass loginForm extends sfForm
{
public function configure()
{
$this->setWidgets(array(
'username' => new sfWidgetFormInput(),
'password' => new sfWidgetFormInputPassword(),
));
$this->setValidators(array(
'username' => new sfValidatorString(array('required' => true)),
'password' => new sfValidatorString(array('required' => true)),
));
$this->widgetSchema->setNameFormat('login[%s]');
// add a post validator
$this->validatorSchema->setPostValidator(
new sfValidatorCallback(array('callback' => array($this, 'checkPassword')))
);
}
public function checkPassword($validator, $values)
{
// before validating the password, check that the username is not empty
if(!empty($values['username']) && $values['password'] != $values['username'])
{
// password is not correct, throw an error
throw new sfValidatorError($validator, 'Invalid password');
}
// password is correct, return the clean values
return $values;
}
}
?>
De este modo, el validador callback arrojará un error "global" cuando el password ingresado no coincida con el username. Si deseamos que al obtener un error nos arroje un error asociado a un campo específico en lugar de un error global, modificamos el método checkPassword():
<?php public function checkPassword($validator, $values) { if(!empty($values['username']) && $values['password'] != $values['username']) { $error = new sfValidatorError($validator, 'Invalid password'); // throw an error bound to the password field throw new sfValidatorErrorSchema($validator, array('password' => $error)); } return $values; } ?>
Espero les sirva esta gran características de los formularios de Symfony.


3 Comentarios:
fred:
16 de Mayo de 2010 a las 13:45:37excelente ejemplo, justo lo que estaba buscando, muchas gracias
Khris7:
02 de Septiembre de 2010 a las 20:47:45Realmente genial, eres seco! sabia que con la palabra magica sfValidatorCallback podia llegar a lo que necesitaba! muchas gracias por compartir
Rodrigo Cubillos:
25 de Marzo de 2011 a las 08:28:23Muchas gracias, este ejemplo está muy bien explicado y era justo lo que llevaba varias horas buscando