Files
JobcardSystem/app/Domain/Jobcard/AssignmentValidator.php
T

59 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Domain\Jobcard;
/**
* Validates and normalizes the command used to replace a jobcard's technician assignments.
*/
final class AssignmentValidator
{
/**
* @return array{valid: bool, jobcard_id: ?int, user_ids: list<int>, errors: array<string, string>}
*/
public function validate(array $payload): array
{
$errors = [];
$jobcardId = $this->positiveInteger($payload['jobcard_id'] ?? null);
if ($jobcardId === null) {
$errors['jobcard_id'] = 'Jobcard ID must be a positive integer.';
}
$userIds = [];
$assignments = $payload['user_ids'] ?? null;
if (!is_array($assignments) || $assignments === []) {
$errors['user_ids'] = 'At least one technician ID is required.';
} else {
foreach ($assignments as $userId) {
$normalized = $this->positiveInteger($userId);
if ($normalized === null) {
$errors['user_ids'] = 'Technician IDs must be positive integers.';
continue;
}
if (!in_array($normalized, $userIds, true)) {
$userIds[] = $normalized;
}
}
}
return [
'valid' => $errors === [],
'jobcard_id' => $jobcardId,
'user_ids' => $userIds,
'errors' => $errors,
];
}
private function positiveInteger(mixed $value): ?int
{
if (is_int($value)) {
return $value > 0 ? $value : null;
}
if (is_string($value) && preg_match('/^[1-9]\d*$/', $value) === 1) {
$integer = filter_var($value, FILTER_VALIDATE_INT);
return $integer !== false ? $integer : null;
}
return null;
}
}