Correctly denormalize parent-child relationships in import, when only children not parent fields are given

This fixes issue #1272
This commit is contained in:
Jan Böhmer 2026-03-07 21:08:32 +01:00
parent b8d1414403
commit 12a760d27e
3 changed files with 81 additions and 33 deletions

View file

@ -219,11 +219,6 @@ class EntityImporter
$entities = [$entities];
}
//The serializer has only set the children attributes. We also have to change the parent value (the real value in DB)
if ($entities[0] instanceof AbstractStructuralDBElement) {
$this->correctParentEntites($entities, null);
}
//Set the parent of the imported elements to the given options
foreach ($entities as $entity) {
if ($entity instanceof AbstractStructuralDBElement) {
@ -297,6 +292,14 @@ class EntityImporter
return $resolver;
}
private function persistRecursively(AbstractStructuralDBElement $entity): void
{
$this->em->persist($entity);
foreach ($entity->getChildren() as $child) {
$this->persistRecursively($child);
}
}
/**
* This method deserializes the given file and writes the entities to the database (and flush the db).
* The imported elements will be checked (validated) before written to database.
@ -322,7 +325,7 @@ class EntityImporter
//Iterate over each $entity write it to DB (the invalid entities were already filtered out).
foreach ($entities as $entity) {
$this->em->persist($entity);
$this->persistRecursively($entity);
}
//Save changes to database, when no error happened, or we should continue on error.
@ -400,7 +403,7 @@ class EntityImporter
*
* @param File $file The Excel file to convert
* @param string $delimiter The CSV delimiter to use
*
*
* @return string The CSV data as string
*/
protected function convertExcelToCsv(File $file, string $delimiter = ';'): string
@ -421,7 +424,7 @@ class EntityImporter
]);
$highestColumnIndex = Coordinate::columnIndexFromString($highestColumn);
for ($row = 1; $row <= $highestRow; $row++) {
$rowData = [];
@ -431,7 +434,7 @@ class EntityImporter
try {
$cellValue = $worksheet->getCell("{$col}{$row}")->getCalculatedValue();
$rowData[] = $cellValue ?? '';
} catch (\Exception $e) {
$this->logger->warning('Error reading cell value', [
'cell' => "{$col}{$row}",
@ -484,21 +487,4 @@ class EntityImporter
throw $e;
}
}
/**
* This functions corrects the parent setting based on the children value of the parent.
*
* @param iterable $entities the list of entities that should be fixed
* @param AbstractStructuralDBElement|null $parent the parent, to which the entity should be set
*/
protected function correctParentEntites(iterable $entities, ?AbstractStructuralDBElement $parent = null): void
{
foreach ($entities as $entity) {
/** @var AbstractStructuralDBElement $entity */
$entity->setParent($parent);
//Do the same for the children of entity
$this->correctParentEntites($entity->getChildren(), $entity);
}
}
}