diff options
Diffstat (limited to 'modules-available/locationinfo/inc/coursebackend')
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"; + } + +} |