Attainly/backend/app/Set/EloquentSetLevelRepository.php

88 lines
2.2 KiB
PHP

<?php
namespace App\Set;
use DomainException;
use RuntimeException;
class EloquentSetLevelRepository implements SetLevelRepository
{
public function __construct(
private SetRepository $setRepository,
) {}
public function create(CreateSetLevelDto $dto): SetLevel
{
$kindExists = SetLevelModel::query()
->where('set_id', $dto->set->getId())
->where('kind', $dto->kind)
->exists();
if ($kindExists) {
throw new DomainException(
'level kind must be unique within set',
);
}
$currentMaximum = SetLevelModel::query()
->where('set_id', $dto->set->getId())
->max('depth');
$depth = $currentMaximum === null
? 0
: (int) $currentMaximum + 1;
$model = SetLevelModel::create([
'set_id' => $dto->set->getId(),
'kind' => $dto->kind,
'depth' => $depth,
]);
return new SetLevel(
id: $model->id,
set: $dto->set,
kind: $model->kind,
depth: $model->depth,
);
}
public function find(int $id): ?SetLevel
{
$model = SetLevelModel::find($id);
return $model === null ? null : $this->toDomain($model);
}
public function findBySet(Set $set): array
{
$models = SetLevelModel::query()
->where('set_id', $set->getId())
->orderBy('depth')
->orderBy('id')
->get();
$levels = [];
foreach ($models as $model) {
$levels[] = new SetLevel(
id: $model->id,
set: $set,
kind: $model->kind,
depth: $model->depth,
);
}
return $levels;
}
private function toDomain(SetLevelModel $model): SetLevel
{
$set = $this->setRepository->find($model->set_id);
if ($set === null) {
throw new RuntimeException('set level set not found');
}
return new SetLevel(
id: $model->id,
set: $set,
kind: $model->kind,
depth: $model->depth,
);
}
}