[ [ 'name' => 'Genesis', 'children' => [ [ 'name' => 'Creation', 'children' => [ [ 'name' => 'Chapter 1', 'children' => [], ], [ 'name' => 'Chapter 2', 'children' => [], ], ], ], [ 'name' => 'Noah', 'children' => [], ], ], ], [ 'name' => 'Exodus', 'children' => [ [ 'name' => 'Shemot', 'children' => [], ], ], ], ], 'Course' => [ [ 'name' => 'Foundations', 'children' => [ [ 'name' => 'Welcome', 'children' => [], ], [ 'name' => 'Core Concepts', 'children' => [], ], ], ], [ 'name' => 'Applied Practice', 'children' => [ [ 'name' => 'Guided Exercise', 'children' => [], ], [ 'name' => 'Final Review', 'children' => [], ], ], ], ], 'Fitness Program' => [ [ 'name' => 'Foundation Phase', 'children' => [ [ 'name' => 'Strength Day', 'children' => [ [ 'name' => 'Squat', 'children' => [], ], [ 'name' => 'Push-up', 'children' => [], ], ], ], [ 'name' => 'Mobility Day', 'children' => [ [ 'name' => 'Hip Flow', 'children' => [], ], ], ], ], ], [ 'name' => 'Build Phase', 'children' => [ [ 'name' => 'Full Body Circuit', 'children' => [], ], ], ], ], ]; public function run(): void { $elementRepository = app(ElementRepository::class); $setLevelRepository = app(SetLevelRepository::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, levels: $setLevelRepository->findBySet($set), depth: 0, parentElement: null, definitions: $definitions, ); } } /** * @param list * }> $definitions * @param list $levels */ private function seedChildren( ElementRepository $repository, Set $set, array $levels, int $depth, ?Element $parentElement, array $definitions, ): void { if ($definitions === []) { return; } $level = $levels[$depth] ?? null; if ($level === null) { throw new RuntimeException('element level not defined'); } $siblings = $parentElement === null ? $repository->findTopLevelBySet($set) : $repository->findByParentElement($parentElement); foreach ($definitions as $definition) { $element = $this->findSibling( siblings: $siblings, name: $definition['name'], level: $level, ); if ($element === null) { $element = $repository->create(new CreateElementDto( name: $definition['name'], level: $level, parentElement: $parentElement, )); $siblings[] = $element; } $this->seedChildren( repository: $repository, set: $set, levels: $levels, depth: $depth + 1, parentElement: $element, definitions: $definition['children'], ); } } /** * @param list $siblings */ private function findSibling( array $siblings, string $name, SetLevel $level, ): ?Element { foreach ($siblings as $sibling) { if ( $sibling->getName() === $name && $sibling->getLevel()->getId() === $level->getId() ) { return $sibling; } } return null; } }