2012-11-12 23:57:50 +01:00
|
|
|
<?php
|
|
|
|
/**
|
2013-03-30 14:55:18 +01:00
|
|
|
* class.icalparser.php zarafa calender to ics im/exporter
|
|
|
|
* http://code.google.com/p/ics-parser/
|
|
|
|
*
|
|
|
|
* Author: Martin Thoma , Christoph Haas <christoph.h@sprinternet.at>
|
2014-05-15 01:30:00 +02:00
|
|
|
* Copyright (C) 2012-2014 Christoph Haas
|
2013-03-30 14:55:18 +01:00
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation; either
|
|
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
2012-11-12 23:57:50 +01:00
|
|
|
*
|
2013-03-30 14:55:18 +01:00
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
2012-11-12 23:57:50 +01:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is the iCal-class
|
2013-03-30 14:55:18 +01:00
|
|
|
* Parse ics file content to array.
|
2012-11-12 23:57:50 +01:00
|
|
|
*
|
|
|
|
* @param {string} filename The name of the file which should be parsed
|
|
|
|
* @constructor
|
|
|
|
*/
|
2012-11-17 12:42:48 +01:00
|
|
|
class ICal {
|
|
|
|
/* How many ToDos are in this ical? */
|
|
|
|
public /** @type {int} */ $todo_count = 0;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/* How many events are in this ical? */
|
|
|
|
public /** @type {int} */ $event_count = 0;
|
2012-12-30 18:18:39 +01:00
|
|
|
|
|
|
|
/* Currently editing an alarm? */
|
2013-03-30 14:55:18 +01:00
|
|
|
private /** @type {boolean} */ $isalarm = false;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/* The parsed calendar */
|
|
|
|
public /** @type {Array} */ $cal;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/* Error message store... null default */
|
|
|
|
public /** @type {String} */ $errors;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/* Which keyword has been added to cal at last? */
|
|
|
|
private /** @type {string} */ $_lastKeyWord;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/* The default timezone, used to convert UTC Time */
|
|
|
|
private /** @type {string} */ $default_timezone = "Europe/Vienna";
|
2013-03-30 14:55:18 +01:00
|
|
|
|
|
|
|
/* The default timezone, used to convert UTC Time */
|
|
|
|
private /** @type {boolean} */ $timezone_set = false;
|
|
|
|
|
|
|
|
/* Ignore Daylight Saving Time */
|
|
|
|
private /** @type {boolean} */ $ignore_dst = false;
|
|
|
|
|
2012-11-12 23:57:50 +01:00
|
|
|
/**
|
2012-11-17 12:42:48 +01:00
|
|
|
* Creates the iCal-Object
|
|
|
|
*
|
|
|
|
* @param {string} $filename The path to the iCal-file
|
|
|
|
*
|
|
|
|
* @return Object The iCal-Object
|
|
|
|
*/
|
2013-03-30 14:55:18 +01:00
|
|
|
public function __construct($filename, $default_timezone, $timezone = false, $igndst = false) {
|
2012-11-17 12:42:48 +01:00
|
|
|
if (!$filename) {
|
|
|
|
$this->errors = "No filename specified";
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
$this->default_timezone = $default_timezone;
|
|
|
|
|
|
|
|
if(isset($timezone) && $timezone != false) {
|
|
|
|
$this->default_timezone = $timezone;
|
|
|
|
$this->timezone_set = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(isset($igndst) && $igndst != false) {
|
|
|
|
$this->ignore_dst = true;
|
|
|
|
}
|
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
|
|
if (stristr($lines[0], 'BEGIN:VCALENDAR') === false) {
|
2012-11-12 23:57:50 +01:00
|
|
|
$this->errors = "Not a valid ical file";
|
2012-11-17 12:42:48 +01:00
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
foreach ($lines as $line) {
|
|
|
|
$line = trim($line);
|
|
|
|
$add = $this->keyValueFromString($line);
|
|
|
|
if ($add === false) {
|
|
|
|
$this->addCalendarComponentWithKeyAndValue($type, false, $line);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
list($keyword, $dummy, $prop, $propvalue, $value) = $add;
|
2012-11-17 12:42:48 +01:00
|
|
|
|
|
|
|
switch ($line) {
|
2012-12-29 19:49:24 +01:00
|
|
|
// http://www.kanzaki.com/docs/ical/vtodo.html
|
|
|
|
case "BEGIN:VTODO":
|
|
|
|
$this->todo_count++;
|
|
|
|
$type = "VTODO";
|
|
|
|
break;
|
2012-12-30 18:18:39 +01:00
|
|
|
|
|
|
|
case "BEGIN:VALARM":
|
|
|
|
//echo "vevent gematcht";
|
|
|
|
$this->isalarm=true;
|
|
|
|
$type = "VEVENT";
|
|
|
|
break;
|
2012-12-29 19:49:24 +01:00
|
|
|
// http://www.kanzaki.com/docs/ical/vevent.html
|
|
|
|
case "BEGIN:VEVENT":
|
|
|
|
//echo "vevent gematcht";
|
|
|
|
$this->event_count++;
|
|
|
|
$type = "VEVENT";
|
|
|
|
break;
|
2012-11-17 12:42:48 +01:00
|
|
|
|
2012-12-29 19:49:24 +01:00
|
|
|
//all other special strings
|
|
|
|
case "BEGIN:VCALENDAR":
|
|
|
|
case "BEGIN:DAYLIGHT":
|
|
|
|
// http://www.kanzaki.com/docs/ical/vtimezone.html
|
|
|
|
case "BEGIN:VTIMEZONE":
|
|
|
|
case "BEGIN:STANDARD":
|
|
|
|
$type = $value;
|
|
|
|
break;
|
|
|
|
case "END:VTODO": // end special text - goto VCALENDAR key
|
2012-12-30 18:18:39 +01:00
|
|
|
case "END:VEVENT":
|
2012-12-29 19:49:24 +01:00
|
|
|
case "END:VCALENDAR":
|
|
|
|
case "END:DAYLIGHT":
|
|
|
|
case "END:VTIMEZONE":
|
|
|
|
case "END:STANDARD":
|
|
|
|
$type = "VCALENDAR";
|
2012-12-30 18:18:39 +01:00
|
|
|
break;
|
|
|
|
case "END:VALARM":
|
|
|
|
$this->isalarm=false;
|
|
|
|
$type = "VEVENT";
|
|
|
|
break;
|
2012-12-29 19:49:24 +01:00
|
|
|
default:
|
2012-12-29 23:55:47 +01:00
|
|
|
$this->addCalendarComponentWithKeyAndValue($type, $keyword, $value, $prop, $propvalue);
|
2012-12-29 19:49:24 +01:00
|
|
|
break;
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->cal;
|
|
|
|
}
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Add to $this->ical array one value and key.
|
|
|
|
*
|
|
|
|
* @param {string} $component This could be VTODO, VEVENT, VCALENDAR, ...
|
|
|
|
* @param {string} $keyword The keyword, for example DTSTART
|
|
|
|
* @param {string} $value The value, for example 20110105T090000Z
|
|
|
|
*
|
|
|
|
* @return {None}
|
|
|
|
*/
|
2012-12-29 23:55:47 +01:00
|
|
|
public function addCalendarComponentWithKeyAndValue($component, $keyword, $value, $prop = false, $propvalue = false) {
|
2012-12-29 19:49:24 +01:00
|
|
|
if ($keyword == false) { // multiline value
|
2012-11-17 12:42:48 +01:00
|
|
|
$keyword = $this->last_keyword;
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
switch ($component) {
|
2012-12-09 22:39:49 +01:00
|
|
|
case 'VEVENT':
|
2012-12-30 18:18:39 +01:00
|
|
|
if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND") or stristr($keyword, "TRIGGER")) {
|
2012-12-29 23:55:47 +01:00
|
|
|
$ts = $this->iCalDateToUnixTimestamp($value, $prop, $propvalue);
|
2012-12-09 22:39:49 +01:00
|
|
|
$value = $ts * 1000;
|
2013-03-30 14:55:18 +01:00
|
|
|
}
|
|
|
|
$value = str_replace("\\n", "\n", $value);
|
|
|
|
|
|
|
|
$value = $this->customFilters($keyword, $value);
|
|
|
|
|
2012-12-30 18:18:39 +01:00
|
|
|
if(!$this->isalarm) {
|
|
|
|
$value = $this->cal[$component][$this->event_count - 1][$keyword].$value;
|
|
|
|
} else {
|
|
|
|
$value = $this->cal[$component][$this->event_count - 1]["VALARM"][$keyword].$value;
|
|
|
|
}
|
2012-12-09 22:39:49 +01:00
|
|
|
break;
|
|
|
|
case 'VTODO' :
|
|
|
|
$value = $this->cal[$component][$this->todo_count - 1]
|
|
|
|
[$keyword].$value;
|
|
|
|
break;
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-12-29 19:49:24 +01:00
|
|
|
/* This should not be neccesary anymore*/
|
2012-12-09 22:39:49 +01:00
|
|
|
//always strip additional content....
|
|
|
|
//if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND")) {
|
2012-12-29 19:49:24 +01:00
|
|
|
//$keyword = explode(";", $keyword);
|
|
|
|
//$keyword = $keyword[0]; // remove additional content like VALUE=DATE
|
2012-12-09 22:39:49 +01:00
|
|
|
//}
|
2012-11-17 12:42:48 +01:00
|
|
|
|
2013-03-30 23:10:58 +01:00
|
|
|
if ((stristr($keyword, "TIMEZONE") || stristr($keyword, "TZID")) && !$this->timezone_set) { // check if timezone already set...
|
|
|
|
$this->default_timezone = $this->trimTimeZone($value); // store the calendertimezone
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
switch ($component) {
|
2012-12-09 22:39:49 +01:00
|
|
|
case "VTODO":
|
|
|
|
$this->cal[$component][$this->todo_count - 1][$keyword] = $value;
|
|
|
|
//$this->cal[$component][$this->todo_count]['Unix'] = $unixtime;
|
|
|
|
break;
|
|
|
|
case "VEVENT":
|
2012-12-30 18:18:39 +01:00
|
|
|
if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND") or stristr($keyword, "TRIGGER")) {
|
2012-12-29 23:55:47 +01:00
|
|
|
$ts = $this->iCalDateToUnixTimestamp($value, $prop, $propvalue);
|
2012-12-09 22:39:49 +01:00
|
|
|
$value = $ts * 1000;
|
|
|
|
}
|
|
|
|
$value = str_replace("\\n", "\n", $value);
|
2012-12-30 18:18:39 +01:00
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
$value = $this->customFilters($keyword, $value);
|
|
|
|
|
2012-12-30 18:18:39 +01:00
|
|
|
if(!$this->isalarm) {
|
|
|
|
$this->cal[$component][$this->event_count - 1][$keyword] = $value;
|
|
|
|
} else {
|
|
|
|
$this->cal[$component][$this->event_count - 1]["VALARM"][$keyword] = $value;
|
|
|
|
}
|
2012-12-09 22:39:49 +01:00
|
|
|
break;
|
2012-12-30 18:18:39 +01:00
|
|
|
default:
|
2012-12-09 22:39:49 +01:00
|
|
|
$this->cal[$component][$keyword] = $value;
|
|
|
|
break;
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
|
|
|
$this->last_keyword = $keyword;
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
/**
|
|
|
|
* Filter some chars out of the value.
|
|
|
|
*
|
|
|
|
* @param {string} $keyword keyword to which the filter is applied
|
|
|
|
* @param {string} $value to filter
|
|
|
|
* @return {string} filtered value
|
|
|
|
*/
|
|
|
|
private function customFilters($keyword, $value) {
|
|
|
|
if (stristr($keyword, "SUMMARY")) {
|
|
|
|
$value = str_replace("\n", " ", $value); // we don't need linebreaks in the summary...
|
|
|
|
}
|
|
|
|
|
|
|
|
if (stristr($keyword, "SUMMARY")) {
|
|
|
|
$value = str_replace("\,", ",", $value); // strange escaped comma
|
|
|
|
}
|
|
|
|
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
|
2013-03-30 23:10:58 +01:00
|
|
|
/**
|
|
|
|
* Trim a Timezone String
|
|
|
|
*
|
|
|
|
* @param {string} $timezone timezone string which should be trimmed
|
|
|
|
* @return {string} trimmed value
|
|
|
|
*/
|
|
|
|
private function trimTimeZone($timezone) {
|
|
|
|
if(preg_match('~([?<=/]*)([^/]*[/|-][^/]*$)~', $timezone, $matches)) { // detects tzurls in tzids
|
|
|
|
if ($matches[2] != "") {
|
|
|
|
return $matches[2]; // 2 = extracted timezone
|
|
|
|
} else {
|
|
|
|
return $timezone;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $timezone;
|
|
|
|
}
|
|
|
|
|
2012-11-12 23:57:50 +01:00
|
|
|
/**
|
2012-11-17 12:42:48 +01:00
|
|
|
* Get a key-value pair of a string.
|
|
|
|
*
|
|
|
|
* @param {string} $text which is like "VCALENDAR:Begin" or "LOCATION:"
|
|
|
|
*
|
2013-03-30 14:55:18 +01:00
|
|
|
* @return {array} array("Argument", "Optional Arg/Val", "Optional Arg", "Optional Value", "Value")
|
2012-11-17 12:42:48 +01:00
|
|
|
*/
|
|
|
|
public function keyValueFromString($text) {
|
2013-03-30 14:55:18 +01:00
|
|
|
|
|
|
|
preg_match('/(^[^a-z:;]+)([;]+([a-zA-Z]*)[=]*([^:"]*|"[\w\W]*"))?[:]([\w\W]*)/', $text, $matches);
|
|
|
|
|
|
|
|
// this regex has problems with multiple attributes... ATTENDEE;RSVP=TRUE;ROLE=REQ-PARTICIPANT:mailto:jsmith@example.com
|
|
|
|
// TODO: fix this
|
2012-12-09 22:39:49 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
if (count($matches) == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
2012-12-09 22:39:49 +01:00
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
$matches = array_splice($matches, 1, 5); // 0 = Arg, 1 = Complete Optional Arg/Val, 2 = Optional Arg, 3 = Optional Val, 4 = Value
|
2012-11-17 12:42:48 +01:00
|
|
|
return $matches;
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
2013-03-30 14:55:18 +01:00
|
|
|
* Return UTC Unix timestamp from ical date time format
|
2012-11-17 12:42:48 +01:00
|
|
|
*
|
|
|
|
* @param {string} $icalDate A Date in the format YYYYMMDD[T]HHMMSS[Z] or
|
|
|
|
* YYYYMMDD[T]HHMMSS
|
|
|
|
*
|
|
|
|
* @return {int}
|
|
|
|
*/
|
2013-03-30 14:55:18 +01:00
|
|
|
private function iCalDateToUTCUnixTimestamp($icalDate, $prop, $propvalue) {
|
2012-12-28 21:10:45 +01:00
|
|
|
|
2012-12-29 23:55:47 +01:00
|
|
|
$timezone = false;
|
2013-06-13 20:49:40 +02:00
|
|
|
$allday = false;
|
2012-12-29 23:55:47 +01:00
|
|
|
|
|
|
|
if($prop) {
|
|
|
|
$pos = strpos("TZIDtzid", $prop);
|
2012-12-30 18:18:39 +01:00
|
|
|
if($pos !== false && $propvalue != false) {
|
2012-12-29 23:55:47 +01:00
|
|
|
$timezone = str_replace('"', '', $propvalue);
|
|
|
|
$timezone = str_replace('\'', '', $timezone);
|
2013-03-30 23:10:58 +01:00
|
|
|
$timezone = $this->trimTimeZone($timezone);
|
2012-12-29 23:55:47 +01:00
|
|
|
}
|
2012-12-29 19:49:24 +01:00
|
|
|
}
|
|
|
|
|
2012-12-28 21:10:45 +01:00
|
|
|
/* timestring format */
|
|
|
|
$utc = strpos("zZ",substr($icalDate, -1)) === false ? false : true;
|
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
$icalDate = str_replace('T', '', $icalDate);
|
|
|
|
$icalDate = str_replace('Z', '', $icalDate);
|
|
|
|
|
|
|
|
$pattern = '/([0-9]{4})'; // 1: YYYY
|
|
|
|
$pattern .= '([0-9]{2})'; // 2: MM
|
|
|
|
$pattern .= '([0-9]{2})'; // 3: DD
|
|
|
|
$pattern .= '([0-9]{0,2})'; // 4: HH
|
|
|
|
$pattern .= '([0-9]{0,2})'; // 5: MM
|
|
|
|
$pattern .= '([0-9]{0,2})/'; // 6: SS
|
2013-06-13 20:49:40 +02:00
|
|
|
preg_match($pattern, $icalDate, $date);
|
2012-11-17 12:42:48 +01:00
|
|
|
|
|
|
|
// Unix timestamp can't represent dates before 1970
|
|
|
|
if ($date[1] <= 1970) {
|
|
|
|
return false;
|
2013-06-13 20:49:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// check if we have a allday event
|
|
|
|
if((!$date[6] || $date[6] === "") || (!$date[5] || $date[5] === "") || (!$date[4] || $date[4] === "")) {
|
|
|
|
$date[6] = 0;
|
|
|
|
$date[5] = 0;
|
|
|
|
$date[4] = 0;
|
|
|
|
$allday = true;
|
|
|
|
|
|
|
|
$dtz = date_default_timezone_get();
|
|
|
|
date_default_timezone_set('UTC');
|
|
|
|
}
|
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
// Unix timestamps after 03:14:07 UTC 2038-01-19 might cause an overflow
|
|
|
|
// if 32 bit integers are used.
|
|
|
|
$timestamp = mktime((int)$date[4],
|
|
|
|
(int)$date[5],
|
|
|
|
(int)$date[6],
|
|
|
|
(int)$date[2],
|
|
|
|
(int)$date[3],
|
|
|
|
(int)$date[1]);
|
|
|
|
|
2013-06-13 20:49:40 +02:00
|
|
|
if($allday) {
|
|
|
|
date_default_timezone_set($dtz);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!$utc && !$allday) {
|
2012-12-29 19:49:24 +01:00
|
|
|
$tz = $this->default_timezone;
|
2012-12-30 18:18:39 +01:00
|
|
|
if($timezone != false) {
|
2012-12-29 19:49:24 +01:00
|
|
|
$tz = $timezone;
|
|
|
|
}
|
|
|
|
|
2012-12-30 18:18:39 +01:00
|
|
|
$error = false;
|
|
|
|
$this_tz = false;
|
|
|
|
|
|
|
|
try {
|
2013-06-13 20:49:40 +02:00
|
|
|
$this_tz = new DateTimeZone($tz);
|
2012-12-30 18:18:39 +01:00
|
|
|
} catch(Exception $e) {
|
|
|
|
error_log($e->getMessage());
|
|
|
|
$error = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if($error) {
|
|
|
|
try { // Try using the default calendar timezone
|
|
|
|
$this_tz = new DateTimeZone($this->default_timezone);
|
|
|
|
} catch(Exception $e) {
|
|
|
|
error_log($e->getMessage());
|
|
|
|
$timestamp_utc = $timestamp; // if that fails, we cannot do anymore
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if($this_tz != false) {
|
|
|
|
$tz_now = new DateTime("now", $this_tz);
|
|
|
|
$tz_offset = $this_tz->getOffset($tz_now);
|
|
|
|
$timestamp_utc = $timestamp - $tz_offset;
|
|
|
|
}
|
2012-12-28 21:10:45 +01:00
|
|
|
} else {
|
2012-12-29 19:49:24 +01:00
|
|
|
$timestamp_utc = $timestamp;
|
2012-12-28 21:10:45 +01:00
|
|
|
}
|
2012-11-17 12:42:48 +01:00
|
|
|
|
2013-06-13 20:49:40 +02:00
|
|
|
return array($timestamp_utc,$allday);
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2013-03-30 14:55:18 +01:00
|
|
|
/**
|
|
|
|
* Return a timezone specific timestamp
|
|
|
|
* @param {int} $timestamp_utc UTC Timestamp to convert
|
|
|
|
* @param {string} $timezone Timezone
|
|
|
|
* @return {int}
|
|
|
|
*/
|
|
|
|
private function UTCTimestampToTZTimestamp($timestamp_utc, $timezone, $ignore_dst = false) {
|
|
|
|
$this_tz = false;
|
|
|
|
try { // Try using the default calendar timezone
|
|
|
|
$this_tz = new DateTimeZone($this->default_timezone);
|
|
|
|
} catch(Exception $e) {
|
|
|
|
error_log($e->getMessage());
|
|
|
|
$timestamp_utc = $timestamp; // if that fails, we cannot do anymore
|
|
|
|
}
|
|
|
|
if($this_tz != false) {
|
|
|
|
$transition = $this_tz->getTransitions($timestamp_utc,$timestamp_utc);
|
|
|
|
$trans_offset = $transition[0]['offset'];
|
|
|
|
$isdst = $transition[0]['isdst'];
|
|
|
|
|
|
|
|
$tz_now = new DateTime("now", $this_tz);
|
|
|
|
$tz_offset = $this_tz->getOffset($tz_now);
|
|
|
|
|
|
|
|
if(!$ignore_dst) {
|
|
|
|
$tz_offset = $trans_offset; // normaly use dst
|
|
|
|
}
|
|
|
|
|
|
|
|
return $timestamp_utc + $tz_offset;
|
|
|
|
}
|
|
|
|
return $timestamp_utc; // maybe timezone conversion will fail...
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Return Timezone specific Unix timestamp from ical date time format
|
|
|
|
*
|
|
|
|
* @param {string} $icalDate A Date in the format YYYYMMDD[T]HHMMSS[Z] or
|
|
|
|
* YYYYMMDD[T]HHMMSS
|
|
|
|
*
|
|
|
|
* @return {int}
|
|
|
|
*/
|
|
|
|
public function iCalDateToUnixTimestamp($icalDate, $prop, $propvalue) {
|
2013-06-13 20:49:40 +02:00
|
|
|
list($timestamp, $allday) = $this->iCalDateToUTCUnixTimestamp($icalDate, $prop, $propvalue);
|
|
|
|
|
|
|
|
if(!$allday) {
|
|
|
|
$timestamp = $this->UTCTimestampToTZTimestamp($timestamp, $this->default_timezone, $this->ignore_dst, $allday);
|
|
|
|
}
|
2013-03-30 14:55:18 +01:00
|
|
|
|
|
|
|
return $timestamp;
|
|
|
|
}
|
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Returns an array of arrays with all events. Every event is an associative
|
|
|
|
* array and each property is an element it.
|
|
|
|
*
|
|
|
|
* @return {array}
|
|
|
|
*/
|
|
|
|
public function events() {
|
|
|
|
$array = $this->cal;
|
|
|
|
return $array['VEVENT'];
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Returns an array of calendar types.
|
|
|
|
*
|
|
|
|
* @return {array}
|
|
|
|
*/
|
|
|
|
public function calendar() {
|
|
|
|
$array = $this->cal;
|
|
|
|
return $array['VCALENDAR'];
|
|
|
|
}
|
2013-03-30 23:10:58 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the default or set timezone
|
|
|
|
*
|
|
|
|
* @return {string}
|
|
|
|
*/
|
|
|
|
public function timezone() {
|
|
|
|
return $this->default_timezone;
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Returns a boolean value whether thr current calendar has events or not
|
|
|
|
*
|
|
|
|
* @return {boolean}
|
|
|
|
*/
|
|
|
|
public function hasEvents() {
|
|
|
|
return ( count($this->events()) > 0 ? true : false );
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Returns false when the current calendar has no events in range, else the
|
|
|
|
* events.
|
|
|
|
*
|
|
|
|
* Note that this function makes use of a UNIX timestamp. This might be a
|
|
|
|
* problem on January the 29th, 2038.
|
|
|
|
* See http://en.wikipedia.org/wiki/Unix_time#Representing_the_number
|
|
|
|
*
|
|
|
|
* @param {boolean} $rangeStart Either true or false
|
|
|
|
* @param {boolean} $rangeEnd Either true or false
|
|
|
|
*
|
|
|
|
* @return {mixed}
|
|
|
|
*/
|
|
|
|
public function eventsFromRange($rangeStart = false, $rangeEnd = false) {
|
|
|
|
$events = $this->sortEventsWithOrder($this->events(), SORT_ASC);
|
|
|
|
|
|
|
|
if (!$events) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
$extendedEvents = array();
|
|
|
|
|
|
|
|
if ($rangeStart !== false) {
|
|
|
|
$rangeStart = new DateTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ($rangeEnd !== false or $rangeEnd <= 0) {
|
|
|
|
$rangeEnd = new DateTime('2038/01/18');
|
|
|
|
} else {
|
|
|
|
$rangeEnd = new DateTime($rangeEnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
$rangeStart = $rangeStart->format('U');
|
|
|
|
$rangeEnd = $rangeEnd->format('U');
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// loop through all events by adding two new elements
|
|
|
|
foreach ($events as $anEvent) {
|
|
|
|
$timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
|
|
if ($timestamp >= $rangeStart && $timestamp <= $rangeEnd) {
|
|
|
|
$extendedEvents[] = $anEvent;
|
|
|
|
}
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
return $extendedEvents;
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
/**
|
|
|
|
* Returns sorted events
|
|
|
|
*
|
|
|
|
* @param {array} $events An array with events.
|
|
|
|
* @param {array} $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR,
|
|
|
|
* SORT_NUMERIC, SORT_STRING
|
|
|
|
*
|
|
|
|
* @return {array}
|
|
|
|
*/
|
|
|
|
public function sortEventsWithOrder($events, $sortOrder = SORT_ASC) {
|
|
|
|
$extendedEvents = array();
|
|
|
|
|
|
|
|
// loop through all events by adding two new elements
|
|
|
|
foreach ($events as $anEvent) {
|
|
|
|
if (!array_key_exists('UNIX_TIMESTAMP', $anEvent)) {
|
2013-03-30 14:55:18 +01:00
|
|
|
$anEvent['UNIX_TIMESTAMP'] = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
|
2012-11-17 12:42:48 +01:00
|
|
|
if (!array_key_exists('REAL_DATETIME', $anEvent)) {
|
2013-03-30 14:55:18 +01:00
|
|
|
$anEvent['REAL_DATETIME'] = date("d.m.Y", $anEvent['UNIX_TIMESTAMP']);
|
2012-11-17 12:42:48 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
$extendedEvents[] = $anEvent;
|
|
|
|
}
|
|
|
|
|
|
|
|
foreach ($extendedEvents as $key => $value) {
|
|
|
|
$timestamp[$key] = $value['UNIX_TIMESTAMP'];
|
|
|
|
}
|
|
|
|
array_multisort($timestamp, $sortOrder, $extendedEvents);
|
|
|
|
|
|
|
|
return $extendedEvents;
|
|
|
|
}
|
2012-11-12 23:57:50 +01:00
|
|
|
}
|
|
|
|
?>
|