socialIssueRepository = $socialIssueRepository; $this->socialActionRepository = $socialActionRepository; $this->goalRepository = $goalRepository; $this->resultRepository = $resultRepository; $this->evaluationRepository = $evaluationRepository; $this->entityManager = $entityManager; } 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) ) ); } return true; } private function import1(array $row): void { // Structure: // Index 0: SocialIssue.parent // Index 1: SocialIssue // Index 2: SocialAction.parent // Index 3: SocialAction // Index 4: Goal // Index 5: Result // Index 6: Evaluation $socialIssue = $this->handleSocialIssue($row[0], $row[1]); $socialAction = $this->handleSocialAction($row[2], $row[3], $socialIssue); $goal = $this->handleGoal($row[4], $socialAction); $result = $this->handleResult($row[5], $socialAction, $goal); $eval = $this->handleEvaluation($row[6], $socialAction); $this->entityManager->flush(); } 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]); $this->entityManager->persist($socialIssueChildren); } /** @var SocialIssue $socialIssue */ $socialIssue = $this->getOrCreateEntity($this->socialIssueRepository, 'title', ['fr' => $socialIssueTitle]); $socialIssue->setTitle(['fr' => $socialIssueTitle]); if (null !== $socialIssueChildrenTitle) { $socialIssue->addChild($socialIssueChildren); } $this->entityManager->persist($socialIssue); return null === $socialIssueChildrenTitle ? $socialIssue : $socialIssueChildren; } 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); } /** @var SocialIssue $socialIssue */ $socialAction = $this->getOrCreateEntity($this->socialActionRepository, 'title', ['fr' => $socialActionTitle]); $socialAction->setTitle(['fr' => $socialActionTitle]); if (null !== $socialActionChildrenTitle) { $socialActionChildren->setIssue($socialIssue); $this->entityManager->persist($socialActionChildren); $socialAction->addChild($socialActionChildren); } else { $socialAction->setIssue($socialIssue); } $this->entityManager->persist($socialAction); return null === $socialActionChildrenTitle ? $socialAction : $socialActionChildren; } private function handleGoal(?string $goalTitle = null, ?SocialAction $socialAction = null): ?Goal { if (null === $goalTitle) { return null; } /** @var Goal $goal */ $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); } $this->entityManager->persist($goal); return $goal; } private function handleResult(?string $resultTitle = null, ?SocialAction $socialAction = null, ?Goal $goal = null): ?Result { if (null === $resultTitle) { return null; } /** @var Result $result */ $result = $this->getOrCreateEntity($this->resultRepository, 'title', ['fr' => $resultTitle]); $result->setTitle(['fr' => $resultTitle]); if (null !== $goal) { $result->addGoal($goal); $goal->addResult($result); $this->entityManager->persist($goal); } else { $result->addSocialAction($socialAction); } $result->addSocialAction($socialAction); $socialAction->addResult($result); $this->entityManager->persist($result); $this->entityManager->persist($socialAction); return $result; } private function handleEvaluation(?string $evaluationTitle, SocialAction $socialAction): ?Evaluation { if (null === $evaluationTitle) { return null; } /** @var Evaluation $eval */ $eval = $this->getOrCreateEntity($this->evaluationRepository, 'title', ['fr' => $evaluationTitle]); $eval->setTitle(['fr' => $evaluationTitle]); $eval->setSocialAction($socialAction); $this->entityManager->persist($eval); return $eval; } private function findByJson(ObjectRepository $repository, string $field, array $jsonCriterias): array { $qb = $this ->entityManager ->createQueryBuilder() ->select('s') ->from($repository->getClassName(), 's'); $expr = $qb->expr(); $temporaryJsonCriterias = $jsonParameters = []; foreach ($jsonCriterias as $key => $value) { $temporaryJsonCriterias[] = [$field, $key, $value, sprintf(':placeholder_%s_%s', $field, $key)]; } $jsonParameters = array_reduce( $temporaryJsonCriterias, static function (array $carry, array $row): array { [,, $value, $placeholder] = $row; return array_merge( $carry, [ $placeholder => sprintf('"%s"', $value), ] ); }, [] ); $jsonPredicates = array_map( static function (array $row) use ($expr): Comparison { [$field, $key,, $placeholder] = $row; $left = sprintf( "GET_JSON_FIELD_BY_KEY(s.%s, '%s')", $field, $key ); return $expr ->eq( $left, $placeholder ); }, $temporaryJsonCriterias ); $query = $qb ->select('s') ->where(...$jsonPredicates) ->setParameters($jsonParameters) ->getQuery(); return $query->getResult(); } private function getOrCreateEntity(ObjectRepository $repository, string $field, array $jsonCriterias = []) { $results = $this ->findByJson( $repository, $field, $jsonCriterias ); 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 $entity; } }