Ver índice de contenidos del libro

10.5. Validadores

Symfony incluye muchos validadores listos para utilizar. Cada validador acepta como parámetros un array de opciones y un array de mensajes de error, en el que siempre puedes redefinir el valor de al menos los errores required e invalid.

// Validador de cadenas de texto
$form->setValidator('mensaje', new sfValidatorString(array(
  'min_length' => 4,
  'max_length' => 50,
),
array(
  'min_length' => 'Escribe por favor un mensaje más largo',
  'max_length' => 'Por favor, no escribas tanto',
)));
 
// Validador de números
// (utiliza 'sfValidatorInteger' si sólo quieres admitir números enteros)
$form->setValidator('edad', new sfValidatorNumber(array( 
  'min'  => 18,
  'max'  => 99.99,
),
array(
  'min' => 'Debes tener al menos 18 años para utilizar este servicio',
  'max' => '¿Crees que soy tonto? ¡Si los de 30 años ya tienen problemas para utilizar Internet!',
)));
 
// Validador de email
$form->setValidator('email', new sfValidatorEmail());
 
// Validador de URL
$form->setValidator('sitio_web', new sfValidatorUrl());
 
// Validador de expresión regular
$form->setValidator('IP', new sfValidatorRegex(array(
  'pattern' => '^[0-9]{3}\.[0-9]{3}\.[0-9]{2}\.[0-9]{3}$'
)));

Aunque algunos campos del formulario (listas, radio button, checkbox) restringen los valores que se pueden utilizar, cualquier usuario malicioso puede manipular el formulario y enviar toda la información que quiera. Por tanto, siempre debes comprobar el valor de los campos restringidos:

// Validador booleano
$form->setValidator('ha_aceptado_las_condiciones', new sfValidatorBoolean());
 
// Validador de selección (para restringir los valores de una lista)
$form->setValidator('asunto', new sfValidatorChoice(array(
  'choices' => array('Asunto A', 'Asunto B', 'Asunto C')
)));
 
// Validador de selección múltiple
$form->setValidator('idiomas', new sfValidatorChoice(array(
  'multiple' => true,
  'choices' => array('en' => 'Inglés', 'fr' => 'Francés', 'otro')
)));

Symfony también incluye validadores internacionalizados para las listas de países (sfValidatorI18nChoiceCountry) y para las listas de idiomas (sfValidatorI18nChoiceLanguage). Estos validadores admiten una lista restringida de países (parámetro countries) e idiomas (parámetro languages) si quieres limitar las posibles opciones.

El validador sfValidatorChoice normalmente se utiliza para validar un widget de tipo sfWidgetFormChoice. Igualmente, Symfony proporciona un validador adecuado para el widget sfWidgetFormChoice, que comprueba si la clave externa existe realmente en la tabla relacionada:

// Validador de selección para Propel
$form->setValidator('seccion_id', new sfValidatorPropelChoice(array(
  'model'  => 'Seccion',
  'column' => 'nombre'
)));
 
// Validador de selección para Doctrine
$form->setValidator('seccion_id', new sfValidatorDoctrineChoice(array(
  'model'  => 'Seccion',
  'column' => 'nombre'
)));

Otro validador muy útil para los modelos es sfValidatorPropelUnique, que comprueba que el valor introducido en el formulario no entra en conflicto con ninguno de los valores de una columna que incluya un índice único. Un ejemplo típico es la columna de login, cuyo valor no puede coincidir para dos usuarios diferentes. La solución consiste en añadir un validador sfValidatorPropelUnique en la columna login al modificar un objeto de tipo Usuario:

// Validador único de Propel
$form->setValidator('login', new sfValidatorPropelUnique(array(
  'model'  => 'Usuario', 
  'column' => 'login'
)));
 
// Validador único de Doctrine
$form->setValidator('login', new sfValidatorDoctrineUnique(array(
  'model'  => 'Usuario', 
  'column' => 'login'
)));

Si quieres aumentar la seguridad de tus formularios evitando los ataques de tipo CSRF, puedes activar la protección CSRF de Symfony:

// Protección CSRF: utiliza una cadena de texto aleatoria que nadie conozca
$form->addCSRFProtection('flkd445rvvrGV34G');

Nota Si quieres utilizar la misma cadena CSRF en todos los formularios, puedes configurarla en el archivo settings.yml:

# en apps/miaplicacion/config/settings.yml
all:
  .settings:
    csrf_secret: ##CSRF_SECRET##    # Sustituye ##CSRF_SECRET## por una cadena aleatoria que nadie conozca

Los validadores múltiples hacen uso de todo el formulario, en vez de utilizar un campo individual. A continuación se muestran los validadores múltiples disponibles:

// Validador de comparación, para comparar dos campos entre sí
$form->setPostValidator(new sfValidatorSchemaCompare('password1', '==', 'password2'));
 
// Validador de campos extra, que busca campos que existen en la petición pero no en el formulario
$form->setOption('allow_extra_fields', false);
$form->setOption('filter_extra_fields', true);