summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/inc/icalcoursebackend.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/locationinfo/inc/icalcoursebackend.inc.php')
-rw-r--r--modules-available/locationinfo/inc/icalcoursebackend.inc.php148
1 files changed, 148 insertions, 0 deletions
diff --git a/modules-available/locationinfo/inc/icalcoursebackend.inc.php b/modules-available/locationinfo/inc/icalcoursebackend.inc.php
new file mode 100644
index 00000000..838d18b7
--- /dev/null
+++ b/modules-available/locationinfo/inc/icalcoursebackend.inc.php
@@ -0,0 +1,148 @@
+<?php
+
+abstract class ICalCourseBackend extends CourseBackend
+{
+
+ /** @var string */
+ private $location;
+ /** @var string */
+ private $authMethod;
+ /** @var string */
+ private $user;
+ /** @var string */
+ private $pass;
+ /** @var bool */
+ private $verifyHostname;
+ /** @var bool */
+ private $verifyCert;
+ /** @var bool|resource */
+ private $curlHandle = false;
+
+ protected function init(
+ string $location, bool $verifyCert, bool $verifyHostname,
+ string $authMethod = 'NONE', string $user = '', string $pass = '')
+ {
+ $this->verifyCert = $verifyCert;
+ $this->verifyHostname = $verifyHostname;
+ if (strpos($location, '%ID%') === false) {
+ $location .= '%ID%';
+ }
+ $this->location = $location;
+ $this->authMethod = $authMethod;
+ $this->user = $user;
+ $this->pass = $pass;
+ }
+
+ /**
+ * @param string $roomId room id
+ * @param callable $errorFunc
+ * @return ICalEvent[]|null all events for this room in the range -7 days to +7 days, or NULL on error
+ */
+ protected function downloadIcal(string $roomId): ?array
+ {
+ if (!$this->isOK())
+ return null;
+
+ try {
+ $ical = new ICalParser(['filterDaysBefore' => 7, 'filterDaysAfter' => 7]);
+ } catch (Exception $e) {
+ $this->addError('Error instantiating ICalParser: ' . $e->getMessage(), true);
+ return null;
+ }
+
+ if ($this->curlHandle === false) {
+ $this->curlHandle = curl_init();
+ }
+
+ $options = [
+ 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 => str_replace('%ID%', $roomId, $this->location),
+ CURLOPT_TIMEOUT => 60,
+ CURLOPT_CONNECTTIMEOUT => 4,
+ ];
+ if ($this->authMethod !== 'NONE' && defined('CURLAUTH_' . $this->authMethod)) {
+ $options[CURLOPT_HTTPAUTH] = constant('CURLAUTH_' . $this->authMethod);
+ $options[CURLOPT_USERPWD] = $this->user;
+ if (!empty($this->pass)) {
+ $options[CURLOPT_USERPWD] .= ':' . $this->pass;
+ }
+ }
+
+ curl_setopt_array($this->curlHandle, $options);
+
+ $curlRet = curl_exec($this->curlHandle);
+ if (!$curlRet) {
+ $this->addError('Curl error: ' . curl_error($this->curlHandle) . ' for ' . $roomId, false);
+ }
+ $ical->finish();
+ if (!$ical->isValid()) {
+ if ($curlRet) {
+ $this->addError("Did not find a VCALENDAR in returned data for $roomId", false);
+ }
+ return null;
+ }
+ return $ical->events();
+ }
+
+ public function fetchSchedulesInternal(array $requestedRoomIds): array
+ {
+ if (empty($requestedRoomIds) || !$this->isOK()) {
+ 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
+ */
+ protected function toTitle(ICalEvent $event): string
+ {
+ $title = $event->summary;
+ if (empty($title)) {
+ $title = $event->description;
+ }
+ if (empty($title)) {
+ $title = 'Unknown';
+ }
+ return (string)preg_replace([',(\s*<br\s*/?>\s*|\r|\n|\\\r|\\\n)+,', '/\\\\([,;:])/'], ["\n", '$1'], $title);
+ }
+
+ protected function isOK(): bool
+ {
+ if (empty($this->location)) {
+ $this->addError("Credentials are not set", true);
+ return false;
+ }
+ return true;
+ }
+
+ public function __destruct()
+ {
+ if ($this->curlHandle !== false) {
+ curl_close($this->curlHandle);
+ }
+ }
+
+} \ No newline at end of file