diff options
Diffstat (limited to 'modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php')
-rw-r--r-- | modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php | 131 |
1 files changed, 22 insertions, 109 deletions
diff --git a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php index ee152684..55d5ed4b 100644 --- a/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php +++ b/modules-available/locationinfo/inc/coursebackend/coursebackend_hisinone.inc.php @@ -1,31 +1,22 @@ <?php -class CourseBackend_HisInOne extends CourseBackend +class CourseBackend_HisInOne extends ICalCourseBackend { - 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 (empty($data['baseUrl'])) { $this->addError("No url is given", true); return false; } - $this->location = $this->mangleProperty('baseUrl', $data['baseUrl']); - $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'), @@ -34,30 +25,36 @@ class CourseBackend_HisInOne extends CourseBackend ]; } - public function mangleProperty($prop, $value) + public function mangleProperty(string $prop, $value) { 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='; + $value = $out[1] . '/qisserver/pages/cm/exa/timetable/roomScheduleCalendarExport.faces?roomId=%ID%'; } elseif (preg_match(',(.*[/=])\d*$', $value, $out)) { - $value = $out[1]; + $value = $out[1] . '%ID%'; } elseif (substr_count($value, '/') <= 3) { if (substr($value, -1) !== '/') { $value .= '/'; } - $value .= 'qisserver/pages/cm/exa/timetable/roomScheduleCalendarExport.faces?roomId='; + $value .= 'qisserver/pages/cm/exa/timetable/roomScheduleCalendarExport.faces?roomId=%ID%'; } } return $value; } - public function checkConnection() + protected function toTitle(ICalEvent $event): string + { + $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); + } + + public function checkConnection(): bool { - if (empty($this->location)) { - $this->addError("Credentials are not set", true); + 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. @@ -68,104 +65,20 @@ class CourseBackend_HisInOne extends CourseBackend return false; } - /** - * @param int $roomId room id - * @return ICalEvent[]|null all events for this room in the range -7 days to +7 days, or NULL on error - */ - private function downloadIcal($roomId) - { - if ($this->curlHandle === false) { - $this->curlHandle = curl_init(); - } - - $ical = new ICalParser(['filterDaysBefore' => 7, 'filterDaysAfter' => 7]); - $options = array( - CURLOPT_WRITEFUNCTION => function ($ch, $data) use ($ical) { - $ical->feedData($data); - return strlen($data); - }, - CURLOPT_FOLLOWLOCATION => true, - CURLOPT_SSL_VERIFYHOST => $this->verifyHostname ? 2 : 0, - CURLOPT_SSL_VERIFYPEER => $this->verifyCert ? 1 : 0, - CURLOPT_URL => $this->location . $roomId, - CURLOPT_TIMEOUT => 60, - CURLOPT_CONNECTTIMEOUT => 4, - ); - - curl_setopt_array($this->curlHandle, $options); - - if (!curl_exec($this->curlHandle)) { - $this->addError('Curl error: ' . curl_error($this->curlHandle), false); - } - $ical->finish(); - if (!$ical->isValid()) { - error_log('Did not find a VCALENDAR in returned data'); - return null; - } - return $ical->events(); - } - - 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(); - } - $tTables = []; - foreach ($requestedRoomIds as $roomId) { - $data = $this->downloadIcal($roomId); - if ($data === null) { - $this->addError("Downloading ical for $roomId failed", false); - continue; - } - foreach ($data as $event) { - $tTables[$roomId][] = array( - 'title' => $this->toTitle($event), - 'start' => $event->dtstart, - 'end' => $event->dtend, - 'cancelled' => false, // ??? How - ); - } - } - return $tTables; - } - - /** - * Get a usable title from either SUMMARY or DESCRIPTION - * @param ICalEvent $event - */ - private function toTitle($event) - { - $title = $event->summary; - if (empty($title)) { - $title = $event->description; - } - if (empty($title)) { - $title = 'Unknown'; - } - return preg_replace([',(\s*<br\s*/?>\s*|\r|\n|\\\r|\\\n)+,', '/\\\\([,;:])/'], ["\n", '$1'], $title); - } - - public function __destruct() - { - if ($this->curlHandle !== false) { - curl_close($this->curlHandle); - } - } - } |