Rabbi_Gerzi/backend/app/Set/UseCases/ReorderSets/ReorderSets.php

128 lines
3.1 KiB
PHP

<?php
namespace App\Set\UseCases\ReorderSets;
use App\Exceptions\BadRequestException;
use App\Set\Set;
use App\Set\SetRepository;
class ReorderSets
{
public function __construct(private SetRepository $setRepository)
{
}
/**
* @return Set[]
* @throws BadRequestException
*/
public function execute(ReorderSetsRequest $request): array
{
if ($request->setIds === null) {
throw new BadRequestException('setIds is required');
}
$setIds = $this->validatedSetIds($request->setIds);
$existingSetIds = $this->setIds($this->setRepository->getAll());
$this->validateNoDuplicateIds($setIds);
$this->validateAllIdsAreSets($setIds, $existingSetIds);
$this->validateEverySetWasSubmitted($setIds, $existingSetIds);
return $this->setRepository->reorder($setIds);
}
/**
* @param mixed[] $setIds
* @return int[]
* @throws BadRequestException
*/
private function validatedSetIds(array $setIds): array
{
$validatedSetIds = [];
foreach ($setIds as $setId) {
if (! is_int($setId)) {
throw new BadRequestException(
'setIds must contain integers',
);
}
$validatedSetIds[] = $setId;
}
return $validatedSetIds;
}
/**
* @param int[] $setIds
* @throws BadRequestException
*/
private function validateNoDuplicateIds(array $setIds): void
{
$seenSetIds = [];
foreach ($setIds as $setId) {
if (isset($seenSetIds[$setId])) {
throw new BadRequestException(
'Set order contains duplicate ids',
);
}
$seenSetIds[$setId] = true;
}
}
/**
* @param int[] $setIds
* @param int[] $existingSetIds
* @throws BadRequestException
*/
private function validateAllIdsAreSets(
array $setIds,
array $existingSetIds,
): void {
$existingSetIdsById = [];
foreach ($existingSetIds as $existingSetId) {
$existingSetIdsById[$existingSetId] = true;
}
foreach ($setIds as $setId) {
if (! isset($existingSetIdsById[$setId])) {
throw new BadRequestException(
'Set order contains invalid set',
);
}
}
}
/**
* @param int[] $setIds
* @param int[] $existingSetIds
* @throws BadRequestException
*/
private function validateEverySetWasSubmitted(
array $setIds,
array $existingSetIds,
): void {
if (count($setIds) === count($existingSetIds)) {
return;
}
throw new BadRequestException(
'Set order must include every set',
);
}
/**
* @param Set[] $sets
* @return int[]
*/
private function setIds(array $sets): array
{
$setIds = [];
foreach ($sets as $set) {
$setIds[] = $set->getId();
}
return $setIds;
}
}