From 668720984d9634d1b3939444c9734704db2ca166 Mon Sep 17 00:00:00 2001 From: Julie Lenaerts Date: Tue, 11 Feb 2025 15:06:04 +0100 Subject: [PATCH] WIP merge service --- .../AccompanyingPeriodWorkMergeService.php | 127 ++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100644 src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php diff --git a/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php new file mode 100644 index 000000000..155a180a7 --- /dev/null +++ b/src/Bundle/ChillPersonBundle/Service/AccompanyingPeriodWork/AccompanyingPeriodWorkMergeService.php @@ -0,0 +1,127 @@ +transferData($toKeep, $toDelete); + + // Update linked entities + $this->updateReferences($toKeep, $toDelete); + + $this->em->remove($toDelete); + $this->em->flush(); + } + + private function transferData(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void + { + $excludedProperties = ['id', 'createdAt', 'createdBy', 'updatedAt', 'updatedBy']; + $reflection = new \ReflectionClass(AccompanyingPeriodWork::class); + + foreach ($reflection->getProperties() as $property) { + if (in_array($property->getName(), $excludedProperties, true)) { + continue; + } + + $toKeepValue = $property->getValue($toKeep); + $toDeleteValue = $property->getValue($toDelete); + + if (null === $toKeepValue && null !== $toDeleteValue) { + $property->setValue($toKeep, $toDeleteValue); + } + + if ($toKeepValue instanceof Collection + && $toDeleteValue instanceof Collection) { + foreach ($toDeleteValue as $item) { + if (!$toKeepValue->contains($item)) { + $toKeepValue->add($item); + } + } + } + } + } + + private function updateReferences(AccompanyingPeriodWork $toKeep, AccompanyingPeriodWork $toDelete): void + { + $allMeta = $this->em->getMetadataFactory()->getAllMetadata(); + + foreach ($allMeta as $meta) { + foreach ($meta->getAssociationMappings() as $assoc) { + if (AccompanyingPeriodWork::class !== $assoc['targetEntity']) { + continue; // Skip unrelated associations + } + + $entityClass = $meta->getName(); + $associationField = $assoc['fieldName']; + + if ($assoc['type'] & ClassMetadata::TO_ONE) { + // Handle ManyToOne or OneToOne + $qb = $this->em->createQueryBuilder(); + $qb->update($entityClass, 'e') + ->set("e.{$associationField}", ':toKeep') + ->where("e.{$associationField} = :toDelete") + ->setParameter('toKeep', $toKeep) + ->setParameter('toDelete', $toDelete) + ->getQuery() + ->execute(); + } + + if ($assoc['type'] & ClassMetadata::TO_MANY) { + // Handle ManyToMany or OneToMany (inverse side) + $repo = $this->em->getRepository($entityClass); + $linkedEntities = $repo->createQueryBuilder('e') + ->join("e.{$associationField}", 't') + ->where('t = :toDelete') + ->setParameter('toDelete', $toDelete) + ->getQuery() + ->getResult(); + + foreach ($linkedEntities as $entity) { + $getter = 'get'.ucfirst($associationField); + $setter = 'set'.ucfirst($associationField); + $adder = 'add'.ucfirst(rtrim($associationField, 's')); + $remover = 'remove'.ucfirst(rtrim($associationField, 's')); + + if (method_exists($entity, $getter) && method_exists($entity, $setter)) { + // For OneToMany owning side + $collection = $entity->{$getter}(); + if ($collection->contains($toDelete)) { + $collection->removeElement($toDelete); + if (!$collection->contains($toKeep)) { + $collection->add($toKeep); + } + } + } elseif (method_exists($entity, $adder) && method_exists($entity, $remover)) { + // For ManyToMany + $entity->{$remover}($toDelete); + $entity->{$adder}($toKeep); + } + + $this->em->persist($entity); + } + } + } + } + + $this->em->flush(); + } +}