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,217 @@
<?php
namespace Database\Seeders;
use App\Element\CreateElementDto;
use App\Element\Element;
use App\Element\ElementRepository;
use App\Set\Set;
use App\Set\SetRepository;
use Illuminate\Database\Seeder;
class ElementSeeder extends Seeder
{
private const array ELEMENTS_BY_SET = [
'Bible' => [
[
'name' => 'Genesis',
'kind' => 'book',
'children' => [
[
'name' => 'Creation',
'kind' => 'portion',
'children' => [
[
'name' => 'Chapter 1',
'kind' => 'chapter',
'children' => [],
],
[
'name' => 'Chapter 2',
'kind' => 'chapter',
'children' => [],
],
],
],
[
'name' => 'Noah',
'kind' => 'portion',
'children' => [],
],
],
],
[
'name' => 'Exodus',
'kind' => 'book',
'children' => [
[
'name' => 'Shemot',
'kind' => 'portion',
'children' => [],
],
],
],
],
'Course' => [
[
'name' => 'Foundations',
'kind' => 'module',
'children' => [
[
'name' => 'Welcome',
'kind' => 'lesson',
'children' => [],
],
[
'name' => 'Core Concepts',
'kind' => 'lesson',
'children' => [],
],
],
],
[
'name' => 'Applied Practice',
'kind' => 'module',
'children' => [
[
'name' => 'Guided Exercise',
'kind' => 'lesson',
'children' => [],
],
[
'name' => 'Final Review',
'kind' => 'lesson',
'children' => [],
],
],
],
],
'Fitness Program' => [
[
'name' => 'Foundation Phase',
'kind' => 'phase',
'children' => [
[
'name' => 'Strength Day',
'kind' => 'workout',
'children' => [
[
'name' => 'Squat',
'kind' => 'exercise',
'children' => [],
],
[
'name' => 'Push-up',
'kind' => 'exercise',
'children' => [],
],
],
],
[
'name' => 'Mobility Day',
'kind' => 'workout',
'children' => [
[
'name' => 'Hip Flow',
'kind' => 'exercise',
'children' => [],
],
],
],
],
],
[
'name' => 'Build Phase',
'kind' => 'phase',
'children' => [
[
'name' => 'Full Body Circuit',
'kind' => 'workout',
'children' => [],
],
],
],
],
];
public function run(): void
{
$elementRepository = app(ElementRepository::class);
foreach (app(SetRepository::class)->all() as $set) {
$definitions = self::ELEMENTS_BY_SET[$set->getName()] ?? null;
if ($definitions === null) {
continue;
}
$this->seedChildren(
repository: $elementRepository,
set: $set,
parentElement: null,
definitions: $definitions,
);
}
}
/**
* @param list<array{
* name: string,
* kind: string,
* children: list<mixed>
* }> $definitions
*/
private function seedChildren(
ElementRepository $repository,
Set $set,
?Element $parentElement,
array $definitions,
): void {
$siblings = $parentElement === null
? $repository->findTopLevelBySet($set)
: $repository->findByParentElement($parentElement);
foreach ($definitions as $definition) {
$element = $this->findSibling(
siblings: $siblings,
name: $definition['name'],
kind: $definition['kind'],
);
if ($element === null) {
$element = $repository->create(new CreateElementDto(
set: $set,
name: $definition['name'],
kind: $definition['kind'],
parentElement: $parentElement,
));
$siblings[] = $element;
}
$this->seedChildren(
repository: $repository,
set: $set,
parentElement: $element,
definitions: $definition['children'],
);
}
}
/**
* @param list<Element> $siblings
*/
private function findSibling(
array $siblings,
string $name,
string $kind,
): ?Element {
foreach ($siblings as $sibling) {
if (
$sibling->getName() === $name
&& $sibling->getKind() === $kind
) {
return $sibling;
}
}
return null;
}
}