diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 6826f854c..1637ee098 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -32,9 +32,8 @@ use Chill\MainBundle\Doctrine\DQL\JsonAggregate; use Chill\MainBundle\Doctrine\DQL\JsonbExistsInArray; use Chill\MainBundle\Doctrine\DQL\Similarity; use Chill\MainBundle\Doctrine\DQL\OverlapsI; -use Symfony\Component\DependencyInjection\Definition; -use Symfony\Component\DependencyInjection\Reference; use Chill\MainBundle\Doctrine\DQL\Replace; +use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator; use Chill\MainBundle\Doctrine\Type\NativeDateIntervalType; use Chill\MainBundle\Doctrine\Type\PointType; use Symfony\Component\HttpFoundation\Request; @@ -186,6 +185,9 @@ class ChillMainExtension extends Extension implements PrependExtensionInterface, 'OVERLAPSI' => OverlapsI::class, ], ], + 'hydrators' => [ + 'chill_flat_hierarchy_list' => FlatHierarchyEntityHydrator::class, + ], ], ], ); diff --git a/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php b/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php new file mode 100644 index 000000000..c389b543d --- /dev/null +++ b/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php @@ -0,0 +1,47 @@ +flatListGenerator($this->buildChildrenHashmap(parent::hydrateAllData())))); + } + + private function flatListGenerator(array $hashMap, ?object $parent = null): Generator + { + $parent = null === $parent ? null : spl_object_id($parent); + $hashMap += [$parent => []]; + + foreach ($hashMap[$parent] as $node) { + yield spl_object_id($node) => $node; + yield from $this->flatListGenerator($hashMap, $node); + } + } + + private function buildChildrenHashmap(array $nodes): array + { + return array_reduce( + $nodes, + static function (array $collect, $node): array { + $parentId = (null === $parent = $node->getParent()) ? + null : + spl_object_id($parent); + + $collect[$parentId][] = $node; + + return $collect; + }, + [] + ); + } + +} diff --git a/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php b/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php index 40d7068ce..c1d251efb 100644 --- a/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php +++ b/src/Bundle/ChillPersonBundle/Controller/SocialIssueApiController.php @@ -3,8 +3,12 @@ namespace Chill\PersonBundle\Controller; use Chill\MainBundle\CRUD\Controller\ApiController; +use Chill\MainBundle\Doctrine\ORM\Hydration\FlatHierarchyEntityHydrator; use Chill\MainBundle\Pagination\PaginatorInterface; +use DateTimeImmutable; +use Doctrine\ORM\Query; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; class SocialIssueApiController extends ApiController { @@ -16,6 +20,25 @@ class SocialIssueApiController extends ApiController $query->expr()->isNull('e.desactivationDate') ) ); - $query->setParameter('now', new \DateTimeImmutable()); + $query->setParameter('now', new DateTimeImmutable()); + } + + protected function getQueryResult(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query) + { + // In order to work, this hydrator only works with + // entities having the field "children" set up. + return $query + ->getQuery() + ->setHint(Query::HINT_INCLUDE_META_COLUMNS, true) + ->getResult(FlatHierarchyEntityHydrator::LIST); + } + + protected function onPostIndexBuildQuery(string $action, Request $request, string $_format, int $totalItems, PaginatorInterface $paginator, $query): ?Response + { + $query + ->orderBy("GET_JSON_FIELD_BY_KEY(e.title, :locale)", 'ASC') + ->setParameter(':locale', $request->getLocale()); + + return null; } }