DashboardController   A
last analyzed

Complexity

Total Complexity 36

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 107
c 1
b 0
f 0
dl 0
loc 184
ccs 0
cts 81
cp 0
rs 9.52
wmc 36

4 Methods

Rating   Name   Duplication   Size   Complexity  
F dashboard() 0 114 23
A index() 0 3 1
A getSectionForDate() 0 28 5
B getListOfSurroundingDays() 0 22 7
1
<?php
2
3
namespace App\Controller;
4
5
use App\Repository\NotificationRepositoryInterface;
6
use Symfony\Component\HttpFoundation\Response;
7
use App\Dashboard\DashboardViewHelper;
8
use App\Dashboard\DashboardViewCollapseHelper;
9
use App\Entity\Section;
10
use App\Entity\Substitution;
11
use App\Entity\User;
12
use App\Entity\UserType;
13
use App\Repository\ImportDateTypeRepositoryInterface;
14
use App\Repository\MessageRepositoryInterface;
15
use App\Repository\SectionRepositoryInterface;
16
use App\Repository\UserRepositoryInterface;
17
use App\Settings\DashboardSettings;
18
use App\Settings\SubstitutionSettings;
19
use App\Settings\TimetableSettings;
20
use App\Utils\EnumArrayUtils;
0 ignored issues
show
Bug introduced by
The type App\Utils\EnumArrayUtils was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
21
use App\View\Filter\RoomFilter;
22
use App\View\Filter\StudentFilter;
23
use App\View\Filter\TeacherFilter;
24
use App\View\Filter\UserTypeFilter;
25
use DateTime;
26
use League\Csv\Exception;
27
use SchulIT\CommonBundle\Helper\DateHelper;
28
use Symfony\Component\HttpFoundation\Request;
29
use Symfony\Component\Routing\Annotation\Route;
30
31
class DashboardController extends AbstractController {
32
33
    use DateTimeHelperTrait;
34
35
    private const ShowTimesKey = 'dashboard.show_times';
36
    private const IncludeGradeMessagesKey = 'dashboard.include_grade_messages';
37
38
    #[Route(path: '/', name: 'index')]
39
    public function index(): Response {
40
        return $this->redirectToRoute('dashboard');
41
    }
42
43
    #[Route(path: '/dashboard', name: 'dashboard')]
44
    public function dashboard(StudentFilter $studentFilter, TeacherFilter $teacherFilter, UserTypeFilter $userTypeFilter, RoomFilter $roomFilter,
45
                              DashboardViewHelper $dashboardViewHelper, DashboardViewCollapseHelper $dashboardViewMergeHelper,
46
                              DateHelper $dateHelper, DashboardSettings $settings, TimetableSettings $timetableSettings, SectionRepositoryInterface $sectionRepository,
47
                              UserRepositoryInterface $userRepository, ImportDateTypeRepositoryInterface $importDateTypeRepository,
48
                              NotificationRepositoryInterface $notificationRepository, Request $request): Response {
49
        /** @var User $user */
50
        $user = $this->getUser();
51
52
        if($request->isMethod('POST')) {
53
            $showTimes = $request->request->getBoolean('show_times', false);
54
            $user->setData(self::ShowTimesKey, $showTimes);
55
56
            $includeGradeMessages = $request->request->getBoolean('include_grade_messages', false);
57
            $user->setData(self::IncludeGradeMessagesKey, $includeGradeMessages);
58
59
            $userRepository->persist($user);
60
61
            return $this->redirectToRoute('dashboard', $request->query->all());
62
        }
63
64
        $selectedDate = null;
65
        try {
66
            if($request->query->has('date')) {
67
                $selectedDate = new DateTime($request->query->get('date', null));
68
                $selectedDate->setTime(0, 0, 0);
69
            }
70
        } catch (\Exception) {
71
            $selectedDate = null;
72
        }
73
74
        if($selectedDate === null) {
75
            $selectedDate = $this->getTodayOrNextDay($dateHelper, $settings->getNextDayThresholdTime());
76
77
            while($settings->skipWeekends() && $selectedDate->format('N') > 5) {
78
                $selectedDate->modify('+1 day');
79
            }
80
        }
81
82
        $dateHasSection = true;
83
        $section = $this->getSectionForDate($selectedDate, $sectionRepository, $dateHasSection);
84
85
        $days = $this->getListOfSurroundingDays($selectedDate, $settings->getNumberFutureDays(), $settings->getNumberPastDays(), $settings->skipWeekends());
86
87
        $roomFilterView = $roomFilter->handle($request->query->get('room', null), $user);
88
        $studentFilterView = $studentFilter->handle($request->query->get('student', null), $section, $user);
89
        $teacherFilterView = $teacherFilter->handle($request->query->get('teacher', null), $section, $user, $studentFilterView->getCurrentStudent() === null && $roomFilterView->getCurrentRoom() === null);
90
        $userTypeFilterView = $userTypeFilter->handle($request->query->get('user_type', null), $user, $user->isStudentOrParent(), UserType::Student, [ UserType::Student, UserType::Parent ]);
91
92
        $includeGradeMessages = $user->getData(self::IncludeGradeMessagesKey, false);
93
94
        if($studentFilterView->getCurrentStudent() !== null) {
95
            if($userTypeFilterView->getCurrentType() === null) {
96
                $userTypeFilterView->setCurrentType(UserType::Student);
97
            }
98
            $view = $dashboardViewHelper->createViewForStudentOrParent($studentFilterView->getCurrentStudent(), $selectedDate, $userTypeFilterView->getCurrentType());
99
        } else if($teacherFilterView->getCurrentTeacher() !== null) {
100
            if($user->getTeacher() === null || $user->getTeacher()->getId() !== $teacherFilterView->getCurrentTeacher()->getId()) {
101
                // Only include grade messages if the current user is the selected user in the teacher filter.
102
                $includeGradeMessages = false;
103
            }
104
105
            $view = $dashboardViewHelper->createViewForTeacher($teacherFilterView->getCurrentTeacher(), $selectedDate, $includeGradeMessages);
106
        } else if($roomFilterView->getCurrentRoom() !== null) {
107
            $view = $dashboardViewHelper->createViewForRoom($roomFilterView->getCurrentRoom(), $selectedDate);
108
        } else {
109
            $view = $dashboardViewHelper->createViewForUser($user, $selectedDate);
110
        }
111
112
        $startTimes = [ ];
113
        $endTimes = [ ];
114
115
        $showTimes = $user->getData(self::ShowTimesKey, true) === true;
116
117
        for ($lesson = 1; $lesson <= $timetableSettings->getMaxLessons(); $lesson++) {
118
            $startTimes[$lesson] = $showTimes ? $timetableSettings->getStart($lesson) : null;
119
            $endTimes[$lesson] = $showTimes ? $timetableSettings->getEnd($lesson) : null;
120
        }
121
122
        if($view !== null) {
123
            $dashboardViewMergeHelper->collapseView($view, $teacherFilterView->getCurrentTeacher());
124
        }
125
126
        $supervisionLabels = [ ];
127
        for($i = 1; $i <= $timetableSettings->getMaxLessons(); $i++) {
128
            $supervisionLabels[$i] = $timetableSettings->getDescriptionBeforeLesson($i);
129
        }
130
131
        $template = 'dashboard/one_column.html.twig';
132
133
        if(count($view->getLessons()) > 0 && (count($view->getAppointments()) > 0 || count($view->getMessages()) > 0 || count($view->getPriorityMessages()) > 0)) {
134
            $template = 'dashboard/two_columns.html.twig';
135
        }
136
137
        return $this->render($template, [
138
            'studentFilter' => $studentFilterView,
139
            'teacherFilter' => $teacherFilterView,
140
            'userTypeFilter' => $userTypeFilterView,
141
            'roomFilter' => $roomFilterView,
142
            'view' => $view,
143
            'days' => $days,
144
            'selectedDate' => $selectedDate,
145
            'startTimes' => $startTimes,
146
            'endTimes' => $endTimes,
147
            'gradesWithCourseNames' => $timetableSettings->getGradeIdsWithCourseNames(),
148
            'supervisionLabels' => $supervisionLabels,
149
            'showTimes' => $showTimes,
150
            'includeGradeMessages' => $user->getData(self::IncludeGradeMessagesKey, false),
151
            'canIncludeGradeMessages' => $user->getTeacher() !== null,
152
            'last_import' => $importDateTypeRepository->findOneByEntityClass(Substitution::class),
153
            'settings' => $settings,
154
            'section' => $section,
155
            'dateHasSection' => $dateHasSection,
156
            'unreadNotificationsCount' => $notificationRepository->countUnreadForUser($user)
157
        ]);
158
    }
159
160
    private function getSectionForDate(DateTime $dateTime, SectionRepositoryInterface $sectionRepository, bool &$dateHasSection): ?Section {
161
        $dateHasSection = true;
162
        $section = $sectionRepository->findOneByDate($dateTime);
163
164
        if($section === null) {
165
            $dateHasSection = false;
166
            $sections = $sectionRepository->findAll();
167
168
            if(count($sections) === 0) {
169
                return null;
170
            }
171
172
            $nearestSection = $sections[0];
173
            $min = $dateTime->diff($sections[0]->getStart())->format('%a');
174
175
            foreach($sections as $section) {
176
                $diff = $dateTime->diff($section->getStart())->format('%a');
177
178
                if($diff < $min) {
179
                    $min = $diff;
180
                    $nearestSection = $section;
181
                }
182
            }
183
184
            return $nearestSection;
185
        }
186
187
        return $section;
188
    }
189
190
    /**
191
     * @return \DateTime[]
192
     */
193
    private function getListOfSurroundingDays(DateTime $dateTime, int $daysInFuture, int $daysInPast, bool $skipWeekends): array {
194
        $days = [ ];
195
196
        for($i = $daysInPast; $i > 0; $i--) {
197
            $day = (clone $dateTime)->modify(sprintf('-%d days', $i));
198
199
            if($skipWeekends === false || $day->format('N') < 6) {
200
                $days[] = $day;
201
            }
202
        }
203
204
        $days[] = $dateTime;
205
206
        for($i = 1; $i <= $daysInFuture; $i++) {
207
            $day = (clone $dateTime)->modify(sprintf('+%d days', $i));
208
209
            if($skipWeekends === false || $day->format('N') < 6) {
210
                $days[] = $day;
211
            }
212
        }
213
214
        return $days;
215
    }
216
}