Lines 90.00% 18 / 20
Methods 50.00% 1 / 2
Classes 0.00% 0 / 1
Name Lines Methods CRAP
 __construct 100.00% 1 / 1 100.00% 1 / 1 1
 validate 89.47% 17 / 19 0.00% 0 / 1 8.07
19final class NoOverlappingTravelValidator extends ConstraintValidator
20{
21    public function __construct(
22        private readonly TimelineEventRepository $timelineEventRepository,
23        private readonly Security $security,
24    ) {
25    }
26
27    public function validate(mixed $value, Constraint $constraint): void
28    {
29        if (!$constraint instanceof NoOverlappingTravel) {
30            throw new UnexpectedTypeException($constraint, NoOverlappingTravel::class);
31        }
32
33        if (!$value instanceof TimelineEvent || !$value->date instanceof \DateTimeImmutable || !$value->endDate instanceof \DateTimeImmutable) {
34            return;
35        }
36
37        $owner = $value->owner ?? $this->security->getUser();
38        if (!$owner instanceof User) {
39            return;
40        }
41
42        $other = $this->timelineEventRepository->findOverlappingTravel($owner, $value, $value->date, $value->endDate);
43        if (!$other instanceof TimelineEvent) {
44            return;
45        }
46
47        $this->context->buildViolation($constraint->message)
48            ->setParameter('{{ travel }}', \sprintf(
49                '%s (%s – %s)',
50                \strtok($other->text, "\n") ?: '',
51                $other->date?->format('Y-m-d'),
52                $other->endDate?->format('Y-m-d'),
53            ))
54            ->atPath('endDate')
55            ->addViolation();
56    }
57}