summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/inc/coursebackend
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/locationinfo/inc/coursebackend')
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php20
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php20
-rwxr-xr-xmodules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php53
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php383
-rw-r--r--modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php61
5 files changed, 149 insertions, 388 deletions
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
index 07c8457d..786ab459 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_davinci.inc.php
@@ -11,7 +11,7 @@ class CourseBackend_Davinci extends CourseBackend
*/
private $curlHandle = false;
- public function setCredentialsInternal($data)
+ public function setCredentialsInternal(array $data): bool
{
if (empty($data['baseUrl'])) {
$this->addError("No url is given", true);
@@ -24,7 +24,7 @@ class CourseBackend_Davinci extends CourseBackend
return true;
}
- public function checkConnection()
+ public function checkConnection(): bool
{
if (empty($this->location)) {
$this->addError("Credentials are not set", true);
@@ -40,7 +40,7 @@ class CourseBackend_Davinci extends CourseBackend
return true;
}
- public function getCredentialDefinitions()
+ public function getCredentialDefinitions(): array
{
return [
new BackendProperty('baseUrl', 'string'),
@@ -49,17 +49,17 @@ class CourseBackend_Davinci extends CourseBackend
];
}
- public function getDisplayName()
+ public function getDisplayName(): string
{
return 'Davinci';
}
- public function getCacheTime()
+ public function getCacheTime(): int
{
return 30 * 60;
}
- public function getRefreshTime()
+ public function getRefreshTime(): int
{
return 0;
}
@@ -68,9 +68,9 @@ class CourseBackend_Davinci extends CourseBackend
* @param string $roomId unique name of the room, as used by davinci
* @param \DateTime $startDate start date to fetch
* @param \DateTime $endDate end date of range to fetch
- * @return array|bool if successful the arrayrepresentation of the timetable
+ * @return false|string if successful the array representation of the timetable
*/
- private function fetchRoomRaw($roomId, $startDate, $endDate)
+ private function fetchRoomRaw(string $roomId, DateTime $startDate, DateTime $endDate)
{
$url = $this->location . "content=xml&type=room&name=" . urlencode($roomId)
. "&startdate=" . $startDate->format('d.m.Y') . "&enddate=" . $endDate->format('d.m.Y');
@@ -97,7 +97,7 @@ class CourseBackend_Davinci extends CourseBackend
}
- public function fetchSchedulesInternal($requestedRoomIds)
+ public function fetchSchedulesInternal(array $requestedRoomIds): array
{
$startDate = new DateTime('last Monday 0:00');
$endDate = new DateTime('+14 days 0:00');
@@ -134,7 +134,7 @@ class CourseBackend_Davinci extends CourseBackend
$start = substr($start, 0, 2) . ':' . substr($start, 2, 2);
$end = $lesson['Finish'];
$end = substr($end, 0, 2) . ':' . substr($end, 2, 2);
- $subject = isset($lesson['Subject']) ? $lesson['Subject'] : '???';
+ $subject = $lesson['Subject'] ?? '???';
$timetable[] = array(
'title' => $subject,
'start' => $date . "T" . $start . ':00',
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php
index 2cb2be18..4588bf7c 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_dummy.inc.php
@@ -15,9 +15,9 @@ class CourseBackend_Dummy extends CourseBackend
* @param int $serverId ID of the server
* @returns bool if the credentials were in the correct format
*/
- public function setCredentialsInternal($json)
+ public function setCredentialsInternal(array $data): bool
{
- $x = $json;
+ $x = $data;
$this->pw = $x['password'];
if ($this->pw === "mfg") {
@@ -30,7 +30,7 @@ class CourseBackend_Dummy extends CourseBackend
/**
* @return boolean true if the connection works, false otherwise
*/
- public function checkConnection()
+ public function checkConnection(): bool
{
if ($this->pw == "mfg") {
return true;
@@ -42,7 +42,7 @@ class CourseBackend_Dummy extends CourseBackend
/**
* @returns array with parameter name as key and and an array with type, help text and mask as value
*/
- public function getCredentialDefinitions()
+ public function getCredentialDefinitions(): array
{
$options = ["opt1", "opt2", "opt3", "opt4", "opt5", "opt6", "opt7", "opt8"];
return [
@@ -58,7 +58,7 @@ class CourseBackend_Dummy extends CourseBackend
/**
* @return string return display name of backend
*/
- public function getDisplayName()
+ public function getDisplayName(): string
{
return 'Dummy with array';
}
@@ -66,7 +66,7 @@ class CourseBackend_Dummy extends CourseBackend
/**
* @return int desired caching time of results, in seconds. 0 = no caching
*/
- public function getCacheTime()
+ public function getCacheTime(): int
{
return 0;
}
@@ -75,7 +75,7 @@ class CourseBackend_Dummy extends CourseBackend
* @return int age after which timetables are no longer refreshed should be
* greater then CacheTime
*/
- public function getRefreshTime()
+ public function getRefreshTime(): int
{
return 0;
}
@@ -83,15 +83,15 @@ class CourseBackend_Dummy extends CourseBackend
/**
* Internal version of fetch, to be overridden by subclasses.
*
- * @param $roomIds array with local ID as key and serverId as value
+ * @param $requestedRoomIds 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 schedule array contains an array in this format:
* ["start"=>'YYYY-MM-DD<T>HH:MM:SS',"end"=>'YYYY-MM-DD<T>HH:MM:SS',"title"=>string]
*/
- public function fetchSchedulesInternal($roomId)
+ public function fetchSchedulesInternal(array $requestedRoomIds): array
{
$a = array();
- foreach ($roomId as $id) {
+ foreach ($requestedRoomIds as $id) {
if ($id == 1) {
$now = time();
return array($id => array(
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php
index 44847ce2..df33dadd 100755
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_exchange.inc.php
@@ -12,6 +12,7 @@ spl_autoload_register(function ($class) {
require_once $file;
});
+use jamesiarmes\PhpEws\ArrayType\NonEmptyArrayOfBaseFolderIdsType;
use jamesiarmes\PhpEws\Client;
use jamesiarmes\PhpEws\Enumeration\DefaultShapeNamesType;
use jamesiarmes\PhpEws\Enumeration\DistinguishedFolderIdNameType;
@@ -38,7 +39,7 @@ class CourseBackend_Exchange extends CourseBackend
/**
* @return string return display name of backend
*/
- public function getDisplayName()
+ public function getDisplayName(): string
{
return "Microsoft Exchange";
}
@@ -46,7 +47,7 @@ class CourseBackend_Exchange extends CourseBackend
/**
* @returns \BackendProperty[] list of properties that need to be set
*/
- public function getCredentialDefinitions()
+ public function getCredentialDefinitions(): array
{
$options = [
Client::VERSION_2007,
@@ -72,7 +73,7 @@ class CourseBackend_Exchange extends CourseBackend
/**
* @return boolean true if the connection works, false otherwise
*/
- public function checkConnection()
+ public function checkConnection(): bool
{
$client = $this->getClient();
$request = new ResolveNamesType();
@@ -104,7 +105,7 @@ class CourseBackend_Exchange extends CourseBackend
* @param array $data assoc array with data required by backend
* @returns bool if the credentials were in the correct format
*/
- public function setCredentialsInternal($data)
+ public function setCredentialsInternal(array $data): bool
{
foreach (['username', 'password'] as $field) {
if (empty($data[$field])) {
@@ -133,7 +134,7 @@ class CourseBackend_Exchange extends CourseBackend
/**
* @return int desired caching time of results, in seconds. 0 = no caching
*/
- public function getCacheTime()
+ public function getCacheTime(): int
{
return 15 * 60;
}
@@ -142,7 +143,7 @@ class CourseBackend_Exchange extends CourseBackend
* @return int age after which timetables are no longer refreshed. should be
* greater than CacheTime.
*/
- public function getRefreshTime()
+ public function getRefreshTime(): int
{
return 30 * 60;
}
@@ -150,12 +151,12 @@ class CourseBackend_Exchange extends CourseBackend
/**
* Internal version of fetch, to be overridden by subclasses.
*
- * @param $roomIds array with local ID as key and serverId as value
+ * @param $requestedRoomIds 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 schedule 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)
+ protected function fetchSchedulesInternal(array $requestedRoomIds): array
{
$startDate = new DateTime('last Monday 0:00');
$endDate = new DateTime('+14 days 0:00');
@@ -172,8 +173,13 @@ class CourseBackend_Exchange extends CourseBackend
// 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);
+ try {
+ $start = new DateTime($item->Start);
+ $end = new DateTime($item->End);
+ } catch (Exception $e) {
+ $this->addError("Invalid date range: '{$item->Start}' -> '{$item->End}'", false);
+ continue;
+ }
$schedules[$roomId][] = array(
'title' => $item->Subject,
@@ -186,13 +192,9 @@ class CourseBackend_Exchange extends CourseBackend
}
/**
- * @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)
+ public function findEventsForRoom(Client $client, DateTime $startDate, DateTime $endDate, string $roomAddress): array
{
$request = new FindItemType();
$request->Traversal = ItemQueryTraversalType::SHALLOW;
@@ -206,12 +208,20 @@ class CourseBackend_Exchange extends CourseBackend
$folderId->Id = DistinguishedFolderIdNameType::CALENDAR;
$folderId->Mailbox = new EmailAddressType();
$folderId->Mailbox->EmailAddress = $roomAddress;
+ $request->ParentFolderIds = new NonEmptyArrayOfBaseFolderIdsType();
$request->ParentFolderIds->DistinguishedFolderId[] = $folderId;
- $response = $client->FindItem($request);
- $response_messages = $response->ResponseMessages->FindItemResponseMessage;
-
+ try {
+ $response = $client->FindItem($request);
+ } catch (Exception $e) {
+ $this->addError('Exception calling FindItem: ' . $e->getMessage(), true);
+ return [];
+ }
+ if (!is_object($response->ResponseMessages)) {
+ $this->addError('FindItem returned response without ResponseMessages', true);
+ return [];
+ }
$items = [];
- foreach ($response_messages as $response_message) {
+ foreach ($response->ResponseMessages->FindItemResponseMessage as $response_message) {
// Make sure the request succeeded.
if ($response_message->ResponseClass !== ResponseClassType::SUCCESS) {
$code = $response_message->ResponseCode;
@@ -224,10 +234,7 @@ class CourseBackend_Exchange extends CourseBackend
return $items;
}
- /**
- * @return \jamesiarmes\PhpEws\Client
- */
- public function getClient()
+ public function getClient(): Client
{
$client = new Client($this->serverAddress, $this->username, $this->password, $this->clientVersion);
$client->setTimezone($this->timezone);
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
index 4664a011..55d5ed4b 100644
--- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php
@@ -1,391 +1,84 @@
<?php
-class CourseBackend_HisInOne extends CourseBackend
+class CourseBackend_HisInOne extends ICalCourseBackend
{
- private $username = '';
- private $password = '';
- private $open = true;
- private $location;
- private $verifyHostname = true;
- private $verifyCert = true;
- /**
- * @var bool|resource
- */
- private $curlHandle = false;
-
- public function setCredentialsInternal($data)
+ public function setCredentialsInternal(array $data): bool
{
- if (!$data['open']) {
- // If not using OpenCourseService, require credentials
- foreach (['username', 'password'] as $field) {
- if (empty($data[$field])) {
- $this->addError('setCredentials: Missing field ' . $field, true);
- return false;
- }
- }
- }
if (empty($data['baseUrl'])) {
$this->addError("No url is given", true);
return false;
}
- $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']);
- if ($this->open) {
- $this->location = $url . "/qisserver/services2/OpenCourseService";
- } else {
- $this->location = $url . "/qisserver/services2/CourseService";
- }
- $this->verifyHostname = $data['verifyHostname'];
- $this->verifyCert = $data['verifyCert'];
+ $this->init($this->mangleProperty('baseUrl', $data['baseUrl']),
+ $data['verifyCert'], $data['verifyHostname']);
return true;
}
- public function getCredentialDefinitions()
+ public function getCredentialDefinitions(): array
{
return [
new BackendProperty('baseUrl', 'string'),
- new BackendProperty('username', 'string'),
- new BackendProperty('role', 'string'),
- new BackendProperty('password', 'password'),
- new BackendProperty('open', ['OpenCourseService', 'CourseService'], 'OpenCourseService'),
new BackendProperty('verifyCert', 'bool', true),
new BackendProperty('verifyHostname', 'bool', true)
];
}
- public function checkConnection()
+ public function mangleProperty(string $prop, $value)
{
- if (empty($this->location)) {
- $this->addError("Credentials are not set", true);
- return false;
- }
- return $this->findUnit(123456789, date('Y-m-d'), true) !== false;
- }
-
- /**
- * @param int $roomId his in one room id to get
- * @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, $day, $connectionCheckOnly = false)
- {
- $doc = new DOMDocument('1.0', 'utf-8');
- $doc->formatOutput = true;
- $envelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:Envelope');
- $doc->appendChild($envelope);
- if ($this->open) {
- $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);
- //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('ns1:individualDatesExecutionDate', $day));
- $findUnit->appendChild($doc->createElement('ns1:roomId', $roomId));
-
- $soap_request = $doc->saveXML();
- $response1 = $this->postToServer($soap_request, "findUnit");
- if ($response1 === false) {
- $this->addError('Could not fetch room ' . $roomId, true);
- return false;
- }
- $response2 = $this->xmlStringToArray($response1, $err);
- if (!is_array($response2)) {
- $this->addError("Parsing room $roomId: $err", false);
- return false;
- }
- if (!isset($response2['soapenvBody'])) {
- $this->addError('Backend reply is missing element soapenvBody', true);
- return false;
- }
- if (isset($response2['soapenvBody']['soapenvFault'])) {
- $this->addError('SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring'], true);
- return false;
- }
- // We only need to check if the connection is working (URL ok, credentials ok, ..) so bail out early
- if ($connectionCheckOnly) {
- return array();
- }
- if ($this->open) {
- $path = '/soapenvBody/hisfindUnitResponse/hisunits';
- $subpath = '/hisunit/hisid';
- } else {
- $path = '/soapenvBody/hisfindUnitResponse/hisunitIds';
- $subpath = '/hisid';
- }
- $idSubDoc = $this->getArrayPath($response2, $path);
- if ($idSubDoc === false) {
- $this->addError('Cannot find ' . $path, false);
- //@file_put_contents('/tmp/findUnit-1.' . $roomId . '.' . microtime(true), print_r($response2, true));
- return false;
- }
- if (empty($idSubDoc))
- return $idSubDoc;
- $idList = $this->getArrayPath($idSubDoc, $subpath);
- if ($idList === false) {
- $this->addError('Cannot find ' . $subpath . ' after ' . $path, false);
- @file_put_contents('/tmp/bwlp-findUnit-2.' . $roomId . '.' . microtime(true), print_r($idSubDoc, true));
+ if ($prop === 'baseUrl') {
+ // Update form SOAP to iCal url
+ if (preg_match(',^(http.*?)/qisserver,', $value, $out)) {
+ $value = $out[1] . '/qisserver/pages/cm/exa/timetable/roomScheduleCalendarExport.faces?roomId=%ID%';
+ } elseif (preg_match(',(.*[/=])\d*$', $value, $out)) {
+ $value = $out[1] . '%ID%';
+ } elseif (substr_count($value, '/') <= 3) {
+ if (substr($value, -1) !== '/') {
+ $value .= '/';
+ }
+ $value .= 'qisserver/pages/cm/exa/timetable/roomScheduleCalendarExport.faces?roomId=%ID%';
+ }
}
- return $idList;
+ return $value;
}
- /**
- * @param $doc DOMDocument
- * @return DOMElement
- */
- private function getHeader($doc)
+ protected function toTitle(ICalEvent $event): string
{
- $header = $doc->createElement('SOAP-ENV:Header');
- $security = $doc->createElementNS('http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd', 'ns2:Security');
- $mustunderstand = $doc->createAttribute('SOAP-ENV:mustUnderstand');
- $mustunderstand->value = 1;
- $security->appendChild($mustunderstand);
- $header->appendChild($security);
- $token = $doc->createElement('ns2:UsernameToken');
- $security->appendChild($token);
- $user = $doc->createElement('ns2:Username', $this->username);
- $token->appendChild($user);
- $pass = $doc->createElement('ns2:Password', $this->password);
- $type = $doc->createAttribute('Type');
- $type->value = 'http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordText';
- $pass->appendChild($type);
- $token->appendChild($pass);
- return $header;
+ $title = parent::toTitle($event);
+ // His in one seems to prefix *some* (but *not* all) of the lectures by their ID/("Nummer")
+ // No clue what that format is supposed to be, this regex is some guesswork after observing this for a while
+ return preg_replace('#^[0-9][0-9A-ZÄÖÜ]{3,9}-[A-Za-z0-9/_ÄÖÜäöüß.-]{4,30}\s+#u', '', $title);
}
- /**
- * @param $request string with xml SOAP request
- * @param $action string with the name of the SOAP action
- * @return bool|string if successful the answer xml from the SOAP server
- */
- private function postToServer($request, $action)
+ public function checkConnection(): bool
{
- $header = array(
- 'Content-type: text/xml;charset="utf-8"',
- 'SOAPAction: "' . $action . '"',
- );
-
- if ($this->curlHandle === false) {
- $this->curlHandle = curl_init();
- }
-
- $options = array(
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_SSL_VERIFYHOST => $this->verifyHostname ? 2 : 0,
- CURLOPT_SSL_VERIFYPEER => $this->verifyCert ? 1 : 0,
- CURLOPT_URL => $this->location,
- CURLOPT_POSTFIELDS => $request,
- CURLOPT_HTTPHEADER => $header,
- CURLOPT_TIMEOUT => 15,
- CURLOPT_CONNECTTIMEOUT => 3,
- );
-
- curl_setopt_array($this->curlHandle, $options);
-
- $output = curl_exec($this->curlHandle);
-
- if ($output === false) {
- $this->addError('Curl error: ' . curl_error($this->curlHandle), false);
- }
- return $output;
+ if (!$this->isOK())
+ return false;
+ // Unfortunately HisInOne returns an internal server error if you pass an invalid roomId.
+ // So we just try a bunch and see if anything works. Even if this fails, using
+ // the backend should work, given the URL is actually correct.
+ foreach ([60, 100, 5, 10, 50, 110, 200, 210, 250, 300, 333, 500, 1000, 2000] as $roomId) {
+ if ($this->downloadIcal($roomId) !== null)
+ return true;
+ }
+ return false;
}
- public function getCacheTime()
+ public function getCacheTime(): int
{
return 30 * 60;
}
-
- public function getRefreshTime()
+ public function getRefreshTime(): int
{
return 60 * 60;
}
- public function getDisplayName()
+ public function getDisplayName(): string
{
return "HisInOne";
}
- public function fetchSchedulesInternal($requestedRoomIds)
- {
- if (empty($requestedRoomIds)) {
- return array();
- }
- $currentWeek = $this->getCurrentWeekDates();
- $tTables = [];
- //get all eventIDs in a given room
- $eventIds = [];
- foreach ($requestedRoomIds as $roomId) {
- $ok = false;
- foreach ($currentWeek as $day) {
- $roomEventIds = $this->findUnit($roomId, $day, false);
- if ($roomEventIds === false)
- continue;
- $ok = true;
- $eventIds = array_merge($eventIds, $roomEventIds);
- }
- if ($ok) {
- $tTables[$roomId] = [];
- }
- }
- $eventIds = array_unique($eventIds);
- if (empty($eventIds)) {
- return $tTables;
- }
- $eventDetails = [];
- //get all information on each event
- foreach ($eventIds as $eventId) {
- $event = $this->readUnit(intval($eventId));
- if ($event === false)
- continue;
- $eventDetails = array_merge($eventDetails, $event);
- }
- $name = false;
- $now = time();
- foreach ($eventDetails as $event) {
- foreach (array('/hisdefaulttext',
- '/hisshorttext',
- '/hisshortcomment') as $path) {
- $name = $this->getArrayPath($event, $path);
- if (!empty($name) && !empty($name[0]))
- break;
- $name = false;
- }
- if ($name === false) {
- $name = ['???'];
- }
- $planElements = $this->getArrayPath($event, '/hisplanelements/hisplanelement');
- if ($planElements === false) {
- $this->addError('Cannot find ./hisplanelements/hisplanelement', false);
- //error_log('Cannot find ./hisplanelements/hisplanelement');
- //error_log(print_r($event, true));
- continue;
- }
- 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->addError('Cannot find ./hisplannedDates/hisplannedDate/hisindividualDates/hisindividualDate', false);
- //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,
- );
- }
- }
- }
- }
- return $tTables;
- }
-
-
- /**
- * @param $unit int ID of the subject in HisInOne database
- * @return bool|array false if there was an error otherwise an array with the information about the subject
- */
- public function readUnit($unit)
- {
- $doc = new DOMDocument('1.0', 'utf-8');
- $doc->formatOutput = true;
- $envelope = $doc->createElementNS('http://schemas.xmlsoap.org/soap/envelope/', 'SOAP-ENV:Envelope');
- $doc->appendChild($envelope);
- if ($this->open) {
- $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);
- //body of the request
- $body = $doc->createElement('SOAP-ENV:Body');
- $envelope->appendChild($body);
- $readUnit = $doc->createElement('ns1:readUnit');
- $body->appendChild($readUnit);
- $readUnit->appendChild($doc->createElement('ns1:unitId', $unit));
-
- $soap_request = $doc->saveXML();
- $response1 = $this->postToServer($soap_request, "readUnit");
- if ($response1 === false) {
- return false;
- }
- $response2 = $this->xmlStringToArray($response1, $err);
- if ($response2 === false) {
- $this->addError("Cannot parse unit $unit as XML: $err", false);
- return false;
- }
- if (!isset($response2['soapenvBody'])) {
- $this->addError('Backend reply is missing element soapenvBody', true);
- return false;
- }
- if (isset($response2['soapenvBody']['soapenvFault'])) {
- $this->addError('SOAP-Fault (' . $response2['soapenvBody']['soapenvFault']['faultcode'] . ") " . $response2['soapenvBody']['soapenvFault']['faultstring'], true);
- return false;
- }
- return $this->getArrayPath($response2, '/soapenvBody/hisreadUnitResponse/hisunit');
- }
-
- /**
- * @return array with days of the current week in datetime format
- */
- private function getCurrentWeekDates()
- {
- $returnValue = array();
- $date = date('Y-m-d', strtotime('last Monday'));
- for ($i = 0; $i < 14; $i++) {
- $returnValue[] = $date;
- $date = date('Y-m-d', strtotime($date.' +1 day'));
- }
- return $returnValue;
- }
-
- public function __destruct()
- {
- if ($this->curlHandle !== false) {
- curl_close($this->curlHandle);
- }
- }
-
}
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php
new file mode 100644
index 00000000..f1791c4e
--- /dev/null
+++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_ical.inc.php
@@ -0,0 +1,61 @@
+<?php
+
+class CourseBackend_ICal extends ICalCourseBackend
+{
+
+ /** @var string room ID for testing connection */
+ private $testId;
+
+ public function setCredentialsInternal(array $data): bool
+ {
+ if (empty($data['baseUrl'])) {
+ $this->addError("No url is given", true);
+ return false;
+ }
+
+ $this->init($data['baseUrl'], $data['verifyCert'], $data['verifyHostname'], $data['authMethod'],
+ $data['user'], $data['pass']);
+ $this->testId = $data['testId'];
+
+ return true;
+ }
+
+ public function getCredentialDefinitions(): array
+ {
+ return [
+ new BackendProperty('baseUrl', 'string'),
+ new BackendProperty('verifyCert', 'bool', true),
+ new BackendProperty('verifyHostname', 'bool', true),
+ new BackendProperty('testId', 'string'),
+ new BackendProperty('authMethod', ['NONE', 'BASIC', 'DIGEST', 'GSSNEGOTIATE', 'NTLM'], 'NONE'),
+ new BackendProperty('user', 'string'),
+ new BackendProperty('pass', 'string'),
+ ];
+ }
+
+ public function checkConnection(): bool
+ {
+ if (!$this->isOK())
+ return false;
+ if (empty($this->testId))
+ return true;
+ return ($this->downloadIcal($this->testId) !== null);
+ }
+
+ public function getCacheTime(): int
+ {
+ return 30 * 60;
+ }
+
+ public function getRefreshTime(): int
+ {
+ return 60 * 60;
+ }
+
+
+ public function getDisplayName(): string
+ {
+ return "iCal";
+ }
+
+}