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; } }