[ 'Bereishis' => 50, 'Shemos' => 40, 'Vayikra' => 27, 'Bamidbar' => 36, 'Devarim' => 34, ], "Nevi'im" => [ 'Yehoshua' => 24, 'Shoftim' => 21, 'Shmuel Alef' => 31, 'Shmuel Beis' => 24, 'Melachim Alef' => 22, 'Melachim Beis' => 25, 'Yeshayahu' => 66, 'Yirmiyahu' => 52, 'Yechezkel' => 48, 'Hoshea' => 14, 'Yoel' => 4, 'Amos' => 9, 'Ovadiah' => 1, 'Yonah' => 4, 'Michah' => 7, 'Nachum' => 3, 'Chavakuk' => 3, 'Tzefaniah' => 3, 'Chaggai' => 2, 'Zechariah' => 14, 'Malachi' => 3, ], 'Kesuvim' => [ 'Tehillim' => 150, 'Mishlei' => 31, 'Iyov' => 42, 'Shir HaShirim' => 8, 'Rus' => 4, 'Eichah' => 5, 'Koheles' => 12, 'Esther' => 10, 'Daniel' => 12, 'Ezra' => 10, 'Nechemiah' => 13, 'Divrei HaYamim Alef' => 29, 'Divrei HaYamim Beis' => 36, ], ]; public function run(): void { $this->call(UserSeeder::class); $user = app(UserRepository::class)->findByEmail( new EmailAddress(UserSeeder::EMAIL), ); if ($user === null) { throw new RuntimeException('seeded user not found'); } $setRepository = app(SetRepository::class); $tanach = $this->findTanach($setRepository); if ($tanach === null) { $tanach = $setRepository->create(new CreateSetDto( name: self::SET_NAME, creator: $user, )); } $levels = $this->seedLevels( repository: app(SetLevelRepository::class), tanach: $tanach, ); $this->seedElements( repository: app(ElementRepository::class), tanach: $tanach, levels: $levels, ); } private function findTanach(SetRepository $repository): ?Set { foreach ($repository->all() as $set) { if ($set->getName() === self::SET_NAME) { return $set; } } return null; } /** * @return array{ * chelek: SetLevel, * sefer: SetLevel, * perek: SetLevel * } */ private function seedLevels( SetLevelRepository $repository, Set $tanach, ): array { $levels = $repository->findBySet($tanach); foreach ($levels as $depth => $level) { $expectedKind = self::LEVEL_KINDS[$depth] ?? null; if ($level->getKind() !== $expectedKind) { throw new RuntimeException( 'Tanach levels do not match the expected hierarchy', ); } } $missingKinds = array_slice(self::LEVEL_KINDS, count($levels)); foreach ($missingKinds as $kind) { $levels[] = $repository->create(new CreateSetLevelDto( set: $tanach, kind: $kind, )); } return [ 'chelek' => $this->findLevel($levels, 'chelek'), 'sefer' => $this->findLevel($levels, 'sefer'), 'perek' => $this->findLevel($levels, 'perek'), ]; } /** * @param list $levels */ private function findLevel(array $levels, string $kind): SetLevel { foreach ($levels as $level) { if ($level->getKind() === $kind) { return $level; } } throw new RuntimeException("Tanach {$kind} level not found"); } /** * @param array{ * chelek: SetLevel, * sefer: SetLevel, * perek: SetLevel * } $levels */ private function seedElements( ElementRepository $repository, Set $tanach, array $levels, ): void { $chelakim = $repository->findTopLevelBySet($tanach); foreach (self::SEFARIM_BY_CHELEK as $chelekName => $sefarim) { $chelek = $this->findOrCreateElement( repository: $repository, siblings: $chelakim, name: $chelekName, level: $levels['chelek'], parentElement: null, ); $seededSefarim = $repository->findByParentElement($chelek); foreach ($sefarim as $seferName => $perekCount) { $sefer = $this->findOrCreateElement( repository: $repository, siblings: $seededSefarim, name: $seferName, level: $levels['sefer'], parentElement: $chelek, ); $perakim = $repository->findByParentElement($sefer); for ( $perekNumber = 1; $perekNumber <= $perekCount; $perekNumber++ ) { $this->findOrCreateElement( repository: $repository, siblings: $perakim, name: "Perek {$perekNumber}", level: $levels['perek'], parentElement: $sefer, ); } } } } /** * @param list $siblings */ private function findOrCreateElement( ElementRepository $repository, array &$siblings, string $name, SetLevel $level, ?Element $parentElement, ): Element { foreach ($siblings as $sibling) { if ( $sibling->getName() === $name && $sibling->getLevel()->getId() === $level->getId() ) { return $sibling; } } $element = $repository->create(new CreateElementDto( name: $name, level: $level, parentElement: $parentElement, )); $siblings[] = $element; return $element; } }