summaryrefslogtreecommitdiffstats
path: root/modules-available/exams/inc/exams.inc.php
blob: b82526bfb271b9fc2169a63834e4300afcbdf09b (plain) (blame)
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;
	}

}