summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/inc/apipanelfrontend.inc.php
blob: 70ea93c0826099b04b0e7908d17d1efaa07692a0 (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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
<?php

/**
 * Functions the panel frontends access to display their data,
 * usually via AJAX calls.
 */
class ApiPanelFrontend
{

	/**
	 * Gets the pc states of the given locations.
	 *
	 * @param int[] $idList list of the location ids.
	 * @return array aggregated PC states
	 */
	public static function getPcStates(array $idList, string $paneluuid): array
	{
		$pcStates = array();
		foreach ($idList as $id) {
			$pcStates[$id] = array(
				'id' => $id,
				'idle' => 0,
				'occupied' => 0,
				'offline' => 0,
				'broken' => 0,
				'standby' => 0,
			);
		}

		$locationInfoList = array();
		InfoPanel::appendMachineData($locationInfoList, $idList);

		$panel = Database::queryFirst('SELECT paneluuid, panelconfig FROM locationinfo_panel WHERE paneluuid = :paneluuid',
			compact('paneluuid'));
		$config = json_decode($panel['panelconfig'], true);

		foreach ($locationInfoList as $locationInfo) {
			$id = $locationInfo['id'];
			foreach ($locationInfo['machines'] as $pc) {
				$key = strtolower($pc['pcState']);
				if (isset($pcStates[$id][$key])) {
					if ($config['roomplanner']) {
						if (isset($pc['x']) && isset($pc['y'])) {
							$pcStates[$id][$key]++;
						}
					} else {
						$pcStates[$id][$key]++;
					}
				}
			}
		}

		return array_values($pcStates);
	}

	/**
	 * Generates a web application manifest for a panel.
	 *
	 * @param string $uuid The UUID of the panel.
	 * @return array The generated manifest file data.
	 */
	public static function generateManifest(string $uuid): array
	{
		$row = Database::queryFirst("SELECT panelname FROM locationinfo_panel WHERE paneluuid = :paneluuid",
			['paneluuid' => $uuid]);
		if ($row === false)
			return ['error' => 'Not found'];
		$data = [
			"name" => $row['panelname'],
			"short_name" => $row['panelname'],
			"start_url" => "/panel/$uuid",
			"display_override" => [
				"fullscreen",
				"standalone",
				"tabbed",
				"minimal-ui"
			],
			"display" => "fullscreen",
			"icons" => [
				[
					"src" => "/panel/style/icon.svg",
					"sizes" => "any",
					"type" => "image/svg+xml"
				]
			],
		];
		foreach (glob('style/icon*.png', GLOB_NOSORT) as $file) {
			if (!preg_match('/icon(\d+)\.png$/', $file, $m))
				continue;
			$data['icons'][] = [
				"src" => "/panel/$file",
				"sizes" => "${m[1]}x${m[1]}",
				"type" => "image/png",
			];
		}
		return $data;
	}

	/**
	 * Get last config modification timestamp for given panel.
	 * This is incomplete however, as it wouldn't react to the
	 * linked room plan being edited, or added/removed PCs
	 * etc. So the advice would simply be "if you want the
	 * panel to reload automatically, hit the edit button
	 * and click save". Might even add a shortcut
	 * reload-button to the list of panels at some point.
	 *
	 * @param string $paneluuid panels uuid
	 * @return int UNIX_TIMESTAMP
	 */
	public static function getLastChangeTs(string $paneluuid): int
	{
		$panel = Database::queryFirst('SELECT lastchange, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid',
			compact('paneluuid'));
		if ($panel === false) {
			http_response_code(404);
			die('Panel not found');
		}
		$lastChange = array((int)$panel['lastchange']);
		if (!empty($panel['locationids'])) {
			$res = Database::simpleQuery('SELECT lastchange FROM locationinfo_locationconfig
				WHERE locationid IN (:locs)', array('locs' => explode(',', $panel['locationids'])));
			while (($lc = $res->fetchColumn()) !== false) {
				$lastChange[] = (int)$lc;
			}
		}
		return max($lastChange);
	}
}