Attainly/backend/app/Set/UseCases/GetSetLayout/GetSetLayout.php
2026-08-08 23:37:52 +03:00

77 lines
2 KiB
PHP

<?php
namespace App\Set\UseCases\GetSetLayout;
use App\Element\Element;
use App\Element\ElementRepository;
use App\Exceptions\NotFoundException;
use App\Set\SetRepository;
class GetSetLayout
{
public function __construct(
private SetRepository $setRepository,
private ElementRepository $elementRepository,
) {}
/**
* @throws NotFoundException
*/
public function execute(int $setId): SetLayout
{
$set = $this->setRepository->find($setId);
if ($set === null) {
throw new NotFoundException('set not found');
}
$elementsByParentId = [];
foreach ($this->elementRepository->findBySet($set) as $element) {
$parentId = $element->getParentElement()?->getId() ?? 0;
$elementsByParentId[$parentId][] = $element;
}
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);
return new SetLayout(
set: $set,
elements: $this->buildNodes(0, $elementsByParentId),
);
}
/**
* @param array<int, list<Element>> $elementsByParentId
* @return list<ElementLayoutNode>
*/
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;
}
}