Un post validator pour gérer les dépendances entre les champs
Aujourd'hui, je partage un post validator qui permet de définir des dépendances entre des champs. Il permet par exemple de définir que le champ postal_code n'est requis que si le champ country vaut FR.
Voici donc cette classe :
<?php
/**
* sfValidatorSchemaDependency allows to define dependency between fields
*/
class sfValidatorSchemaDependency extends sfValidatorSchema
{
/**
* Constructor.
*
* Available options:
*
* * affected_field: The field that is required or not
* * expected_values: A key/value array that represents the fields and their value
* that must be matched to set the affected_field as required
*
* @param string $affected_field The field that is required or not
* @param array $expected_values A key/value array that represents the fields and their value
* that must be matched to set the affected_field as required
* @param array $options An array of options
* @param array $messages An array of error messages
*
* @see sfValidatorBase
*/
public function __construct($affected_field, $expected_values, $options = array(), $messages = array())
{
$this->addOption('affected_field', $affected_field);
$this->addOption('expected_values', $expected_values);
parent::__construct(null, $options, $messages);
}
/**
* @see sfValidatorBase
*/
protected function doClean($values)
{
if (null === $values)
{
$values = array();
}
if (!is_array($values))
{
throw new InvalidArgumentException('You must pass an array parameter to the clean() method');
}
$affected_field = isset($values[$this->getOption('affected_field')]) ? $values[$this->getOption('affected_field')] : null;
$bAllValuesMatched = true;
foreach ($this->getOption('expected_values') as $field => $value)
{
// if a field has not the expected value
if (!isset($values[$field]) || $values[$field] != $value)
{
$bAllValuesMatched = false;
break;
}
}
// if every field has the expected value, and affected_field not defined
if ($bAllValuesMatched && !$affected_field)
{
// "affected_field is required" error
throw new sfValidatorErrorSchema($this, array(
$this->getOption('affected_field') => new sfValidatorError($this, 'required')
));
}
return $values;
}
}
Et voici comment l'utiliser dans le cas de l'exemple de notre introduction :
/**
* @see sfForm::configure()
*/
public function configure()
{
// ...
$this->mergePostValidator(new sfValidatorSchemaDependency('postal_code', array('country' => 'FR')));
}
Ainsi, lors de la validation du formulaire, si le champ country vaut FR et si le champ postal_code est vide, une sfValidatorError de type required va être liée au champ postal_code.
Notez qu'il est possible de définir plusieurs dépendances, en passant plusieurs éléments dans le tableau en second paramètre du constructeur de sfValidatorSchemaDependency.
ValidatorEmailList : valider une liste d’e-mails
Voici un petit validateur pas très compliqué mais pratique, qui valide une liste d'adresses e-mails présentes dans un champ type "textarea".
-
class ValidatorEmailList extends sfValidatorBase
-
{
-
public function doClean($value)
-
{
-
$aValues = explode("\n", $value);
-
$aValues = array_map('trim', $aValues);
-
$aEmails = array();
-
-
$oEmailValidator = new sfValidatorEmail();
-
-
foreach ($aValues as $sEmail)
-
{
-
// ignore empty lines
-
if ($sEmail != '')
-
{
-
// verify email syntax using sfValidatorEmail
-
// sfValidatorError exception will be thrown if invalid
-
$oEmailValidator->clean($sEmail);
-
$aEmails[] = $sEmail;
-
}
-
}
-
-
return $aEmails;
-
}
-
}
Ça me fait penser qu'on pourrait améliorer ça en passant le validateur (ici "new sfValidatorEmail()") en option de ValidatorEmailList pour pouvoir valider des listes de ce qu'on veut en fait... Enfin je vous laisse le faire !