phpvalidationemailzend-framework2jquery-select2

Validator EmailAddress can validate an array of email


I have a select2 field (tags) which need to be validated with EmailAddress validator from Zend framework 2.

the post from select2 field is like this:

'email@domain.com, email2@domain.com'

From here, my form has an input filter which looks like this:

public function getInputFilterSpecification()
    {
        return array(
            'name'  => array(
                'required'   => true,
                'filters'    => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                ),
            ),
            'emailList'  => array(
                'required'   => true,
                'filters'    => array(
                    array('name' => 'StripTags'),
                    array('name' => 'StringTrim'),
                    array(
                        'name' => 'Callback',
                        'options' => array(
                            'callback' => function($value) {
                                if (is_string($value)) {
                                    $value = explode(',', $value);
                                }
                                return $value;
                            },
                        ),
                    )
                ),
                'validators' => array(
                    array(
                        'name' => 'EmailAddress',
                    ),
                ),
            ),
        );
    }

Like you see, I want to validate all mails I've got from the form, so I explode my string into an array for validating each email in a loop.

One problem I don't know how and where to validate this array. In this example I get the error 'invalid type. String expected' means that only one email is accepted for this validator.

Is possible to do this? Can I put a foreach into an option callback for validating each of my emails?

Tried:

From my Fieldset:

$this->add(
    array(
        'name'    => 'emailList',
        'type' => 'Zend\Form\Element\Email',
        'options' => array(
            'label' => 'email_list',
            'label_attributes' => array(
                'class'  => 'control-label col-xs-5'
            ),
        ),
        'attributes' => array(
            'class' => 'form-control select-tags col-xs-5 nopadding',
            'multiple' => true,
        )
    )
);

My vue:

<?=$this->formEmail($reporting->get('emailList'));?>
<p class="col-xs-4 help-block">
  <?php 
    if ($this->formElementErrors($reporting->get('emailList'))) {
      echo $this->formElementErrors()
        ->setMessageOpenFormat('- ')
        ->setMessageSeparatorString('<br/>- ')
        ->setMessageCloseString('')
        ->render($reporting->get('emailList'));
    }
  ?>
</p>

I tried to change the type to Zend\Form\Email and even with that... nothing works as expected

And I get the same error message I had before:

- 'test@domain.com,lol' ne correspond pas au format dot-atom
- 'test@domain.com,lol' ne correspond pas au format quoted-string
- 'test@domain.com,lol' n'est pas une partie locale valide pour l'adresse email

Sorry it's in French, basically it says that the string doesn't match dot-atom pattern, quoted-string pattern and not valid email address. But

test@domain.com was the first email, and lol@test.com was the second. so the comma is a problem


Solution

  • Why are you not embracing OOP? Create new validator for this:

    namespace YourApp\Validator;
    
    use Zend\Validator\EmailAddress;
    
    class EmailAddressList extends EmailAddress
    {
        public function isValid($value)
        {
            $emails = array_map('trim', explode(',', $value));
            foreach ($emails as $email) {
                if (!parent::isValid($email)) {
                    return false;
                }
            }
    
            return true;
        }
    }
    

    and in your validator spec:

    public function getInputFilterSpecification()
    {
        return [
            // other fields
            'emailList'  => [
                'required'   => true,
                'validators' => [
                    ['name'=> EmailAddressList::class],
                ],
            ],
        ];
        }