10000 [Form][Bug] Embedded form validation bubbling · Issue #8557 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Form][Bug] Embedded form validation bubbling #8557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
sirian opened this issue Jul 24, 2013 · 1 comment
Closed

[Form][Bug] Embedded form validation bubbling #8557

sirian opened this issue Jul 24, 2013 · 1 comment
Labels

Comments

@sirian
Copy link
Contributor
sirian commented Jul 24, 2013

See example of embedded form.

class Item
{
    public $title;
}

class Foo implements \IteratorAggregate
{
    public $items;

    public function __construct()
    {
        $this->items = [new Item()];
    }

    public function getIterator()
    {
        return new \ArrayIterator([
            'items' => $this->items
        ]);
    }
}

class ItemType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('title', 'text');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => __NAMESPACE__ . '\Item',
            'error_bubbling' => false
        ]);
    }


    public function getName()
    {
        return 'item';
    }
}

class FooType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('items', 'collection', [
            'type' => new ItemType()
        ]);
    }
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults([
            'data_class' => __NAMESPACE__ . '\Foo',
            'error_bubbling' => false
        ]);
    }

    public function getName()
    {
        return 'foo';
    }
}

Resources/config/validation.yml:

Foo\Item:
    properties:
        title:
            - NotBlank:
                message: XXX

Now when I call this

$form = $this->get('form.factory')
    ->createNamed('form', new FooType(), new Foo(), [
        'csrf_protection' => false,
        'error_bubbling' => false
    ]);
;

$form->submit([]);
var_dump($form->getErrors());

Error from items[0].title bubbles to the root of the form

array(1) {
  [0]=>
  object(Symfony\Component\Form\FormError)#534 (4) {
    ["message":"Symfony\Component\Form\FormError":private]=>
    string(3) "XXX"
    ["messageTemplate":protected]=>
    string(3) "XXX"
    ["messageParameters":protected]=>
    array(0) {
    }
    ["messagePluralization":protected]=>
    NULL
  }
}
@webmozart
Copy link
Contributor

The reason for your problem is that Foo implements \IteratorAggregate. Currently, the Form component enables object traversal for the data of the root form when launching the validation. Consequently, the generated violation has the path

data[items][0].title

instead of

data.items[0].title

To fix your problem, you can either remove the \IteratorAggregate interface from Foo or overwrite the property path for all fields in FooType:

$builder->add('items', 'collection', [
    'type' => new ItemType(),
    'property_path' => '[items]',
]);

#8617 will also be a solution to this problem, but I can't tell yet when exactly this will be implemented.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants
0