Description
Symfony version(s) affected
7.1.1
Description
When mapping a CollectionType ('allow_delete' => true
) to an entity property of type ArrayCollection, the following exception is thrown when setting the new 'keep_as_list' option true
:
array_values(): Argument #1 ($array) must be of type array, Doctrine\ORM\PersistentCollection given
How to reproduce
Map a CollectionType to an ArrayCollection with 'keep_as_list' => true
.
ExampleEntity:
#[ORM\OneToMany(targetEntity: Dataset::class, mappedBy: 'ExampleEntity', orphanRemoval: true, cascade: ['persist'])]
private Collection $dataset_collection;
public function __construct()
{
$this->dataset_collection = new ArrayCollection();
}
Form with CollectionType:
$builder
->add('dataset_collection', CollectionType::class, [
'entry_type' => DatasetFormType::class,
'allow_add' => true,
'allow_delete' => true,
'by_reference' => false,
'keep_as_list' => true,
])
;
Possible Solution
Before the 'keep_as_list' option was introduced in Symfony 7.1. I used to re-index my collections manually - which still works for collections of type ArrayCollection, too.
(https://symfonycasts.com/screencast/collections/embedded-validation#fixing-collectiontype-validation-bug).
Not a solution, but a quick fix: Check the type of $data
in the onSubmit
method in ResizeFormListener.php
and convert it into an array if it is an instance of ArrayCollection or PersistentCollection.
if ($this->keepAsList) {
$formReindex = [];
foreach ($form as $name => $child) {
$formReindex[] = $child;
$form->remove($name);
}
foreach ($formReindex as $index => $child) {
$form->add($index, $this->type, array_replace([
'property_path' => '['.$index.']',
], $this->options));
}
if ($data instanceof ArrayCollection || $data instanceof PersistentCollection) {
$data = $data->toArray();
}
$data = array_values($data);
}
EDIT: 'keep_as_list' also breaks embedded forms that contain unmapped file upload inputs. Model-, norm- and viewData return empty string/null instead of an UploadedFile object.
Additional Context
No response