NoReservationCollisionValidator::validate()   D
last analyzed

Complexity

Conditions 22
Paths 56

Size

Total Lines 76
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 506

Importance

Changes 0
Metric Value
eloc 49
c 0
b 0
f 0
dl 0
loc 76
rs 4.1666
ccs 0
cts 45
cp 0
cc 22
nc 56
nop 2
crap 506

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Validator;
4
5
use App\Converter\TeacherStringConverter;
6
use App\Entity\Exam;
7
use App\Entity\ResourceReservation;
8
use App\Rooms\Reservation\ResourceAvailabilityHelper;
9
use Symfony\Component\Validator\Constraint;
10
use Symfony\Component\Validator\ConstraintValidator;
11
use Symfony\Component\Validator\Exception\UnexpectedTypeException;
12
13
class NoReservationCollisionValidator extends ConstraintValidator {
14
15
    public function __construct(private ResourceAvailabilityHelper $availabilityHelper, private TeacherStringConverter $teacherConverter)
16
    {
17
    }
18
19
    /**
20
     * @inheritDoc
21
     */
22
    public function validate($value, Constraint $constraint) {
23
        if(!$constraint instanceof NoReservationCollision) {
24
            throw new UnexpectedTypeException($constraint, NoReservationCollision::class);
25
        }
26
27
        if(!$value instanceof ResourceReservation && !$value instanceof Exam) {
28
            throw new UnexpectedTypeException($value, ResourceReservation::class);
29
        }
30
31
        $room = $value instanceof Exam ? $value->getRoom() : $value->getResource();
32
        $date = $value->getDate();
33
        $lessonStart = $value->getLessonStart();
34
        $lessonEnd = $value->getLessonEnd();
35
36
        if($room === null || $date === null || $lessonStart <= 0 || $lessonEnd <= 0 || $lessonStart > $lessonEnd) {
37
            // reservation must be filled with serious information first
38
            return;
39
        }
40
41
        for($lessonNumber = $lessonStart; $lessonNumber <= $lessonEnd; $lessonNumber++) {
42
            $availability = $this->availabilityHelper->getAvailability($room, $date, $lessonNumber);
43
44
            if($availability === null) {
45
                continue;
46
            }
47
48
            $timetableLesson = $availability->getTimetableLesson();
49
50
            if($timetableLesson !== null && $availability->isTimetableLessonCancelled() === false) {
51
                $tuition = null;
52
53
                if($timetableLesson->getTuition() !== null) {
54
                    $tuition = $timetableLesson->getTuition()->getName();
55
                } else {
56
                    $tuition = $timetableLesson->getSubject();
57
                }
58
59
                $this->context
60
                    ->buildViolation($constraint->messageTimetable)
61
                    ->setParameter('{{ tuition }}', $tuition)
0 ignored issues
show
Bug introduced by
It seems like $tuition can also be of type null; however, parameter $value of Symfony\Component\Valida...terface::setParameter() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
                    ->setParameter('{{ tuition }}', /** @scrutinizer ignore-type */ $tuition)
Loading history...
62
                    ->setParameter('{{ teacher }}', $this->teacherConverter->convert($timetableLesson->getTeachers()->first()))
63
                    ->setParameter('{{ lessonNumber }}', (string)$lessonNumber)
64
                    ->addViolation();
65
            }
66
67
            $substitution = $availability->getSubstitution();
68
69
            if($substitution !== null) {
70
                $this->context
71
                    ->buildViolation($constraint->messageSubstitution)
72
                    ->setParameter('{{ lessonNumber }}', (string)$lessonNumber)
73
                    ->addViolation();
74
            }
75
76
            $existingReservation = $availability->getReservation();
77
78
            if($existingReservation !== null && $existingReservation->getId() !== $value->getId()) {
79
                $this->context
80
                    ->buildViolation($constraint->messageReservation)
81
                    ->setParameter('{{ teacher }}', $this->teacherConverter->convert($existingReservation->getTeacher()))
82
                    ->setParameter('{{ lessonNumber }}', (string)$lessonNumber)
83
                    ->addViolation();
84
            }
85
86
            $exams = $availability->getExams();
87
88
            if(count($exams) > 0) {
89
                foreach($exams as $collidingExam) {
90
                    if($value instanceof Exam && $value->getId() === $collidingExam->getId()) {
91
                        continue;
92
                    }
93
94
                    $this->context
95
                        ->buildViolation($constraint->messageExam)
96
                        ->setParameter('{{ lessonNumber }}', (string)$lessonNumber)
97
                        ->addViolation();
98
                }
99
            }
100
        }
101
    }
102
}