Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why are Symfony2 validation propertyPath valus in square brackets?

Tags:

symfony

I am validating some values:

$collectionConstraint = new Collection(array(
    'email' => array(
        new NotBlank(),
        new Email(),
    ),
    'password'  => array(
         new NotBlank(),
         new MinLength(array('limit' => 6)),
         new MaxLength(array('limit' => 25)),
    ),
));
$data = array('email' => $this->getRequest()->get('email'), 'password' => $this->getRequest()->get('password'));
$errors = $this->get('validator')->validateValue($data, $collectionConstraint);

But for some reason the fields (propertyPath) are stored with square brackets - I'd like to understand why Sf does that. I have to manually remove all the brackets which seems absurd so I think I am missing some functionality somewhere.

Dump of $errors:

Symfony\Component\Validator\ConstraintViolationList Object
(
    [violations:protected] => Array
        (
            [0] => Symfony\Component\Validator\ConstraintViolation Object
                (
                    [messageTemplate:protected] => This value should not be blank
                    [messageParameters:protected] => Array
                        (
                        )

                    [root:protected] => Array
                        (
                            [email] => 
                            [password] => 
                        )

                    [propertyPath:protected] => [email]
                    [invalidValue:protected] => 
                )

            [1] => Symfony\Component\Validator\ConstraintViolation Object
                (
                    [messageTemplate:protected] => This value should not be blank
                    [messageParameters:protected] => Array
                        (
                        )

                    [root:protected] => Array
                        (
                            [email] => 
                            [password] => 
                        )

                    [propertyPath:protected] => [password]
                    [invalidValue:protected] => 
                )

        )

)

Even the toString function is useless.

"[email]: This value should not be blank","[password]: This value should not be blank"
like image 895
cyberwombat Avatar asked Dec 08 '11 20:12

cyberwombat


1 Answers

Property paths can map either to properties or to indices. Consider a class OptionBag which implements \ArrayAccess and a method getSize().

  • The property path size refers to $optionBag->getSize()
  • The property path [size] refers to $optionBag['size']

In your case, you validate an array. Since array elements are also accessed by index, the resulting property path in the violation contains squared brackets.

Update:

You don't have to manually remove the squared brackets. You can use Symfony's PropertyAccess component to map errors to an array with the same structure as your data, for example:

$collectionConstraint = new Collection(array(
    'email' => array(
        new NotBlank(),
        new Email(),
    ),
    'password'  => array(
         new NotBlank(),
         new MinLength(array('limit' => 6)),
         new MaxLength(array('limit' => 25)),
    ),
));

$data = array(
    'email' => $this->getRequest()->get('email'), 
    'password' => $this->getRequest()->get('password')
);

$violations = $this->get('validator')->validateValue($data, $collectionConstraint);

$errors = array();
$accessor = $this->get('property_accessor');

foreach ($violations as $violation) {
    $accessor->setValue($errors, $violation->getPropertyPath(), $violation->getMessage());
}

=> array(
    'email' => 'This value should not be blank.',
    'password' => 'This value should have 6 characters or more.',
)

This also works with multi-dimensional data arrays. There the property paths will be something like [author][name]. The PropertyAccessor will insert the error messages in the same location in the $errors array, i.e. $errors['author']['name'] = 'Message'.

like image 190
Bernhard Schussek Avatar answered Sep 21 '22 07:09

Bernhard Schussek