add set layout api

This commit is contained in:
Yisroel Baum 2026-08-08 23:32:45 +03:00
parent eb7ac7d261
commit 4222d4c0a2
Signed by: yisroelbaum
GPG key ID: 0FA60884F75520A9
16 changed files with 487 additions and 6 deletions

View file

@ -0,0 +1,29 @@
<?php
namespace App\Set\UseCases\GetSetLayout;
use App\Element\Element;
final readonly class ElementLayoutNode
{
/**
* @param list<ElementLayoutNode> $children
*/
public function __construct(
private Element $element,
private array $children,
) {}
public function getElement(): Element
{
return $this->element;
}
/**
* @return list<ElementLayoutNode>
*/
public function getChildren(): array
{
return $this->children;
}
}

View file

@ -0,0 +1,77 @@
<?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;
}
}

View file

@ -0,0 +1,29 @@
<?php
namespace App\Set\UseCases\GetSetLayout;
use App\Set\Set;
final readonly class SetLayout
{
/**
* @param list<ElementLayoutNode> $elements
*/
public function __construct(
private Set $set,
private array $elements,
) {}
public function getSet(): Set
{
return $this->set;
}
/**
* @return list<ElementLayoutNode>
*/
public function getElements(): array
{
return $this->elements;
}
}