diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php index c5ca7d18a..64e4e79d8 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialAction.php @@ -98,7 +98,7 @@ class SocialAction { if (!$this->children->contains($child)) { $this->children[] = $child; - $child->setParent($this); + $child->setParent($this)->setIssue($this->getIssue()); } return $this; @@ -266,9 +266,16 @@ class SocialAction { $this->issue = $issue; + foreach ($this->getChildren() as $child) { + $child->setIssue($issue); + } + return $this; } + /** + * @internal use $parent->addChild() instead (@see{self::addChild()}) + */ public function setParent(?self $parent): self { $this->parent = $parent; diff --git a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php index 80b106b4e..b0be1ae00 100644 --- a/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php +++ b/src/Bundle/ChillPersonBundle/Entity/SocialWork/SocialIssue.php @@ -305,6 +305,9 @@ class SocialIssue return $this; } + /** + * @internal use @see{SocialIssue::addChild()} instead + */ public function setParent(?self $parent): self { $this->parent = $parent; diff --git a/src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php b/src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php index 3affec5b3..101695463 100644 --- a/src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php +++ b/src/Bundle/ChillPersonBundle/Service/Import/SocialWorkMetadata.php @@ -57,20 +57,45 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $this->entityManager = $entityManager; } + /** + * @throws Exception + */ public function import(iterable $dataset): bool { - foreach ($dataset as $row) { - $this->import1( - array_map( - static fn (string $column): ?string => '' === $column ? null : $column, - array_map('trim', $row) - ) - ); + // Initialisation of the previous result row with the proper data structure. + $result = [ + 'socialIssues' => [ + 'socialIssue' => null, + 'socialIssueChild' => null, + ], + 'socialActions' => [ + 'socialAction' => null, + 'socialActionChild' => null, + ], + 'goal' => null, + 'result' => null, + 'eval' => null, + ]; + + foreach ($dataset as $key => $row) { + $result = $this + ->import1( + $key, + // Columns cleanup before importing data. + array_map( + static fn (string $column): ?string => '' === $column ? null : $column, + array_map('trim', $row) + ), + $result + ); } return true; } + /** + * @return array + */ private function findByJson(ObjectRepository $repository, string $field, array $jsonCriterias): array { $qb = $this @@ -81,7 +106,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $expr = $qb->expr(); - $temporaryJsonCriterias = $jsonParameters = []; + $temporaryJsonCriterias = []; foreach ($jsonCriterias as $key => $value) { $temporaryJsonCriterias[] = [$field, $key, $value, sprintf(':placeholder_%s_%s', $field, $key)]; @@ -121,15 +146,19 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $temporaryJsonCriterias ); - $query = $qb + return $qb ->select('s') ->where(...$jsonPredicates) ->setParameters($jsonParameters) - ->getQuery(); - - return $query->getResult(); + ->getQuery() + ->getResult(); } + /** + * @throws Exception + * + * @return object + */ private function getOrCreateEntity(ObjectRepository $repository, string $field, array $jsonCriterias = []) { $results = $this @@ -139,34 +168,19 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $jsonCriterias ); - $entity = null; + if ([] === $results) { + $entity = $repository->getClassName(); - switch (true) { - case count($results) === 0: - $entity = $repository->getClassName(); - $entity = new $entity(); - - break; - - case count($results) === 1: - $entity = current($results); - - break; - - case count($results) > 1: - throw new Exception( - sprintf( - 'More than one entity(%s) found.', - $repository->getClassName() - ) - ); + return new $entity(); } - if (null === $entity) { - throw new Exception('Unable to create entity.'); + if (count($results) === 1) { + return reset($results); } - return $entity; + throw new Exception( + 'Unable to create entity.' + ); } private function handleEvaluation(?string $evaluationTitle, SocialAction $socialAction): ?Evaluation @@ -185,7 +199,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface return $eval; } - private function handleGoal(?string $goalTitle = null, ?SocialAction $socialAction = null): ?Goal + private function handleGoal(?string $goalTitle, SocialAction $socialAction): ?Goal { if (null === $goalTitle) { return null; @@ -195,19 +209,16 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $goal = $this->getOrCreateEntity($this->goalRepository, 'title', ['fr' => $goalTitle]); $goal->setTitle(['fr' => $goalTitle]); - if (null !== $socialAction) { - $socialAction->addGoal($goal); - $goal->addSocialAction($socialAction); - - $this->entityManager->persist($socialAction); - } + $socialAction->addGoal($goal); + $goal->addSocialAction($socialAction); + //$this->entityManager->persist($socialAction); $this->entityManager->persist($goal); return $goal; } - private function handleResult(?string $resultTitle = null, ?SocialAction $socialAction = null, ?Goal $goal = null): ?Result + private function handleResult(?string $resultTitle, SocialAction $socialAction, ?Goal $goal): ?Result { if (null === $resultTitle) { return null; @@ -224,89 +235,162 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface $this->entityManager->persist($goal); } else { $result->addSocialAction($socialAction); + $socialAction->addResult($result); } - $result->addSocialAction($socialAction); - $socialAction->addResult($result); - $this->entityManager->persist($result); - $this->entityManager->persist($socialAction); + //$this->entityManager->persist($socialAction); return $result; } - private function handleSocialAction(?string $socialActionTitle, ?string $socialActionChildrenTitle, SocialIssue $socialIssue): SocialAction - { - if (null !== $socialActionChildrenTitle) { - /** @var SocialAction $socialActionChildren */ - $socialActionChildren = $this->getOrCreateEntity($this->socialActionRepository, 'title', ['fr' => $socialActionChildrenTitle]); - $socialActionChildren->setTitle(['fr' => $socialActionChildrenTitle]); - - $this->entityManager->persist($socialActionChildren); + /** + * @throws Exception + * + * @return array + */ + private function handleSocialAction( + ?string $socialActionTitle, + ?string $socialActionChildTitle, + SocialIssue $socialIssue, + ?SocialAction $previousSocialAction, + ?SocialAction $previousSocialActionChild + ): array { + if (null === $socialActionTitle) { + return [ + 'socialAction' => null, + 'socialActionChild' => null, + ]; } - /** @var SocialIssue $socialIssue */ - $socialAction = $this->getOrCreateEntity($this->socialActionRepository, 'title', ['fr' => $socialActionTitle]); - $socialAction->setTitle(['fr' => $socialActionTitle]); + $return = []; - if (null !== $socialActionChildrenTitle) { - $socialActionChildren->setIssue($socialIssue); - $this->entityManager->persist($socialActionChildren); - - $socialAction->addChild($socialActionChildren); + if (null !== $previousSocialAction && ($previousSocialAction->getTitle()['fr'] === $socialActionTitle)) { + $return = [ + 'socialAction' => $parent = $previousSocialAction, + ]; + $parentIsSame = true; } else { - $socialAction->setIssue($socialIssue); + $return['socialAction'] = $parent = (new SocialAction())->setTitle(['fr' => $socialActionTitle]); + $parent->setIssue($socialIssue); + $this->entityManager->persist($parent); + $parentIsSame = false; } - $this->entityManager->persist($socialAction); + if (null === $socialActionChildTitle) { + $return['socialActionChild'] = null; + } elseif ($parentIsSame && null !== $previousSocialActionChild && $previousSocialActionChild->getTitle()['fr'] === $socialActionChildTitle) { + $return['socialActionChild'] = $previousSocialActionChild; + } else { + $return['socialActionChild'] = $child = (new SocialAction())->setTitle(['fr' => $socialActionChildTitle]); + $parent->addChild($child); + $this->entityManager->persist($child); + } - return null === $socialActionChildrenTitle ? $socialAction : $socialActionChildren; + return $return; } - private function handleSocialIssue(?string $socialIssueTitle = null, ?string $socialIssueChildrenTitle = null): SocialIssue - { - if (null !== $socialIssueChildrenTitle) { - /** @var SocialIssue $socialIssueChildren */ - $socialIssueChildren = $this->getOrCreateEntity($this->socialIssueRepository, 'title', ['fr' => $socialIssueChildrenTitle]); - $socialIssueChildren->setTitle(['fr' => $socialIssueChildrenTitle]); + /** + * @throws Exception + * + * @return array + */ + private function handleSocialIssue( + ?string $socialIssueTitle, + ?string $socialIssueChildTitle, + ?SocialIssue $previousSocialIssue, + ?SocialIssue $previousSocialIssueChild + ): array { + $return = []; - $this->entityManager->persist($socialIssueChildren); + if (null !== $previousSocialIssue && ($previousSocialIssue->getTitle()['fr'] === $socialIssueTitle)) { + $return = [ + 'socialIssue' => $parent = $previousSocialIssue, + ]; + $parentIsSame = true; + } elseif (null !== $socialIssueTitle) { + $return['socialIssue'] = $parent = (new SocialIssue())->setTitle(['fr' => $socialIssueTitle]); + $this->entityManager->persist($parent); + $parentIsSame = false; + } else { + return [ + 'socialIssue' => null, + 'socialIssueChild' => null, + ]; } - /** @var SocialIssue $socialIssue */ - $socialIssue = $this->getOrCreateEntity($this->socialIssueRepository, 'title', ['fr' => $socialIssueTitle]); - $socialIssue->setTitle(['fr' => $socialIssueTitle]); - - if (null !== $socialIssueChildrenTitle) { - $socialIssue->addChild($socialIssueChildren); + if ($parentIsSame && null !== $previousSocialIssueChild && ($previousSocialIssueChild->getTitle()['fr'] === $socialIssueChildTitle)) { + $return['socialIssueChild'] = $previousSocialIssueChild; + } elseif (null !== $socialIssueChildTitle) { + $return['socialIssueChild'] = $child = (new SocialIssue())->setTitle(['fr' => $socialIssueChildTitle]); + $parent->addChild($child); + $this->entityManager->persist($child); + } else { + $return['socialIssueChild'] = null; } - $this->entityManager->persist($socialIssue); - - return null === $socialIssueChildrenTitle ? $socialIssue : $socialIssueChildren; + return $return; } - private function import1(array $row): void + /** + * Row Structure:. + * + * Index 0: Parent SocialIssue + * Index 1: Child SocialIssue + * Index 2: Parent SocialAction + * Index 3: Child SocialAction + * Index 4: Goal + * Index 5: Result + * Index 6: Evaluation + * + * @param array $row + * @param array|SocialIssue|string, SocialAction|null>|Evaluation|Goal|Result> $previousRow + * + * @throws Exception + * + * @return array|SocialIssue|string, SocialAction|null>|Evaluation|Goal|Result> + */ + private function import1(int $key, array $row, array $previousRow): array { - // Structure: - // Index 0: SocialIssue.parent - // Index 1: SocialIssue - // Index 2: SocialAction.parent - // Index 3: SocialAction - // Index 4: Goal - // Index 5: Result - // Index 6: Evaluation + $socialIssues = $this + ->handleSocialIssue( + $row[0], + $row[1], + $previousRow['socialIssues']['socialIssue'] ?? null, + $previousRow['socialIssues']['socialIssueChild'] ?? null + ); - $socialIssue = $this->handleSocialIssue($row[0], $row[1]); + $socialIssue = $socialIssues['socialIssueChild'] ?? $socialIssues['socialIssue']; - $socialAction = $this->handleSocialAction($row[2], $row[3], $socialIssue); + if (null === $socialIssue) { + throw new Exception(sprintf("no social issue on row {$key}, values: %s", implode(', ', $row))); + } - $goal = $this->handleGoal($row[4], $socialAction); + $socialActions = $this + ->handleSocialAction( + $row[2], + $row[3], + $socialIssues['socialIssue'] ?? $socialIssues, + $previousRow['socialActions']['socialAction'] ?? null, + $previousRow['socialActions']['socialActionChild'] ?? null + ); - $result = $this->handleResult($row[5], $socialAction, $goal); + $socialAction = $socialActions['socialActionChild'] ?? $socialActions['socialAction']; - $eval = $this->handleEvaluation($row[6], $socialAction); + if (null !== $socialAction) { + $goal = $this->handleGoal($row[4], $socialAction); + $result = $this->handleResult($row[5], $socialActions['socialAction'], $goal); + $eval = $this->handleEvaluation($row[6], $socialActions['socialAction']); + } $this->entityManager->flush(); + + return [ + 'socialIssues' => $socialIssues, + 'socialActions' => $socialActions, + 'goal' => $goal ?? null, + 'result' => $result ?? null, + 'eval' => $eval ?? null, + ]; } }