summaryrefslogtreecommitdiffstats
path: root/modules-available/locationinfo/inc/icalparser.inc.php
diff options
context:
space:
mode:
Diffstat (limited to 'modules-available/locationinfo/inc/icalparser.inc.php')
-rw-r--r--modules-available/locationinfo/inc/icalparser.inc.php151
1 files changed, 54 insertions, 97 deletions
diff --git a/modules-available/locationinfo/inc/icalparser.inc.php b/modules-available/locationinfo/inc/icalparser.inc.php
index 0be8777b..eacb67b1 100644
--- a/modules-available/locationinfo/inc/icalparser.inc.php
+++ b/modules-available/locationinfo/inc/icalparser.inc.php
@@ -23,7 +23,6 @@ class ICalParser
const ICAL_DATE_TIME_TEMPLATE = 'TZID=%s:';
const ISO_8601_WEEK_START = 'MO';
const RECURRENCE_EVENT = 'Generated recurrence event';
- const TIME_FORMAT = 'His';
const TIME_ZONE_UTC = 'UTC';
const UNIX_FORMAT = 'U';
@@ -481,15 +480,12 @@ class ICalParser
/**
* Creates the ICal object
*
- * @param mixed $files
* @param array $options
* @return void
* @throws Exception
*/
public function __construct(array $options = array())
{
- ini_set('auto_detect_line_endings', '1');
-
foreach ($options as $option => $value) {
if (in_array($option, self::$configurableOptions)) {
$this->{$option} = $value;
@@ -501,10 +497,7 @@ class ICalParser
$this->defaultTimeZone = date_default_timezone_get();
}
- // Ideally you would use `PHP_INT_MIN` from PHP 7
- $php_int_min = -2147483648;
-
- $this->windowMinTimestamp = is_null($this->filterDaysBefore) ? $php_int_min : (new DateTime('now'))->sub(new DateInterval('P' . $this->filterDaysBefore . 'D'))->getTimestamp();
+ $this->windowMinTimestamp = is_null($this->filterDaysBefore) ? PHP_INT_MIN : (new DateTime('now'))->sub(new DateInterval('P' . $this->filterDaysBefore . 'D'))->getTimestamp();
$this->windowMaxTimestamp = is_null($this->filterDaysAfter) ? PHP_INT_MAX : (new DateTime('now'))->add(new DateInterval('P' . $this->filterDaysAfter . 'D'))->getTimestamp();
$this->shouldFilterByWindow = !is_null($this->filterDaysBefore) || !is_null($this->filterDaysAfter);
@@ -516,7 +509,7 @@ class ICalParser
*
* @param string $data
*/
- public function feedData($data)
+ public function feedData(string $data)
{
$this->feedBuffer .= $data;
$start = 0;
@@ -581,7 +574,7 @@ class ICalParser
*
* @return bool
*/
- public function isValid()
+ public function isValid(): bool
{
return $this->hasSeenStart;
}
@@ -591,7 +584,7 @@ class ICalParser
*
* @param string $line
*/
- protected function handleLine($line)
+ protected function handleLine(string $line)
{
$line = rtrim($line); // Trim trailing whitespace
$line = $this->removeUnprintableChars($line);
@@ -602,18 +595,18 @@ class ICalParser
$add = $this->keyValueFromString($line);
- if ($add === false) {
+ if ($add === null) {
return;
}
- $keyword = $add[0];
+ $keyword = $add[0]; // string
$values = $add[1]; // May be an array containing multiple values
if (!is_array($values)) {
if (!empty($values)) {
$values = array($values); // Make an array as not already
$blankArray = array(); // Empty placeholder array
- array_push($values, $blankArray);
+ $values[] = $blankArray;
} else {
$values = array(); // Use blank array to ignore this line
}
@@ -752,16 +745,9 @@ class ICalParser
foreach ($events as $key => $anEvent) {
if ($anEvent === null) {
unset($events[$key]);
-
- continue;
- }
-
- if ($this->doesEventStartOutsideWindow($anEvent)) {
+ } elseif ($this->doesEventStartOutsideWindow($anEvent)) {
$this->eventCount--;
-
unset($events[$key]);
-
- continue;
}
}
@@ -776,7 +762,7 @@ class ICalParser
* @param array $event
* @return boolean
*/
- protected function doesEventStartOutsideWindow(array $event)
+ protected function doesEventStartOutsideWindow(array $event): bool
{
return !isset($event['DTSTART']) || !$this->isValidDate($event['DTSTART'])
|| $this->isOutOfRange($event['DTSTART'], $this->windowMinTimestamp, $this->windowMaxTimestamp);
@@ -790,7 +776,7 @@ class ICalParser
* @param integer $maxTimestamp
* @return boolean
*/
- protected function isOutOfRange($calendarDate, $minTimestamp, $maxTimestamp)
+ protected function isOutOfRange(string $calendarDate, int $minTimestamp, int $maxTimestamp): bool
{
$timestamp = strtotime(explode('T', $calendarDate)[0]);
@@ -798,36 +784,15 @@ class ICalParser
}
/**
- * Unfolds an iCal file in preparation for parsing
- * (https://icalendar.org/iCalendar-RFC-5545/3-1-content-lines.html)
- *
- * @param array $lines
- * @return array
- */
- protected function unfold(array $lines)
- {
- $string = implode(PHP_EOL, $lines);
- $string = preg_replace('/' . PHP_EOL . '[ \t]/', '', $string);
-
- $lines = explode(PHP_EOL, $string);
-
- return $lines;
- }
-
- /**
* Add one key and value pair to the `$this->cal` array
*
* @param string $component
- * @param string|boolean $keyword
- * @param string $value
+ * @param string $keyword
+ * @param string|string[] $value
* @return void
*/
- protected function addCalendarComponentWithKeyAndValue($component, $keyword, $value)
+ protected function addCalendarComponentWithKeyAndValue(string $component, string $keyword, $value)
{
- if ($keyword == false) {
- $keyword = $this->lastKeyword;
- }
-
switch ($component) {
case 'VALARM':
$key1 = 'VEVENT';
@@ -840,7 +805,7 @@ class ICalParser
if (is_array($value)) {
// Add array of properties to the end
- array_push($this->cal[$key1][$key2][$key3]["{$keyword}_array"], $value);
+ $this->cal[$key1][$key2][$key3]["{$keyword}_array"][] = $value;
} else {
if (!isset($this->cal[$key1][$key2][$key3][$keyword])) {
$this->cal[$key1][$key2][$key3][$keyword] = $value;
@@ -862,7 +827,7 @@ class ICalParser
if (is_array($value)) {
// Add array of properties to the end
- array_push($this->cal[$key1][$key2]["{$keyword}_array"], $value);
+ $this->cal[$key1][$key2]["{$keyword}_array"][] = $value;
} else {
if (!isset($this->cal[$key1][$key2][$keyword])) {
$this->cal[$key1][$key2][$keyword] = $value;
@@ -882,7 +847,7 @@ class ICalParser
if ($keyword === 'DURATION') {
try {
$duration = new DateInterval($value);
- array_push($this->cal[$key1][$key2]["{$keyword}_array"], $duration);
+ $this->cal[$key1][$key2]["{$keyword}_array"][] = $duration;
} catch (Exception $e) {
error_log('Ignoring invalid duration ' . $value);
}
@@ -928,6 +893,7 @@ class ICalParser
break;
}
+ // Remove?
$this->lastKeyword = $keyword;
}
@@ -935,9 +901,9 @@ class ICalParser
* Gets the key value pair from an iCal string
*
* @param string $text
- * @return array|boolean
+ * @return ?array
*/
- protected function keyValueFromString($text)
+ protected function keyValueFromString(string $text): ?array
{
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
@@ -974,14 +940,14 @@ class ICalParser
}
if (count($matches) === 0) {
- return false;
+ return null;
}
- if (preg_match('/^([A-Z-]+)([;][\w\W]*)?$/', $matches[1])) {
+ if (preg_match('/^([A-Z-]+)(;[\w\W]*)?$/', $matches[1])) {
$matches = array_splice($matches, 1, 2); // Remove first match and re-align ordering
// Process properties
- if (preg_match('/([A-Z-]+)[;]([\w\W]*)/', $matches[0], $properties)) {
+ if (preg_match('/([A-Z-]+);([\w\W]*)/', $matches[0], $properties)) {
// Remove first match
array_shift($properties);
// Fix to ignore everything in keyword after a ; (e.g. Language, TZID, etc.)
@@ -1023,9 +989,8 @@ class ICalParser
}
return $matches;
- } else {
- return false; // Ignore this match
}
+ return null; // Ignore this match
}
/**
@@ -1034,7 +999,7 @@ class ICalParser
* @param string $icalDate
* @return DateTime
*/
- public function iCalDateToDateTime($icalDate)
+ public function iCalDateToDateTime(string $icalDate): DateTime
{
/**
* iCal times may be in 3 formats, (https://www.kanzaki.com/docs/ical/dateTime.html)
@@ -1091,7 +1056,7 @@ class ICalParser
* @param string $icalDate
* @return integer
*/
- public function iCalDateToUnixTimestamp($icalDate)
+ public function iCalDateToUnixTimestamp(string $icalDate): int
{
return $this->iCalDateToDateTime($icalDate)->getTimestamp();
}
@@ -1104,7 +1069,7 @@ class ICalParser
* @param string $format
* @return string|boolean
*/
- public function iCalDateWithTimeZone(array $event, $key, $format = self::DATE_TIME_FORMAT)
+ public function iCalDateWithTimeZone(array $event, string $key, string $format = self::DATE_TIME_FORMAT)
{
if (!isset($event["{$key}_array"]) || !isset($event[$key])) {
return false;
@@ -1141,7 +1106,6 @@ class ICalParser
if (empty($this->cal['VEVENT']))
return;
$events =& $this->cal['VEVENT'];
- $checks = null;
foreach ($events as $key => $anEvent) {
foreach (array('DTSTART', 'DTEND', 'RECURRENCE-ID') as $type) {
@@ -1175,23 +1139,20 @@ class ICalParser
$eventKeysToRemove = array();
foreach ($events as $key => $event) {
- $checks[] = !isset($event['RECURRENCE-ID']);
- $checks[] = isset($event['UID']);
- $checks[] = isset($event['UID']) && isset($this->alteredRecurrenceInstances[$event['UID']]);
+ $checks = !isset($event['RECURRENCE-ID'])
+ && isset($event['UID']) && isset($this->alteredRecurrenceInstances[$event['UID']]);
- if ((bool)array_product($checks)) {
+ if ($checks) {
$eventDtstartUnix = $this->iCalDateToUnixTimestamp($event['DTSTART_array'][3]);
// phpcs:ignore CustomPHPCS.ControlStructures.AssignmentInCondition
if (($alteredEventKey = array_search($eventDtstartUnix, $this->alteredRecurrenceInstances[$event['UID']])) !== false) {
$eventKeysToRemove[] = $alteredEventKey;
- $alteredEvent = array_replace_recursive($events[$key], $events[$alteredEventKey]);
+ $alteredEvent = array_replace_recursive($event, $events[$alteredEventKey]);
$this->alteredRecurrenceInstances[$event['UID']]['altered-event'] = array($key => $alteredEvent);
}
}
-
- unset($checks);
}
foreach ($eventKeysToRemove as $eventKeyToRemove) {
@@ -1568,7 +1529,7 @@ class ICalParser
* @param DateTime $initialDateTime
* @return array
*/
- protected function getDaysOfMonthMatchingByDayRRule(array $byDays, $initialDateTime)
+ protected function getDaysOfMonthMatchingByDayRRule(array $byDays, DateTime $initialDateTime): array
{
$matchingDays = array();
@@ -1628,7 +1589,7 @@ class ICalParser
* @param array $valuesList
* @return array
*/
- protected function filterValuesUsingBySetPosRRule(array $bySetPos, array $valuesList)
+ protected function filterValuesUsingBySetPosRRule(array $bySetPos, array $valuesList): array
{
$filteredMatches = array();
@@ -1688,7 +1649,7 @@ class ICalParser
*
* @return ICalEvent[]
*/
- public function events()
+ public function events(): array
{
if (empty($this->cal) || empty($this->cal['VEVENT']))
return [];
@@ -1706,9 +1667,9 @@ class ICalParser
*
* @return string
*/
- public function calendarName()
+ public function calendarName(): string
{
- return isset($this->cal['VCALENDAR']['X-WR-CALNAME']) ? $this->cal['VCALENDAR']['X-WR-CALNAME'] : '';
+ return $this->cal['VCALENDAR']['X-WR-CALNAME'] ?? '';
}
/**
@@ -1716,9 +1677,9 @@ class ICalParser
*
* @return string
*/
- public function calendarDescription()
+ public function calendarDescription(): string
{
- return isset($this->cal['VCALENDAR']['X-WR-CALDESC']) ? $this->cal['VCALENDAR']['X-WR-CALDESC'] : '';
+ return $this->cal['VCALENDAR']['X-WR-CALDESC'] ?? '';
}
/**
@@ -1727,7 +1688,7 @@ class ICalParser
* @param boolean $ignoreUtc
* @return string
*/
- public function calendarTimeZone($ignoreUtc = false)
+ public function calendarTimeZone(bool $ignoreUtc = false): ?string
{
if (isset($this->cal['VCALENDAR']['X-WR-TIMEZONE'])) {
$timeZone = $this->cal['VCALENDAR']['X-WR-TIMEZONE'];
@@ -1754,11 +1715,11 @@ class ICalParser
*
* @return array
*/
- public function freeBusyEvents()
+ public function freeBusyEvents(): array
{
$array = $this->cal;
- return isset($array['VFREEBUSY']) ? $array['VFREEBUSY'] : array();
+ return $array['VFREEBUSY'] ?? array();
}
/**
@@ -1784,7 +1745,7 @@ class ICalParser
* @return array
* @throws Exception
*/
- public function eventsFromRange($rangeStart = null, $rangeEnd = null)
+ public function eventsFromRange(string $rangeStart = null, string $rangeEnd = null): array
{
// Sort events before processing range
$events = $this->sortEventsWithOrder($this->events());
@@ -1857,7 +1818,7 @@ class ICalParser
* @param integer $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR, SORT_NUMERIC, SORT_STRING
* @return array
*/
- public function sortEventsWithOrder(array $events, $sortOrder = SORT_ASC)
+ public function sortEventsWithOrder(array $events, int $sortOrder = SORT_ASC): array
{
$extendedEvents = array();
$timestamp = array();
@@ -1878,7 +1839,7 @@ class ICalParser
* @param string $timeZone
* @return boolean
*/
- protected function isValidTimeZoneId($timeZone)
+ protected function isValidTimeZoneId(string $timeZone): bool
{
return $this->isValidIanaTimeZoneId($timeZone) !== false
|| $this->isValidCldrTimeZoneId($timeZone) !== false
@@ -1891,7 +1852,7 @@ class ICalParser
* @param string $timeZone
* @return boolean
*/
- protected function isValidIanaTimeZoneId($timeZone)
+ protected function isValidIanaTimeZoneId(string $timeZone): bool
{
if (in_array($timeZone, $this->validIanaTimeZones)) {
return true;
@@ -1923,7 +1884,7 @@ class ICalParser
* @param string $timeZone
* @return boolean
*/
- public function isValidCldrTimeZoneId($timeZone)
+ public function isValidCldrTimeZoneId(string $timeZone): bool
{
return array_key_exists(html_entity_decode($timeZone), self::$cldrTimeZonesMap);
}
@@ -1934,7 +1895,7 @@ class ICalParser
* @param string $timeZone
* @return boolean
*/
- public function isValidWindowsTimeZoneId($timeZone)
+ public function isValidWindowsTimeZoneId(string $timeZone): bool
{
return array_key_exists(html_entity_decode($timeZone), self::$windowsTimeZonesMap);
}
@@ -1942,12 +1903,9 @@ class ICalParser
/**
* Parses a duration and applies it to a date
*
- * @param string $date
- * @param DateInterval $duration
- * @param string $format
* @return integer|DateTime
*/
- protected function parseDuration($date, $duration, $format = self::UNIX_FORMAT)
+ protected function parseDuration(string $date, DateInterval $duration, ?string $format = self::UNIX_FORMAT)
{
$dateTime = date_create($date);
$dateTime->modify("{$duration->y} year");
@@ -1974,7 +1932,7 @@ class ICalParser
* @param string $data
* @return string
*/
- protected function removeUnprintableChars($data)
+ protected function removeUnprintableChars(string $data): string
{
return preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $data);
}
@@ -1986,7 +1944,7 @@ class ICalParser
* @param string $candidateText
* @return string
*/
- protected function escapeParamText($candidateText)
+ protected function escapeParamText(string $candidateText): string
{
if (strpbrk($candidateText, ':;,') !== false) {
return '"' . $candidateText . '"';
@@ -2002,13 +1960,12 @@ class ICalParser
* @param array $event
* @return array
*/
- public function parseExdates(array $event)
+ public function parseExdates(array $event): array
{
if (empty($event['EXDATE_array'])) {
return array();
- } else {
- $exdates = $event['EXDATE_array'];
}
+ $exdates = $event['EXDATE_array'];
$output = array();
$currentTimeZone = $this->defaultTimeZone;
@@ -2046,7 +2003,7 @@ class ICalParser
* @param string $value
* @return boolean
*/
- public function isValidDate($value)
+ public function isValidDate(string $value): bool
{
if (!$value) {
return false;
@@ -2065,10 +2022,10 @@ class ICalParser
* Returns a `DateTimeZone` object based on a string containing a time zone name.
* Falls back to the default time zone if string passed not a recognised time zone.
*
- * @param string $timeZoneString
+ * @param DateTimeZone|string $timeZoneString
* @return DateTimeZone
*/
- public function timeZoneStringToDateTimeZone($timeZoneString)
+ public function timeZoneStringToDateTimeZone($timeZoneString): DateTimeZone
{
if ($timeZoneString instanceof DateTimeZone)
return $timeZoneString;