diff options
author | root | 2019-02-19 18:53:50 +0100 |
---|---|---|
committer | root | 2019-02-19 18:53:50 +0100 |
commit | 0ad4c0f8196b61699754762aacbaab0223478ab9 (patch) | |
tree | de434c4aea8d07ecd01cd3badd48d057d62c2d1b /modules-available/locationinfo/inc | |
parent | [usb-lock-off] Edit rule cleanup and fix of the dropdown boxes. (diff) | |
parent | [statistics] Fix RAM change warning to handle increase too (diff) | |
download | slx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.tar.gz slx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.tar.xz slx-admin-0ad4c0f8196b61699754762aacbaab0223478ab9.zip |
Merge branch 'master' into usb-lock-offusb-lock-off
Diffstat (limited to 'modules-available/locationinfo/inc')
8 files changed, 457 insertions, 276 deletions
diff --git a/modules-available/locationinfo/inc/coursebackend.inc.php b/modules-available/locationinfo/inc/coursebackend.inc.php index 7162c885..dcd92f6f 100644 --- a/modules-available/locationinfo/inc/coursebackend.inc.php +++ b/modules-available/locationinfo/inc/coursebackend.inc.php @@ -334,7 +334,7 @@ abstract class CourseBackend { $cleanresponse = preg_replace('/(<\/?)(\w+):([^>]*>)/', '$1$2$3', $response); try { - $xml = new SimpleXMLElement($cleanresponse); + $xml = @new SimpleXMLElement($cleanresponse); // This spams before throwing exception } catch (Exception $e) { $this->error = 'Could not parse reply as XML, got ' . get_class($e) . ': ' . $e->getMessage(); if (CONFIG_DEBUG) { @@ -370,6 +370,9 @@ class BackendProperty { * @param mixed $current current value of this property. */ public function initForRender($current = null) { + if ($current === null) { + $current = $this->default; + } if (is_array($this->type)) { $this->template = 'dropdown'; $this->select_list = []; @@ -391,7 +394,7 @@ class BackendProperty { } elseif ($this->type === 'password') { $this->inputtype = Property::getPasswordFieldType(); } - $this->currentvalue = $current === null ? $this->default : $current; + $this->currentvalue = $current; } public $inputtype; public $template; diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php index 8843e372..ed3d7ec2 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php @@ -6,6 +6,10 @@ class CourseBackend_Davinci extends CourseBackend private $location; private $verifyHostname = true; private $verifyCert = true; + /** + * @var bool|resource + */ + private $curlHandle = false; public function setCredentialsInternal($data) { @@ -69,7 +73,9 @@ class CourseBackend_Davinci extends CourseBackend { $url = $this->location . "content=xml&type=room&name=" . urlencode($roomId) . "&startdate=" . $startDate->format('d.m.Y') . "&enddate=" . $endDate->format('d.m.Y'); - $ch = curl_init(); + if ($this->curlHandle === false) { + $this->curlHandle = curl_init(); + } $options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_FOLLOWLOCATION => true, @@ -78,16 +84,15 @@ class CourseBackend_Davinci extends CourseBackend CURLOPT_URL => $url, ); - curl_setopt_array($ch, $options); - $output = curl_exec($ch); + curl_setopt_array($this->curlHandle, $options); + $output = curl_exec($this->curlHandle); if ($output === false) { - $this->error = 'Curl error: ' . curl_error($ch); + $this->error = 'Curl error: ' . curl_error($this->curlHandle); return false; } else { $this->error = false; ///Operation completed successfully } - curl_close($ch); return $output; } @@ -142,4 +147,11 @@ class CourseBackend_Davinci extends CourseBackend } return $schedules; } + + public function __destruct() + { + if ($this->curlHandle !== false) { + curl_close($this->curlHandle); + } + } } diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php new file mode 100755 index 00000000..a62ea6d5 --- /dev/null +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php @@ -0,0 +1,242 @@ +<?php + +/** + * Autoloader for the php-ews classes + */ +spl_autoload_register(function ($class) { + if (strpos($class, 'jamesiarmes') === false) + return; + $file = __DIR__ . '/../../exchange-includes/' . str_replace('\\', '/', $class) . '.php'; + if (!file_exists($file)) + return; + require_once $file; +}); + +use jamesiarmes\PhpEws\Client; +use jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType; +use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType; +use jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType; +use jamesiarmes\PhpEws\Enumeration\ResponseClassType; +use jamesiarmes\PhpEws\Request\FindItemType; +use jamesiarmes\PhpEws\Request\ResolveNamesType; +use jamesiarmes\PhpEws\Type\CalendarViewType; +use jamesiarmes\PhpEws\Type\DistinguishedFolderIdType; +use jamesiarmes\PhpEws\Type\EmailAddressType; +use jamesiarmes\PhpEws\Type\ItemResponseShapeType; + +class CourseBackend_Exchange extends CourseBackend +{ + + private $username = ''; + private $password = ''; + private $serverAddress; + private $clientVersion; + private $timezone = 'W. Europe Standard Time'; // TODO: make this configurable some time + private $verifyHostname = true; + private $verifyCert = true; + + /** + * @return string return display name of backend + */ + public function getDisplayName() + { + return "Microsoft Exchange"; + } + + /** + * @returns \BackendProperty[] list of properties that need to be set + */ + public function getCredentialDefinitions() + { + $options = [ + Client::VERSION_2007, + Client::VERSION_2007_SP1, + Client::VERSION_2009, + Client::VERSION_2010, + Client::VERSION_2010_SP1, + Client::VERSION_2010_SP2, + Client::VERSION_2013, + Client::VERSION_2013_SP1, + Client::VERSION_2016, + ]; + return [ + new BackendProperty('serverAddress', 'string'), + new BackendProperty('username', 'string'), + new BackendProperty('password', 'password'), + new BackendProperty('clientVersion', $options, Client::VERSION_2016), + new BackendProperty('verifyCert', 'bool', true), + new BackendProperty('verifyHostname', 'bool', true) + ]; + } + + /** + * @return boolean true if the connection works, false otherwise + */ + public function checkConnection() + { + $client = $this->getClient(); + $request = new ResolveNamesType(); + $request->UnresolvedEntry = $this->username; + $request->ReturnFullContactData = false; + + try { + $response = $client->ResolveNames($request); + } catch (Exception $e) { + $this->error = $e->getMessage(); + return false; + } + + try { + if ($response->ResponseMessages->ResolveNamesResponseMessage[0]->ResponseCode === "NoError") { + $mailadress = $response->ResponseMessages->ResolveNamesResponseMessage[0]->ResolutionSet->Resolution[0]->Mailbox->EmailAddress; + return !empty($mailadress); + } + } catch (Exception $e) { + $this->error = $e->getMessage(); + } + return false; + } + + /** + * uses json to setCredentials, the json must follow the form given in + * getCredentials + * + * @param array $data assoc array with data required by backend + * @returns bool if the credentials were in the correct format + */ + public function setCredentialsInternal($data) + { + foreach (['username', 'password'] as $field) { + if (empty($data[$field])) { + $this->error = 'setCredentials: Missing field ' . $field; + return false; + } + } + + if (empty($data['serverAddress'])) { + $this->error = "No url is given"; + return false; + } + + $this->username = $data['username']; + $this->password = $data['password']; + + $this->serverAddress = $data['serverAddress']; + $this->clientVersion = $data['clientVersion']; + + $this->verifyHostname = $data['verifyHostname']; + $this->verifyCert = $data['verifyCert']; + + return true; + } + + /** + * @return int desired caching time of results, in seconds. 0 = no caching + */ + public function getCacheTime() + { + return 0; + } + + /** + * @return int age after which timetables are no longer refreshed. should be + * greater than CacheTime. + */ + public function getRefreshTime() + { + return 0; + } + + /** + * Internal version of fetch, to be overridden by subclasses. + * + * @param $roomIds array with local ID as key and serverId as value + * @return array a recursive array that uses the roomID as key + * and has the schedule array as value. A shedule array contains an array in this format: + * ["start"=>'JJJJ-MM-DD HH:MM:SS',"end"=>'JJJJ-MM-DD HH:MM:SS',"title"=>string] + */ + protected function fetchSchedulesInternal($requestedRoomIds) + { + $startDate = new DateTime('today 0:00'); + $endDate = new DateTime('+7 days 0:00'); + $client = $this->getClient(); + + $schedules = []; + foreach ($requestedRoomIds as $roomId) { + try { + $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId); + } catch (Exception $e) { + $this->error .= "Failed to search for events for room $roomId: '{$e->getMessage()}'\n"; + continue; + } + + // Iterate over the events that were found, printing some data for each. + foreach ($items as $item) { + $start = new DateTime($item->Start); + $end = new DateTime($item->End); + + $schedules[$roomId][] = array( + 'title' => $item->Subject, + 'start' => $start->format('Y-m-d') . "T" . $start->format('G:i:s'), + 'end' => $end->format('Y-m-d') . "T" . $end->format('G:i:s') + ); + } + } + return $schedules; + } + + /** + * @param \jamesiarmes\PhpEws\Client $client + * @param \DateTime $startDate + * @param \DateTime $endDate + * @param string $roomAddress + * @return \jamesiarmes\PhpEws\Type\CalendarItemType[] + */ + public function findEventsForRoom($client, $startDate, $endDate, $roomAddress) + { + $request = new FindItemType(); + $request->Traversal = ItemQueryTraversalType::SHALLOW; + $request->ItemShape = new ItemResponseShapeType(); + $request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES; + + $request->CalendarView = new CalendarViewType(); + $request->CalendarView->StartDate = $startDate->format('c'); + $request->CalendarView->EndDate = $endDate->format('c'); + $folderId = new DistinguishedFolderIdType(); + $folderId->Id = DistinguishedFolderIdNameType::CALENDAR; + $folderId->Mailbox = new EmailAddressType(); + $folderId->Mailbox->EmailAddress = $roomAddress; + $request->ParentFolderIds->DistinguishedFolderId[] = $folderId; + $response = $client->FindItem($request); + $response_messages = $response->ResponseMessages->FindItemResponseMessage; + + $items = []; + foreach ($response_messages as $response_message) { + // Make sure the request succeeded. + if ($response_message->ResponseClass !== ResponseClassType::SUCCESS) { + $code = $response_message->ResponseCode; + $message = $response_message->MessageText; + $this->error .= "Failed to search for events for room $roomAddress: '$code: $message'\n"; + continue; + } + $items = array_merge($items, $response_message->RootFolder->Items->CalendarItem); + } + return $items; + } + + /** + * @return \jamesiarmes\PhpEws\Client + */ + public function getClient() + { + $client = new Client($this->serverAddress, $this->username, $this->password, $this->clientVersion); + $client->setTimezone($this->timezone); + $client->setCurlOptions(array( + CURLOPT_SSL_VERIFYPEER => $this->verifyHostname, + CURLOPT_SSL_VERIFYHOST => $this->verifyCert + )); + + return $client; + } + +} diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php index 59bd9dc8..2ffb9f41 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php @@ -8,6 +8,10 @@ class CourseBackend_HisInOne extends CourseBackend private $location; private $verifyHostname = true; private $verifyCert = true; + /** + * @var bool|resource + */ + private $curlHandle = false; public function setCredentialsInternal($data) @@ -27,7 +31,10 @@ class CourseBackend_HisInOne extends CourseBackend } $this->error = false; - $this->username = $data['username'] . "\t" . $data['role']; + $this->username = $data['username']; + if (!empty($data['role'])) { + $this->username .= "\t" . $data['role']; + } $this->password = $data['password']; $this->open = $data['open'] !== 'CourseService'; $url = preg_replace('#(/+qisserver(/+services\d+(/+OpenCourseService)?)?)?\W*$#i', '', $data['baseUrl']); @@ -60,7 +67,7 @@ class CourseBackend_HisInOne extends CourseBackend if (empty($this->location)) { $this->error = "Credentials are not set"; } else { - $this->findUnit(123456789, true); + $this->findUnit(123456789, date('Y-m-d'), true); } return $this->error === false; } @@ -70,18 +77,8 @@ class CourseBackend_HisInOne extends CourseBackend * @param bool $connectionCheckOnly true will only check if no soapError is returned, return value will be empty * @return array|bool if successful an array with the event ids that take place in the room */ - public function findUnit($roomId, $connectionCheckOnly = false) + public function findUnit($roomId, $day, $connectionCheckOnly = false) { - $termYear = date('Y'); - $termType1 = date('n'); - if ($termType1 > 3 && $termType1 < 10) { - $termType = 2; - } elseif ($termType1 > 10) { - $termType = 1; - $termYear = $termYear + 1; - } else { - $termType = 1; - } $doc = new DOMDocument('1.0', 'utf-8'); $doc->formatOutput = true; $envelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:Envelope'); @@ -90,18 +87,15 @@ class CourseBackend_HisInOne extends CourseBackend $envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/OpenCourseService'); } else { $envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/CourseService'); - $header = $this->getHeader($doc); - $envelope->appendChild($header); } + $header = $this->getHeader($doc); + $envelope->appendChild($header); //Body of the request $body = $doc->createElement('SOAP-ENV:Body'); $envelope->appendChild($body); $findUnit = $doc->createElement('ns1:findUnit'); $body->appendChild($findUnit); - $findUnit->appendChild($doc->createElement('termYear', $termYear)); - if ($termType1 != 3 && $termType1 != 10) { - $findUnit->appendChild($doc->createElement('termTypeValueId', $termType)); - } + $findUnit->appendChild($doc->createElement('ns1:individualDatesExecutionDate', $day)); $findUnit->appendChild($doc->createElement('ns1:roomId', $roomId)); $soap_request = $doc->saveXML(); @@ -146,7 +140,7 @@ class CourseBackend_HisInOne extends CourseBackend $idList = $this->getArrayPath($idSubDoc, $subpath); if ($idList === false) { $this->error = 'Cannot find ' . $subpath . ' after ' . $path; - @file_put_contents('/tmp/findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true)); + @file_put_contents('/tmp/bwlp-findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true)); } return $idList; } @@ -188,7 +182,9 @@ class CourseBackend_HisInOne extends CourseBackend "Content-length: " . strlen($request), ); - $soap_do = curl_init(); + if ($this->curlHandle === false) { + $this->curlHandle = curl_init(); + } $options = array( CURLOPT_RETURNTRANSFER => true, @@ -200,17 +196,16 @@ class CourseBackend_HisInOne extends CourseBackend CURLOPT_HTTPHEADER => $header, ); - curl_setopt_array($soap_do, $options); + curl_setopt_array($this->curlHandle, $options); - $output = curl_exec($soap_do); + $output = curl_exec($this->curlHandle); if ($output === false) { - $this->error = 'Curl error: ' . curl_error($soap_do); + $this->error = 'Curl error: ' . curl_error($this->curlHandle); } else { $this->error = false; ///Operation completed successfully } - curl_close($soap_do); return $output; } @@ -236,21 +231,28 @@ class CourseBackend_HisInOne extends CourseBackend if (empty($requestedRoomIds)) { return array(); } + $currentWeek = $this->getCurrentWeekDates(); $tTables = []; //get all eventIDs in a given room $eventIds = []; foreach ($requestedRoomIds as $roomId) { - $roomEventIds = $this->findUnit($roomId); - if ($roomEventIds === false) { - if ($this->error !== false) { - error_log('Cannot findUnit(' . $roomId . '): ' . $this->error); - $this->error = false; + $ok = false; + foreach ($currentWeek as $day) { + $roomEventIds = $this->findUnit($roomId, $day, false); + if ($roomEventIds === false) { + if ($this->error !== false) { + error_log('Cannot findUnit(' . $roomId . '): ' . $this->error); + $this->error = false; + } + // TODO: Error gets swallowed + continue; } - // TODO: Error gets swallowed - continue; + $ok = true; + $eventIds = array_merge($eventIds, $roomEventIds); + } + if ($ok) { + $tTables[$roomId] = []; } - $tTables[$roomId] = []; - $eventIds = array_merge($eventIds, $roomEventIds); } $eventIds = array_unique($eventIds); if (empty($eventIds)) { @@ -268,13 +270,12 @@ class CourseBackend_HisInOne extends CourseBackend } $eventDetails = array_merge($eventDetails, $event); } - $currentWeek = $this->getCurrentWeekDates(); $name = false; + $now = time(); foreach ($eventDetails as $event) { foreach (array('/hisdefaulttext', '/hisshorttext', - '/hisshortcomment', - '/hisplanelements/hisplanelement/hisdefaulttext') as $path) { + '/hisshortcomment') as $path) { $name = $this->getArrayPath($event, $path); if (!empty($name) && !empty($name[0])) break; @@ -283,25 +284,52 @@ class CourseBackend_HisInOne extends CourseBackend if ($name === false) { $name = ['???']; } - $unitPlannedDates = $this->getArrayPath($event, - '/hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); - if ($unitPlannedDates === false) { - $this->error = 'Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'; - error_log('Cannot find ./hisplanelements/hisplanelement/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + $planElements = $this->getArrayPath($event, '/hisplanelements/hisplanelement'); + if ($planElements === false) { + $this->error = 'Cannot find ./hisplanelements/hisplanelement'; + error_log('Cannot find ./hisplanelements/hisplanelement'); error_log(print_r($event, true)); continue; } - foreach ($unitPlannedDates as $plannedDate) { - $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0]; - $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0]; - if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) { - $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0]; - $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0]; - $tTables[$eventRoomId][] = array( - 'title' => $name[0], - 'start' => $eventDate . "T" . $startTime, - 'end' => $eventDate . "T" . $endTime - ); + foreach ($planElements as $planElement) { + if (empty($planElement['hisplannedDates'])) + continue; + // Do not use -- is set improperly for some courses :-( + /* + $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisenddate'); + if (!empty($checkDate) && strtotime($checkDate[0]) + 86400 < $now) + continue; // Course ended + $checkDate = $this->getArrayPath($planElement, '/hisplannedDates/hisplannedDate/hisstartdate'); + if (!empty($checkDate) && strtotime($checkDate[0]) - 86400 > $now) + continue; // Course didn't start yet + */ + $cancelled = $this->getArrayPath($planElement, '/hiscancelled'); + $cancelled = $cancelled !== false && is_array($cancelled) && ($cancelled[0] > 0 || strtolower($cancelled[0]) === 'true'); + $unitPlannedDates = $this->getArrayPath($planElement, + '/hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + if ($unitPlannedDates === false) { + $this->error = 'Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'; + error_log('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate'); + error_log(print_r($planElement, true)); + continue; + } + $localName = $this->getArrayPath($planElement, '/hisdefaulttext'); + if ($localName === false || empty($localName[0])) { + $localName = $name; + } + foreach ($unitPlannedDates as $plannedDate) { + $eventRoomId = $this->getArrayPath($plannedDate, '/hisroomId')[0]; + $eventDate = $this->getArrayPath($plannedDate, '/hisexecutiondate')[0]; + if (in_array($eventRoomId, $requestedRoomIds) && in_array($eventDate, $currentWeek)) { + $startTime = $this->getArrayPath($plannedDate, '/hisstarttime')[0]; + $endTime = $this->getArrayPath($plannedDate, '/hisendtime')[0]; + $tTables[$eventRoomId][] = array( + 'title' => $localName[0], + 'start' => $eventDate . "T" . $startTime, + 'end' => $eventDate . "T" . $endTime, + 'cancelled' => $cancelled, + ); + } } } } @@ -323,9 +351,9 @@ class CourseBackend_HisInOne extends CourseBackend $envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/OpenCourseService'); } else { $envelope->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:ns1', 'http://www.his.de/ws/CourseService'); - $header = $this->getHeader($doc); - $envelope->appendChild($header); } + $header = $this->getHeader($doc); + $envelope->appendChild($header); //body of the request $body = $doc->createElement('SOAP-ENV:Body'); $envelope->appendChild($body); @@ -359,10 +387,17 @@ class CourseBackend_HisInOne extends CourseBackend { $returnValue = array(); $startDate = time(); - for ($i = 0; $i <= 7; $i++) { + for ($i = 0; $i < 7; $i++) { $returnValue[] = date('Y-m-d', strtotime("+{$i} day 12:00", $startDate)); } return $returnValue; } + public function __destruct() + { + if ($this->curlHandle !== false) { + curl_close($this->curlHandle); + } + } + } diff --git a/modules-available/locationinfo/inc/coursebackend/exchange.todo b/modules-available/locationinfo/inc/coursebackend/exchange.todo deleted file mode 100755 index 538f7382..00000000 --- a/modules-available/locationinfo/inc/coursebackend/exchange.todo +++ /dev/null @@ -1,203 +0,0 @@ -<?php - -require_once __DIR__ . '/../../vendor/autoload.php'; - -use jamesiarmes\PhpEws\Client; -use jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType; -use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType; -use jamesiarmes\PhpEws\Enumeration\ItemQueryTraversalType; -use jamesiarmes\PhpEws\Enumeration\ResponseClassType; -use jamesiarmes\PhpEws\Request\FindItemType; -use jamesiarmes\PhpEws\Request\ResolveNamesType; -use jamesiarmes\PhpEws\Type\CalendarViewType; -use jamesiarmes\PhpEws\Type\DistinguishedFolderIdType; -use jamesiarmes\PhpEws\Type\EmailAddressType; -use jamesiarmes\PhpEws\Type\ItemResponseShapeType; - -class CourseBackend_Exchange extends CourseBackend { - - private $username = ''; - private $password = ''; - private $baseUrl; - private $client_version; - private $timezone = 'W. Europe Standard Time'; // TODO: make this configurable some time - private $verifyHostname = true; - private $verifyCert = true; - - /** - * @return string return display name of backend - */ - public function getDisplayName() { - return "Microsoft Exchange"; - } - - /** - * @returns \BackendProperty[] list of properties that need to be set - */ - public function getCredentialDefinitions() { - $options = [Client::VERSION_2007, Client::VERSION_2007_SP1, Client::VERSION_2009, Client::VERSION_2010, - Client::VERSION_2010_SP1, Client::VERSION_2010_SP2, Client::VERSION_2013, Client::VERSION_2013_SP1, Client::VERSION_2016]; - return [ - new BackendProperty('baseUrl', 'string'), - new BackendProperty('username', 'string'), - new BackendProperty('password', 'password'), - new BackendProperty('client_version', $options), - new BackendProperty('verifyCert', 'bool', true), - new BackendProperty('verifyHostname', 'bool', true) - ]; - } - - /** - * @return boolean true if the connection works, false otherwise - */ - public function checkConnection() { - $client = $this->getClient(); - $request = new ResolveNamesType(); - $request->UnresolvedEntry = $this->username; - $request->ReturnFullContactData = false; - - try { - $response = $client->ResolveNames($request); - } catch (Exception $e) { - error_log("There was an error"); - error_log($e->getMessage()); - return false; - } - - if ($response->ResponseMessages->ResolveNamesResponseMessage[0]->ResponseCode == "NoError") { - $mailadress = $response->ResponseMessages->ResolveNamesResponseMessage[0]->ResolutionSet->Resolution[0]->Mailbox->EmailAddress; - return !empty($mailadress); - } - return false; - } - - /** - * uses json to setCredentials, the json must follow the form given in - * getCredentials - * - * @param array $data assoc array with data required by backend - * @returns bool if the credentials were in the correct format - */ - public function setCredentialsInternal($data) { - foreach (['username', 'password'] as $field) { - if (empty($data[$field])) { - $this->error = 'setCredentials: Missing field ' . $field; - return false; - } - } - - if (empty($data['baseUrl'])) { - $this->error = "No url is given"; - return false; - } - - $this->username = $data['username']; - $this->password = $data['password']; - - $this->baseUrl = $data['baseUrl']; - $this->client_version = $data['client_version']; - - $this->verifyHostname = $data['verifyHostname']; - $this->verifyCert = $data['verifyCert']; - - return true; - } - - /** - * @return int desired caching time of results, in seconds. 0 = no caching - */ - public function getCacheTime() { - return 0; - } - - /** - * @return int age after which timetables are no longer refreshed should be - * greater then CacheTime - */ - public function getRefreshTime() { - return 0; - } - - /** - * Internal version of fetch, to be overridden by subclasses. - * - * @param $roomIds array with local ID as key and serverId as value - * @return array a recursive array that uses the roomID as key - * and has the schedule array as value. A shedule array contains an array in this format: - * ["start"=>'JJJJ-MM-DD HH:MM:SS',"end"=>'JJJJ-MM-DD HH:MM:SS',"title"=>string] - */ - protected function fetchSchedulesInternal($requestedRoomIds) { - $startDate = new DateTime('today 0:00'); - $endDate = new DateTime('+7 days 0:00'); - $client = $this->getClient(); - - $schedules = []; - foreach ($requestedRoomIds as $roomId) { - $items = $this->findEventsForRoom($client, $startDate, $endDate, $roomId); - - // Iterate over the events that were found, printing some data for each. - foreach ($items as $item) { - $start = new DateTime($item->Start); - $end = new DateTime($item->End); - - $schedules[$roomId][] = array( - 'title' => $item->Subject, - 'start' => $start->format('Y-m-d') . "T" . $start->format('G:i:s'), - 'end' => $end->format('Y-m-d') . "T" . $end->format('G:i:s') - ); - } - } - return $schedules; - } - - public function findEventsForRoom($client, $start_date, $end_date, $email_room) { - $request = new FindItemType(); - $request->Traversal = ItemQueryTraversalType::SHALLOW; - $request->ItemShape = new ItemResponseShapeType(); - $request->ItemShape->BaseShape = DefaultShapeNamesType::ALL_PROPERTIES; - - $request->CalendarView = new CalendarViewType(); - $request->CalendarView->StartDate = $start_date->format('c'); - $request->CalendarView->EndDate = $end_date->format('c'); - $folder_id = new DistinguishedFolderIdType(); - $folder_id->Id = DistinguishedFolderIdNameType::CALENDAR; - $folder_id->Mailbox = new EmailAddressType(); - $folder_id->Mailbox->EmailAddress = $email_room; - $request->ParentFolderIds->DistinguishedFolderId[] = $folder_id; - $response = $client->FindItem($request); - $response_messages = $response->ResponseMessages->FindItemResponseMessage; - - $items = []; - foreach ($response_messages as $response_message) { - // Make sure the request succeeded. - if ($response_message->ResponseClass != ResponseClassType::SUCCESS) { - $code = $response_message->ResponseCode; - $message = $response_message->MessageText; - error_log("Failed to search for events with \"$code: $message\"\n"); - continue; - } - $items = $response_message->RootFolder->Items->CalendarItem; - } - return $items; - } - - public function getClient() { - $client = new Client($this->baseUrl, $this->username, $this->password, $this->client_version); - $client->setTimezone($this->timezone); - $client->setCurlOptions(array( - CURLOPT_SSL_VERIFYPEER => $this->verifyHostname, - CURLOPT_SSL_VERIFYHOST => $this->verifyCert - )); - - return $client; - } - - function var_error_log($object = null) { - ob_start(); // start buffer capture - var_dump($object); // dump the values - $contents = ob_get_contents(); // put the buffer into a variable - ob_end_clean(); // end capture - error_log($contents); // log contents of the result of var_dump( $object ) - } -} -?> diff --git a/modules-available/locationinfo/inc/infopanel.inc.php b/modules-available/locationinfo/inc/infopanel.inc.php index edeb9ccf..fdc253f0 100644 --- a/modules-available/locationinfo/inc/infopanel.inc.php +++ b/modules-available/locationinfo/inc/infopanel.inc.php @@ -37,6 +37,9 @@ class InfoPanel $overrides = $json['overrides']; } unset($json['overrides']); + if (!isset($json['roomplanner'])) { + $config['roomplanner'] = false; + } $config = $json + $config; } } @@ -75,6 +78,8 @@ class InfoPanel } /** + * {"language":"de","mode":1,"vertical":true,"eco":false,"scaledaysauto":true,"daystoshow":7,"rotation":0,"scale":56,"switchtime":10,"calupdate":120,"roomupdate":20, + * "overrides": { "12" : { "mode":4} } * Gets the location info of the given locations. * Append to passed array which is expected to * map location ids to properties of that location. @@ -157,6 +162,8 @@ class InfoPanel // Iterate over the locations we're actually interested in $locations = Location::getLocationsAssoc(); foreach ($idList as $locationId) { + if (empty($locationId)) + continue; // Start checking at actual location... $currentId = $locationId; while ($currentId !== 0) { @@ -175,6 +182,8 @@ class InfoPanel } } // Keep trying with parent + if (!isset($locations[$currentId])) + break; $currentId = $locations[$currentId]['parentlocationid']; } } diff --git a/modules-available/locationinfo/inc/locationinfo.inc.php b/modules-available/locationinfo/inc/locationinfo.inc.php index 38e271fe..377e960b 100644 --- a/modules-available/locationinfo/inc/locationinfo.inc.php +++ b/modules-available/locationinfo/inc/locationinfo.inc.php @@ -75,11 +75,12 @@ class LocationInfo { if ($type === 'DEFAULT') { return array( - 'language' => 'en', + 'language' => defined('LANG') ? LANG : 'en', 'mode' => 1, 'vertical' => false, 'eco' => false, 'prettytime' => true, + 'roomplanner' => true, 'scaledaysauto' => true, 'daystoshow' => 7, 'rotation' => 0, @@ -92,10 +93,10 @@ class LocationInfo } if ($type === 'SUMMARY') { return array( - 'language' => 'en', - 'calupdate' => 30, - 'roomupdate' => 15, - 'configupdate' => 180, + 'language' => defined('LANG') ? LANG : 'en', + 'roomplanner' => true, + 'eco' => false, + 'panelupdate' => 60, ); } return array(); @@ -127,11 +128,13 @@ class LocationInfo } elseif ($row['paneltype'] === 'URL') { // Check if we should set the insecure SSL mode (accept invalid/self signed certs etc.) $data = json_decode($row['panelconfig'], true); - if ($data && $data['insecure-ssl']) { - ConfigHolder::add('SLX_BROWSER_INSECURE', '1'); - } - if ($data && $data['reload-minutes']) { - ConfigHolder::add('SLX_BROWSER_RELOAD_SECS', $data['reload-minutes'] * 60); + if (is_array($data)) { + if (isset($data['insecure-ssl']) && $data['insecure-ssl']) { + ConfigHolder::add('SLX_BROWSER_INSECURE', '1'); + } + if (isset($data['reload-minutes']) && $data['reload-minutes']) { + ConfigHolder::add('SLX_BROWSER_RELOAD_SECS', $data['reload-minutes'] * 60); + } } } ConfigHolder::add('SLX_BROWSER_URL', 'http://' . $_SERVER['SERVER_ADDR'] . '/panel/' . $panelUuid); diff --git a/modules-available/locationinfo/inc/splittime.php.txt b/modules-available/locationinfo/inc/splittime.php.txt new file mode 100644 index 00000000..53510fee --- /dev/null +++ b/modules-available/locationinfo/inc/splittime.php.txt @@ -0,0 +1,80 @@ +(Unfinished) + + /* + error_log('Pre calendar: ' . print_r($calendar, true)); + $bad = array(); + for ($i = 0; $i < count($calendar); ++$i) { // Use for..count as we append while iterating + $entry =& $calendar[$i]; + // YYYY-MM-DD<T>HH:MM:SS + $s = explode('T', $entry['start']); + $e = explode('T', $entry['end']); + if (count($s) !== 2 || count($e) !== 2) { + error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry)); + $bad[] = $i; + continue; + } + if ($e[0] === $s[0]) // Same day + continue; + $stime = explode(':', $s[1]); + $etime = explode(':', $e[1]); + if (count($stime) < 2 || count($etime) < 2) { + error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry)); + $bad[] = $i; + continue; + } + // Fix start + if ($stime[0] == 23 && $stime[1] >= 30) { + // clamp to next day + $day = strtotime($s[0] . ' 12:00 +1 day'); + if ($day === false || $day <= 0) { + error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry)); + $bad[] = $i; + continue; + } + $day = date('Y-m-d', $day); + $bad[] = $i; + $calendar[] = array( + 'title' => $entry['title'], + 'start' => $day . 'T00:00:01', + 'end' => $entry['end'] + ); + continue; + } + + // Fix end + if ($etime[0] == 0 && $etime[1] <= 30) { + // clamp to next day + $day = strtotime($e[0] . ' 12:00 -1 day'); + if ($day === false || $day <= 0) { + error_log('Ignoring invalid calendar entry from backend ' . $this->serverId . ': ' . json_encode($entry)); + $bad[] = $i; + continue; + } + $day = date('Y-m-d', $day); + $bad[] = $i; + $calendar[] = array( + 'title' => $entry['title'], + 'start' => $day . 'T23:59:59', + 'end' => $entry['end'] + ); + continue; + } + // Split + $nextday = strtotime($s[0] . ' 12:00 +1 day'); + $nextday = date('Y-m-d', $nextday); + $calendar[] = array( + 'title' => $entry['title'], + 'start' => $nextday . 'T00:00:01', + 'end' => $entry['end'] + ); + $entry['end'] = $s[0] . 'T23:59:59'; + } + unset($entry); + if (!empty($bad)) { + foreach ($bad as $i) { + unset($calendar[$i]); + } + $calendar = array_values($calendar); + } + */ + error_log('Post calendar: ' . print_r($calendar, true));
\ No newline at end of file |