*/ private array $levels = []; public function create(CreateSetLevelDto $dto): SetLevel { foreach ($this->levels as $level) { if ( $level->getSet()->getId() === $dto->set->getId() && $level->getKind() === $dto->kind ) { throw new DomainException( 'level kind must be unique within set', ); } } $id = count($this->levels) + 1; $level = new SetLevel( id: $id, set: $dto->set, kind: $dto->kind, depth: count($this->findBySet($dto->set)), ); $this->levels[$id] = $level; return $this->copy($level); } public function find(int $id): ?SetLevel { $level = $this->levels[$id] ?? null; return $level === null ? null : $this->copy($level); } public function findBySet(Set $set): array { $levels = array_filter( $this->levels, function (SetLevel $level) use ($set): bool { return $level->getSet()->getId() === $set->getId(); }, ); usort($levels, function (SetLevel $first, SetLevel $second): int { return $first->getDepth() <=> $second->getDepth(); }); return array_map(function (SetLevel $level): SetLevel { return $this->copy($level); }, $levels); } private function copy(SetLevel $level): SetLevel { return new SetLevel( id: $level->getId(), set: $level->getSet(), kind: $level->getKind(), depth: $level->getDepth(), ); } }