Passed
Push — master ( 20f36e...862b31 )
by Marcel
10:03
created

Builder::listsMenu()   B

Complexity

Conditions 6
Paths 32

Size

Total Lines 43
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 6.256

Importance

Changes 0
Metric Value
cc 6
eloc 25
nc 32
nop 1
dl 0
loc 43
rs 8.8977
c 0
b 0
f 0
ccs 21
cts 26
cp 0.8077
crap 6.256
1
<?php
2
3
namespace App\Menu;
4
5
use App\Entity\User;
6
use App\Repository\TimetableLessonRepositoryInterface;
7
use App\Repository\WikiArticleRepositoryInterface;
8
use App\Section\SectionResolverInterface;
9
use App\Security\Voter\ListsVoter;
10
use App\Security\Voter\ResourceReservationVoter;
11
use App\Security\Voter\StudentAbsenceVoter;
12
use App\Security\Voter\TeacherAbsenceVoter;
13
use App\Security\Voter\WikiVoter;
14
use App\Settings\StudentAbsenceSettings;
15
use App\Settings\TeacherAbsenceSettings;
16
use Knp\Menu\FactoryInterface;
17
use Knp\Menu\ItemInterface;
18
use SchulIT\CommonBundle\Helper\DateHelper;
19
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
20
use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
21
22
class Builder {
23
    public function __construct(private readonly FactoryInterface $factory,
24
                                private readonly AuthorizationCheckerInterface $authorizationChecker,
25
                                private readonly WikiArticleRepositoryInterface $wikiRepository,
26
                                private readonly TimetableLessonRepositoryInterface $lessonRepository,
27
                                private readonly TokenStorageInterface $tokenStorage,
28
                                private readonly DateHelper $dateHelper,
29
                                private readonly SectionResolverInterface $sectionResolver)
30
    {
31
    }
32
33
    public function mainMenu(array $options) {
0 ignored issues
show
Unused Code introduced by
The parameter $options is not used and could be removed. ( Ignorable by Annotation )

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

33
    public function mainMenu(/** @scrutinizer ignore-unused */ array $options) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
34
        $menu = $this->factory->createItem('root')
35
            ->setChildrenAttribute('class', 'navbar-nav mr-auto');
36
37
        $menu->addChild('dashboard.label', [
38
            'route' => 'dashboard'
39
        ])
40
            ->setExtra('icon', 'fa fa-home');
41
42
        $menu->addChild('messages.overview.label', [
43
            'route' => 'messages'
44
        ])
45
            ->setExtra('icon', 'fas fa-envelope-open-text');
46
47 4
        $plansMenu = $this->plansMenu($menu);
48
        $this->setFirstChildAsUri($plansMenu);
49
        $listsMenu = $this->listsMenu($menu);
50
        $this->setFirstChildAsUri($listsMenu);
51
52 4
53 4
        $menu->addChild('documents.label', [
54 4
            'route' => 'documents'
55 4
        ])
56 4
            ->setExtra('icon', 'fas fa-file-alt');
57 4
58 4
        $this->wikiMenu($menu);
59 4
60 4
        if($this->authorizationChecker->isGranted('ROLE_SICK_NOTE_VIEWER')
61 4
            || $this->authorizationChecker->isGranted('ROLE_SICK_NOTE_CREATOR')
62 4
            || $this->authorizationChecker->isGranted(StudentAbsenceVoter::New)
63 4
            || $this->authorizationChecker->isGranted(TeacherAbsenceVoter::NewAbsence)
64 4
            || $this->authorizationChecker->isGranted(TeacherAbsenceVoter::CanViewAny)) {
65
            $absenceMenu = $this->absencesMenu($menu);
66 4
            $this->setFirstChildAsUri($absenceMenu);
67 4
        }
68 4
69 4
        if($this->authorizationChecker->isGranted('ROLE_BOOK_VIEWER')) {
70 4
            $this->bookMenu($menu);
71
        }
72 4
73 4
        return $menu;
74
    }
75 4
76
    private function plansMenu(ItemInterface $menu): ItemInterface {
77
        $plans = $menu->addChild('plans.label')
78 4
            ->setExtra('menu', 'plans')
79 4
            ->setExtra('menu-container', '#submenu')
80
            ->setExtra('icon', 'fa fa-school');
81 4
82
        $plans->addChild('plans.timetable.label', [
83 4
            'route' => 'timetable'
84 4
        ])
85
            ->setExtra('icon', 'fa fa-clock');
86 4
87
88 4
        $plans->addChild('plans.substitutions.label', [
89 4
            'route' => 'substitutions'
90
        ])
91 4
            ->setExtra('icon', 'fas fa-random');
92
93 4
        $plans->addChild('plans.exams.label', [
94 2
            'route' => 'exams'
95 2
        ])
96
            ->setExtra('icon', 'fas fa-edit');
97 2
98
        $plans->addChild('plans.appointments.label', [
99
            'route' => 'appointments'
100 4
        ])
101
            ->setExtra('icon', 'far fa-calendar');
102
103 4
        if($this->authorizationChecker->isGranted(ResourceReservationVoter::View)) {
104 4
            $plans->addChild('resources.reservations.label', [
105 4
                'route' => 'resource_reservations'
106 4
            ])
107 4
                ->setExtra('icon', 'fas fa-laptop-house');
108
        }
109 4
110 2
        return $plans;
111 2
    }
112
113 2
    private function listsMenu(ItemInterface $menu): ItemInterface {
114
        $lists = $menu->addChild('lists.label')
115
            ->setExtra('menu', 'lists')
116
            ->setExtra('menu-container', '#submenu')
117 4
            ->setExtra('icon', 'fas fa-list');
118 2
119 2
        if($this->authorizationChecker->isGranted(ListsVoter::Tuitions)) {
120
            $lists->addChild('lists.tuitions.label', [
121 2
                'route' => 'list_tuitions'
122
            ])
123
                ->setExtra('icon', 'fas fa-chalkboard-teacher');
124 4
        }
125 4
126 4
127
        if($this->authorizationChecker->isGranted(ListsVoter::StudyGroups)) {
128 4
            $lists->addChild('lists.study_groups.label', [
129
                'route' => 'list_studygroups'
130
            ])
131 4
                ->setExtra('icon', 'fas fa-users');
132 2
        }
133 2
134
        if($this->authorizationChecker->isGranted(ListsVoter::Teachers)) {
135 2
            $lists->addChild('lists.teachers.label', [
136
                'route' => 'list_teachers'
137
            ])
138 4
                ->setExtra('icon', 'fas fa-user-tie');
139
        }
140
141 4
        if($this->authorizationChecker->isGranted(ListsVoter::Privacy)) {
142 4
            $lists->addChild('lists.privacy.label', [
143 4
                'route' => 'list_privacy'
144
            ])
145 4
                ->setExtra('icon', 'fas fa-user-shield');
146 4
        }
147 4
148
        if($this->authorizationChecker->isGranted(ListsVoter::LearningManagementSystems)) {
149 4
            $lists->addChild('lists.lms.label', [
150
                'route' => 'list_lms'
151
            ])
152
                ->setExtra('icon', 'fas fa-mail-bulk');
153
        }
154
155
        return $lists;
156
    }
157
158
    private function wikiMenu(ItemInterface $menu): ItemInterface {
159
        $wiki = $menu->addChild('wiki.label', [
160
            'route' => 'wiki'
161
        ])
162 4
            ->setExtra('menu', 'wiki')
163
            ->setExtra('icon', 'fab fa-wikipedia-w')
164
            ->setExtra('menu-container', '#submenu');
165 4
166 4
        foreach($this->wikiRepository->findAll() as $article) {
167 4
            if($article->isOnline() && $this->authorizationChecker->isGranted(WikiVoter::View, $article)) {
168 4
                $item = $wiki->addChild(sprintf('wiki.%s', $article->getUuid()), [
0 ignored issues
show
Unused Code introduced by
The assignment to $item is dead and can be removed.
Loading history...
169
                    'label' => $article->getTitle(),
170
                    'route' => 'show_wiki_article',
171 4
                    'routeParameters' => [
172
                        'uuid' => (string)$article->getUuid(),
173 4
                    ]
174
                ])
175
                    ->setExtra('icon', !empty($article->getIcon()) ? $article->getIcon() : 'far fa-file');
176
            }
177 4
        }
178
179 4
        return $wiki;
180 4
    }
181
182 4
    private function bookMenu(ItemInterface $menu): ItemInterface {
183 4
        $book = $menu->addChild('book.label', [
184 4
            'route' => 'book'
185 4
        ])
186
            ->setExtra('menu', 'book')
187 4
            ->setExtra('icon', 'fas fa-book-open')
188 4
            ->setExtra('menu-container', '#submenu');
189
190 4
        $book->addChild('book.label', [
191
            'route' => 'book'
192 4
        ])
193 4
            ->setExtra('icon', 'fas fa-book-open');
194
195 4
        $missing = $book->addChild('book.missing.label', [
196 4
            'route' => 'missing_book_entries'
197
        ])
198 4
            ->setExtra('icon', 'fas fa-times');
199 4
200
        if($this->tokenStorage->getToken() === null) {
201 4
            return $book;
202
        }
203
204
        $user = $this->tokenStorage->getToken()->getUser();
205
        $currentSection = $this->sectionResolver->getCurrentSection();
206 4
207 4
        if($user instanceof User && $user->getTeacher() !== null && $currentSection !== null) {
208
            $count = $this->lessonRepository->countMissingByTeacher($user->getTeacher(), $currentSection->getStart(), $this->dateHelper->getToday());
0 ignored issues
show
Bug introduced by
It seems like $currentSection->getStart() can also be of type null; however, parameter $start of App\Repository\Timetable...countMissingByTeacher() does only seem to accept DateTime, 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

208
            $count = $this->lessonRepository->countMissingByTeacher($user->getTeacher(), /** @scrutinizer ignore-type */ $currentSection->getStart(), $this->dateHelper->getToday());
Loading history...
209 4
            $missing->setExtra('count', $count);
210
        }
211 4
212 4
        $book->addChild('book.students.label', [
213
            'route' => 'book_students'
214
        ])
215 4
            ->setExtra('icon', 'fas fa-users');
216 4
217
        $book->addChild('book.grades.label', [
218 4
            'route' => 'gradebook'
219
        ])
220
            ->setExtra('icon', 'fas fa-user-graduate');
221 4
222 4
        $book->addChild('book.excuse_note.label', [
223
            'route' => 'excuse_notes'
224 4
        ])
225
            ->setExtra('icon', 'fas fa-pen-alt');
226
227
        $book->addChild('book.export.label', [
228
            'route' => 'book_export'
229
        ])
230
            ->setExtra('icon', 'fas fa-download');
231 4
232
        return $book;
233
    }
234
235
    private function absencesMenu(ItemInterface $menu): ItemInterface {
236
        $plans = $menu->addChild('absences.label')
237
            ->setExtra('menu', 'absences')
238 4
            ->setExtra('menu-container', '#submenu')
239
            ->setExtra('icon', 'fas fa-user-times');
240
241
        if($this->authorizationChecker->isGranted('ROLE_SICK_NOTE_VIEWER')
242
            || $this->authorizationChecker->isGranted('ROLE_SICK_NOTE_CREATOR')
243
            || $this->authorizationChecker->isGranted(StudentAbsenceVoter::New)) {
244
            $plans->addChild('absences.students.label', [
245 4
                'route' => 'student_absences'
246
            ])
247
                ->setExtra('icon', 'fas fa-user-graduate');
248
        }
249
250
        if($this->authorizationChecker->isGranted('ROLE_ADMIN')) {
251
            $plans->addChild('absences.students.export.label', [
252 4
                'route' => 'export_student_absences'
253
            ])
254
                ->setExtra('icon', 'fas fa-download');
255
        }
256
257
        if($this->authorizationChecker->isGranted(TeacherAbsenceVoter::NewAbsence) || $this->authorizationChecker->isGranted(TeacherAbsenceVoter::CanViewAny)) {
258
            $plans->addChild('absences.teachers.label', [
259 4
                'route' => 'teacher_absences'
260
            ])
261
                ->setExtra('icon', 'fas fa-chalkboard-teacher');
262
        }
263
264
        return $plans;
265
    }
266
267
    private function setFirstChildAsUri(ItemInterface $root): void {
268
        if(count($root->getChildren()) === 0) {
269
            return;
270
        }
271
272
        $firstKey = array_key_first($root->getChildren());
273
        $firstItem = $root->getChildren()[$firstKey];
274
275
        $root->setUri($firstItem->getUri());
276 4
277
    }
278
}
279