/
home
/
faureele
/
extra-til
/
wp-content
/
uploads
/
dpProEventCalendar
/
includes
/
Upload File
HOME
<?php /** * This PHP-Class should only read a iCal-File (*.ics), parse it and give an * array with its content. * * PHP Version 5 * * @category Parser * @package Ics-parser * @author Martin Thoma <info@martin-thoma.de> * @license http://www.opensource.org/licenses/mit-license.php MIT License * @version SVN: <svn_id> * @link http://code.google.com/p/ics-parser/ * @example $ical = new ical('MyCal.ics'); * print_r( $ical->events() ); */ //error_reporting(E_ALL); /** * This is the iCal-class * * @category Parser * @package Ics-parser * @author Martin Thoma <info@martin-thoma.de> * @license http://www.opensource.org/licenses/mit-license.php MIT License * @link http://code.google.com/p/ics-parser/ * * @param {string} filename The name of the file which should be parsed * @constructor */ class ICal { /* How many ToDos are in this ical? */ public /** @type {int} */ $todo_count = 0; /* How many events are in this ical? */ public /** @type {int} */ $event_count = 0; /* The parsed calendar */ public /** @type {Array} */ $cal; /* Which keyword has been added to cal at last? */ private /** @type {string} */ $_lastKeyWord; /** * Creates the iCal-Object * * @param {string} $filename The path to the iCal-file * * @return Object The iCal-Object */ public function __construct($filename) { if (!$filename) { return false; } if(substr($filename, 0, 1) == "/") { $filename = "file://".$filename; } if(substr($filename, 0, 2) == "C:") { $filename = "file://".$filename; } if( strpos($filename, 'facebook.com') === -1 && ini_get('allow_url_fopen') ) { $lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); } else { // Get cURL resource $curl = curl_init(); // Set some options - we are passing in a useragent too here curl_setopt_array($curl, array( CURLOPT_RETURNTRANSFER => 1, CURLOPT_URL => $filename, CURLOPT_FOLLOWLOCATION => 1, CURLOPT_USERAGENT => "Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0" )); // Send the request & save response to $resp $resp = curl_exec($curl); /*if (curl_error($curl)) { $error_msg = curl_error($curl); echo $error_msg; }*/ $lines_tmp = explode(PHP_EOL, $resp); $lines = array(); foreach ($lines_tmp as $line) { $lines[] = rtrim($line); } // Close request to clear up some resources curl_close($curl); } if (stristr($lines[0], 'BEGIN:VCALENDAR') === false) { return false; } else { // TODO: Fix multiline-description problem (see http://tools.ietf.org/html/rfc2445#section-4.8.1.5) $skipnextline = false; $is_apple = false; foreach ($lines as $line) { if($line == "") { continue; } $line = str_replace('\n', '<br>', $line); $line = str_replace("’", "'", $line); if(strpos($line, 'X-APPLE-') !== false) { $is_apple = true; continue; } if(substr($line, 0, 1) == " ") { if(!$is_apple) { $line = substr($line, 1); //echo $line.'<br>'; $this->addCalendarComponentWithKeyAndValue('VEVENT', false, $line); } else { } continue; } else { $is_apple = false; //$skipnextline = true; //continue; } if($skipnextline) { $skipnextline = false; continue; } $line = ltrim($line); $add = $this->keyValueFromString($line); if ($add === false) { $this->addCalendarComponentWithKeyAndValue($type, false, $line); continue; } list($keyword, $value) = $add; switch ($line) { // http://www.kanzaki.com/docs/ical/vtodo.html case "BEGIN:VTODO": $this->todo_count++; $type = "VTODO"; break; // http://www.kanzaki.com/docs/ical/vevent.html case "BEGIN:VEVENT": //echo "vevent gematcht"; $this->event_count++; $type = "VEVENT"; break; //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 case "END:VEVENT": case "END:VCALENDAR": case "END:DAYLIGHT": case "END:VTIMEZONE": case "END:STANDARD": $type = "VCALENDAR"; break; default: $this->addCalendarComponentWithKeyAndValue($type, $keyword, $value); break; } } /*echo '<pre>'; print_r($this->cal); echo '</pre>';*/ return $this->cal; } } /** * 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} */ public function addCalendarComponentWithKeyAndValue($component, $keyword, $value) { $concatenate = true; if ($keyword == false) { $keyword = $this->last_keyword; switch ($component) { case 'VEVENT': $value = $this->cal[$component][$this->event_count - 1] [$keyword].$value; $concatenate = false; break; case 'VTODO' : $value = $this->cal[$component][$this->todo_count - 1] [$keyword].$value; $concatenate = false; break; } } $dstart_complete = ""; if (stristr($keyword, "DTSTART") or stristr($keyword, "DTEND")) { if(strpos($keyword, "TZID") !== false) { $dstart_complete = substr($keyword, strpos($keyword, "TZID")); $dstart_complete = str_replace("TZID=", "", $dstart_complete); } $keyword = explode(";", $keyword); $keyword = $keyword[0]; } switch ($component) { case "VTODO": $this->cal[$component][$this->todo_count - 1][$keyword] = $value; //$this->cal[$component][$this->todo_count]['Unix'] = $unixtime; break; case "VEVENT": if(!isset($this->cal[$component][$this->event_count - 1][$keyword])) { if(($keyword == 'DTSTART' || $keyword == 'DTEND') && strpos($value, ':') !== false) { $this->cal[$component][$this->event_count - 1][$keyword] = substr($value, stripos($value, ':') + 1); } else { $this->cal[$component][$this->event_count - 1][$keyword] = $value; if($dstart_complete != "") { $this->cal[$component][$this->event_count - 1]["TZID"] = $dstart_complete; } } } else { if($concatenate) { $this->cal[$component][$this->event_count - 1][$keyword] .= $value; } else { $this->cal[$component][$this->event_count - 1][$keyword] = $value; } } break; default: if($component == 'VTIMEZONE' || $component == 'STANDARD') { if($component == 'STANDARD') { if($keyword != 'TZOFFSETTO') { continue; } $this->cal[$component][][$keyword] = $value; } else { //echo $keyword; $this->cal[$component][][$keyword] = $value; } } else { $this->cal[$component][$keyword] = $value; } break; } $this->last_keyword = $keyword; } /** * Get a key-value pair of a string. * * @param {string} $text which is like "VCALENDAR:Begin" or "LOCATION:" * * @return {array} array("VCALENDAR", "Begin") */ public function keyValueFromString($text) { preg_match("/([^:]+)[:]([\w\W]*)/", $text, $matches); if (count($matches) == 0) { return false; } $matches = array_splice($matches, 1, 2); return $matches; } /** * Return 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) { $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 preg_match($pattern, $icalDate, $date); // Unix timestamp can't represent dates before 1970 if ($date[1] <= 1970) { return false; } // 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]); return $timestamp; } /** * 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']; } /** * Returns a boolean value whether thr current calendar has events or not * * @return {boolean} */ public function hasEvents() { return ( count($this->events()) > 0 ? true : false ); } /** * 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; } } return $extendedEvents; } /** * Returns a boolean value whether thr current calendar has events or not * * @param {array} $events An array with events. * @param {array} $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR, * SORT_NUMERIC, SORT_STRING * * @return {boolean} */ 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)) { $anEvent['UNIX_TIMESTAMP'] = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']); } if (!array_key_exists('REAL_DATETIME', $anEvent)) { $anEvent['REAL_DATETIME'] = date("d.m.Y", $anEvent['UNIX_TIMESTAMP']); } $extendedEvents[] = $anEvent; } foreach ($extendedEvents as $key => $value) { $timestamp[$key] = $value['UNIX_TIMESTAMP']; } array_multisort($timestamp, $sortOrder, $extendedEvents); return $extendedEvents; } } ?>