8000 [Form] CollectionType 'keep_as_list' Option with Doctrine Collections · Issue #57430 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[Form] CollectionType 'keep_as_list' Option with Doctrine Collections #57430
Closed
@chris-k-k

Description

@chris-k-k

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0