|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace App\Dashboard; |
|
4
|
|
|
|
|
5
|
|
|
use App\Entity\Teacher; |
|
6
|
|
|
use App\Settings\DashboardSettings; |
|
7
|
|
|
use App\Sorting\Sorter; |
|
8
|
|
|
use App\Sorting\SubstitutionViewItemStrategy; |
|
|
|
|
|
|
9
|
|
|
use App\Utils\ArrayUtils; |
|
10
|
|
|
use InvalidArgumentException; |
|
11
|
|
|
|
|
12
|
|
|
/** |
|
13
|
|
|
* Applies an algorithm in order to reduce the amount of items of one lesson to one. |
|
14
|
|
|
*/ |
|
15
|
|
|
class DashboardViewCollapseHelper { |
|
16
|
|
|
|
|
17
|
|
|
public function __construct(private DashboardSettings $settings) |
|
18
|
|
|
{ |
|
19
|
|
|
} |
|
20
|
|
|
|
|
21
|
|
|
public function collapseView(DashboardView $view, ?Teacher $teacher) { |
|
22
|
|
|
foreach($view->getLessons() as $lesson) { |
|
23
|
|
|
$this->collapseLesson($lesson, $view, $teacher); |
|
24
|
|
|
} |
|
25
|
|
|
|
|
26
|
|
|
// Post-validation |
|
27
|
|
|
$this->validateTimetableSupervisionsAndExamSupervisions($view); |
|
28
|
|
|
|
|
29
|
|
|
// Sort mentions and exams |
|
30
|
|
|
$this->sortMentions($view); |
|
31
|
|
|
$this->sortExams($view); |
|
32
|
|
|
} |
|
33
|
|
|
|
|
34
|
|
|
private function sortMentions(DashboardView $view): void { |
|
35
|
|
|
$mentions = $view->getSubstitutionMentions(); |
|
36
|
|
|
$view->clearSubstitutionMentions(); |
|
37
|
|
|
|
|
38
|
|
|
usort($mentions, fn(SubstitutionViewItem $viewItemA, SubstitutionViewItem $viewItemB) => $viewItemA->getSubstitution()->getLessonStart() - $viewItemB->getSubstitution()->getLessonEnd()); |
|
39
|
|
|
|
|
40
|
|
|
foreach($mentions as $mention) { |
|
41
|
|
|
$view->addSubstitutonMention($mention); |
|
42
|
|
|
} |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
private function sortExams(DashboardView $view): void { |
|
46
|
|
|
$exams = $view->getExams(); |
|
47
|
|
|
$view->clearExams(); |
|
48
|
|
|
|
|
49
|
|
|
usort($exams, fn(ExamViewItem $examA, ExamViewItem $examB) => $examA->getExam()->getLessonStart() - $examB->getExam()->getLessonStart()); |
|
50
|
|
|
|
|
51
|
|
|
foreach($exams as $exam) { |
|
52
|
|
|
$view->addExam($exam); |
|
53
|
|
|
} |
|
54
|
|
|
} |
|
55
|
|
|
|
|
56
|
|
|
private function validateTimetableSupervisionsAndExamSupervisions(DashboardView $view) { |
|
57
|
|
|
$lessonNumbers = $view->getLessonNumbers(); |
|
58
|
|
|
|
|
59
|
|
|
foreach($lessonNumbers as $lessonNumber) { |
|
60
|
|
|
$lesson = $view->getLesson($lessonNumber, true); |
|
61
|
|
|
|
|
62
|
|
|
if($lesson === null) { |
|
63
|
|
|
continue; |
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
$lessonBefore = $view->getLesson($lessonNumber - 1, false); |
|
67
|
|
|
$lessonAfter = $view->getLesson($lessonNumber, false); |
|
68
|
|
|
|
|
69
|
|
|
if($lessonBefore === null || $lessonAfter === null) { |
|
70
|
|
|
continue; |
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
// is supervision? |
|
74
|
|
|
$isSupervision = count(ArrayUtils::filterByType($lesson->getItems(), SupervisionViewItem::class)) > 0; |
|
75
|
|
|
$isExamSupervisionBefore = count(ArrayUtils::filterByType($lessonBefore->getItems(), ExamSupervisionViewItem::class)) > 0; |
|
76
|
|
|
$isExamSupervisionAfter = count(ArrayUtils::filterByType($lessonAfter->getItems(), ExamSupervisionViewItem::class)) > 0; |
|
77
|
|
|
|
|
78
|
|
|
if($isSupervision === true && $isExamSupervisionBefore === true && $isExamSupervisionAfter === true) { |
|
79
|
|
|
$lesson->setWarning(); |
|
80
|
|
|
} |
|
81
|
|
|
} |
|
82
|
|
|
} |
|
83
|
|
|
|
|
84
|
|
|
private function collapseLesson(DashboardLesson $lesson, DashboardView $view, ?Teacher $teacher): void { |
|
85
|
|
|
// Merge supervisions |
|
86
|
|
|
$this->mergeExamSupervisions($lesson); |
|
87
|
|
|
|
|
88
|
|
|
// Add exams because they may not cause any troubles |
|
89
|
|
|
$this->addExamsToView($lesson, $view); |
|
90
|
|
|
|
|
91
|
|
|
// Store all items |
|
92
|
|
|
$originalItems = $lesson->getItems(); |
|
93
|
|
|
|
|
94
|
|
|
// ... and all items as we will re-add them |
|
95
|
|
|
$lesson->clearItems(); |
|
96
|
|
|
|
|
97
|
|
|
// STEP 1: TIMETABLE LESSONS |
|
98
|
|
|
/** @var TimetableLessonViewItem[] $timetableLessons */ |
|
99
|
|
|
$timetableLessons = ArrayUtils::filterByType($originalItems, TimetableLessonViewItem::class); |
|
100
|
|
|
$timetableCount = count($timetableLessons); |
|
101
|
|
|
$freeTimetableLessons = ArrayUtils::filterByType($originalItems, FreeLessonView::class); |
|
102
|
|
|
$mergeTimetableLessons = false; |
|
103
|
|
|
|
|
104
|
|
|
if($timetableCount === 1 && $timetableLessons[0]->getLesson() !== null) { |
|
105
|
|
|
if(count($freeTimetableLessons) > 0) { |
|
106
|
|
|
$lesson->addItem($freeTimetableLessons[0]); |
|
107
|
|
|
} else { |
|
108
|
|
|
$lesson->addItem($timetableLessons[0]); |
|
109
|
|
|
} |
|
110
|
|
|
} else if($timetableCount > 1) { |
|
111
|
|
|
if($this->canMergeTimetableLessons($timetableLessons)) { |
|
112
|
|
|
$mergeTimetableLessons = true; |
|
113
|
|
|
$lesson->addItem($this->mergeTimetableLessons($timetableLessons)); |
|
114
|
|
|
} else { |
|
115
|
|
|
$lesson->setWarning(); |
|
116
|
|
|
$lesson->replaceItems($originalItems); |
|
117
|
|
|
return; |
|
118
|
|
|
} |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
// STEP 2: SUPERVISIONS |
|
122
|
|
|
/** @var SupervisionViewItem[] $supervisions */ |
|
123
|
|
|
$supervisions = ArrayUtils::filterByType($originalItems, SupervisionViewItem::class); |
|
124
|
|
|
$supervisionCount = count($supervisions); |
|
125
|
|
|
|
|
126
|
|
|
if($supervisionCount === 1) { |
|
127
|
|
|
$lesson->addItem($supervisions[0]); |
|
128
|
|
|
} else if($supervisionCount > 1) { |
|
129
|
|
|
$lesson->setWarning(); |
|
130
|
|
|
$lesson->replaceItems($originalItems); |
|
131
|
|
|
return; |
|
132
|
|
|
} |
|
133
|
|
|
|
|
134
|
|
|
// STEP 3: SUBSTITUTIONS |
|
135
|
|
|
/** @var SubstitutionViewItem[] $originalSubstitutions */ |
|
136
|
|
|
$originalSubstitutions = ArrayUtils::filterByType($originalItems, SubstitutionViewItem::class); |
|
137
|
|
|
|
|
138
|
|
|
// Classify |
|
139
|
|
|
$substitutions = [ ]; |
|
140
|
|
|
$substitutionMentions = [ ]; |
|
141
|
|
|
|
|
142
|
|
|
foreach($originalSubstitutions as $substitution) { |
|
143
|
|
|
if($teacher !== null && $this->isMentionedInSubstitution($substitution, $teacher) === true) { |
|
144
|
|
|
$substitutionMentions[] = $substitution; |
|
145
|
|
|
} |
|
146
|
|
|
|
|
147
|
|
|
if ($teacher === null || $this->onlyMentionedInSubstitution($substitution, $teacher) === false) { |
|
148
|
|
|
$substitutions[] = $substitution; |
|
149
|
|
|
} else { |
|
150
|
|
|
$substitutionMentions[] = $substitution; |
|
151
|
|
|
} |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
// Further classication |
|
155
|
|
|
/** @var SubstitutionViewItem[] $additionalSubstitutions */ |
|
156
|
|
|
$additionalSubstitutions = array_values(array_filter($substitutions, [ $this, 'isAdditionalSubstitution'])); |
|
157
|
|
|
/** @var SubstitutionViewItem[] $removableSubstitutions */ |
|
158
|
|
|
$removableSubstitutions = array_values(array_filter($substitutions, fn(SubstitutionViewItem $viewItem) => $this->isRemovableSubstitution($viewItem, $teacher))); |
|
159
|
|
|
/** @var SubstitutionViewItem[] $defaultSubstitutions */ |
|
160
|
|
|
$defaultSubstitutions = array_values(array_filter($substitutions, fn(SubstitutionViewItem $viewItem) => $this->isDefault($viewItem, $teacher))); |
|
161
|
|
|
|
|
162
|
|
|
$defaultSubstitutionsCount = $this->countDefaultSubstitutions($defaultSubstitutions); |
|
163
|
|
|
|
|
164
|
|
|
if(count($removableSubstitutions) > 1 || $defaultSubstitutionsCount > 1) { |
|
165
|
|
|
$lesson->setWarning(); |
|
166
|
|
|
$lesson->replaceItems($originalItems); |
|
167
|
|
|
return; |
|
168
|
|
|
} |
|
169
|
|
|
|
|
170
|
|
|
foreach($removableSubstitutions as $substitution) { |
|
171
|
|
|
if($mergeTimetableLessons === false) { |
|
172
|
|
|
$lesson->clearItems(); |
|
173
|
|
|
} |
|
174
|
|
|
$lesson->addItem($substitution); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
if($defaultSubstitutionsCount > 0) { |
|
178
|
|
|
if($mergeTimetableLessons === false) { |
|
179
|
|
|
$lesson->clearItems(); |
|
180
|
|
|
} |
|
181
|
|
|
$mergedDefaultSubstitutions = $this->mergeSubstitutions($defaultSubstitutions); |
|
182
|
|
|
|
|
183
|
|
|
foreach ($mergedDefaultSubstitutions as $substitution) { |
|
184
|
|
|
$lesson->addItem($substitution); |
|
185
|
|
|
} |
|
186
|
|
|
} |
|
187
|
|
|
|
|
188
|
|
|
// Add Non-Replacing substitutions |
|
189
|
|
|
foreach($additionalSubstitutions as $substitution) { |
|
190
|
|
|
if($lesson->hasItem($substitution) === false) { |
|
191
|
|
|
$lesson->addItem($substitution); |
|
192
|
|
|
} |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
// STEP 4: EXAM SUPERVISION |
|
196
|
|
|
/** @var ExamSupervisionViewItem[] $examSupervisions */ |
|
197
|
|
|
$examSupervisions = ArrayUtils::filterByType($originalItems, ExamSupervisionViewItem::class); |
|
198
|
|
|
$examSupervisionCount = count($examSupervisions); |
|
199
|
|
|
|
|
200
|
|
|
if($examSupervisionCount > 1) { |
|
201
|
|
|
$lesson->setWarning(); |
|
202
|
|
|
$lesson->replaceItems($originalItems); |
|
203
|
|
|
return; |
|
204
|
|
|
} else if($examSupervisionCount === 1) { |
|
205
|
|
|
$collision = false; |
|
206
|
|
|
|
|
207
|
|
|
foreach($lesson->getItems() as $item) { |
|
208
|
|
|
if(!($item instanceof SubstitutionViewItem) || $this->isDefault($item, $teacher)) { |
|
209
|
|
|
$collision = true; |
|
210
|
|
|
} |
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
if($collision === true) { |
|
214
|
|
|
$lesson->setWarning(); |
|
215
|
|
|
$lesson->replaceItems($originalItems); |
|
216
|
|
|
return; |
|
217
|
|
|
} else { |
|
218
|
|
|
$lesson->clearItems(); |
|
219
|
|
|
$lesson->addItem($examSupervisions[0]); |
|
220
|
|
|
} |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
// EVERYTHING WORKED SO FAR: move certain items to view |
|
224
|
|
|
foreach($substitutionMentions as $mention) { |
|
225
|
|
|
$view->addSubstitutonMention($mention); |
|
226
|
|
|
} |
|
227
|
|
|
|
|
228
|
|
|
foreach(ArrayUtils::filterByType($originalItems, ExamViewItem::class) as $examItem) { |
|
229
|
|
|
$view->addExam($examItem); |
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
// ADD FREE HOURS |
|
233
|
|
|
if(count($lesson->getItems()) === 0) { |
|
234
|
|
|
$lesson->addItem(new TimetableLessonViewItem(null, [ ], null)); |
|
235
|
|
|
} |
|
236
|
|
|
|
|
237
|
|
|
// ADD ALL ITEMS THAT HAVE NOT BEEN TAKE CONCIDERATION |
|
238
|
|
|
$consideredTypes = [ |
|
239
|
|
|
ExamViewItem::class, |
|
240
|
|
|
SubstitutionViewItem::class, |
|
241
|
|
|
SupervisionViewItem::class, |
|
242
|
|
|
TimetableLessonViewItem::class, |
|
243
|
|
|
ExamSupervisionViewItem::class, |
|
244
|
|
|
FreeLessonView::class |
|
245
|
|
|
]; |
|
246
|
|
|
|
|
247
|
|
|
foreach($originalItems as $originalItem) { |
|
248
|
|
|
if(!in_array($originalItem::class, $consideredTypes)) { |
|
249
|
|
|
$lesson->addItem($originalItem); |
|
250
|
|
|
} |
|
251
|
|
|
} |
|
252
|
|
|
} |
|
253
|
|
|
|
|
254
|
|
|
/** |
|
255
|
|
|
* @param TimetableLessonViewItem[] $lessonViews |
|
256
|
|
|
* @return boolean |
|
257
|
|
|
*/ |
|
258
|
|
|
private function canMergeTimetableLessons(array $lessonViews) { |
|
259
|
|
|
$rooms = [ ]; |
|
260
|
|
|
$locations = [ ]; |
|
261
|
|
|
|
|
262
|
|
|
foreach($lessonViews as $view) { |
|
263
|
|
|
$lesson = $view->getLesson(); |
|
264
|
|
|
|
|
265
|
|
|
if($lesson->getRoom() !== null) { |
|
266
|
|
|
$rooms[] = $lesson->getRoom()->getId(); |
|
267
|
|
|
} |
|
268
|
|
|
|
|
269
|
|
|
if($lesson->getLocation() !== null) { |
|
270
|
|
|
$locations[] = $lesson->getLocation(); |
|
271
|
|
|
} |
|
272
|
|
|
} |
|
273
|
|
|
|
|
274
|
|
|
$distinctRooms = array_unique($rooms); |
|
275
|
|
|
$distinctLocations = array_unique($locations); |
|
276
|
|
|
|
|
277
|
|
|
if(count($distinctRooms) === 0 && count($distinctLocations) === 0) { |
|
278
|
|
|
return true; |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
if(count($distinctRooms) === 1 && count($distinctLocations) === 0) { |
|
282
|
|
|
return true; |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
if(count($distinctRooms) === 0 && count($distinctLocations) === 1) { |
|
286
|
|
|
return true; |
|
287
|
|
|
} |
|
288
|
|
|
|
|
289
|
|
|
return false; |
|
290
|
|
|
} |
|
291
|
|
|
|
|
292
|
|
|
/** |
|
293
|
|
|
* @param TimetableLessonViewItem[] $lessonViews |
|
294
|
|
|
* @return TimetableLessonViewItem |
|
295
|
|
|
*/ |
|
296
|
|
|
private function mergeTimetableLessons(array $lessonViews) { |
|
297
|
|
|
if(count($lessonViews) === 0) { |
|
298
|
|
|
throw new InvalidArgumentException('$lessonView must at least contain one element.'); |
|
299
|
|
|
} |
|
300
|
|
|
|
|
301
|
|
|
$absentGroups = [ ]; |
|
302
|
|
|
|
|
303
|
|
|
foreach($lessonViews as $lessonView) { |
|
304
|
|
|
$absentGroups = array_merge($lessonView->getAbsentStudentGroups()); |
|
305
|
|
|
} |
|
306
|
|
|
|
|
307
|
|
|
$firstView = array_shift($lessonViews); |
|
308
|
|
|
|
|
309
|
|
|
$view = new TimetableLessonViewItem($firstView->getLesson(), $absentGroups, $firstView->getAbsenceLesson()); |
|
310
|
|
|
|
|
311
|
|
|
foreach($lessonViews as $lessonView) { |
|
312
|
|
|
$view->addAdditionalLesson($lessonView->getLesson()); |
|
313
|
|
|
} |
|
314
|
|
|
|
|
315
|
|
|
return $view; |
|
316
|
|
|
} |
|
317
|
|
|
|
|
318
|
|
|
private function addExamsToView(DashboardLesson $lesson, DashboardView $view) { |
|
319
|
|
|
$items = $lesson->getItems(); |
|
320
|
|
|
$lesson->clearItems(); |
|
321
|
|
|
|
|
322
|
|
|
foreach($items as $item) { |
|
323
|
|
|
if($item instanceof ExamViewItem) { |
|
324
|
|
|
$view->addExam($item); |
|
325
|
|
|
} else { |
|
326
|
|
|
$lesson->addItem($item); |
|
327
|
|
|
} |
|
328
|
|
|
} |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
private function mergeExamSupervisions(DashboardLesson $lesson): void { |
|
332
|
|
|
$items = $lesson->getItems(); |
|
333
|
|
|
$supervisions = [ ]; |
|
334
|
|
|
|
|
335
|
|
|
$lesson->clearItems(); |
|
336
|
|
|
|
|
337
|
|
|
foreach($items as $item) { |
|
338
|
|
|
if($item instanceof ExamSupervisionViewItem) { |
|
339
|
|
|
$supervisions[] = $item; |
|
340
|
|
|
} else { |
|
341
|
|
|
$lesson->addItem($item); |
|
342
|
|
|
} |
|
343
|
|
|
} |
|
344
|
|
|
|
|
345
|
|
|
/** @var ExamSupervisionViewItem[] $merged */ |
|
346
|
|
|
$merged = [ ]; |
|
347
|
|
|
|
|
348
|
|
|
foreach($supervisions as $supervision) { |
|
349
|
|
|
$firstExam = $supervision->getFirst(); |
|
350
|
|
|
|
|
351
|
|
|
if($firstExam === null) { |
|
352
|
|
|
continue; |
|
353
|
|
|
} |
|
354
|
|
|
|
|
355
|
|
|
$isMerged = false; |
|
356
|
|
|
|
|
357
|
|
|
foreach($merged as $mergedSupervisionItem) { |
|
358
|
|
|
$firstMergedExam = $mergedSupervisionItem->getFirst(); |
|
359
|
|
|
|
|
360
|
|
|
if($firstMergedExam !== null && $firstExam->getRoom() === $firstMergedExam->getRoom()) { |
|
361
|
|
|
$isMerged = true; |
|
362
|
|
|
$mergedSupervisionItem->addExam($firstExam); |
|
363
|
|
|
} |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
if($isMerged === false) { |
|
367
|
|
|
$merged[] = $supervision; |
|
368
|
|
|
} |
|
369
|
|
|
} |
|
370
|
|
|
|
|
371
|
|
|
foreach($merged as $item) { |
|
372
|
|
|
$lesson->addItem($item); |
|
373
|
|
|
} |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
/** |
|
377
|
|
|
* @param SubstitutionViewItem[] $substitutions |
|
378
|
|
|
* @return SubstitutionViewItem[] |
|
379
|
|
|
*/ |
|
380
|
|
|
private function mergeSubstitutions(array $substitutions) { |
|
381
|
|
|
/** @var SubstitutionViewItem[] $merged */ |
|
382
|
|
|
$merged = [ ]; |
|
383
|
|
|
|
|
384
|
|
|
foreach($substitutions as $substitutionViewItem) { |
|
385
|
|
|
$substitution = $substitutionViewItem->getSubstitution(); |
|
386
|
|
|
$isMerged = false; |
|
387
|
|
|
|
|
388
|
|
|
foreach($merged as $mergedViewItem) { |
|
389
|
|
|
$mergedSubstitution = $mergedViewItem->getSubstitution(); |
|
390
|
|
|
|
|
391
|
|
|
if($substitution->getType() === $mergedSubstitution->getType() |
|
392
|
|
|
&& $substitution->getSubject() === $mergedSubstitution->getSubject() |
|
393
|
|
|
&& $substitution->getRemark() === $mergedSubstitution->getRemark() |
|
394
|
|
|
&& ArrayUtils::areEqual($substitution->getRooms(), $mergedSubstitution->getRooms()) |
|
395
|
|
|
&& $substitution->getRoomName() === $mergedSubstitution->getRoomName()) { |
|
396
|
|
|
|
|
397
|
|
|
// merge study groups |
|
398
|
|
|
foreach($substitution->getStudyGroups() as $studyGroup) { |
|
399
|
|
|
if($mergedSubstitution->getStudyGroups()->contains($studyGroup) === false) { |
|
400
|
|
|
$mergedSubstitution->addStudyGroup($studyGroup); |
|
401
|
|
|
} |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
foreach ($substitution->getReplacementStudyGroups() as $studyGroup) { |
|
405
|
|
|
if($mergedSubstitution->getReplacementStudyGroups()->contains($studyGroup) === false) { |
|
406
|
|
|
$mergedSubstitution->addReplacementStudyGroup($studyGroup); |
|
407
|
|
|
} |
|
408
|
|
|
} |
|
409
|
|
|
|
|
410
|
|
|
// merge teachers |
|
411
|
|
|
foreach($substitution->getTeachers() as $teacher) { |
|
412
|
|
|
if($mergedSubstitution->getTeachers()->contains($teacher) === false) { |
|
413
|
|
|
$mergedSubstitution->addTeacher($teacher); |
|
414
|
|
|
} |
|
415
|
|
|
} |
|
416
|
|
|
foreach($substitution->getReplacementTeachers() as $teacher) { |
|
417
|
|
|
if($mergedSubstitution->getReplacementTeachers()->contains($teacher) === false) { |
|
418
|
|
|
$mergedSubstitution->addReplacementTeacher($teacher); |
|
419
|
|
|
} |
|
420
|
|
|
} |
|
421
|
|
|
|
|
422
|
|
|
$isMerged = true; |
|
423
|
|
|
} |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
if($isMerged === false) { |
|
427
|
|
|
$clonedSubstitution = $substitution->clone(); // Somehow, clone $substitution does not work (when renameing clone() to __clone()) |
|
428
|
|
|
$item = new SubstitutionViewItem($clonedSubstitution, false, $substitutionViewItem->getStudents(), $substitutionViewItem->getAbsentStudentGroups(), $substitutionViewItem->getTimetableLesson(), $substitutionViewItem->getAbsenceLesson()); |
|
429
|
|
|
$merged[] = $item; |
|
430
|
|
|
} |
|
431
|
|
|
} |
|
432
|
|
|
|
|
433
|
|
|
return $merged; |
|
434
|
|
|
} |
|
435
|
|
|
|
|
436
|
|
|
/** |
|
437
|
|
|
* @param SubstitutionViewItem[] $defaultSubstitutions |
|
438
|
|
|
* @return int |
|
439
|
|
|
*/ |
|
440
|
|
|
private function countDefaultSubstitutions(array $defaultSubstitutions) { |
|
441
|
|
|
$count = count($defaultSubstitutions); |
|
442
|
|
|
|
|
443
|
|
|
for($i = 0; $i < count($defaultSubstitutions); $i++) { |
|
|
|
|
|
|
444
|
|
|
for($j = $i + 1; $j < count($defaultSubstitutions); $j++) { |
|
|
|
|
|
|
445
|
|
|
$leftSubstitution = $defaultSubstitutions[$i]->getSubstitution(); |
|
446
|
|
|
$rightSubstitution = $defaultSubstitutions[$j]->getSubstitution(); |
|
447
|
|
|
|
|
448
|
|
|
// If subject and room are same: remove count by 1 |
|
449
|
|
|
if($leftSubstitution->getSubject() === $rightSubstitution->getSubject() && ArrayUtils::areEqual($leftSubstitution->getRooms(), $rightSubstitution->getRooms())) { |
|
450
|
|
|
$count--; |
|
451
|
|
|
} |
|
452
|
|
|
} |
|
453
|
|
|
} |
|
454
|
|
|
|
|
455
|
|
|
return $count; |
|
456
|
|
|
} |
|
457
|
|
|
|
|
458
|
|
|
private function isRemovableSubstitution(SubstitutionViewItem $viewItem, ?Teacher $teacher) { |
|
459
|
|
|
if($this->isAdditionalSubstitution($viewItem)) { |
|
460
|
|
|
return false; |
|
461
|
|
|
} |
|
462
|
|
|
|
|
463
|
|
|
if(in_array($viewItem->getSubstitution()->getType(), $this->settings->getRemovableSubstitutionTypes())) { |
|
464
|
|
|
return true; |
|
465
|
|
|
} |
|
466
|
|
|
|
|
467
|
|
|
$substitution = $viewItem->getSubstitution(); |
|
468
|
|
|
|
|
469
|
|
|
if($teacher !== null) { |
|
470
|
|
|
return $substitution->getTeachers()->contains($teacher) && $substitution->getReplacementTeachers()->contains($teacher) === false; |
|
471
|
|
|
} |
|
472
|
|
|
|
|
473
|
|
|
return false; |
|
474
|
|
|
} |
|
475
|
|
|
|
|
476
|
|
|
private function isAdditionalSubstitution(SubstitutionViewItem $viewItem) { |
|
477
|
|
|
return in_array($viewItem->getSubstitution()->getType(), $this->settings->getAdditionalSubstitutionTypes()); |
|
478
|
|
|
} |
|
479
|
|
|
|
|
480
|
|
|
private function onlyMentionedInSubstitution(SubstitutionViewItem $viewItem, Teacher $teacher): bool { |
|
481
|
|
|
$substitution = $viewItem->getSubstitution(); |
|
482
|
|
|
|
|
483
|
|
|
foreach($substitution->getTeachers() as $substitutionTeacher) { |
|
484
|
|
|
if($substitutionTeacher->getId() === $teacher->getId()) { |
|
485
|
|
|
return false; |
|
486
|
|
|
} |
|
487
|
|
|
} |
|
488
|
|
|
|
|
489
|
|
|
foreach($substitution->getReplacementTeachers() as $substitutionTeacher) { |
|
490
|
|
|
if($substitutionTeacher->getId() === $teacher->getId()) { |
|
491
|
|
|
return false; |
|
492
|
|
|
} |
|
493
|
|
|
} |
|
494
|
|
|
|
|
495
|
|
|
return true; |
|
496
|
|
|
} |
|
497
|
|
|
|
|
498
|
|
|
private function isMentionedInSubstitution(SubstitutionViewItem $viewItem, Teacher $teacher): bool { |
|
499
|
|
|
return !empty($viewItem->getSubstitution()->getRemark()) && preg_match('~\W*' . $teacher->getAcronym() . '\W*~', $viewItem->getSubstitution()->getRemark()); |
|
500
|
|
|
} |
|
501
|
|
|
|
|
502
|
|
|
private function isDefault(SubstitutionViewItem $viewItem, ?Teacher $teacher) { |
|
503
|
|
|
return $this->isRemovableSubstitution($viewItem, $teacher) === false && $this->isAdditionalSubstitution($viewItem) === false; |
|
504
|
|
|
} |
|
505
|
|
|
} |
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:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths