diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php b/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php index 40d7068ce..4b8d87180 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php @@ -4,6 +4,9 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; use Chill\MainBundle\Pagination\PaginatorInterface; +use Chill\PersonBundle\Entity\SocialWork\SocialIssue; +use Doctrine\ORM\QueryBuilder; +use Generator; use Symfony\Component\HttpFoundation\Request; class SocialIssueApiController extends ApiController @@ -18,4 +21,41 @@ class SocialIssueApiController extends ApiController ); $query->setParameter('now', new \DateTimeImmutable()); } + + protected function getQueryResult(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, QueryBuilder $queryBuilder): array + { + // Create a lazy generator to avoid performance issues. + $generator = $this->buildRecursively( + $queryBuilder->getQuery()->getResult(), + static fn (SocialIssue $socialIssue): iterable => $socialIssue->getChildren() + ); + + // Sadly, we must convert the generator into an array... + // so we lose all the performance gain we could have by using an iterator. + $results = []; + + // Reduce the generator into an array containing once each SocialIssue. + foreach ($generator as $socialIssue) { + // If the current item hasn't been seen yet, add it to the resultset. + $results += [$socialIssue->getId() => $socialIssue]; + } + + return $results; + } + + /** + * @param iterable $iterable + * @param callable(SocialIssue): iterable $childrenAccessor + * + * @return Generator + */ + private function buildRecursively(iterable $iterable, callable $childrenAccessor): Generator + { + foreach ($iterable as $item) + { + yield $item; + + yield from $this->buildRecursively($childrenAccessor($item), $childrenAccessor); + } + } }