简体   繁体   中英

Unable to get FormFactory to fill array values on `submit`. Wrong EntityType definition?

I have created an integration test to debug an actual issue that seems to stem from upgrading from Symfony 3.3 to 3.4. The issue is that all my array fields on the entity (Doctrine ORM annotated as the type json_array on the field and stored as json in Postgres) should be filled from values in the $requestEntity that I submit, but they all turn out as null . Is there something off in the type definitions? I am really not sure how the entity class ties in with the "filling" of the entity vs the form type definition, so I will list the relevant bits from both.

EDIT: Clarification on what this data is

The $requestEntity here is not literal user input, but parsed JSON from an API endpoint. I am not sure whether using the Forms functionality is the right way to go about validating and working with non-form data, but that was the choice of whomever wrote this.

Code where scoreCols is always null after submit()

        $requestEntry = array(
            'id' => 'C4F1D2A3-762D-4548-B0E3-C0B3912FC02C',
            'score_cols' =>
                array(
                    0 => 'REPS',
                    1 => 'PAUSE',
                    2 => 'KG_WEIGHTS',
                )
        // other fields trimmed for brevity
        );

        $model = new ExerciseInfo();
        $formFactory = $container->get("form.factory");
        $form = $formFactory->create(ApiExerciseInfoType::class, $model);
        $form->submit($requestEntry);

        /**
         * @var $data ExerciseInfo
         */
        $entity = $form->getData();

        // $cols should be something like ["REPS", "PAUSE", "REPS"], but is always null!
        $cols = $entity->getScoreCols();

Entity class: ExerciseInfo

class ExerciseInfo
{
   /**
     * @var string
     *
     * @ORM\Column(name="id", type="guid")
     * @ORM\Id
     * @Assert\NotNull()
     */
    private $id;

    /**
     * @var array
     *
     * @ORM\Column(name="score_cols", type="json_array", nullable=true)
     * @Assert\NotBlank()
     */
    private $scoreCols; // will contain array  of types eg:  ["REPS", "KG_WEIGHTS", "PAUSE"]
...

Form Type definition

class ApiExerciseInfoType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id', HiddenType::class)
            ->add('exercise_id', EntityType::class, [
                'class' => 'PETE\BackendBundle\Entity\Exercise',
                'property_path' => 'exercise',
            ])
            ->add('notes_sets', null, [])
            ->add('exercise_notes', null, [])
            ->add('score_cols', TextType::class, [
                'property_path' => 'scoreCols'
            ])
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'MyProj\BackendBundle\Entity\ExerciseInfo',
            'csrf_protection' => false,
            'allow_extra_fields' => true,
        ));
    }
}

Symfony made a breaking change in its 3.4.21 release by being stricter about what TextType would allow. It is now filtering arrays out of scalar types .

In a related issue , one Alexander Schranz posted a workaround :

class UnstructuredType extends AbstractType
{
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'compound' => false,
            'multiple' => true,
        ));
    }
}

That was what I needed. As Cerad mentions in the comments, the general approach is probably wrong and one should probably go for a data transformer (I have not yet looked at that).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM