diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2badcbe --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +icalparser/* diff --git a/README.md b/README.md index e575fd8..44b64b0 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ Hinweis: kal3000-gcal-import nutzt für das Parsen von ICAL-Files und -Feeds das 3. Im Admin-Teil kann man das Zeitintervall einstellen, mit dem die Kalender synchronisiert werden. Standardeinstellung ist 60 Minuten. Bitte beachten, dass der Wordpress-Scheduler die Zeitintervalle nur ungefähr und abhängig von der Seitenaktivität einhält. -4. Im Admin-Teil kann man das Geocoding aktivieren. Derzeit ist nur ein inoffizieller Weg über Google Maps verfügbar, den Google nicht gerne sieht. Das offizielle Google-API erfordert einen API-Key, der bei intensiver Nutzung nicht kostenlos ist. Auf die Google-Policy wird hingewiesen. Außerdem soll es irgendwann OpenStreetMap geben. +4. Im Admin-Teil kann man das Geocoding aktivieren. Derzeit ist nur ein inoffizieller Weg über Google Maps verfügbar, den Google nicht gerne sieht. Das offizielle Google-API erfordert einen API-Key, der bei intensiver Nutzung nicht kostenlos ist. Auf die Google-Policy wird hingewiesen. Außerdem ist OpenStreetMap verfügbar, aber es kann nicht sehr gut mit den Lokationen aus Google Maps umgehen zu können. 5. Speichern und fertig. diff --git a/tests/Freq.php b/tests/Freq.php deleted file mode 100644 index 682ede2..0000000 --- a/tests/Freq.php +++ /dev/null @@ -1,609 +0,0 @@ - - */ - -/** - * A class to store Frequency-rules in. Will allow a easy way to find the - * last and next occurrence of the rule. - * - * No - this is so not pretty. But.. ehh.. You do it better, and I will - * gladly accept patches. - * - * Created by trail-and-error on the examples given in the RFC. - * - * TODO: Update to a better way of doing calculating the different options. - * Instead of only keeping track of the best of the current dates found - * it should instead keep a array of all the calculated dates within the - * period. - * This should fix the issues with multi-rule + multi-rule interference, - * and make it possible to implement the SETPOS rule. - * By pushing the next period onto the stack as the last option will - * (hopefully) remove the need for the awful simpleMode - * - * @author Morten Fangel (C) 2008 - * @author Michael Kahn (C) 2013 - * @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK - */ -class Freq { - protected $weekdays = [ - 'MO' => 'monday', 'TU' => 'tuesday', 'WE' => 'wednesday', 'TH' => 'thursday', 'FR' => 'friday', 'SA' => 'saturday', - 'SU' => 'sunday' - ]; - protected $knownRules = [ - 'month', 'weekno', 'day', 'monthday', 'yearday', 'hour', 'minute' - ]; //others : 'setpos', 'second' - protected $ruleModifiers = ['wkst']; - protected $simpleMode = true; - - protected $rules = ['freq' => 'yearly', 'interval' => 1]; - protected $start = 0; - protected $freq = ''; - - protected $excluded; //EXDATE - protected $added; //RDATE - - protected $cache; // getAllOccurrences() - - /** - * Constructs a new Freqency-rule - * - * @param $rule string - * @param $start int Unix-timestamp (important : Need to be the start of Event) - * @param $excluded array of int (timestamps), see EXDATE documentation - * @param $added array of int (timestamps), see RDATE documentation - */ - public function __construct($rule, $start, $excluded = [], $added = []) { - $this->start = $start; - $this->excluded = []; - - $rules = []; - foreach ($rule AS $k => $v) { - $this->rules[strtolower($k)] = $v; - } - - if (isset($this->rules['until']) && is_string($this->rules['until'])) { - $this->rules['until'] = strtotime($this->rules['until']); - } else if ($this->rules['until'] instanceof \DateTime) { - $this->rules['until'] = $this->rules['until']->getTimestamp(); - } - $this->freq = strtolower($this->rules['freq']); - - foreach ($this->knownRules AS $rule) { - if (isset($this->rules['by' . $rule])) { - if ($this->isPrerule($rule, $this->freq)) { - $this->simpleMode = false; - } - } - } - - if (!$this->simpleMode) { - if (!(isset($this->rules['byday']) || isset($this->rules['bymonthday']) || isset($this->rules['byyearday']))) { - $this->rules['bymonthday'] = date('d', $this->start); - } - } - - //set until, and cache - if (isset($this->rules['count'])) { - - $cache[$ts] = $ts = $this->start; - for ($n = 1; $n < $this->rules['count']; $n++) { - $ts = $this->findNext($ts); - $cache[$ts] = $ts; - } - $this->rules['until'] = $ts; - - //EXDATE - if (!empty($excluded)) { - foreach ($excluded as $ts) { - unset($cache[$ts]); - } - } - //RDATE - if (!empty($added)) { - $cache = array_unique(array_merge(array_values($cache), $added)); - asort($cache); - } - - $this->cache = array_values($cache); - } - - $this->excluded = $excluded; - $this->added = $added; - } - - /** - * Returns all timestamps array(), build the cache if not made before - * - * @return array - */ - public function getAllOccurrences() { - if (empty($this->cache)) { - $cache = []; - - //build cache - $next = $this->firstOccurrence(); - while ($next) { - $cache[] = $next; - $next = $this->findNext($next); - } - if (!empty($this->added)) { - $cache = array_unique(array_merge($cache, $this->added)); - asort($cache); - } - $this->cache = $cache; - } - - return $this->cache; - } - - /** - * Returns the previous (most recent) occurrence of the rule from the - * given offset - * - * @param int $offset - * @return int - */ - public function previousOccurrence($offset) { - if (!empty($this->cache)) { - $t2 = $this->start; - foreach ($this->cache as $ts) { - if ($ts >= $offset) - return $t2; - $t2 = $ts; - } - } else { - $ts = $this->start; - while (($t2 = $this->findNext($ts)) < $offset) { - if ($t2 == false) { - break; - } - $ts = $t2; - } - } - - return $ts; - } - - /** - * Returns the next occurrence of this rule after the given offset - * - * @param int $offset - * @return int - */ - public function nextOccurrence($offset) { - if ($offset < $this->start) - return $this->firstOccurrence(); - return $this->findNext($offset); - } - - /** - * Finds the first occurrence of the rule. - * - * @return int timestamp - */ - public function firstOccurrence() { - $t = $this->start; - if (in_array($t, $this->excluded)) - $t = $this->findNext($t); - - return $t; - } - - /** - * Finds the absolute last occurrence of the rule from the given offset. - * Builds also the cache, if not set before... - * - * @return int timestamp - */ - public function lastOccurrence() { - //build cache if not done - $this->getAllOccurrences(); - //return last timestamp in cache - return end($this->cache); - } - - /** - * Calculates the next time after the given offset that the rule - * will apply. - * - * The approach to finding the next is as follows: - * First we establish a timeframe to find timestamps in. This is - * between $offset and the end of the period that $offset is in. - * - * We then loop though all the rules (that is a Prerule in the - * current freq.), and finds the smallest timestamp inside the - * timeframe. - * - * If we find something, we check if the date is a valid recurrence - * (with validDate). If it is, we return it. Otherwise we try to - * find a new date inside the same timeframe (but using the new- - * found date as offset) - * - * If no new timestamps were found in the period, we try in the - * next period - * - * @param int $offset - * @return int - */ - public function findNext($offset) { - if (!empty($this->cache)) { - foreach ($this->cache as $ts) { - if ($ts > $offset) - return $ts; - } - } - - $debug = false; - - //make sure the offset is valid - if ($offset === false || (isset($this->rules['until']) && $offset > $this->rules['until'])) { - if ($debug) echo 'STOP: ' . date('r', $offset) . "\n"; - - return false; - } - - $found = true; - - //set the timestamp of the offset (ignoring hours and minutes unless we want them to be - //part of the calculations. - if ($debug) echo 'O: ' . date('r', $offset) . "\n"; - $hour = (in_array($this->freq, ['hourly', 'minutely']) && $offset > $this->start) ? date('H', $offset) : date( - 'H', $this->start - ); - $minute = (($this->freq === 'minutely' || isset($this->rules['byminute'])) && $offset > $this->start) ? date( - 'i', $offset - ) : date('i', $this->start); - $t = mktime($hour, $minute, date('s', $this->start), date('m', $offset), date('d', $offset), date('Y', $offset)); - if ($debug) echo 'START: ' . date('r', $t) . "\n"; - - if ($this->simpleMode) { - if ($offset < $t) { - $ts = $t; - if ($ts && in_array($ts, $this->excluded)) - $ts = $this->findNext($ts); - } else { - $ts = $this->findStartingPoint($t, $this->rules['interval'], false); - if (!$this->validDate($ts)) { - $ts = $this->findNext($ts); - } - } - - return $ts; - } - - //EOP needs to have the same TIME as START ($t) - $tO = new \DateTime('@'.$t, new \DateTimeZone('UTC')); - - $eop = $this->findEndOfPeriod($offset); - $eopO = new \DateTime('@'.$eop, new \DateTimeZone('UTC')); - $eopO->setTime($tO->format('H'),$tO->format('i'),$tO->format('s')); - $eop = $eopO->getTimestamp(); - unset($eopO); - unset($tO); - - if ($debug) echo 'EOP: ' . date('r', $eop) . "\n"; - - foreach ($this->knownRules AS $rule) { - if ($found && isset($this->rules['by' . $rule])) { - if ($this->isPrerule($rule, $this->freq)) { - $subrules = explode(',', $this->rules['by' . $rule]); - $_t = null; - foreach ($subrules AS $subrule) { - $imm = call_user_func_array([$this, 'ruleBy' . $rule], [$subrule, $t]); - if ($imm === false) { - break; - } - if ($debug) echo strtoupper($rule) . ': ' . date( - 'r', $imm - ) . ' A: ' . ((int)($imm > $offset && $imm < $eop)) . "\n"; - if ($imm > $offset && $imm <= $eop && ($_t == null || $imm < $_t)) { - $_t = $imm; - } - } - if ($_t !== null) { - $t = $_t; - } else { - $found = $this->validDate($t); - } - } - } - } - - if ($offset < $this->start && $this->start < $t) { - $ts = $this->start; - } elseif ($found && ($t != $offset)) { - if ($this->validDate($t)) { - if ($debug) echo 'OK' . "\n"; - $ts = $t; - } else { - if ($debug) echo 'Invalid' . "\n"; - $ts = $this->findNext($t); - } - } else { - if ($debug) echo 'Not found' . "\n"; - $ts = $this->findNext($this->findStartingPoint($offset, $this->rules['interval'])); - } - if ($ts && in_array($ts, $this->excluded)) - return $this->findNext($ts); - - return $ts; - } - - /** - * Finds the starting point for the next rule. It goes $interval - * 'freq' forward in time since the given offset - * - * @param int $offset - * @param int $interval - * @param boolean $truncate - * @return int - */ - private function findStartingPoint($offset, $interval, $truncate = true) { - $_freq = ($this->freq === 'daily') ? 'day__' : $this->freq; - $t = '+' . $interval . ' ' . substr($_freq, 0, -2) . 's'; - if ($_freq === 'monthly' && $truncate) { - if ($interval > 1) { - $offset = strtotime('+' . ($interval - 1) . ' months ', $offset); - } - $t = '+' . (date('t', $offset) - date('d', $offset) + 1) . ' days'; - } - - $sp = strtotime($t, $offset); - - if ($truncate) { - $sp = $this->truncateToPeriod($sp, $this->freq); - } - - return $sp; - } - - /** - * Finds the earliest timestamp posible outside this perioid - * - * @param int $offset - * @return int - */ - public function findEndOfPeriod($offset) { - return $this->findStartingPoint($offset, 1); - } - - /** - * Resets the timestamp to the beginning of the - * period specified by freq - * - * Yes - the fall-through is on purpose! - * - * @param int $time - * @param int $freq - * @return int - */ - private function truncateToPeriod($time, $freq) { - $date = getdate($time); - switch ($freq) { - case 'yearly': - $date['mon'] = 1; - case 'monthly': - $date['mday'] = 1; - case 'daily': - $date['hours'] = 0; - case 'hourly': - $date['minutes'] = 0; - case 'minutely': - $date['seconds'] = 0; - break; - case 'weekly': - if (date('N', $time) == 1) { - $date['hours'] = 0; - $date['minutes'] = 0; - $date['seconds'] = 0; - } else { - $date = getdate(strtotime('last monday 0:00', $time)); - } - break; - } - $d = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']); - - return $d; - } - - /** - * Applies the BYDAY rule to the given timestamp - * - * @param string $rule - * @param int $t - * @return int - */ - private function ruleByday($rule, $t) { - $dir = ($rule{0} == '-') ? -1 : 1; - $dir_t = ($dir == 1) ? 'next' : 'last'; - - $d = $this->weekdays[substr($rule, -2)]; - $s = $dir_t . ' ' . $d . ' ' . date('H:i:s', $t); - - if ($rule == substr($rule, -2)) { - if (date('l', $t) == ucfirst($d)) { - $s = 'today ' . date('H:i:s', $t); - } - - $_t = strtotime($s, $t); - - if ($_t == $t && in_array($this->freq, ['weekly', 'monthly', 'yearly'])) { - // Yes. This is not a great idea.. but hey, it works.. for now - $s = 'next ' . $d . ' ' . date('H:i:s', $t); - $_t = strtotime($s, $_t); - } - - return $_t; - } else { - $_f = $this->freq; - if (isset($this->rules['bymonth']) && $this->freq === 'yearly') { - $this->freq = 'monthly'; - } - if ($dir == -1) { - $_t = $this->findEndOfPeriod($t); - } else { - $_t = $this->truncateToPeriod($t, $this->freq); - } - $this->freq = $_f; - - $c = preg_replace('/[^0-9]/', '', $rule); - $c = ($c == '') ? 1 : $c; - - $n = $_t; - while ($c > 0) { - if ($dir == 1 && $c == 1 && date('l', $t) == ucfirst($d)) { - $s = 'today ' . date('H:i:s', $t); - } - $n = strtotime($s, $n); - $c--; - } - - return $n; - } - } - - private function ruleBymonth($rule, $t) { - $_t = mktime(date('H', $t), date('i', $t), date('s', $t), $rule, date('d', $t), date('Y', $t)); - if ($t == $_t && isset($this->rules['byday'])) { - // TODO: this should check if one of the by*day's exists, and have a multi-day value - return false; - } else { - return $_t; - } - } - - private function ruleBymonthday($rule, $t) { - if ($rule < 0) { - $rule = date('t', $t) + $rule + 1; - } - - return mktime(date('H', $t), date('i', $t), date('s', $t), date('m', $t), $rule, date('Y', $t)); - } - - private function ruleByyearday($rule, $t) { - if ($rule < 0) { - $_t = $this->findEndOfPeriod(); - $d = '-'; - } else { - $_t = $this->truncateToPeriod($t, $this->freq); - $d = '+'; - } - $s = $d . abs($rule - 1) . ' days ' . date('H:i:s', $t); - - return strtotime($s, $_t); - } - - private function ruleByweekno($rule, $t) { - if ($rule < 0) { - $_t = $this->findEndOfPeriod(); - $d = '-'; - } else { - $_t = $this->truncateToPeriod($t, $this->freq); - $d = '+'; - } - - $sub = (date('W', $_t) == 1) ? 2 : 1; - $s = $d . abs($rule - $sub) . ' weeks ' . date('H:i:s', $t); - $_t = strtotime($s, $_t); - - return $_t; - } - - private function ruleByhour($rule, $t) { - $_t = mktime($rule, date('i', $t), date('s', $t), date('m', $t), date('d', $t), date('Y', $t)); - - return $_t; - } - - private function ruleByminute($rule, $t) { - $_t = mktime(date('h', $t), $rule, date('s', $t), date('m', $t), date('d', $t), date('Y', $t)); - - return $_t; - } - - private function validDate($t) { - if (isset($this->rules['until']) && $t > $this->rules['until']) { - return false; - } - - if (in_array($t, $this->excluded)) { - return false; - } - - if (isset($this->rules['bymonth'])) { - $months = explode(',', $this->rules['bymonth']); - if (!in_array(date('m', $t), $months)) { - return false; - } - } - if (isset($this->rules['byday'])) { - $days = explode(',', $this->rules['byday']); - foreach ($days As $i => $k) { - $days[$i] = $this->weekdays[preg_replace('/[^A-Z]/', '', $k)]; - } - if (!in_array(strtolower(date('l', $t)), $days)) { - return false; - } - } - if (isset($this->rules['byweekno'])) { - $weeks = explode(',', $this->rules['byweekno']); - if (!in_array(date('W', $t), $weeks)) { - return false; - } - } - if (isset($this->rules['bymonthday'])) { - $weekdays = explode(',', $this->rules['bymonthday']); - foreach ($weekdays As $i => $k) { - if ($k < 0) { - $weekdays[$i] = date('t', $t) + $k + 1; - } - } - if (!in_array(date('d', $t), $weekdays)) { - return false; - } - } - if (isset($this->rules['byhour'])) { - $hours = explode(',', $this->rules['byhour']); - if (!in_array(date('H', $t), $hours)) { - return false; - } - } - - return true; - } - - private function isPrerule($rule, $freq) { - if ($rule === 'year') - - return false; - if ($rule === 'month' && $freq === 'yearly') - - return true; - if ($rule === 'monthday' && in_array($freq, ['yearly', 'monthly']) && !isset($this->rules['byday'])) - - return true; - // TODO: is it faster to do monthday first, and ignore day if monthday exists? - prolly by a factor of 4.. - if ($rule === 'yearday' && $freq === 'yearly') - - return true; - if ($rule === 'weekno' && $freq === 'yearly') - - return true; - if ($rule === 'day' && in_array($freq, ['yearly', 'monthly', 'weekly'])) - - return true; - if ($rule === 'hour' && in_array($freq, ['yearly', 'monthly', 'weekly', 'daily'])) - - return true; - if ($rule === 'minute') - - return true; - - return false; - } -} diff --git a/tests/IcalParser.php b/tests/IcalParser.php deleted file mode 100644 index 9a91656..0000000 --- a/tests/IcalParser.php +++ /dev/null @@ -1,471 +0,0 @@ - - */ -class IcalParser { - - /** @var \DateTimeZone */ - public $timezone; - - /** @var array */ - public $data = []; - - /** @var array */ - protected $counters = []; - - /** @var array */ - private $windowsTimezones; - - protected $arrayKeyMappings = [ - 'ATTACH' => 'ATTACHMENTS', - 'EXDATE' => 'EXDATES', - 'RDATE' => 'RDATES', - ]; - - public function __construct() { - $this->windowsTimezones = require __DIR__ . '/WindowsTimezones.php'; // load Windows timezones from separate file - } - - /** - * @param string $file - * @param null $callback - * @return array|null - * @throws \RuntimeException - * @throws \InvalidArgumentException - * @throws \Exception - */ - public function parseFile($file, $callback = null) { - if (!$handle = fopen($file, 'r')) { - throw new \RuntimeException('Can\'t open file' . $file . ' for reading'); - } - fclose($handle); - - return $this->parseString(file_get_contents($file), $callback); - } - - /** - * @param string $string - * @param null $callback - * @param boolean $add if true the parsed string is added to existing data - * @return array|null - * @throws \InvalidArgumentException - * @throws \Exception - */ - public function parseString($string, $callback = null, $add = false) { - if ($add === false) { - // delete old data - $this->data = []; - $this->counters = []; - } - - if (!preg_match('/BEGIN:VCALENDAR/', $string)) { - throw new \InvalidArgumentException('Invalid ICAL data format'); - } - - $section = 'VCALENDAR'; - - // Replace \r\n with \n - $string = str_replace("\r\n", "\n", $string); - - // Unfold multi-line strings - $string = str_replace("\n ", '', $string); - - foreach (explode("\n", $string) as $row) { - - switch ($row) { - case 'BEGIN:DAYLIGHT': - case 'BEGIN:VALARM': - case 'BEGIN:VTIMEZONE': - case 'BEGIN:VFREEBUSY': - case 'BEGIN:VJOURNAL': - case 'BEGIN:STANDARD': - case 'BEGIN:VTODO': - case 'BEGIN:VEVENT': - $section = substr($row, 6); - $this->counters[$section] = isset($this->counters[$section]) ? $this->counters[$section] + 1 : 0; - continue 2; // while - break; - case 'END:VEVENT': - $section = substr($row, 4); - $currCounter = $this->counters[$section]; - $event = $this->data[$section][$currCounter]; - if (!empty($event['RECURRENCE-ID'])) { - $this->data['_RECURRENCE_IDS'][$event['RECURRENCE-ID']] = $event; - } - - continue 2; // while - break; - case 'END:DAYLIGHT': - case 'END:VALARM': - case 'END:VTIMEZONE': - case 'END:VFREEBUSY': - case 'END:VJOURNAL': - case 'END:STANDARD': - case 'END:VTODO': - continue 2; // while - break; - - case 'END:VCALENDAR': - $veventSection = 'VEVENT'; - if (!empty($this->data[$veventSection])) { - foreach ($this->data[$veventSection] as $currCounter => $event) { - if (!empty($event['RRULE']) || !empty($event['RDATE'])) { - $recurrences = $this->parseRecurrences($event); - if (!empty($recurrences)) { - $this->data[$veventSection][$currCounter]['RECURRENCES'] = $recurrences; - } - - if (!empty($event['UID'])) { - $this->data["_RECURRENCE_COUNTERS_BY_UID"][$event['UID']] = $currCounter; - } - } - } - } - continue 2; // while - break; - } - - list($key, $middle, $value) = $this->parseRow($row); - - - if ($callback) { - // call user function for processing line - call_user_func($callback, $row, $key, $middle, $value, $section, $this->counters[$section]); - } else { - if ($section === 'VCALENDAR') { - $this->data[$key] = $value; - } else { - if (isset($this->arrayKeyMappings[$key])) { - // use an array since there can be multiple entries for this key. This does not - // break the current implementation--it leaves the original key alone and adds - // a new one specifically for the array of values. - $arrayKey = $this->arrayKeyMappings[$key]; - $this->data[$section][$this->counters[$section]][$arrayKey][] = $value; - } - - $this->data[$section][$this->counters[$section]][$key] = $value; - } - - } - } - - return ($callback) ? null : $this->data; - } - - /** - * @param $row - * @return array - */ - private function parseRow($row) { - preg_match('#^([\w-]+);?([\w-]+="[^"]*"|.*?):(.*)$#i', $row, $matches); - - $key = false; - $middle = null; - $value = null; - - if ($matches) { - $key = $matches[1]; - $middle = $matches[2]; - $value = $matches[3]; - $timezone = null; - - if ($key === 'X-WR-TIMEZONE' || $key === 'TZID') { - if (preg_match('#(\w+/\w+)$#i', $value, $matches)) { - $value = $matches[1]; - } - $value = $this->toTimezone($value); - $this->timezone = new \DateTimeZone($value); - } - - // have some middle part ? - if ($middle && preg_match_all('#(?[^=;]+)=(?[^;]+)#', $middle, $matches, PREG_SET_ORDER)) { - $middle = []; - foreach ($matches as $match) { - if ($match['key'] === 'TZID') { - $match['value'] = trim($match['value'], "'\""); - $match['value'] = $this->toTimezone($match['value']); - try { - $middle[$match['key']] = $timezone = new \DateTimeZone($match['value']); - } catch (\Exception $e) { - $middle[$match['key']] = $match['value']; - } - } else if ($match['key'] === 'ENCODING') { - if ($match['value'] === 'QUOTED-PRINTABLE') { - $value = quoted_printable_decode($value); - } - } - } - } - } - - // process simple dates with timezone - if (in_array($key, ['DTSTAMP', 'LAST-MODIFIED', 'CREATED', 'DTSTART', 'DTEND'], true)) { - try { - $value = new \DateTime($value, ($timezone ?: $this->timezone)); - } catch (\Exception $e) { - $value = null; - } - } else if (in_array($key, ['EXDATE', 'RDATE'])) { - $values = []; - foreach (explode(',', $value) as $singleValue) { - try { - $values[] = new \DateTime($singleValue, ($timezone ?: $this->timezone)); - } catch (\Exception $e) { - // pass - } - } - if (count($values) === 1) { - $value = $values[0]; - } else { - $value = $values; - } - } - - if ($key === 'RRULE' && preg_match_all('#(?[^=;]+)=(?[^;]+)#', $value, $matches, PREG_SET_ORDER)) { - $middle = null; - $value = []; - foreach ($matches as $match) { - if (in_array($match['key'], ['UNTIL'])) { - try { - $value[$match['key']] = new \DateTime($match['value'], ($timezone ?: $this->timezone)); - } catch (\Exception $e) { - $value[$match['key']] = $match['value']; - } - } else { - $value[$match['key']] = $match['value']; - } - } - } - - //split by comma, escape \, - if ($key === 'CATEGORIES') { - $value = preg_split('/(? '\\', '\\N' => "\n", '\\n' => "\n", '\\;' => ';', '\\,' => ',']); - } - } else { - $value = strtr($value, ['\\\\' => '\\', '\\N' => "\n", '\\n' => "\n", '\\;' => ';', '\\,' => ',']); - } - } - - return [$key, $middle, $value]; - } - - /** - * @param $event - * @return array - * @throws \Exception - */ - public function parseRecurrences($event) { - $recurring = new Recurrence($event['RRULE']); - $exclusions = []; - $additions = []; - - if (!empty($event['EXDATES'])) { - foreach ($event['EXDATES'] as $exDate) { - if (is_array($exDate)) { - foreach ($exDate as $singleExDate) { - $exclusions[] = $singleExDate->getTimestamp(); - } - } else { - $exclusions[] = $exDate->getTimestamp(); - } - } - } - - if (!empty($event['RDATES'])) { - foreach ($event['RDATES'] as $rDate) { - if (is_array($rDate)) { - foreach ($rDate as $singleRDate) { - $additions[] = $singleRDate->getTimestamp(); - } - } else { - $additions[] = $rDate->getTimestamp(); - } - } - } - - $until = $recurring->getUntil(); - if ($until === false) { - //forever... limit to 3 years - $end = clone($event['DTSTART']); - $end->add(new \DateInterval('P3Y')); // + 3 years - $recurring->setUntil($end); - $until = $recurring->getUntil(); - } - - date_default_timezone_set($event['DTSTART']->getTimezone()->getName()); - $frequency = new Freq($recurring->rrule, $event['DTSTART']->getTimestamp(), $exclusions, $additions); - $recurrenceTimestamps = $frequency->getAllOccurrences(); - $recurrences = []; - foreach ($recurrenceTimestamps as $recurrenceTimestamp) { - $tmp = new \DateTime('now', $event['DTSTART']->getTimezone()); - $tmp->setTimestamp($recurrenceTimestamp); - - $recurrenceIDDate = $tmp->format('Ymd'); - $recurrenceIDDateTime = $tmp->format('Ymd\THis'); - if (empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDate]) && - empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDateTime])) { - $gmtCheck = new \DateTime("now", new \DateTimeZone('UTC')); - $gmtCheck->setTimestamp($recurrenceTimestamp); - $recurrenceIDDateTimeZ = $gmtCheck->format('Ymd\THis\Z'); - if (empty($this->data['_RECURRENCE_IDS'][$recurrenceIDDateTimeZ])) { - $recurrences[] = $tmp; - } - } - } - - return $recurrences; - } - - /** - * @return array - */ - public function getEvents() { - $events = []; - if (isset($this->data['VEVENT'])) { - for ($i = 0; $i < count($this->data['VEVENT']); $i++) { - $event = $this->data['VEVENT'][$i]; - - if (empty($event['RECURRENCES'])) { - if (!empty($event['RECURRENCE-ID']) && !empty($event['UID']) && isset($event['SEQUENCE'])) { - $modifiedEventUID = $event['UID']; - $modifiedEventRecurID = $event['RECURRENCE-ID']; - $modifiedEventSeq = intval($event['SEQUENCE'], 10); - - if (isset($this->data["_RECURRENCE_COUNTERS_BY_UID"][$modifiedEventUID])) { - $counter = $this->data["_RECURRENCE_COUNTERS_BY_UID"][$modifiedEventUID]; - - $originalEvent = $this->data["VEVENT"][$counter]; - if (isset($originalEvent['SEQUENCE'])) { - $originalEventSeq = intval($originalEvent['SEQUENCE'], 10); - $originalEventFormattedStartDate = $originalEvent['DTSTART']->format('Ymd\THis'); - if ($modifiedEventRecurID === $originalEventFormattedStartDate && $modifiedEventSeq > $originalEventSeq) { - // this modifies the original event - $modifiedEvent = array_replace_recursive($originalEvent, $event); - $this->data["VEVENT"][$counter] = $modifiedEvent; - foreach ($events as $z => $event) { - if ($events[$z]['UID'] === $originalEvent['UID'] && - $events[$z]['SEQUENCE'] === $originalEvent['SEQUENCE']) { - // replace the original event with the modified event - $events[$z] = $modifiedEvent; - break; - } - } - $event = null; // don't add this to the $events[] array again - } else if (!empty($originalEvent['RECURRENCES'])) { - for ($j = 0; $j < count($originalEvent['RECURRENCES']); $j++) { - $recurDate = $originalEvent['RECURRENCES'][$j]; - $formattedStartDate = $recurDate->format('Ymd\THis'); - if ($formattedStartDate === $modifiedEventRecurID) { - unset($this->data["VEVENT"][$counter]['RECURRENCES'][$j]); - $this->data["VEVENT"][$counter]['RECURRENCES'] = array_values($this->data["VEVENT"][$counter]['RECURRENCES']); - break; - } - } - } - } - } - } - - if (!empty($event)) { - $events[] = $event; - } - } else { - $recurrences = $event['RECURRENCES']; - $event['RECURRING'] = true; - $event['DTEND'] = !empty($event['DTEND']) ? $event['DTEND'] : $event['DTSTART']; - $eventInterval = $event['DTSTART']->diff($event['DTEND']); - - $firstEvent = true; - foreach ($recurrences as $j => $recurDate) { - $newEvent = $event; - if (!$firstEvent) { - unset($newEvent['RECURRENCES']); - $newEvent['DTSTART'] = $recurDate; - $newEvent['DTEND'] = clone($recurDate); - $newEvent['DTEND']->add($eventInterval); - } - - $newEvent['RECURRENCE_INSTANCE'] = $j; - $events[] = $newEvent; - $firstEvent = false; - } - } - } - } - return $events; - } - - - /** - * Process timezone and return correct one... - * - * @param string $zone - * @return mixed|null - */ - private function toTimezone($zone) { - return isset($this->windowsTimezones[$zone]) ? $this->windowsTimezones[$zone] : $zone; - } - - /** - * @return array - */ - public function getAlarms() { - return isset($this->data['VALARM']) ? $this->data['VALARM'] : []; - } - - /** - * @return array - */ - public function getTimezones() { - return isset($this->data['VTIMEZONE']) ? $this->data['VTIMEZONE'] : []; - } - - /** - * Return sorted event list as array - * - * @return array - */ - public function getSortedEvents() { - if ($events = $this->getEvents()) { - usort( - $events, function ($a, $b) { - return $a['DTSTART'] > $b['DTSTART']; - } - ); - return $events; - } - return []; - } - - /** - * @return array - */ - public function getReverseSortedEvents() { - if ($events = $this->getEvents()) { - usort( - $events, function ($a, $b) { - return $a['DTSTART'] < $b['DTSTART']; - } - ); - return $events; - } - return []; - } - -} diff --git a/tests/Recurrence.php b/tests/Recurrence.php deleted file mode 100644 index b199532..0000000 --- a/tests/Recurrence.php +++ /dev/null @@ -1,234 +0,0 @@ -parseRrule($rrule); - } - - /** - * Parses an 'RRULE' array and sets the member variables of this object. - * Expects a string that looks like this: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=SU,TU,WE' - * - * @param $rrule - */ - protected function parseRrule($rrule) { - $this->rrule = $rrule; - //loop through the properties in the line and set their associated - //member variables - foreach ($this->rrule as $propertyName => $propertyValue) { - //need the lower-case name for setting the member variable - $propertyName = strtolower($propertyName); - //split up the list of values into an array (if it's a list) - if (in_array($propertyName, $this->listProperties, true)) { - $propertyValue = explode(',', $propertyValue); - } - $this->$propertyName = $propertyValue; - } - } - - /** - * Set the $until member - * - * @param mixed timestamp (int) / Valid DateTime format (string) - */ - public function setUntil($ts) { - if ($ts instanceof DateTime) { - $dt = $ts; - } else if (is_int($ts)) { - $dt = new DateTime('@' . $ts); - } else { - $dt = new DateTime($ts); - } - $this->until = $dt->format('Ymd\THisO'); - $this->rrule['until'] = $this->until; - } - - /** - * Retrieves the desired member variable and returns it (if it's set) - * - * @param string $member name of the member variable - * @return mixed the variable value (if set), false otherwise - */ - protected function getMember($member) { - if (isset($this->$member)) { - return $this->$member; - } - return false; - } - - /** - * Returns the frequency - corresponds to FREQ in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getFreq() { - return $this->getMember('freq'); - } - - /** - * Returns when the event will go until - corresponds to UNTIL in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getUntil() { - return $this->getMember('until'); - } - - /** - * Returns the count of the times the event will occur (should only appear if 'until' - * does not appear) - corresponds to COUNT in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getCount() { - return $this->getMember('count'); - } - - /** - * Returns the interval - corresponds to INTERVAL in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getInterval() { - return $this->getMember('interval'); - } - - /** - * Returns the bysecond part of the event - corresponds to BYSECOND in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getBySecond() { - return $this->getMember('bysecond'); - } - - /** - * Returns the byminute information for the event - corresponds to BYMINUTE in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByMinute() { - return $this->getMember('byminute'); - } - - /** - * Corresponds to BYHOUR in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByHour() { - return $this->getMember('byhour'); - } - - /** - *Corresponds to BYDAY in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByDay() { - return $this->getMember('byday'); - } - - /** - * Corresponds to BYMONTHDAY in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByMonthDay() { - return $this->getMember('bymonthday'); - } - - /** - * Corresponds to BYYEARDAY in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByYearDay() { - return $this->getMember('byyearday'); - } - - /** - * Corresponds to BYWEEKNO in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByWeekNo() { - return $this->getMember('byweekno'); - } - - /** - * Corresponds to BYMONTH in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getByMonth() { - return $this->getMember('bymonth'); - } - - /** - * Corresponds to BYSETPOS in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getBySetPos() { - return $this->getMember('bysetpos'); - } - - /** - * Corresponds to WKST in RFC 2445. - * - * @return mixed string if the member has been set, false otherwise - */ - public function getWkst() { - return $this->getMember('wkst'); - } -} diff --git a/tests/WindowsTimezones.php b/tests/WindowsTimezones.php deleted file mode 100644 index f2105c3..0000000 --- a/tests/WindowsTimezones.php +++ /dev/null @@ -1,210 +0,0 @@ - 'Etc/GMT+12', - '(UTC-12:00) International Date Line West' => 'Etc/GMT+12', - 'UTC-11' => 'Etc/GMT+11', - '(UTC-11:00) Coordinated Universal Time -11' => 'Etc/GMT+11', - 'Hawaiian Standard Time' => 'Pacific/Honolulu', - '(UTC-10:00) Hawaii' => 'Pacific/Honolulu', - 'Alaskan Standard Time' => 'America/Anchorage', - '(UTC-09:00) Alaska' => 'America/Anchorage', - 'Pacific Standard Time (Mexico)' => 'America/Santa_Isabel', - '(UTC-08:00) Baja California' => 'America/Santa_Isabel', - 'Pacific Standard Time' => 'America/Los_Angeles', - 'Pacific Time' => 'America/Los_Angeles', - '(UTC-08:00) Pacific Time (US and Canada)' => 'America/Los_Angeles', - '(UTC-08:00) Pacific Time (US & Canada)' => 'America/Los_Angeles', - 'US Mountain Standard Time' => 'America/Phoenix', - '(UTC-07:00) Arizona' => 'America/Phoenix', - 'Mountain Standard Time (Mexico)' => 'America/Chihuahua', - '(UTC-07:00) Chihuahua, La Paz, Mazatlan' => 'America/Chihuahua', - 'Mountain Standard Time' => 'America/Denver', - 'Mountain Time' => 'America/Denver', - '(UTC-07:00) Mountain Time (US and Canada)' => 'America/Denver', - '(UTC-07:00) Mountain Time (US & Canada)' => 'America/Denver', - 'Central America Standard Time' => 'America/Guatemala', - '(UTC-06:00) Central America' => 'America/Guatemala', - 'Central Standard Time' => 'America/Chicago', - 'Central Time' => 'America/Chicago', - '(UTC-06:00) Central Time (US and Canada)' => 'America/Chicago', - '(UTC-06:00) Central Time (US & Canada)' => 'America/Chicago', - 'Central Standard Time (Mexico)' => 'America/Mexico_City', - '(UTC-06:00) Guadalajara, Mexico City, Monterrey' => 'America/Mexico_City', - 'Canada Central Standard Time' => 'America/Regina', - '(UTC-06:00) Saskatchewan' => 'America/Regina', - 'SA Pacific Standard Time' => 'America/Bogota', - '(UTC-05:00) Bogota, Lima, Quito' => 'America/Bogota', - 'Eastern Standard Time' => 'America/New_York', - 'Eastern Time' => 'America/New_York', - '(UTC-05:00) Eastern Time (US and Canada)' => 'America/New_York', - '(UTC-05:00) Eastern Time (US & Canada)' => 'America/New_York', - 'US Eastern Standard Time' => 'America/Indianapolis', - '(UTC-05:00) Indiana (East)' => 'America/Indianapolis', - 'Venezuela Standard Time' => 'America/Caracas', - '(UTC-04:30) Caracas' => 'America/Caracas', - 'Paraguay Standard Time' => 'America/Asuncion', - '(UTC-04:00) Asuncion' => 'America/Asuncion', - 'Atlantic Standard Time' => 'America/Halifax', - '(UTC-04:00) Atlantic Time (Canada)' => 'America/Halifax', - 'Central Brazilian Standard Time' => 'America/Cuiaba', - '(UTC-04:00) Cuiaba' => 'America/Cuiaba', - 'SA Western Standard Time' => 'America/La_Paz', - '(UTC-04:00) Georgetown, La Paz, Manaus, San Juan' => 'America/La_Paz', - 'Pacific SA Standard Time' => 'America/Santiago', - '(UTC-04:00) Santiago' => 'America/Santiago', - 'Newfoundland Standard Time' => 'America/St_Johns', - '(UTC-03:30) Newfoundland' => 'America/St_Johns', - 'E. South America Standard Time' => 'America/Sao_Paulo', - '(UTC-03:00) Brasilia' => 'America/Sao_Paulo', - 'Argentina Standard Time' => 'America/Buenos_Aires', - '(UTC-03:00) Buenos Aires' => 'America/Buenos_Aires', - 'SA Eastern Standard Time' => 'America/Cayenne', - '(UTC-03:00) Cayenne, Fortaleza' => 'America/Cayenne', - 'Greenland Standard Time' => 'America/Godthab', - '(UTC-03:00) Greenland' => 'America/Godthab', - 'Montevideo Standard Time' => 'America/Montevideo', - '(UTC-03:00) Montevideo' => 'America/Montevideo', - 'Bahia Standard Time' => 'America/Bahia', - 'UTC-02' => 'Etc/GMT+2', - '(UTC-02:00) Coordinated Universal Time -02' => 'Etc/GMT+2', - 'Azores Standard Time' => 'Atlantic/Azores', - '(UTC-01:00) Azores' => 'Atlantic/Azores', - 'Cape Verde Standard Time' => 'Atlantic/Cape_Verde', - '(UTC-01:00) Cabo Verde Is.' => 'Atlantic/Cape_Verde', - 'Morocco Standard Time' => 'Africa/Casablanca', - '(UTC) Casablanca' => 'Africa/Casablanca', - 'UTC' => 'Etc/GMT', - 'Microsoft/Utc' => 'Etc/GMT', - 'GMT Standard Time' => 'Europe/London', - '(UTC) Dublin, Edinburgh, Lisbon, London' => 'Europe/London', - 'Greenwich Standard Time' => 'Atlantic/Reykjavik', - '(UTC) Monrovia, Reykjavik' => 'Atlantic/Reykjavik', - 'W. Europe Standard Time' => 'Europe/Berlin', - '(UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna' => 'Europe/Berlin', - 'Central Europe Standard Time' => 'Europe/Budapest', - '(UTC+01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague' => 'Europe/Budapest', - 'Romance Standard Time' => 'Europe/Paris', - '(UTC+01:00) Brussels, Copenhagen, Madrid, Paris' => 'Europe/Paris', - 'Central European Standard Time' => 'Europe/Warsaw', - '(UTC+01:00) Sarajevo, Skopje, Warsaw, Zagreb' => 'Europe/Warsaw', - 'W. Central Africa Standard Time' => 'Africa/Lagos', - '(UTC+01:00) West Central Africa' => 'Africa/Lagos', - 'Namibia Standard Time' => 'Africa/Windhoek', - '(UTC+01:00) Windhoek' => 'Africa/Windhoek', - 'GTB Standard Time' => 'Europe/Bucharest', - '(UTC+02:00) Athens, Bucharest' => 'Europe/Bucharest', - 'Middle East Standard Time' => 'Asia/Beirut', - '(UTC+02:00) Beirut' => 'Asia/Beirut', - 'Egypt Standard Time' => 'Africa/Cairo', - '(UTC+02:00) Cairo' => 'Africa/Cairo', - 'Syria Standard Time' => 'Asia/Damascus', - '(UTC+02:00) Damascus' => 'Asia/Damascus', - 'South Africa Standard Time' => 'Africa/Johannesburg', - '(UTC+02:00) Harare, Pretoria' => 'Africa/Johannesburg', - 'FLE Standard Time' => 'Europe/Kiev', - '(UTC+02:00) Helsinki, Kyiv, Riga, Sofia, Tallinn, Vilnius' => 'Europe/Kiev', - 'Turkey Standard Time' => 'Europe/Istanbul', - '(UTC+02:00) Istanbul' => 'Europe/Istanbul', - 'Israel Standard Time' => 'Asia/Jerusalem', - '(UTC+02:00) Jerusalem' => 'Asia/Jerusalem', - 'Libya Standard Time' => 'Africa/Tripoli', - 'Jordan Standard Time' => 'Asia/Amman', - '(UTC+02:00) Amman' => 'Asia/Amman', - 'Arabic Standard Time' => 'Asia/Baghdad', - '(UTC+03:00) Baghdad' => 'Asia/Baghdad', - 'Kaliningrad Standard Time' => 'Europe/Kaliningrad', - '(UTC+03:00) Kaliningrad' => 'Europe/Kaliningrad', - 'Arab Standard Time' => 'Asia/Riyadh', - '(UTC+03:00) Kuwait, Riyadh' => 'Asia/Riyadh', - 'E. Africa Standard Time' => 'Africa/Nairobi', - '(UTC+03:00) Nairobi' => 'Africa/Nairobi', - 'Iran Standard Time' => 'Asia/Tehran', - '(UTC+03:30) Tehran' => 'Asia/Tehran', - 'Arabian Standard Time' => 'Asia/Dubai', - '(UTC+04:00) Abu Dhabi, Muscat' => 'Asia/Dubai', - 'Azerbaijan Standard Time' => 'Asia/Baku', - '(UTC+04:00) Baku' => 'Asia/Baku', - 'Russian Standard Time' => 'Europe/Moscow', - '(UTC+04:00) Moscow, St. Petersburg, Volgograd' => 'Europe/Moscow', - 'Mauritius Standard Time' => 'Indian/Mauritius', - '(UTC+04:00) Port Louis' => 'Indian/Mauritius', - 'Georgian Standard Time' => 'Asia/Tbilisi', - '(UTC+04:00) Tbilisi' => 'Asia/Tbilisi', - 'Caucasus Standard Time' => 'Asia/Yerevan', - '(UTC+04:00) Yerevan' => 'Asia/Yerevan', - 'Afghanistan Standard Time' => 'Asia/Kabul', - '(UTC+04:30) Kabul' => 'Asia/Kabul', - 'West Asia Standard Time' => 'Asia/Tashkent', - '(UTC+05:00) Tashkent' => 'Asia/Tashkent', - 'Pakistan Standard Time' => 'Asia/Karachi', - '(UTC+05:00) Islamabad, Karachi' => 'Asia/Karachi', - 'India Standard Time' => 'Asia/Calcutta', - '(UTC+05:30) Chennai, Kolkata, Mumbai, New Delhi' => 'Asia/Calcutta', - 'Sri Lanka Standard Time' => 'Asia/Colombo', - '(UTC+05:30) Sri Jayawardenepura' => 'Asia/Colombo', - 'Nepal Standard Time' => 'Asia/Katmandu', - '(UTC+05:45) Kathmandu' => 'Asia/Katmandu', - 'Central Asia Standard Time' => 'Asia/Almaty', - '(UTC+06:00) Astana' => 'Asia/Almaty', - 'Bangladesh Standard Time' => 'Asia/Dhaka', - '(UTC+06:00) Dhaka' => 'Asia/Dhaka', - 'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg', - '(UTC+06:00) Ekaterinburg' => 'Asia/Yekaterinburg', - 'Myanmar Standard Time' => 'Asia/Rangoon', - '(UTC+06:30) Yangon (Rangoon)' => 'Asia/Rangoon', - 'SE Asia Standard Time' => 'Asia/Bangkok', - '(UTC+07:00) Bangkok, Hanoi, Jakarta' => 'Asia/Bangkok', - 'N. Central Asia Standard Time' => 'Asia/Novosibirsk', - '(UTC+07:00) Novosibirsk' => 'Asia/Novosibirsk', - 'China Standard Time' => 'Asia/Shanghai', - '(UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi' => 'Asia/Shanghai', - 'North Asia Standard Time' => 'Asia/Krasnoyarsk', - '(UTC+08:00) Krasnoyarsk' => 'Asia/Krasnoyarsk', - 'Singapore Standard Time' => 'Asia/Singapore', - '(UTC+08:00) Kuala Lumpur, Singapore' => 'Asia/Singapore', - 'W. Australia Standard Time' => 'Australia/Perth', - '(UTC+08:00) Perth' => 'Australia/Perth', - 'Taipei Standard Time' => 'Asia/Taipei', - '(UTC+08:00) Taipei' => 'Asia/Taipei', - 'Ulaanbaatar Standard Time' => 'Asia/Ulaanbaatar', - '(UTC+08:00) Ulaanbaatar' => 'Asia/Ulaanbaatar', - 'North Asia East Standard Time' => 'Asia/Irkutsk', - '(UTC+09:00) Irkutsk' => 'Asia/Irkutsk', - 'Tokyo Standard Time' => 'Asia/Tokyo', - '(UTC+09:00) Osaka, Sapporo, Tokyo' => 'Asia/Tokyo', - 'Korea Standard Time' => 'Asia/Seoul', - '(UTC+09:00) Seoul' => 'Asia/Seoul', - 'Cen. Australia Standard Time' => 'Australia/Adelaide', - '(UTC+09:30) Adelaide' => 'Australia/Adelaide', - 'AUS Central Standard Time' => 'Australia/Darwin', - '(UTC+09:30) Darwin' => 'Australia/Darwin', - 'E. Australia Standard Time' => 'Australia/Brisbane', - '(UTC+10:00) Brisbane' => 'Australia/Brisbane', - 'AUS Eastern Standard Time' => 'Australia/Sydney', - '(UTC+10:00) Canberra, Melbourne, Sydney' => 'Australia/Sydney', - 'West Pacific Standard Time' => 'Pacific/Port_Moresby', - '(UTC+10:00) Guam, Port Moresby' => 'Pacific/Port_Moresby', - 'Tasmania Standard Time' => 'Australia/Hobart', - '(UTC+10:00) Hobart' => 'Australia/Hobart', - 'Yakutsk Standard Time' => 'Asia/Yakutsk', - '(UTC+10:00) Yakutsk' => 'Asia/Yakutsk', - 'Central Pacific Standard Time' => 'Pacific/Guadalcanal', - '(UTC+11:00) Solomon Is., New Caledonia' => 'Pacific/Guadalcanal', - 'Vladivostok Standard Time' => 'Asia/Vladivostok', - '(UTC+11:00) Vladivostok' => 'Asia/Vladivostok', - 'New Zealand Standard Time' => 'Pacific/Auckland', - '(UTC+12:00) Auckland, Wellington' => 'Pacific/Auckland', - 'UTC+12' => 'Etc/GMT-12', - '(UTC+12:00) Coordinated Universal Time +12' => 'Etc/GMT-12', - 'Fiji Standard Time' => 'Pacific/Fiji', - '(UTC+12:00) Fiji' => 'Pacific/Fiji', - 'Magadan Standard Time' => 'Asia/Magadan', - '(UTC+12:00) Magadan' => 'Asia/Magadan', - 'Tonga Standard Time' => 'Pacific/Tongatapu', - '(UTC+13:00) Nuku\'alofa' => 'Pacific/Tongatapu', - 'Samoa Standard Time' => 'Pacific/Apia', - '(UTC-11:00)Samoa' => 'Pacific/Apia', -]; \ No newline at end of file diff --git a/tests/test-icalparser.php b/tests/test-icalparser.php deleted file mode 100644 index 3f6dadf..0000000 --- a/tests/test-icalparser.php +++ /dev/null @@ -1,16 +0,0 @@ -"; - require_once __DIR__ . '/../vendor/autoload.php'; - $cal = new \om\IcalParser(); - $results = $cal->parseFile( - 'https://calendar.google.com/calendar/ical/gruene.freising%40gmail.com/public/basic.ics' - ); - foreach ($cal->getSortedEvents() as $r) { - echo sprintf('
  • %s - %s
  • ' . PHP_EOL, $r['DTSTART']->format('j.n.Y'), $r['SUMMARY']); - } - echo ""; - -?> - -