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.