diff --git a/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php b/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php index d28c7af09..0bd9505a6 100644 --- a/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php +++ b/src/Bundle/ChillMainBundle/Doctrine/ORM/Hydration/FlatHierarchyEntityHydrator.php @@ -11,44 +11,38 @@ final class FlatHierarchyEntityHydrator extends ObjectHydrator { public const LIST = 'chill_flat_hierarchy_list'; - protected function hydrateAllData(): array + protected function hydrateAllData() { - $generator = $this->buildRecursively( - parent::hydrateAllData(), - static function($value): iterable { - $children = $value->getChildren(); - - $children->setInitialized(true); - - return $children; - } - ); - - $result = []; - - foreach ($generator as $entity) { - // We cannot expect anything from the object entity - // so, we cannot expect it to have a ::getId() method. - // So we use spl_object_hash() instead. - $result += [spl_object_hash($entity) => $entity]; - } - - return array_values($result); + return array_values(iterator_to_array($this->flatListGenerator($this->buildChildrenHashmap(parent::hydrateAllData())))); } - /** - * @param iterable $iterable - * @param callable(SocialIssue): iterable $childrenAccessor - * - * @return Generator - */ - private function buildRecursively(iterable $iterable, callable $childrenAccessor): Generator + private function flatListGenerator(array $hashMap, $parent = null): Generator { - foreach ($iterable as $item) - { - yield $item; + $parent = null === $parent ? + null : + spl_object_hash($parent); - yield from $this->buildRecursively($childrenAccessor($item), $childrenAccessor); + $hashMap += [$parent => []]; + + foreach ($hashMap[$parent] as $node) { + yield $node->getId() => $node; + yield from $this->flatListGenerator($hashMap, $node); } } + + private function buildChildrenHashmap(array $nodes): array + { + $r = []; + + foreach ($nodes as $node) { + $parentId = (null !== $parent = $node->getParent()) + ? spl_object_hash($parent) + : null; + + $r[$parentId][] = $node; + } + + return $r; + } + }