Associative Array Fields in Form Builder - Symfony3

Let's start with the background.

I need a user profile that will have basic information such as name, email address, phone, etc. And for this I have a user.

I also need to save the answers from the questionnaire. I thought to store them in the database as json in a text box. These questions may change in the future, there are currently ~ 30 questions, so I do not want to store it as an entity. So, currently in my User object, I have the following:

/** * @var array * * @ORM\Column(name="questionnaire", type="json_array", nullable=true) */ private $questionnaire; 

I understand that Symfony will take care of json_encode / json_decode. So this is great.

But now I have a little problem with creating a form with symfony creator.

At first I thought I could try something like this:

 $builder->add('questionnaire[source]'); 

What does not work. For symfony masters, this is obvious, I know; o)

So, currently I see my options: CollectionType or Data Transformers.

From what I see, CollectionType will not work, since it only works with numeric arrays, where we have a field with some JS β€œAdd another line” or something like that. http://symfony.com/doc/current/reference/forms/types/collection.html#adding-and-removing-items But if I am wrong about this and I have to go with CollectionType, there is some magic way , please, say Me. I can not find much about it.

So, I was thinking about Data Transformers or just creating an array to send without this Transformer thing. Create all the fields in the Questionnaire using "mapped => false", and then set these values ​​as an associative array in $ questionnaire. It "feels" good, but I'm not sure how to process it later in the "Edit" form (from the documents I think with http://symfony.com/doc/current/reference/forms/types/form.html #data ).

In the questionnaire itself there will be many ChoiceType, CollectionType fields with "Add more rows", etc., and he will have many questions. So it will be a little difficult. I would like to avoid creating an object for this with every question as a property (not sure if it is the right choice, but considering everything that I consider to be the best,).

This is my first date with symfony, so any help / advice is appreciated.

+7
php forms symfony
source share
2 answers

A few days later I found the answer to my question. The bounty did not help to achieve this faster, but hey, there is a solution !; ABOUT)

So it turns out it's very simple. I really have not found much in this particular problem, so if you need something like this, here it is.

In an entity class with this json_array, define all the necessary keys:

 /** * @var array * * @ORM\Column(name="questionnaire", type="json_array", nullable=true) */ private $questionnaire = [ 'favPet'=>'', 'favFood'=>'', 'favColor'=>'' ]; 

Next, in the form builder, use "property_path"! It is just ... https://symfony.com/doc/current/reference/forms/types/form.html#property-path like this:

 /** * @param FormBuilderInterface $builder * @param array $options */ public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('name') ->add('email', EmailType::class) ->add('phone') ->add('address') ->add('favPet',TextType::class,[ 'label'=>'Fav pet', 'property_path'=>'questionnaire[favPet]' ]) ->add('favFood',TextType::class,[ 'label'=>'Fav food', 'property_path'=>'questionnaire[favFood]' ]) ->add('favColor',TextType::class,[ 'label'=>'Fav color', 'property_path'=>'questionnaire[favColor]' ]) ; } 

And symfony will handle the rest. Since we used json_array as a type, symfony will handle json_encode / json_decode. For symfony to display / populate values ​​in edit mode, the property must have a key. Otherwise, you will receive an error message:

The PropertyAccessor property needs to use a graph of objects or arrays, but it detected a type of "NULL" when trying to cross a path

And then in the branch template you can do this:

 {{ user.questionnaire.favPet }} 

And this !: O))

Regarding JSON or Entity. I know that I did not write a single entity, but I did not decide. After some IRC talk, reading and fooobar.com/questions/38879 / ... , I will probably go with EAV. Therefore, if you decide between JSON vs Entity, add EAV to the race.

+4
source share

I had a similar problem with Sylius: the object had an array field called "setup" and this application expected the application to have this format:

 ['configuration' => ['filters' => ['taxons' => ['frg', 'books'] ] ] ]; 

I managed to save an associative array formatted as it was requested using nested forms:

The hierarchy of the form class is as follows:

  • PercentageDiscountConfigurationType - for configuration
  • ActionFiltersType - for filters
  • TaxonFilterType - for taxa

Here you can see a PR with similar functionality: https://github.com/Sylius/Sylius/pull/6054/files

0
source share

All Articles