. */ if (!defined('BASEPATH')) exit('No direct script access allowed'); // require_once('../../include/ical.class.php'); class FreeBusyLib { private $_ci; // Code igniter instance public function __construct() { $this->_ci =& get_instance(); $this->_ci->load->model("ressource/Zeitsperre_model", "ZeitsperreModel"); } //------------------------------------------------------------------------------------------------------------------ // Public methods public function getFreeBusy($url) { $fileStream = @fopen($url, "r"); if (!$fileStream) return []; $busyTimeslots = []; $fileContent = file_get_contents($url); if (mb_strpos($fileContent, "BEGIN:VFREEBUSY") !== false) { $busyTimeslots = $this->parseFreeBusyFormat($fileContent); } else { $busyTimeslots = $this->parseConventionalFormat($fileContent); } return $busyTimeslots; } public function getDefaultInternalFreeBusy($uid) { $events = []; $this->_ci->load->library('StundenplanLib'); $startDate = new DateTime(); $startDate = $startDate->format("Y-m-d"); $endDate = new DateTime(); $endDate->modify("+1 year"); $endDate = $endDate->format("Y-m-d"); $userEvents = getData($this->_ci->stundenplanlib->getEventsUser($startDate, $endDate, $uid)); if ($userEvents && count($userEvents)) { $userEvents = array_map( function ($event) { return [ "start" => $event->datum . " " . $event->beginn, "end" => $event->datum . " " . $event->ende, ]; }, $userEvents ); $events = array_merge($events, $userEvents); } $userAbsences = getData($this->_ci->ZeitsperreModel->getZeitsperre($uid)); if ($userAbsences && count($userAbsences)) { $today = new DateTime(); $today = $today->format("Y-m-d"); $userAbsences = array_filter( $userAbsences, function ($absence) use ($today) { return $absence->bisdatum >= $today; } ); $userAbsences = array_map( function ($absence) { return [ "start" => $absence->vondatum . " 00:00:00", "end" => $absence->bisdatum . " 23:59:00", ]; }, $userAbsences ); $events = array_merge($events, $userAbsences); } return $events; } //------------------------------------------------------------------------------------------------------------------ // Private methods private function parseConventionalFormat($fileContent) { $fileContentRows = explode("\n", $fileContent); $fileContentRows = array_map(function ($row) { return trim($row); }, $fileContentRows); $busyTimeslots = []; $isParsingEvent = false; $parsedEvent = ["start" => null, "end" => null]; $currentDateTime = new DateTime(); $currentDateTime = $currentDateTime->format("Y-m-d H:i:s"); foreach ($fileContentRows as $row) { if (mb_strpos($row, "BEGIN:VEVENT") !== false) { $isParsingEvent = true; } else if (mb_strpos($row, "END:VEVENT") !== false) { if ( $isParsingEvent && $parsedEvent["start"] && $parsedEvent["end"] && $parsedEvent["end"] > $currentDateTime ) { $busyTimeslots[] = $parsedEvent; } $isParsingEvent = false; $parsedEvent["start"] = null; $parsedEvent["end"] = null; } else if (mb_strpos($row, "DTSTART;VALUE=DATE") !== false) { $startDateString = explode(":", $row)[1]; $start = substr($startDateString, 0, 4) . "-" . substr($startDateString, 4, 2) . "-" . substr($startDateString, 6, 2) . " 00:00:00"; $parsedEvent["start"] = $start; } else if (mb_strpos($row, "DTSTART") !== false) { $timestamp = explode(":", $row)[1]; if (mb_substr($timestamp, -1) === "Z") { $timestamp = $this->convertTimestampToLocalTimezone($timestamp); } else if (mb_strpos($row, "TZID=") !== false) { $remainingString = explode("TZID=", $row)[1]; $remainingString = explode(":", $remainingString)[0]; $timezoneIdentifier = explode(";", $remainingString)[0]; $timestamp = $this->convertTimestampToLocalTimezone($timestamp, $timezoneIdentifier); } $startDate = substr($timestamp, 0, 4) . "-" . substr($timestamp, 4, 2) . "-" . substr($timestamp, 6, 2); $startTime = substr($timestamp, 9, 2) . ":" . substr($timestamp, 11, 2) . ":" . substr($timestamp, 13, 2); $parsedEvent["start"] = $startDate . " " . $startTime; } else if (mb_strpos($row, "DTEND;VALUE=DATE") !== false) { $endDateString = explode(":", $row)[1]; $end = substr($endDateString, 0, 4) . "-" . substr($endDateString, 4, 2) . "-" . substr($endDateString, 6, 2) . " 00:00:00"; $parsedEvent["end"] = $end; } else if (mb_strpos($row, "DTEND") !== false) { $timestamp = explode(":", $row)[1]; if (mb_substr($timestamp, -1) === "Z") { $timestamp = $this->convertTimestampToLocalTimezone($timestamp); } else if (mb_strpos($row, "TZID=") !== false) { $remainingString = explode("TZID=", $row)[1]; $remainingString = explode(":", $remainingString)[0]; $timezoneIdentifier = explode(";", $remainingString)[0]; $timestamp = $this->convertTimestampToLocalTimezone($timestamp, $timezoneIdentifier); } $endDate = substr($timestamp, 0, 4) . "-" . substr($timestamp, 4, 2) . "-" . substr($timestamp, 6, 2); $endTime = substr($timestamp, 9, 2) . ":" . substr($timestamp, 11, 2) . ":" . substr($timestamp, 13, 2); $parsedEvent["end"] = $endDate . " " . $endTime; } } return $busyTimeslots; } private function parseFreeBusyFormat($fileContent) { $fileContentRows = explode("\n", $fileContent); $fileContentRows = array_map(function ($row) { return trim($row); }, $fileContentRows); $busyTimeslots = []; $currentDateTime = new DateTime(); $currentDateTime = $currentDateTime->format("Y-m-d H:i:s"); foreach ($fileContentRows as $row) { if ( mb_strpos($row, "VFREEBUSY") !== false || mb_strpos($row, "FREEBUSY") === false || mb_strpos($row, "FBTYPE=FREE") !== false ) continue; $timestamps = explode(":", $row)[1]; $timestamps = explode(",", $timestamps); foreach ($timestamps as $timestamp) { $startEndTimestamps = explode("/", $timestamp); $startTimestamp = $startEndTimestamps[0]; $endTimestamp = $startEndTimestamps[1]; if (mb_substr($startTimestamp, -1) === "Z") { $startTimestamp = $this->convertTimestampToLocalTimezone($startTimestamp); } if (mb_substr($endTimestamp, -1) === "Z") { $endTimestamp = $this->convertTimestampToLocalTimezone($endTimestamp); } $startDate = substr($startTimestamp, 0, 4) . "-" . substr($startTimestamp, 4, 2) . "-" . substr($startTimestamp, 6, 2); $startTime = substr($startTimestamp, 9, 2) . ":" . substr($startTimestamp, 11, 2) . ":" . substr($startTimestamp, 13, 2); $start = $startDate . " " . $startTime; $endDate = substr($endTimestamp, 0, 4) . "-" . substr($endTimestamp, 4, 2) . "-" . substr($endTimestamp, 6, 2); $endTime = substr($endTimestamp, 9, 2) . ":" . substr($endTimestamp, 11, 2) . ":" . substr($endTimestamp, 13, 2); $end = $endDate . " " . $endTime; if ($end < $currentDateTime) continue; $busyTimeslots[] = ["start" => $start, "end" => $end]; } } return $busyTimeslots; } private function convertTimestampToLocalTimezone($timestamp, $originalTimezoneIdentifier = "UTC") { $originalTimezone = new DateTimeZone($originalTimezoneIdentifier); $localTimezone = new DateTimeZone("Europe/Vienna"); $date = new DateTime($timestamp, $originalTimezone); $date->setTimezone($localTimezone); return $date->format("Ymd\THis"); } }