setRepository->find($request->setId); if ($set === null) { throw new NotFoundException('set not found'); } $elements = $this->elementRepository->findBySet($set); $elementsByParentId = []; $elementCountsByLevelId = []; foreach ($elements as $element) { $parentId = $element->getParentElement()?->getId() ?? 0; $elementsByParentId[$parentId][] = $element; $levelId = $element->getLevel()->getId(); $elementCountsByLevelId[$levelId] = ($elementCountsByLevelId[$levelId] ?? 0) + 1; } foreach ($elementsByParentId as &$siblings) { usort($siblings, function ( Element $first, Element $second, ): int { $positionComparison = $first->getPosition() <=> $second->getPosition(); if ($positionComparison !== 0) { return $positionComparison; } return $first->getId() <=> $second->getId(); }); } unset($siblings); $layoutLevels = []; foreach ($this->setLevelRepository->findBySet($set) as $level) { $layoutLevels[] = new SetLayoutLevel( level: $level, elementCount: $elementCountsByLevelId[$level->getId()] ?? 0, ); } return new SetLayout( set: $set, levels: $layoutLevels, elements: $this->buildNodes(0, $elementsByParentId), ); } /** * @param array> $elementsByParentId * @return list */ private function buildNodes( int $parentId, array $elementsByParentId, ): array { $nodes = []; foreach ($elementsByParentId[$parentId] ?? [] as $element) { $nodes[] = new ElementLayoutNode( element: $element, children: $this->buildNodes( $element->getId(), $elementsByParentId, ), ); } return $nodes; } }