Sort entities recursively.

This commit is contained in:
Pol Dellaiera 2021-06-29 13:54:01 +02:00
parent c37b98cecd
commit c25c302466

View File

@ -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<int, SocialIssue> $iterable
* @param callable(SocialIssue): iterable<int, SocialIssue> $childrenAccessor
*
* @return Generator<int, SocialIssue>
*/
private function buildRecursively(iterable $iterable, callable $childrenAccessor): Generator
{
foreach ($iterable as $item)
{
yield $item;
yield from $this->buildRecursively($childrenAccessor($item), $childrenAccessor);
}
}
}