8000 PropertyPathMapper crashing with CollectionType when framework.property_access.throw_exception_on_invalid_index is true · Issue #29354 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
PropertyPathMapper crashing with CollectionType when framework.property_access.throw_exception_on_invalid_index is true #29354
Closed
@VincentChalnot

Description

@VincentChalnot

Symfony version(s) affected: 3.4.*|4.* (Probably also 2.7+?)

Description
If you enable the option in the framework to throw exceptions on invalid index for the propery accessor:

framework:
    property_access:
        throw_exception_on_invalid_index: true

(Which I think should be the default behavior by the way, but this is outside the scope of this bug)

When you have a form using a CollectionType, the PropertyPathMapper will crash when trying to access invalid indexes when the ResizeFormListener adds a new field to the form. (Which happens when you add an element to your collection)

How to reproduce
On a Symfony 3.4 standard edition, enable the throw_exception_on_invalid_index option as mentionned before.
Then use this code in the DefaultController

class DefaultController extends Controller
{
    /**
     * @Route("/", name="homepage")
     *
     * @param Request $request
     *
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function indexAction(Request $request)
    {
        $formBuilder = $this->createFormBuilder(['collection' => ['test']]);
        $formBuilder->add(
            'collection',
            CollectionType::class,
            [
                'allow_add' => true,
                'entry_type' => TextType::class,
            ]
        );
        $form = $formBuilder->getForm();
        $form->handleRequest($request);

        return $this->render(
            'default/index.html.twig',
            [
                'form' => $form->createView(),
            ]
        );
    }
}

And this code for the template:

{% extends 'base.html.twig' %}

{% block body %}
    {{ form_start(form) }}
    {{ form_widget(form) }}
    <input type="text" name="form[collection][1]" value="invalid index">
    <button type="submit">Submit</button>
    {{ form_end(form) }}
{% endblock %}

This adds the element manually because this a the simplest way to test this.

Submit : Crash

Cannot read index "1" while trying to traverse path "[1]". Available indices are "Array
(
[0] => 0
)
".

Possible Solutions
There are many way to tackle this problem :

  • Remove the throw_exception_on_invalid_index option if it's not meant to be used (I'm against this because I think it should be true by default)
  • Inject a custom PropertyAccessor in the PropertyPathMapper; not form.property_accessor. (I find this solution a bit strange)
  • Make the form.property_accessor ignore any settings from the framework.property_accessor.\* configuration.
  • Catch the exception properly inside the PropertyPathMapper
  • Create a custom CollectionPropertyPathMapper only for the CollectionType that uses a dedicated property accessor that ignores the global setting.
  • Create a custom CollectionPropertyPathMapper only for the CollectionType that catches the exception properly. (I'm in favor of this one)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0