La version de Symfony 1.3 vient de passer en ALPHA2. Etant en cours de développement d’un projet sur cette version j’en profite pour tester les nouvelles fonctionnalités. Parmi celles-ci, il y a le sfMailer. Je ne vais pas m’étendre sur le sujet car on peut déjà trouver pas mal de posts sur internet concernant cette classe notamment dans les jobeet : Day 16 The Mailer .
Je me suis par contre amusé à coder un petit validator, qui il me semble, se couple bien avec le sfMailer : sfValidatorEmailList. Son nom est assez explicite mais pourquoi tester des listes de mails ? Tout simplement parceque sfMailer permet d’envoyer des mails groupés !
/**
* Creates a new message.
*
* @param string|array $from The from address
* @param string|array $to The recipient(s)
* @param string $subject The subject
* @param string $body The body
*
* @return Swift_Message A Swift_Message instance
*/
Dans les commentaires de la fonction compose() on peut voir que l’on a la possibilité de passer un string ou un tableau. sfValidatorEmailList va ainsi nous permettre de valider une liste de mails séparés par un caractère quelconque.
Tout d’abord je vais créer un formulaire classique qui me permettra de saisir les adresses emails, le sujet et le corps de mon email.
class lkInvitationForm extends sfForm
{
public function setup()
{
if ( ! $this->getOption('mailer') instanceof sfMailer )
{
throw new RuntimeException('A valid mailer option is required to send an email from this form');
}
$this->setWidgets(array(
'email' => new sfWidgetFormInputText(array('label' => 'Adresse(s) email')),
'title' => new sfWidgetFormInputText(array('label' => 'titre du mail')),
'body' => new sfWidgetFormTextarea(array('label' => 'Corps du mail')),
));
$this->setValidators(array(
'email' => new sfValidatorEmailList(array('required' => true), array('invalid' => '"%value%" invalide')),
'title' => new sfValidatorString(array('required' => true), array('invalid' => '"%value%" invalide')),
'body' => new sfValidatorString(array('required' => true), array('invalid' => '"%value%" invalide')),
));
$this->widgetSchema->setNameFormat('invitation[%s]');
$this->errorSchema = new sfValidatorErrorSchema($this->validatorSchema);
}
/**
* Bind form and send mail
*
* @param sfWebRequest $request
*/
public function bindAndSend(array $taintedValues = array())
{
$this->bind($taintedValues);
if ( $this->isValid() )
{
$mailer = $this->options['mailer'];
return $mailer->composeAndSend('contact@lexik.fr', $this->getValue('email'), $this->getValue('title'), $this->getValue('body'));
}
}
}
J’utilise donc pour mon email le sfValidatorEmailList dont voici le code :
class sfValidatorEmailList extends sfValidatorEmail
{
/**
* @see sfValidatorEmail
*/
protected function configure($options = array(), $messages = array())
{
parent::configure($options, $messages);
$this->addOption('separator', ',');
}
/**
* @see sfValidatorString
*/
public function doClean($value)
{
$retVal = array();
$valueError = array();
$mails = explode($this->getOption('separator'), $value);
foreach ($mails as $mail)
{
try
{
$retVal[] = parent::doClean(trim($mail));
}
catch (sfValidatorError $e)
{
$valueError[] = $e->getValue();
}
}
if ( ! empty ($valueError) )
{
throw new sfValidatorError($this, 'invalid', array('value' => implode(', ', $valueError)));
}
return $retVal;
}
}
Quelques explications :
Au niveau de la configuration on peut indiquer quel sera le caractère de séparation. Ensuite, la fonction doClean() qui se charge de tester la validité d’une valeur va transformer le string que l’on récupère en tableau et va appeler le doClean de sfEmailValidator. Afin de permettre un rendu plus propre du message d’erreur, j’utilise un try-catch qui me permet de lister tous les emails invalides. Une fois la boucle terminée, je n’ai plus qu’a créer mon exception avec toutes les valeurs catchées.
Je peux par la suite passer le $this->getValue(’email’) à ma fonction composeAndSend() puisque le validator me retourne un tableau.
Exemple d’une erreur dans un seul email
Exemple d’une erreur dans plusieurs emails
Maintenant lorsque j’affiche mon formulaire, les utilisateurs pourront saisir des adresses emails séparées d’une virgule pour envoyer à plusieurs contacts.