summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/inc
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/locationinfo/inc')
-rw-r--r--modules-available/locationinfo/inc/coursebackend.inc.php7
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php22
-rwxr-xr-xmodules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php242
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php147
-rwxr-xr-xmodules-available/locationinfo/inc/coursebackend/exchange.todo203
-rw-r--r--modules-available/locationinfo/inc/infopanel.inc.php9
-rw-r--r--modules-available/locationinfo/inc/locationinfo.inc.php23
-rw-r--r--modules-available/locationinfo/inc/splittime.php.txt80
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