Skip to content

Instantly share code, notes, and snippets.

@benglass
Last active December 15, 2015 14:58
Show Gist options
  • Save benglass/5277987 to your computer and use it in GitHub Desktop.
Save benglass/5277987 to your computer and use it in GitHub Desktop.
// YML: Does not work
VDW\IssueTrackerBundle\Entity\Author:
properties:
profileData:
- Collection:
fields:
alternate_email:
Collection\Optional:
- Email
// Annotations
/**
* @Assert\Collection(
* fields={
* "primary_email" = @Required({@Assert\NotBlank, @Assert\Email}),
* "alternate_email" = @Optional({@Assert\Email}),
* }
* )
*/
$profileData = array();
// PHP
public static function loadValidatorMetadata(ClassMetadata $metadata)
{
$metadata->addPropertyConstraint('profileData', new Assert\Collection(array(
'fields' => array(
'primary_email' => new Required(array(new Assert\NotBlank(), new Assert\Email())),
'alternate_email' => new Optional(array(new Assert\Email())),
)
)));
}
// Controller Code
$author = new Author();
$author->setProfileData('primary_email', 'foo');
$author->setProfileData('alternate_email', 'bar');
$validator = $this->get('validator');
$errors = $validator->validate($author);
Error:
The options "Collection\Optional" do not exist in constraint Symfony\Component\Validator\Constraints\Collection\Required
@weaverryan
Copy link

    /**
     * @Assert\Collection(fields={
     *     "alternate_email" = @Assert\Collection\Optional({@Assert\Email}),
     *     "primary_email"   = @Assert\Collection\Required({@Assert\Email, @Assert\NotBlank})
     * })
     */
    private $profileData = array();

@weaverryan
Copy link

Check out: https://github.com/symfony/symfony-docs/pull/2370/files#L0R239

It will end up looking something like:

VDW\IssueTrackerBundle\Entity\Author:
    properties:
        profileData:
             - Collection:
                fields:
                    alternate_email:  Collection\Optional: [Email]

I'm not sure that works, and I actually thought (might still be) that it would be invalid YAML, but it might not be :).

@wouterj
Copy link

wouterj commented Apr 1, 2013

@weaverryan: doesn't work either:

The value Collection\Optional: [Email] of the field alternate_email is not an instance of Constraint in constraint Symfony\Component\Validator\Constraints\Collection

@webmozart
Copy link

Can't try it right now, but maybe:

VDW\IssueTrackerBundle\Entity\Author:
    properties:
        profileData:
             - Collection:
                fields:
                    alternate_email: [Collection\Optional: [Email]]

@wouterj
Copy link

wouterj commented Apr 1, 2013

@bschussek I'm sorry, but that gave another error:

Malformed inline YAML string ({Collection\Optional: [Email})

And changing it to: { Collection\Optional: [Email] } gives this error: (which is what we got too)

The options "Collection\Optional" do not exist in constraint Symfony\Component\Validator\Constraints\Collection\Required

@webmozart
Copy link

What about

VDW\IssueTrackerBundle\Entity\Author:
    properties:
        profileData:
             - Collection:
                fields:
                    alternate_email:
                        - Collection\Optional:
                            - Email: ~

There might be room for improvement here.

@wouterj
Copy link

wouterj commented Apr 4, 2013

Then we get:

Fatal error: Class 'Symfony\Component\Validator\Constraints\Collection\OptionalValidator'

It's going wrong in Collection line 50:

if (!$field instanceof Optional && !$field instanceof Required) {
    $this->fields[$fieldName] = $field = new Required($field);
}

$field is an instance of Optional or Required when using PHP or annotations. When using Yaml, $field is an array:

array (size=1)
  0 => 
    object(Symfony\Component\Validator\Constraints\Collection\Optional)[4300]
      public 'constraints' => 
        array (size=1)
          0 => 
            object(Symfony\Component\Validator\Constraints\Email)[4301]
              ...
      public 'groups' => 
        array (size=1)
          0 => string 'Default' (length=7)

Because it's not an instance of Optional or Required, it becomes:

object(Symfony\Component\Validator\Constraints\Collection\Required)[4302]
  public 'constraints' => 
    array (size=1)
      0 => 
        object(Symfony\Component\Validator\Constraints\Collection\Optional)[4300]
          public 'constraints' => 
            array (size=1)
              ...
          public 'groups' => 
            array (size=1)
              ...
  public 'groups' => 
    array (size=1)
      0 => string 'Default' (length=7)

And that's when we are in trouble, because the ValidatorFactory will search for OptionalValidator.

I have tried every Yaml syntax I know to make $field a class and not an array, but I can't find it. I think some change in the YamlFileLoader is needed to make this work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment