Merge branch 'fix/236-update-social-work-metadata-importer' into 'master'

Update Social Work Metadata importer

Closes champs-libres/departement-de-la-vendee/chill#236

See merge request Chill-Projet/chill-bundles!190
This commit is contained in:
Julien Fastré 2021-12-13 12:49:03 +00:00
commit 2bafdd9e62
3 changed files with 191 additions and 97 deletions

View File

@ -98,7 +98,7 @@ class SocialAction
{ {
if (!$this->children->contains($child)) { if (!$this->children->contains($child)) {
$this->children[] = $child; $this->children[] = $child;
$child->setParent($this); $child->setParent($this)->setIssue($this->getIssue());
} }
return $this; return $this;
@ -266,9 +266,16 @@ class SocialAction
{ {
$this->issue = $issue; $this->issue = $issue;
foreach ($this->getChildren() as $child) {
$child->setIssue($issue);
}
return $this; return $this;
} }
/**
* @internal use $parent->addChild() instead (@see{self::addChild()})
*/
public function setParent(?self $parent): self public function setParent(?self $parent): self
{ {
$this->parent = $parent; $this->parent = $parent;

View File

@ -305,6 +305,9 @@ class SocialIssue
return $this; return $this;
} }
/**
* @internal use @see{SocialIssue::addChild()} instead
*/
public function setParent(?self $parent): self public function setParent(?self $parent): self
{ {
$this->parent = $parent; $this->parent = $parent;

View File

@ -57,20 +57,45 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$this->entityManager = $entityManager; $this->entityManager = $entityManager;
} }
/**
* @throws Exception
*/
public function import(iterable $dataset): bool public function import(iterable $dataset): bool
{ {
foreach ($dataset as $row) { // Initialisation of the previous result row with the proper data structure.
$this->import1( $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( array_map(
static fn (string $column): ?string => '' === $column ? null : $column, static fn (string $column): ?string => '' === $column ? null : $column,
array_map('trim', $row) array_map('trim', $row)
) ),
$result
); );
} }
return true; return true;
} }
/**
* @return array<int, object>
*/
private function findByJson(ObjectRepository $repository, string $field, array $jsonCriterias): array private function findByJson(ObjectRepository $repository, string $field, array $jsonCriterias): array
{ {
$qb = $this $qb = $this
@ -81,7 +106,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$expr = $qb->expr(); $expr = $qb->expr();
$temporaryJsonCriterias = $jsonParameters = []; $temporaryJsonCriterias = [];
foreach ($jsonCriterias as $key => $value) { foreach ($jsonCriterias as $key => $value) {
$temporaryJsonCriterias[] = [$field, $key, $value, sprintf(':placeholder_%s_%s', $field, $key)]; $temporaryJsonCriterias[] = [$field, $key, $value, sprintf(':placeholder_%s_%s', $field, $key)];
@ -121,15 +146,19 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$temporaryJsonCriterias $temporaryJsonCriterias
); );
$query = $qb return $qb
->select('s') ->select('s')
->where(...$jsonPredicates) ->where(...$jsonPredicates)
->setParameters($jsonParameters) ->setParameters($jsonParameters)
->getQuery(); ->getQuery()
->getResult();
return $query->getResult();
} }
/**
* @throws Exception
*
* @return object
*/
private function getOrCreateEntity(ObjectRepository $repository, string $field, array $jsonCriterias = []) private function getOrCreateEntity(ObjectRepository $repository, string $field, array $jsonCriterias = [])
{ {
$results = $this $results = $this
@ -139,36 +168,21 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$jsonCriterias $jsonCriterias
); );
$entity = null; if ([] === $results) {
switch (true) {
case count($results) === 0:
$entity = $repository->getClassName(); $entity = $repository->getClassName();
$entity = new $entity();
break; return new $entity();
}
case count($results) === 1: if (count($results) === 1) {
$entity = current($results); return reset($results);
}
break;
case count($results) > 1:
throw new Exception( throw new Exception(
sprintf( 'Unable to create entity.'
'More than one entity(%s) found.',
$repository->getClassName()
)
); );
} }
if (null === $entity) {
throw new Exception('Unable to create entity.');
}
return $entity;
}
private function handleEvaluation(?string $evaluationTitle, SocialAction $socialAction): ?Evaluation private function handleEvaluation(?string $evaluationTitle, SocialAction $socialAction): ?Evaluation
{ {
if (null === $evaluationTitle) { if (null === $evaluationTitle) {
@ -185,7 +199,7 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
return $eval; return $eval;
} }
private function handleGoal(?string $goalTitle = null, ?SocialAction $socialAction = null): ?Goal private function handleGoal(?string $goalTitle, SocialAction $socialAction): ?Goal
{ {
if (null === $goalTitle) { if (null === $goalTitle) {
return null; return null;
@ -195,19 +209,16 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$goal = $this->getOrCreateEntity($this->goalRepository, 'title', ['fr' => $goalTitle]); $goal = $this->getOrCreateEntity($this->goalRepository, 'title', ['fr' => $goalTitle]);
$goal->setTitle(['fr' => $goalTitle]); $goal->setTitle(['fr' => $goalTitle]);
if (null !== $socialAction) {
$socialAction->addGoal($goal); $socialAction->addGoal($goal);
$goal->addSocialAction($socialAction); $goal->addSocialAction($socialAction);
$this->entityManager->persist($socialAction); //$this->entityManager->persist($socialAction);
}
$this->entityManager->persist($goal); $this->entityManager->persist($goal);
return $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) { if (null === $resultTitle) {
return null; return null;
@ -224,89 +235,162 @@ final class SocialWorkMetadata implements SocialWorkMetadataInterface
$this->entityManager->persist($goal); $this->entityManager->persist($goal);
} else { } else {
$result->addSocialAction($socialAction); $result->addSocialAction($socialAction);
$socialAction->addResult($result);
} }
$result->addSocialAction($socialAction);
$socialAction->addResult($result);
$this->entityManager->persist($result); $this->entityManager->persist($result);
$this->entityManager->persist($socialAction); //$this->entityManager->persist($socialAction);
return $result; return $result;
} }
private function handleSocialAction(?string $socialActionTitle, ?string $socialActionChildrenTitle, SocialIssue $socialIssue): SocialAction /**
{ * @throws Exception
if (null !== $socialActionChildrenTitle) { *
/** @var SocialAction $socialActionChildren */ * @return array<string, SocialAction|null>
$socialActionChildren = $this->getOrCreateEntity($this->socialActionRepository, 'title', ['fr' => $socialActionChildrenTitle]); */
$socialActionChildren->setTitle(['fr' => $socialActionChildrenTitle]); private function handleSocialAction(
?string $socialActionTitle,
$this->entityManager->persist($socialActionChildren); ?string $socialActionChildTitle,
SocialIssue $socialIssue,
?SocialAction $previousSocialAction,
?SocialAction $previousSocialActionChild
): array {
if (null === $socialActionTitle) {
return [
'socialAction' => null,
'socialActionChild' => null,
];
} }
/** @var SocialIssue $socialIssue */ $return = [];
$socialAction = $this->getOrCreateEntity($this->socialActionRepository, 'title', ['fr' => $socialActionTitle]);
$socialAction->setTitle(['fr' => $socialActionTitle]);
if (null !== $socialActionChildrenTitle) { if (null !== $previousSocialAction && ($previousSocialAction->getTitle()['fr'] === $socialActionTitle)) {
$socialActionChildren->setIssue($socialIssue); $return = [
$this->entityManager->persist($socialActionChildren); 'socialAction' => $parent = $previousSocialAction,
];
$socialAction->addChild($socialActionChildren); $parentIsSame = true;
} else { } 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;
return null === $socialActionChildrenTitle ? $socialAction : $socialActionChildren; } 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);
} }
private function handleSocialIssue(?string $socialIssueTitle = null, ?string $socialIssueChildrenTitle = null): SocialIssue return $return;
}
/**
* @throws Exception
*
* @return array<string, SocialIssue|null>
*/
private function handleSocialIssue(
?string $socialIssueTitle,
?string $socialIssueChildTitle,
?SocialIssue $previousSocialIssue,
?SocialIssue $previousSocialIssueChild
): array {
$return = [];
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,
];
}
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;
}
return $return;
}
/**
* 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<int, ?string> $row
* @param array<string, array<string, <|array|null>|SocialIssue|string, SocialAction|null>|Evaluation|Goal|Result> $previousRow
*
* @throws Exception
*
* @return array<string, array<string, <|array|null>|SocialIssue|string, SocialAction|null>|Evaluation|Goal|Result>
*/
private function import1(int $key, array $row, array $previousRow): array
{ {
if (null !== $socialIssueChildrenTitle) { $socialIssues = $this
/** @var SocialIssue $socialIssueChildren */ ->handleSocialIssue(
$socialIssueChildren = $this->getOrCreateEntity($this->socialIssueRepository, 'title', ['fr' => $socialIssueChildrenTitle]); $row[0],
$socialIssueChildren->setTitle(['fr' => $socialIssueChildrenTitle]); $row[1],
$previousRow['socialIssues']['socialIssue'] ?? null,
$previousRow['socialIssues']['socialIssueChild'] ?? null
);
$this->entityManager->persist($socialIssueChildren); $socialIssue = $socialIssues['socialIssueChild'] ?? $socialIssues['socialIssue'];
if (null === $socialIssue) {
throw new Exception(sprintf("no social issue on row {$key}, values: %s", implode(', ', $row)));
} }
/** @var SocialIssue $socialIssue */ $socialActions = $this
$socialIssue = $this->getOrCreateEntity($this->socialIssueRepository, 'title', ['fr' => $socialIssueTitle]); ->handleSocialAction(
$socialIssue->setTitle(['fr' => $socialIssueTitle]); $row[2],
$row[3],
$socialIssues['socialIssue'] ?? $socialIssues,
$previousRow['socialActions']['socialAction'] ?? null,
$previousRow['socialActions']['socialActionChild'] ?? null
);
if (null !== $socialIssueChildrenTitle) { $socialAction = $socialActions['socialActionChild'] ?? $socialActions['socialAction'];
$socialIssue->addChild($socialIssueChildren);
}
$this->entityManager->persist($socialIssue);
return null === $socialIssueChildrenTitle ? $socialIssue : $socialIssueChildren;
}
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);
if (null !== $socialAction) {
$goal = $this->handleGoal($row[4], $socialAction); $goal = $this->handleGoal($row[4], $socialAction);
$result = $this->handleResult($row[5], $socialActions['socialAction'], $goal);
$result = $this->handleResult($row[5], $socialAction, $goal); $eval = $this->handleEvaluation($row[6], $socialActions['socialAction']);
}
$eval = $this->handleEvaluation($row[6], $socialAction);
$this->entityManager->flush(); $this->entityManager->flush();
return [
'socialIssues' => $socialIssues,
'socialActions' => $socialActions,
'goal' => $goal ?? null,
'result' => $result ?? null,
'eval' => $eval ?? null,
];
} }
} }