Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Doctrine Bridge] DoctrineType choiceList cache-key conflict #9556

Copy link
Copy link
Closed
@DRvanR

Description

@DRvanR
Issue body actions

Hello,

I've ran into an issue with the Symfony\Bridge\Doctrine\Form\Type\EntityType form type in very dynamic form.
The context:
A Project has multiple ProjectSteps. Each ProjectStep has 0 or more ActorLists, which contains a mask and multiple actors. The form described below serves to let users choose, based on the mask given, which actors should be included in the ActorList for execution of the project.

This leads to the following form: A ProjectType that has a CollectionType for the ProjectSteps: Each ProjectStep has a CollectionType for the ActorLists. The ActorList contains an EventSubscriber that adds the actor choices as an EntityType.

The issue is that for each of the EntityTypes, always the choices of the first one added are used, even though the choices are (verified) different per EntityType. The choices are added as a Doctrine ArrayCollection and according to the docs \Traversable is supported, which the ArrayCollection implements (1).

After some research, it turns out the $choiceList closure in the setDefaults method of the DoctrineType (which the EntityType extends) use a cache to prevent having to instantiate multiple Symfony\Bridge\Doctrine\Form\ChoiceList\EntityChoiceList for forms that have the same options (for reference, see here). The cache-key, based on which the lookup is done, includes the choices option. If the choices given is an array, the values are converted to the spl_object_hashes of those values (see lines 82-92). If the choices given is an ArrayCollection, no conversion is made. Within the actual creation of the cache-key, the $choiceHashes, together with several other identifiers, are run through json_encode and the resulting string is hashed to get the cache-key (see lines 112-120).
With the lack of getting the spl_object_hashes for the values of the ArrayCollection as the $choiceHashes and the json_encond converting the ArrayCollection to an empty object, if all other options are the same, this leads to the same key being generated for different forms, leading to always getting the same choice-options.

This can be fixed two ways:

  1. Remove the \Traversable support from the docs, and always require an array
  2. Add support for \Traversable objects such that the $choiceHashes value is set to an array of spl_object_hashes, one for each value in the \Traversable object.

For now I'm just using ->toArray() when assigning the choices to the options array to circumvent the cache-key conflict, which would indicate option 1. However I can imagine option 2 is preferred (and it has my personal preference).
Either way I will make a pull request for it (be it for the docs or the code), I'm just wondering what the preferred route is.

Regards,

Daan.

(1): ArrayCollection implements \Doctrine\Common\Collections\Collection, which extends IteratorAggregate, which in turn extends Traversable

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.