xx, 'lastseen' => xxx) * @return string pc state */ public static function getPcState(array $pc): string { $lastseen = (int)$pc['lastseen']; $NOW = time(); if ($pc['state'] === 'OFFLINE' && $NOW - $lastseen > 30 * 86400) { return "BROKEN"; } return $pc['state']; } /** * Return list of locationids associated with given panel. * * @param string $paneluuid panel * @param bool $recursive if true and paneltype == SUMMARY the result is recursive with all child room ids. * @return int[] locationIds */ public static function getLocationsOr404(string $paneluuid, bool $recursive = true): array { $panel = Database::queryFirst('SELECT paneltype, locationids FROM locationinfo_panel WHERE paneluuid = :paneluuid', compact('paneluuid')); if ($panel !== false) { $idArray = array_map('intval', explode(',', $panel['locationids'])); if ($panel['paneltype'] == "SUMMARY" && $recursive) { $idList = Location::getRecursiveFlat($idArray); $idArray = array_keys($idList); } return $idArray; } http_response_code(404); die('Panel not found'); } /** * Set current error message of given server. Pass null or false to clear. * * @param int $serverId id of server * @param string|array $message error message to set, array of error message struct, null or false clears error. */ public static function setServerError(int $serverId, $message): void { if (is_array($message)) { $fatal = false; foreach ($message as $m) { if ($m['fatal']) { $fatal = $m['message']; } Database::exec('INSERT INTO locationinfo_backendlog (serverid, dateline, message) VALUES (:sid, :dateline, :message)', [ 'sid' => $serverId, 'dateline' => $m['time'], 'message' => ($m['fatal'] ? '[F]' : '[W]') . $m['message'], ]); } $message = $fatal; } if ($message === false || $message === null) { Database::exec("UPDATE `locationinfo_coursebackend` SET error = NULL WHERE serverid = :id", array('id' => $serverId)); } else { if (empty($message)) { $message = ''; } $error = json_encode(array( 'timestamp' => time(), 'error' => (string)$message )); Database::exec("UPDATE `locationinfo_coursebackend` SET error = :error WHERE serverid = :id", array('id' => $serverId, 'error' => $error)); } } /** * Creates and returns a default config for room that didn't save a config yet. * * @return array Return a default config. */ public static function defaultPanelConfig(string $type): array { if ($type === 'DEFAULT') { return array( 'language' => defined('LANG') ? LANG : 'en', 'mode' => 1, 'vertical' => false, 'eco' => false, 'prettytime' => true, 'roomplanner' => true, 'scaledaysauto' => true, 'startday' => 0, 'daystoshow' => 7, 'rotation' => 0, 'scale' => 50, 'switchtime' => 20, 'calupdate' => 30, 'roomupdate' => 15, 'configupdate' => 180, 'overrides' => [], 'hostname' => false, ); } if ($type === 'SUMMARY') { return array( 'language' => defined('LANG') ? LANG : 'en', 'roomplanner' => true, 'eco' => false, 'panelupdate' => 60, ); } if ($type === 'URL') { return array( 'whitelist' => '*', 'blacklist' => '', 'insecure-ssl' => 0, 'reload-minutes' => 0, 'split-login' => 0, 'browser' => 'slx-browser', 'interactive' => 0, 'bookmarks' => '', 'allow-tty' => '', 'url' => '', 'zoom-factor' => 100, ); } return array(); } /** * Gets the calendar of the given ids. * * @param int[] $idList list with the location ids. * @return array Calendar. */ public static function getCalendar(array $idList, bool $forceCached = false): array { if (empty($idList)) return []; $resultArray = array(); if ($forceCached) { $res = Database::simpleQuery("SELECT locationid, calendar FROM locationinfo_locationconfig WHERE Length(calendar) > 10 AND lastcalendarupdate > UNIX_TIMESTAMP() - 86400*3"); foreach ($res as $row) { $resultArray[] = [ 'id' => (int)$row['locationid'], 'calendar' => json_decode($row['calendar'], true), ]; } return $resultArray; } // Build SQL query for multiple ids. $query = "SELECT l.locationid, l.serverid, l.serverlocationid, s.servertype, s.credentials FROM `locationinfo_locationconfig` AS l INNER JOIN locationinfo_coursebackend AS s ON (s.serverid = l.serverid) WHERE l.locationid IN (:idlist) ORDER BY s.servertype ASC"; $dbquery = Database::simpleQuery($query, array('idlist' => array_values($idList))); $serverList = array(); foreach ($dbquery as $dbresult) { if (!isset($serverList[$dbresult['serverid']])) { $serverList[$dbresult['serverid']] = array( 'credentials' => (array)json_decode($dbresult['credentials'], true), 'type' => $dbresult['servertype'], 'idlist' => array() ); } $serverList[$dbresult['serverid']]['idlist'][] = $dbresult['locationid']; } foreach ($serverList as $serverid => $server) { $serverInstance = CourseBackend::getInstance($server['type']); if ($serverInstance === false) { EventLog::warning('Cannot fetch schedule for location (' . implode(', ', $server['idlist']) . ')' . ': Backend type ' . $server['type'] . ' unknown. Disabling location.'); Database::exec("UPDATE locationinfo_locationconfig SET serverid = NULL WHERE locationid IN (:lid)", array('lid' => $server['idlist'])); continue; } $credentialsOk = $serverInstance->setCredentials($serverid, $server['credentials']); if ($credentialsOk) { $calendarFromBackend = $serverInstance->fetchSchedule($server['idlist']); } else { $calendarFromBackend = array(); } LocationInfo::setServerError($serverid, $serverInstance->getErrors()); if (is_array($calendarFromBackend)) { foreach ($calendarFromBackend as $key => $value) { $resultArray[] = array( 'id' => (int)$key, 'calendar' => $value, ); } } } return $resultArray; } public static function getAllCalendars(bool $forceCached): array { $locations = Database::queryColumnArray("SELECT locationid FROM location"); $calendars = []; foreach (LocationInfo::getCalendar($locations, $forceCached) as $cal) { if (empty($cal['calendar'])) continue; $calendars[$cal['id']] = $cal['calendar']; } return $calendars; } public static function extractCurrentEvent(array $calendar): string { $NOW = time(); foreach ($calendar as $event) { $start = strtotime($event['start']); $end = strtotime($event['end']) + 60; if ($NOW >= $start && $NOW <= $end) return $event['title']; } return ''; } }