1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
<?php
class Exams
{
/**
* @param int[] $locationIds of location ids. must be an associative array.
* @return bool true iff for any of the given location ids an exam is scheduled.
**/
public static function isInExamMode(array $locationIds, ?string &$lectureId = null, ?string &$autoLogin = null): bool
{
if (empty($locationIds)) {
$locationIds[] = 0;
}
$res = Database::queryFirst("SELECT lectureid, autologin FROM exams"
. " INNER JOIN exams_x_location USING (examid)"
. " WHERE UNIX_TIMESTAMP() BETWEEN starttime AND endtime AND (locationid IN (:lids) OR locationid IS NULL) LIMIT 1", [
'lids' => array_values($locationIds),
]);
if ($res !== false) {
$lectureId = $res['lectureid'];
$autoLogin = $res['autologin'];
}
return $res !== false;
}
/**
* Check if the system is plausibly in exam mode and retrieve relevant information.
* Returns array of arrays with keys:
* - examtitle (string) - Description of the exam
* - estart (int) - Start time of the exam as a UNIX timestamp
* - eend (int) - End time of the exam as a UNIX timestamp
* - lecturetitle (string) - Display name of the lecture
* - lstart (int) - Start time of the linked lecture as a UNIX timestamp
* - lend (int) - End time of the linked lecture as a UNIX timestamp
* - machines (int) - Count of machines
*
* @return array{examtitle: string, estart: int, eend: int, lecturetitle: string, lstart: int, lend: int, machines: int}[]
**/
public static function plausiblyInExamMode(): array
{
$res = Database::simpleQuery("SELECT
e.description AS examtitle, e.starttime AS estart, e.endtime AS eend,
l.displayname AS lecturetitle, l.starttime AS lstart, l.endtime AS lend,
Count(m.machineuuid) AS machines
FROM exams e
LEFT JOIN sat.lecture l USING (lectureid)
LEFT JOIN exams_x_location exl USING (examid)
LEFT JOIN machine m ON (m.locationid = exl.locationid AND m.state <> 'OFFLINE')
WHERE UNIX_TIMESTAMP() BETWEEN e.starttime AND e.endtime
GROUP BY e.examid");
$return = [];
$now = time();
foreach ($res as $row) {
$duration = $row['eend'] - $row['estart'];
if ($duration > 86400 && $row['lstart'] !== null) {
// Too long, consider assigned lecture bounds
if ($now > $row['lstart'] && $now < $row['lend']) {
$duration = $row['lend'] - $row['lstart'];
}
}
if ($duration > 86400 && (int)$row['machines'] === 0) {
continue; // Too long, no machines, ignore
}
$return[] = $row;
}
return $return;
}
}
|