Example #1
0
 /**
  * @return array
  */
 private function getICalPeriods()
 {
     $response = [];
     $iCalLink = $this->checkForICalHref();
     if ($this->checkAccessToFile($iCalLink)) {
         $startArray = array();
         $endArray = array();
         require_once 'iCalcreator.php';
         $v = new \vcalendar();
         // initiate new CALENDAR
         $config = array("unique_id" => "ukrapts.com", "url" => "{$iCalLink}");
         $v->setConfig($config);
         $v->parse();
         $v->sort();
         $i = 0;
         while ($comp = $v->getComponent("VEVENT")) {
             $dtstart_array = $comp->getProperty("DTSTART", 1, TRUE);
             $dtstart = $dtstart_array["value"];
             $startDate = "{$dtstart["year"]}-{$dtstart["month"]}-{$dtstart["day"]}";
             $dtend_array = $comp->getProperty("dtend", 1, TRUE);
             $dtend = $dtend_array["value"];
             $endDate = "{$dtend["year"]}-{$dtend["month"]}-{$dtend["day"]}";
             if ($endDate >= $this->DBQueries()->currentDate()) {
                 $startArray[] = $startDate;
                 $endArray[] = $endDate;
             }
             $i++;
         }
         sort($startArray);
         sort($endArray);
         $response['start'] = $startArray;
         $response['end'] = $endArray;
     }
     return $response;
 }
Example #2
0
 /**
  * The file contents is looked at and events are created here.
  * @param string $fileContents
  * @return integer The number of events saved.
  */
 public function setEventsFromICal($fullDir, $fullFileName, $personId)
 {
     //start parse of local file
     $v = new vcalendar();
     // set directory
     $v->setConfig('directory', $fullDir);
     // set file name
     $v->setConfig('filename', $fullFileName);
     $v->parse();
     $count = 0;
     foreach ($v->components as $component => $info) {
         # get first vevent
         $comp = $v->getComponent("VEVENT");
         $summary_array = $comp->getProperty("summary", 1, TRUE);
         //echo "Event: ", $summary_array["value"], "\n";
         $dtstart_array = $comp->getProperty("dtstart", 1, TRUE);
         $dtstart = $dtstart_array["value"];
         $startDate = "{$dtstart["year"]}-{$dtstart["month"]}-{$dtstart["day"]}";
         $startTime = "{$dtstart["hour"]}:{$dtstart["min"]}:{$dtstart["sec"]}";
         $dtend_array = $comp->getProperty("dtend", 1, TRUE);
         $dtend = $dtend_array["value"];
         $endDate = "{$dtend["year"]}-{$dtend["month"]}-{$dtend["day"]}";
         $endTime = "{$dtend["hour"]}:{$dtend["min"]}:{$dtend["sec"]}";
         //echo "start: ",  $startDate,"T",$startTime, "\n";
         //echo "end: ",  $endDate,"T",$endTime, "\n";
         $location_array = $comp->getProperty("location", 1, TRUE);
         //echo "Location: ", $location_array["value"], "\n <br>";
         //TODO: Check that this event does not already exist.
         $event = new Event();
         $event->setPersonId($personId);
         $event->setName($summary_array["value"]);
         $event->setStartTime($startDate . "T" . $startTime);
         $event->setEndTime($endDate . "T" . $endTime);
         $event->setLocation($location_array["value"]);
         $event->save();
         $count++;
     }
     return $count;
 }
 /**
  * @param string $uri
  * @param array $start
  * @param array $end
  * @param string $subject
  * @param bool $allday
  * @param string $description
  * @param string $location
  * @param null $color
  * @param string $timezone
  * @param bool $notification
  * @param null $notification_type
  * @param null $notification_value
  * @throws Sabre_DAV_Exception_NotFound
  * @throws Sabre_DAV_Exception_Conflict
  */
 public function updateItem($uri, $start, $end, $subject = "", $allday = false, $description = "", $location = "", $color = null, $timezone = "", $notification = true, $notification_type = null, $notification_value = null)
 {
     $a = get_app();
     $usr_id = IntVal($this->calendarDb->uid);
     $old = q("SELECT * FROM %s%sjqcalendar WHERE `uid` = %d AND `namespace` = %d AND `namespace_id` = %d AND `ical_uri` = '%s'", CALDAV_SQL_DB, CALDAV_SQL_PREFIX, $usr_id, $this->getNamespace(), $this->namespace_id, dbesc($uri));
     if (count($old) == 0) {
         throw new Sabre_DAV_Exception_NotFound("Not Found 1");
     }
     $old_obj = new DBClass_friendica_jqcalendar($old[0]);
     $calendarBackend = new Sabre_CalDAV_Backend_Std();
     $obj = $calendarBackend->getCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $old_obj->ical_uri);
     if (!$obj) {
         throw new Sabre_DAV_Exception_NotFound("Not Found 2");
     }
     $v = new vcalendar();
     $v->setConfig('unique_id', $a->get_hostname());
     $v->setMethod('PUBLISH');
     $v->setProperty("x-wr-calname", "AnimexxCal");
     $v->setProperty("X-WR-CALDESC", "Animexx Calendar");
     $v->setProperty("X-WR-TIMEZONE", $a->timezone);
     $obj["calendardata"] = icalendar_sanitize_string($obj["calendardata"]);
     $v->parse($obj["calendardata"]);
     /** @var $vevent vevent */
     $vevent = $v->getComponent('vevent');
     if (trim($vevent->getProperty('uid')) . ".ics" != $old_obj->ical_uri) {
         throw new Sabre_DAV_Exception_Conflict("URI != URI: " . $old_obj->ical_uri . " vs. " . trim($vevent->getProperty("uid")));
     }
     if ($end["year"] < $start["year"] || $end["year"] == $start["year"] && $end["month"] < $start["month"] || $end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] < $start["day"] || $end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] < $start["hour"] || $end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] < $start["minute"] || $end["year"] == $start["year"] && $end["month"] == $start["month"] && $end["day"] == $start["day"] && $end["hour"] == $start["hour"] && $end["minute"] == $start["minute"] && $end["second"] < $start["second"]) {
         $end = $start;
         if ($end["hour"] < 23) {
             $end["hour"]++;
         }
     }
     // DTEND muss <= DTSTART
     if ($start["hour"] == 0 && $start["minute"] == 0 && $end["hour"] == 23 && $end["minute"] == 59) {
         $allday = true;
     }
     if ($allday) {
         $vevent->setDtstart($start["year"], $start["month"], $start["day"], FALSE, FALSE, FALSE, FALSE, array("VALUE" => "DATE"));
         $end = mktime(0, 0, 0, $end["month"], $end["day"], $end["year"]) + 3600 * 24;
         // If a DST change occurs on the current day
         $end += date("Z", $end - 3600 * 24) - date("Z", $end);
         $vevent->setDtend(date("Y", $end), date("m", $end), date("d", $end), FALSE, FALSE, FALSE, FALSE, array("VALUE" => "DATE"));
     } else {
         $vevent->setDtstart($start["year"], $start["month"], $start["day"], $start["hour"], $start["minute"], $start["second"], FALSE, array("VALUE" => "DATE-TIME"));
         $vevent->setDtend($end["year"], $end["month"], $end["day"], $end["hour"], $end["minute"], $end["second"], FALSE, array("VALUE" => "DATE-TIME"));
     }
     if ($subject != "") {
         $vevent->setProperty('LOCATION', $location);
         $vevent->setProperty('summary', $subject);
         $vevent->setProperty('description', $description);
     }
     if (!is_null($color) && $color >= 0) {
         $vevent->setProperty("X-ANIMEXX-COLOR", $color);
     }
     if (!$notification || $notification_type != null) {
         $vevent->deleteComponent("VALARM");
         if ($notification) {
             $valarm = new valarm();
             $valarm->setTrigger($notification_type == "year" ? $notification_value : 0, $notification_type == "month" ? $notification_value : 0, $notification_type == "day" ? $notification_value : 0, $notification_type == "week" ? $notification_value : 0, $notification_type == "hour" ? $notification_value : 0, $notification_type == "minute" ? $notification_value : 0, $notification_type == "minute" ? $notification_value : 0, true, $notification_value > 0);
             $valarm->setProperty("ACTION", "DISPLAY");
             $valarm->setProperty("DESCRIPTION", $subject);
             $vevent->setComponent($valarm);
         }
     }
     $v->deleteComponent("vevent");
     $v->setComponent($vevent, trim($vevent->getProperty("uid")));
     $ical = $v->createCalendar();
     $calendarBackend->updateCalendarObject($this->getNamespace() . "-" . $this->namespace_id, $old_obj->ical_uri, $ical);
 }
Example #4
0
 public function get_json()
 {
     $event_json = array();
     $filters = $this->in->exists('filters', 'int') ? $this->in->getArray('filters', 'int') : false;
     // parse the feeds
     $feeds = $this->pdh->get('calendars', 'idlist', array('feed', $filters));
     if (is_array($feeds) && count($feeds) > 0) {
         foreach ($feeds as $feed) {
             $feedurl = $this->pdh->get('calendars', 'feed', array($feed));
             if (isValidURL($feedurl)) {
                 require_once $this->root_path . 'libraries/icalcreator/iCalcreator.class.php';
                 $vcalendar = new vcalendar(array('url' => $feedurl));
                 if (TRUE === $vcalendar->parse()) {
                     $vcalendar->sort();
                     while ($comp = $vcalendar->getComponent('vevent')) {
                         $startdate = $comp->getProperty('dtstart', 1);
                         $enddate = $comp->getProperty('dtend', 1);
                         $startdate_out = $startdate['year'] . '-' . $startdate['month'] . '-' . $startdate['day'] . ' ' . (isset($startdate['hour']) ? $startdate['hour'] . ':' . $startdate['min'] : '00:00');
                         $enddate_out = $enddate['year'] . '-' . $enddate['month'] . '-' . $enddate['day'] . ' ' . (isset($enddate['hour']) ? $enddate['hour'] . ':' . $enddate['min'] : '00:00');
                         $allday = isset($enddate['hour']) && isset($startdate['hour']) ? false : true;
                         $eventcolor = $this->pdh->get('calendars', 'color', $feed);
                         $eventcolor_txt = get_brightness($eventcolor) > 130 ? 'black' : 'white';
                         $event_json[] = array('eventid' => $calid, 'title' => $comp->getProperty('summary', 1), 'start' => $startdate_out, 'end' => $enddate_out, 'allDay' => $allday, 'note' => $comp->getProperty('description', 1), 'color' => '#' . $eventcolor, 'textColor' => $eventcolor_txt);
                     }
                 }
             }
         }
     }
     // add the calendar events to the json feed
     $calendars = $this->pdh->get('calendars', 'idlist', array('nofeed', $filters));
     $caleventids = $this->pdh->get('calendar_events', 'id_list', array(false, $this->in->get('start', 0), $this->in->get('end', 0)));
     if (is_array($caleventids) && count($caleventids) > 0) {
         foreach ($caleventids as $calid) {
             $eventextension = $this->pdh->get('calendar_events', 'extension', array($calid));
             $raidmode = $eventextension['calendarmode'];
             $eventcolor = $this->pdh->get('calendars', 'color', $this->pdh->get('calendar_events', 'calendar_id', array($calid)));
             $eventcolor_txt = get_brightness($eventcolor) > 130 ? 'black' : 'white';
             if (in_array($this->pdh->get('calendar_events', 'calendar_id', array($calid)), $calendars)) {
                 if ($raidmode == 'raid') {
                     // fetch the attendees
                     $attendees_raw = $this->pdh->get('calendar_raids_attendees', 'attendees', array($calid));
                     $attendees = array();
                     if (is_array($attendees_raw)) {
                         foreach ($attendees_raw as $attendeeid => $attendeerow) {
                             $attendees[$attendeerow['signup_status']][$attendeeid] = $attendeerow;
                         }
                     }
                     // Build the guest array
                     $guests = array();
                     if (registry::register('config')->get('calendar_raid_guests') == 1) {
                         $guestarray = registry::register('plus_datahandler')->get('calendar_raids_guests', 'members', array($calid));
                         if (is_array($guestarray)) {
                             foreach ($guestarray as $guest_row) {
                                 $guests[] = $guest_row['name'];
                             }
                         }
                     }
                     // fetch per raid data
                     $raidcal_status = unserialize($this->config->get('calendar_raid_status'));
                     $rstatusdata = '';
                     if (is_array($raidcal_status)) {
                         foreach ($raidcal_status as $raidcalstat_id) {
                             if ($raidcalstat_id != 4) {
                                 $actcount = isset($attendees[$raidcalstat_id]) ? count($attendees[$raidcalstat_id]) : 0;
                                 if ($raidcalstat_id == 0) {
                                     $actcount += is_array($guests) ? count($guests) : 0;
                                 }
                                 $rstatusdata .= '<div class="raid_status' . $raidcalstat_id . '">' . $this->user->lang(array('raidevent_raid_status', $raidcalstat_id)) . ': ' . $actcount . '</div>';
                             }
                         }
                     }
                     $rstatusdata .= '<div class="raid_status_total">' . $this->user->lang('raidevent_raid_required') . ': ' . (isset($eventextension) ? $eventextension['attendee_count'] : 0) . '</div>';
                     $deadlinedate = $this->pdh->get('calendar_events', 'time_start', array($calid)) - $eventextension['deadlinedate'] * 3600;
                     $deadline = $deadlinedate > $this->time->time || $this->config->get('calendar_raid_allowstatuschange') == '1' && $this->pdh->get('calendar_raids_attendees', 'status', array($calid, $this->user->id)) > 0 && $this->pdh->get('calendar_raids_attendees', 'status', array($calid, $this->user->id)) != 4 && $this->pdh->get('calendar_events', 'time_end', array($calid)) > $this->time->time ? false : true;
                     $deadlineflag = $deadline ? '<img src="' . $this->root_path . 'images/calendar/clock_s.png" alt="Deadline" title="' . $this->user->lang('raidevent_raid_deadl_reach') . '" />' : '';
                     // Build the JSON
                     $event_json[] = array('title' => $this->in->decode_entity($this->pdh->get('calendar_events', 'name', array($calid))), 'start' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_start', array($calid))), 'end' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_end', array($calid))), 'closed' => $this->pdh->get('calendar_events', 'raidstatus', array($calid)) == 1 ? true : false, 'editable' => true, 'eventid' => $calid, 'flag' => $deadlineflag . $this->pdh->get('calendar_raids_attendees', 'html_status', array($calid, $this->user->data['user_id'])), 'url' => 'calendar/viewcalraid.php' . $this->SID . '&eventid=' . $calid, 'icon' => $eventextension['raid_eventid'] ? $this->pdh->get('event', 'icon', array($eventextension['raid_eventid'], true, true)) : '', 'note' => $this->pdh->get('calendar_events', 'notes', array($calid)), 'raidleader' => $eventextension['raidleader'] > 0 ? implode(', ', $this->pdh->aget('member', 'name', 0, array($eventextension['raidleader']))) : '', 'rstatusdata' => $rstatusdata, 'color' => '#' . $eventcolor, 'textColor' => $eventcolor_txt);
                 } else {
                     $event_json[] = array('eventid' => $calid, 'title' => $this->pdh->get('calendar_events', 'name', array($calid)), 'start' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_start', array($calid))), 'end' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_end', array($calid))), 'allDay' => $this->pdh->get('calendar_events', 'allday', array($calid)) > 0 ? true : false, 'note' => $this->pdh->get('calendar_events', 'notes', array($calid)), 'color' => '#' . $eventcolor, 'textColor' => $eventcolor_txt);
                 }
             }
         }
     }
     // Output the array as JSON
     echo json_encode($event_json);
     exit;
 }
Example #5
0
 /**
  * Process vcalendar instance - add events to database.
  *
  * @param vcalendar $v    Calendar to retrieve data from.
  * @param array     $args Arbitrary arguments map.
  *
  * @throws Ai1ec_Parse_Exception
  *
  * @internal param stdClass $feed           Instance of feed (see Ai1ecIcs plugin).
  * @internal param string   $comment_status WP comment status: 'open' or 'closed'.
  * @internal param int      $do_show_map    Map display status (DB boolean: 0 or 1).
  *
  * @return int Count of events added to database.
  */
 public function add_vcalendar_events_to_db(vcalendar $v, array $args)
 {
     $forced_timezone = null;
     $feed = isset($args['feed']) ? $args['feed'] : null;
     $comment_status = isset($args['comment_status']) ? $args['comment_status'] : 'open';
     $do_show_map = isset($args['do_show_map']) ? $args['do_show_map'] : 0;
     $count = 0;
     $events_in_db = isset($args['events_in_db']) ? $args['events_in_db'] : 0;
     //sort by event date function _cmpfcn of iCalcreator.class.php
     $v->sort();
     // Reverse the sort order, so that RECURRENCE-IDs are listed before the
     // defining recurrence events, and therefore take precedence during
     // caching.
     $v->components = array_reverse($v->components);
     // TODO: select only VEVENT components that occur after, say, 1 month ago.
     // Maybe use $v->selectComponents(), which takes into account recurrence
     // Fetch default timezone in case individual properties don't define it
     $tz = $v->getComponent('vtimezone');
     $local_timezone = $this->_registry->get('date.timezone')->get_default_timezone();
     $timezone = $local_timezone;
     if (!empty($tz)) {
         $timezone = $tz->getProperty('TZID');
     }
     $feed_name = $v->getProperty('X-WR-CALNAME');
     $x_wr_timezone = $v->getProperty('X-WR-TIMEZONE');
     if (isset($x_wr_timezone[1]) && is_array($x_wr_timezone)) {
         $forced_timezone = (string) $x_wr_timezone[1];
         $timezone = $forced_timezone;
     }
     $messages = array();
     if (empty($forced_timezone)) {
         $forced_timezone = $local_timezone;
     }
     $current_timestamp = $this->_registry->get('date.time')->format_to_gmt();
     // initialize empty custom exclusions structure
     $exclusions = array();
     // go over each event
     while ($e = $v->getComponent('vevent')) {
         // Event data array.
         $data = array();
         // =====================
         // = Start & end times =
         // =====================
         $start = $e->getProperty('dtstart', 1, true);
         $end = $e->getProperty('dtend', 1, true);
         // For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE value type but none
         // of "DTEND" nor "DURATION" property, the event duration is taken to
         // be one day.  For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE-TIME value type but no
         // "DTEND" property, the event ends on the same calendar date and
         // time of day specified by the "DTSTART" property.
         if (empty($end)) {
             // #1 if duration is present, assign it to end time
             $end = $e->getProperty('duration', 1, true, true);
             if (empty($end)) {
                 // #2 if only DATE value is set for start, set duration to 1 day
                 if (!isset($start['value']['hour'])) {
                     $end = array('value' => array('year' => $start['value']['year'], 'month' => $start['value']['month'], 'day' => $start['value']['day'] + 1, 'hour' => 0, 'min' => 0, 'sec' => 0));
                     if (isset($start['value']['tz'])) {
                         $end['value']['tz'] = $start['value']['tz'];
                     }
                 } else {
                     // #3 set end date to start time
                     $end = $start;
                 }
             }
         }
         $categories = $e->getProperty("CATEGORIES", false, true);
         $imported_cat = array(Ai1ec_Event_Taxonomy::CATEGORIES => array());
         // If the user chose to preserve taxonomies during import, add categories.
         if ($categories && $feed->keep_tags_categories) {
             $imported_cat = $this->add_categories_and_tags($categories['value'], $imported_cat, false, true);
         }
         $feed_categories = $feed->feed_category;
         if (!empty($feed_categories)) {
             $imported_cat = $this->add_categories_and_tags($feed_categories, $imported_cat, false, false);
         }
         $tags = $e->getProperty("X-TAGS", false, true);
         $imported_tags = array(Ai1ec_Event_Taxonomy::TAGS => array());
         // If the user chose to preserve taxonomies during import, add tags.
         if ($tags && $feed->keep_tags_categories) {
             $imported_tags = $this->add_categories_and_tags($tags[1]['value'], $imported_tags, true, true);
         }
         $feed_tags = $feed->feed_tags;
         if (!empty($feed_tags)) {
             $imported_tags = $this->add_categories_and_tags($feed_tags, $imported_tags, true, true);
         }
         // Event is all-day if no time components are defined
         $allday = $this->_is_timeless($start['value']) && $this->_is_timeless($end['value']);
         // Also check the proprietary MS all-day field.
         $ms_allday = $e->getProperty('X-MICROSOFT-CDO-ALLDAYEVENT');
         if (!empty($ms_allday) && $ms_allday[1] == 'TRUE') {
             $allday = true;
         }
         $event_timezone = $timezone;
         if ($allday) {
             $event_timezone = $local_timezone;
         }
         $start = $this->_time_array_to_datetime($start, $event_timezone, $feed->import_timezone ? $forced_timezone : null);
         $end = $this->_time_array_to_datetime($end, $event_timezone, $feed->import_timezone ? $forced_timezone : null);
         if (false === $start || false === $end) {
             throw new Ai1ec_Parse_Exception('Failed to parse one or more dates given timezone "' . var_export($event_timezone, true) . '"');
             continue;
         }
         // If all-day, and start and end times are equal, then this event has
         // invalid end time (happens sometimes with poorly implemented iCalendar
         // exports, such as in The Event Calendar), so set end time to 1 day
         // after start time.
         if ($allday && $start->format() === $end->format()) {
             $end->adjust_day(+1);
         }
         $data += compact('start', 'end', 'allday');
         // =======================================
         // = Recurrence rules & recurrence dates =
         // =======================================
         if ($rrule = $e->createRrule()) {
             $rrule = explode(':', $rrule);
             $rrule = trim(end($rrule));
         }
         if ($exrule = $e->createExrule()) {
             $exrule = explode(':', $exrule);
             $exrule = trim(end($exrule));
         }
         if ($rdate = $e->createRdate()) {
             $arr = explode('RDATE', $rdate);
             $matches = null;
             foreach ($arr as $value) {
                 $arr2 = explode(':', $value);
                 if (2 === count($arr2)) {
                     $matches[] = $arr2[1];
                 }
             }
             if (null !== $matches) {
                 $rdate = implode(',', $matches);
                 unset($matches);
                 unset($arr);
             } else {
                 $rdate = null;
             }
         }
         // ===================
         // = Exception dates =
         // ===================
         $exdate = '';
         if ($exdates = $e->createExdate()) {
             // We may have two formats:
             // one exdate with many dates ot more EXDATE rules
             $exdates = explode('EXDATE', $exdates);
             $def_timezone = $this->_get_import_timezone($event_timezone);
             foreach ($exdates as $exd) {
                 if (empty($exd)) {
                     continue;
                 }
                 $exploded = explode(':', $exd);
                 $excpt_timezone = $def_timezone;
                 $excpt_date = null;
                 foreach ($exploded as $particle) {
                     if (';TZID=' === substr($particle, 0, 6)) {
                         $excpt_timezone = substr($particle, 6);
                     } else {
                         $excpt_date = trim($particle);
                     }
                 }
                 $exploded = explode(',', $excpt_date);
                 foreach ($exploded as $particle) {
                     // Google sends YYYYMMDD for all-day excluded events
                     if ($allday && 8 === strlen($particle)) {
                         $particle .= 'T000000Z';
                         $excpt_timezone = 'UTC';
                     }
                     $ex_dt = $this->_registry->get('date.time', $particle, $excpt_timezone);
                     if ($ex_dt) {
                         if (isset($exdate[0])) {
                             $exdate .= ',';
                         }
                         $exdate .= $ex_dt->format('Ymd\\THis', $excpt_timezone);
                     }
                 }
             }
         }
         // Add custom exclusions if there any
         $recurrence_id = $e->getProperty('recurrence-id');
         if (false === $recurrence_id && !empty($exclusions[$e->getProperty('uid')])) {
             if (isset($exdate[0])) {
                 $exdate .= ',';
             }
             $exdate .= implode(',', $exclusions[$e->getProperty('uid')]);
         }
         // ========================
         // = Latitude & longitude =
         // ========================
         $latitude = $longitude = NULL;
         $geo_tag = $e->getProperty('geo');
         if (is_array($geo_tag)) {
             if (isset($geo_tag['latitude']) && isset($geo_tag['longitude'])) {
                 $latitude = (double) $geo_tag['latitude'];
                 $longitude = (double) $geo_tag['longitude'];
             }
         } else {
             if (!empty($geo_tag) && false !== strpos($geo_tag, ';')) {
                 list($latitude, $longitude) = explode(';', $geo_tag, 2);
                 $latitude = (double) $latitude;
                 $longitude = (double) $longitude;
             }
         }
         unset($geo_tag);
         if (NULL !== $latitude) {
             $data += compact('latitude', 'longitude');
             // Check the input coordinates checkbox, otherwise lat/long data
             // is not present on the edit event page
             $data['show_coordinates'] = 1;
         }
         // ===================
         // = Venue & address =
         // ===================
         $address = $venue = '';
         $location = $e->getProperty('location');
         $matches = array();
         // This regexp matches a venue / address in the format
         // "venue @ address" or "venue - address".
         preg_match('/\\s*(.*\\S)\\s+[\\-@]\\s+(.*)\\s*/', $location, $matches);
         // if there is no match, it's not a combined venue + address
         if (empty($matches)) {
             // temporary fix for Mac ICS import. Se AIOEC-2187
             // and https://github.com/iCalcreator/iCalcreator/issues/13
             $location = str_replace('\\n', "\n", $location);
             // if there is a comma, probably it's an address
             if (false === strpos($location, ',')) {
                 $venue = $location;
             } else {
                 $address = $location;
             }
         } else {
             $venue = isset($matches[1]) ? $matches[1] : '';
             $address = isset($matches[2]) ? $matches[2] : '';
         }
         // =====================================================
         // = Set show map status based on presence of location =
         // =====================================================
         $event_do_show_map = $do_show_map;
         if (1 === $do_show_map && NULL === $latitude && empty($address)) {
             $event_do_show_map = 0;
         }
         // ==================
         // = Cost & tickets =
         // ==================
         $cost = $e->getProperty('X-COST');
         $cost = $cost ? $cost[1] : '';
         $ticket_url = $e->getProperty('X-TICKETS-URL');
         $ticket_url = $ticket_url ? $ticket_url[1] : '';
         // ===============================
         // = Contact name, phone, e-mail =
         // ===============================
         $organizer = $e->getProperty('organizer');
         if ('MAILTO:' === substr($organizer, 0, 7) && false === strpos($organizer, '@')) {
             $organizer = substr($organizer, 7);
         }
         $contact = $e->getProperty('contact');
         $elements = explode(';', $contact, 4);
         foreach ($elements as $el) {
             $el = trim($el);
             // Detect e-mail address.
             if (false !== strpos($el, '@')) {
                 $data['contact_email'] = $el;
             } elseif (false !== strpos($el, '://')) {
                 $data['contact_url'] = $el;
             } elseif (preg_match('/\\d/', $el)) {
                 $data['contact_phone'] = $el;
             } else {
                 $data['contact_name'] = $el;
             }
         }
         if (!isset($data['contact_name']) || !$data['contact_name']) {
             // If no contact name, default to organizer property.
             $data['contact_name'] = $organizer;
         }
         $description = stripslashes(str_replace('\\n', "\n", $e->getProperty('description')));
         $description = $this->_remove_ticket_url($description);
         // Store yet-unsaved values to the $data array.
         $data += array('recurrence_rules' => $rrule, 'exception_rules' => $exrule, 'recurrence_dates' => $rdate, 'exception_dates' => $exdate, 'venue' => $venue, 'address' => $address, 'cost' => $cost, 'ticket_url' => $ticket_url, 'show_map' => $event_do_show_map, 'ical_feed_url' => $feed->feed_url, 'ical_source_url' => $e->getProperty('url'), 'ical_organizer' => $organizer, 'ical_contact' => $contact, 'ical_uid' => $this->_get_ical_uid($e), 'categories' => array_keys($imported_cat[Ai1ec_Event_Taxonomy::CATEGORIES]), 'tags' => array_keys($imported_tags[Ai1ec_Event_Taxonomy::TAGS]), 'feed' => $feed, 'post' => array('post_status' => 'publish', 'comment_status' => $comment_status, 'post_type' => AI1EC_POST_TYPE, 'post_author' => 1, 'post_title' => $e->getProperty('summary'), 'post_content' => $description));
         // register any custom exclusions for given event
         $exclusions = $this->_add_recurring_events_exclusions($e, $exclusions, $start);
         // Create event object.
         $data = apply_filters('ai1ec_pre_init_event_from_feed', $data, $e, $feed);
         $event = $this->_registry->get('model.event', $data);
         // Instant Event
         $is_instant = $e->getProperty('X-INSTANT-EVENT');
         if ($is_instant) {
             $event->set_no_end_time();
         }
         $recurrence = $event->get('recurrence_rules');
         $search = $this->_registry->get('model.search');
         // first let's check by UID
         $matching_event_id = $search->get_matching_event_by_uid_and_url($event->get('ical_uid'), $event->get('ical_feed_url'));
         // if no result, perform the legacy check.
         if (null === $matching_event_id) {
             $matching_event_id = $search->get_matching_event_id($event->get('ical_uid'), $event->get('ical_feed_url'), $event->get('start'), !empty($recurrence));
         }
         if (null === $matching_event_id) {
             // =================================================
             // = Event was not found, so store it and the post =
             // =================================================
             $event->save();
             $count++;
         } else {
             // ======================================================
             // = Event was found, let's store the new event details =
             // ======================================================
             $uid_cal = $e->getProperty('uid');
             if (!ai1ec_is_blank($uid_cal)) {
                 $uid_cal_original = sprintf($event->get_uid_pattern(), $matching_event_id);
                 if ($uid_cal_original === $uid_cal) {
                     //avoiding cycle import
                     //ignore the event, it belongs to site
                     unset($events_in_db[$matching_event_id]);
                     continue;
                 }
             }
             // Update the post
             $post = get_post($matching_event_id);
             if (null !== $post) {
                 $post->post_title = $event->get('post')->post_title;
                 $post->post_content = $event->get('post')->post_content;
                 wp_update_post($post);
                 // Update the event
                 $event->set('post_id', $matching_event_id);
                 $event->set('post', $post);
                 $event->save(true);
                 $count++;
             }
         }
         do_action('ai1ec_ics_event_saved', $event, $feed);
         // import not standard taxonomies.
         unset($imported_cat[Ai1ec_Event_Taxonomy::CATEGORIES]);
         foreach ($imported_cat as $tax_name => $ids) {
             wp_set_post_terms($event->get('post_id'), array_keys($ids), $tax_name);
         }
         unset($imported_tags[Ai1ec_Event_Taxonomy::TAGS]);
         foreach ($imported_tags as $tax_name => $ids) {
             wp_set_post_terms($event->get('post_id'), array_keys($ids), $tax_name);
         }
         // import the metadata used by ticket events
         $cost_type = $e->getProperty('X-COST-TYPE');
         if ($cost_type && false === ai1ec_is_blank($cost_type[1])) {
             update_post_meta($event->get('post_id'), '_ai1ec_cost_type', $cost_type[1]);
         }
         $api_event_id = $e->getProperty('X-API-EVENT-ID');
         if ($api_event_id && false === ai1ec_is_blank($api_event_id[1])) {
             $api_event_id = $api_event_id[1];
         } else {
             $api_event_id = null;
         }
         $api_url = $e->getProperty('X-API-URL');
         if ($api_url && false === ai1ec_is_blank($api_url[1])) {
             $api_url = $api_url[1];
         } else {
             $api_url = null;
         }
         $checkout_url = $e->getProperty('X-CHECKOUT-URL');
         if ($checkout_url && false === ai1ec_is_blank($checkout_url[1])) {
             $checkout_url = $checkout_url[1];
         } else {
             $checkout_url = null;
         }
         $currency = $e->getProperty('X-API-EVENT-CURRENCY');
         if ($currency && false === ai1ec_is_blank($currency[1])) {
             $currency = $currency[1];
         } else {
             $currency = null;
         }
         if ($api_event_id || $api_url || $checkout_url || $currency) {
             if (!isset($api)) {
                 $api = $this->_registry->get('model.api.api-ticketing');
             }
             $api->save_api_event_data($event->get('post_id'), $api_event_id, $api_url, $checkout_url, $currency);
         }
         $wp_images_url = $e->getProperty('X-WP-IMAGES-URL');
         if ($wp_images_url && false === ai1ec_is_blank($wp_images_url[1])) {
             $images_arr = explode(',', $wp_images_url[1]);
             foreach ($images_arr as $key => $value) {
                 $images_arr[$key] = explode(';', $value);
             }
             if (count($images_arr) > 0) {
                 update_post_meta($event->get('post_id'), '_featured_image', $images_arr);
             }
         }
         unset($events_in_db[$event->get('post_id')]);
     }
     //close while iteration
     return array('count' => $count, 'events_to_delete' => $events_in_db, 'messages' => $messages, 'name' => $feed_name);
 }
Example #6
0
{
	#http://www.fbcalendar.com/cal/707610112/9b857cca655089425da6d912-707610112/events/ics/attending,unsure,not_replied/
	$data = file_get_contents("http://www.fbcalendar.com/cal/$uid/$key-$uid/events/ics/attending,unsure,not_replied/");
	if ($data == "")
		die("Can't read from Facebook!\n");
	file_put_contents($fname, $data);
}

$v->parse($fname);

$tz = genTimezone ($timezone);
$tzid = $tz->getProperty("TZID");

$out->addComponent($tz);

while( $vevent = $v->getComponent( 'vevent' )) {
	$url = $vevent->getProperty('URL');
	preg_match("/eid%3D(\d+)/", $url, $matches);
	if (count($matches) != 2) 
	{
		print_r($matches);
		die("Wrong number of matches!");
	}
	$url = "http://www.facebook.com/event.php?eid=".$matches[1];
	$vevent->setProperty("URL", $url);

	$description = $vevent->getProperty( 'description' );
	#$description = urlencode($description);
	$description = substr($description,0,strrpos($description, "\\n"));
	$description .= "\\n\\n$url";
	$vevent->deleteProperty('description');
Example #7
0
/**
 * Import an iCal file into the database
 * @param   array   Course info
 * @return  boolean True on success, false otherwise
 */
function agenda_import_ical($course_info, $file)
{
    require_once api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php';
    $charset = api_get_system_encoding();
    $filepath = api_get_path(SYS_ARCHIVE_PATH) . $file['name'];
    if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
        error_log('Problem moving uploaded file: ' . $file['error'] . ' in ' . __FILE__ . ' line ' . __LINE__);
        return false;
    }
    require_once api_get_path(LIBRARY_PATH) . 'icalcreator/iCalcreator.class.php';
    $ical = new vcalendar();
    $ical->setConfig('directory', dirname($filepath));
    $ical->setConfig('filename', basename($filepath));
    $ical->parse();
    //we need to recover: summary, description, dtstart, dtend, organizer, attendee, location (=course name),
    // rrule
    $ve = $ical->getComponent(VEVENT);
    //print_r($ve);
    $ttitle = $ve->getProperty('summary');
    //print_r($ttitle);
    $title = api_convert_encoding($ttitle, $charset, 'UTF-8');
    $tdesc = $ve->getProperty('description');
    $desc = api_convert_encoding($tdesc, $charset, 'UTF-8');
    $ts = $ve->getProperty('dtstart');
    $start_date = $ts['year'] . '-' . $ts['month'] . '-' . $ts['day'] . ' ' . $ts['hour'] . ':' . $ts['min'] . ':' . $ts['sec'];
    $ts = $ve->getProperty('dtend');
    $end_date = $ts['year'] . '-' . $ts['month'] . '-' . $ts['day'] . ' ' . $ts['hour'] . ':' . $ts['min'] . ':' . $ts['sec'];
    //echo $start_date.' - '.$end_date;
    $organizer = $ve->getProperty('organizer');
    $attendee = $ve->getProperty('attendee');
    $course_name = $ve->getProperty('location');
    //insert the event in our database
    $id = agenda_add_item($course_info, $title, $desc, $start_date, $end_date, $_POST['selectedform']);
    $repeat = $ve->getProperty('rrule');
    if (is_array($repeat) && !empty($repeat['FREQ'])) {
        $trans = array('DAILY' => 'daily', 'WEEKLY' => 'weekly', 'MONTHLY' => 'monthlyByDate', 'YEARLY' => 'yearly');
        $freq = $trans[$repeat['FREQ']];
        $interval = $repeat['INTERVAL'];
        if (isset($repeat['UNTIL']) && is_array($repeat['UNTIL'])) {
            $until = mktime(23, 59, 59, $repeat['UNTIL']['month'], $repeat['UNTIL']['day'], $repeat['UNTIL']['year']);
            $res = agenda_add_repeat_item($course_info, $id, $freq, $until, $_POST['selectedform']);
        }
        //TODO: deal with count
        if (!empty($repeat['COUNT'])) {
            $count = $repeat['COUNT'];
            $res = agenda_add_repeat_item($course_info, $id, $freq, $count, $_POST['selectedform']);
        }
    }
    return true;
}
Example #8
0
 /**
  * Process vcalendar instance - add events to database.
  *
  * @param vcalendar $v    Calendar to retrieve data from.
  * @param array     $args Arbitrary arguments map.
  *
  * @throws Ai1ec_Parse_Exception
  *
  * @internal param stdClass $feed           Instance of feed (see Ai1ecIcs plugin).
  * @internal param string   $comment_status WP comment status: 'open' or 'closed'.
  * @internal param int      $do_show_map    Map display status (DB boolean: 0 or 1).
  *
  * @return int Count of events added to database.
  */
 public function add_vcalendar_events_to_db(vcalendar $v, array $args)
 {
     $feed = isset($args['feed']) ? $args['feed'] : null;
     $comment_status = isset($args['comment_status']) ? $args['comment_status'] : 'open';
     $do_show_map = isset($args['do_show_map']) ? $args['do_show_map'] : 0;
     $count = 0;
     $events_in_db = $args['events_in_db'];
     $v->sort();
     // Reverse the sort order, so that RECURRENCE-IDs are listed before the
     // defining recurrence events, and therefore take precedence during
     // caching.
     $v->components = array_reverse($v->components);
     // TODO: select only VEVENT components that occur after, say, 1 month ago.
     // Maybe use $v->selectComponents(), which takes into account recurrence
     // Fetch default timezone in case individual properties don't define it
     $timezone = $v->getProperty('X-WR-TIMEZONE');
     $timezone = (string) $timezone[1];
     // go over each event
     while ($e = $v->getComponent('vevent')) {
         // Event data array.
         $data = array();
         // =====================
         // = Start & end times =
         // =====================
         $start = $e->getProperty('dtstart', 1, true);
         $end = $e->getProperty('dtend', 1, true);
         // For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE value type but none
         // of "DTEND" nor "DURATION" property, the event duration is taken to
         // be one day.  For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE-TIME value type but no
         // "DTEND" property, the event ends on the same calendar date and
         // time of day specified by the "DTSTART" property.
         if (empty($end)) {
             // #1 if duration is present, assign it to end time
             $end = $e->getProperty('duration', 1, true, true);
             if (empty($end)) {
                 // #2 if only DATE value is set for start, set duration to 1 day
                 if (!isset($start['value']['hour'])) {
                     $end = array('value' => array('year' => $start['value']['year'], 'month' => $start['value']['month'], 'day' => $start['value']['day'] + 1, 'hour' => 0, 'min' => 0, 'sec' => 0));
                     if (isset($start['value']['tz'])) {
                         $end['value']['tz'] = $start['value']['tz'];
                     }
                 } else {
                     // #3 set end date to start time
                     $end = $start;
                 }
             }
         }
         $categories = $e->getProperty("CATEGORIES", false, true);
         $imported_cat = array();
         // If the user chose to preserve taxonomies during import, add categories.
         if ($categories && $feed->keep_tags_categories) {
             $imported_cat = $this->_add_categories_and_tags($categories['value'], $imported_cat, false, true);
         }
         $feed_categories = $feed->feed_category;
         if (!empty($feed_categories)) {
             $imported_cat = $this->_add_categories_and_tags($feed_categories, $imported_cat, false, false);
         }
         $tags = $e->getProperty("X-TAGS", false, true);
         $imported_tags = array();
         // If the user chose to preserve taxonomies during import, add tags.
         if ($tags && $feed->keep_tags_categories) {
             $imported_tags = $this->_add_categories_and_tags($tags[1]['value'], $imported_tags, true, true);
         }
         $feed_tags = $feed->feed_tags;
         if (!empty($feed_tags)) {
             $imported_tags = $this->_add_categories_and_tags($feed_tags, $imported_tags, true, true);
         }
         // Event is all-day if no time components are defined
         $allday = $this->_is_timeless($start['value']) && $this->_is_timeless($end['value']);
         // Also check the proprietary MS all-day field.
         $ms_allday = $e->getProperty('X-MICROSOFT-CDO-ALLDAYEVENT');
         if (!empty($ms_allday) && $ms_allday[1] == 'TRUE') {
             $allday = true;
         }
         $start = $this->_time_array_to_datetime($start, $timezone);
         $end = $this->_time_array_to_datetime($end, $timezone);
         if (false === $start || false === $end) {
             throw new Ai1ec_Parse_Exception('Failed to parse one or more dates given timezone "' . var_export($timezone, true) . '"');
             continue;
         }
         // If all-day, and start and end times are equal, then this event has
         // invalid end time (happens sometimes with poorly implemented iCalendar
         // exports, such as in The Event Calendar), so set end time to 1 day
         // after start time.
         if ($allday && $start->format() === $end->format()) {
             $end->adjust_day(+1);
         }
         $data += compact('start', 'end', 'allday');
         // =======================================
         // = Recurrence rules & recurrence dates =
         // =======================================
         if ($rrule = $e->createRrule()) {
             $rrule = explode(':', $rrule);
             $rrule = trim(end($rrule));
         }
         if ($exrule = $e->createExrule()) {
             $exrule = explode(':', $exrule);
             $exrule = trim(end($exrule));
         }
         if ($rdate = $e->createRdate()) {
             $rdate = explode(':', $rdate);
             $rdate = trim(end($rdate));
         }
         // ===================
         // = Exception dates =
         // ===================
         $exdate_array = array();
         if ($exdates = $e->createExdate()) {
             // We may have two formats:
             // one exdate with many dates ot more EXDATE rules
             $exdates = explode("EXDATE", $exdates);
             foreach ($exdates as $exd) {
                 if (empty($exd)) {
                     continue;
                 }
                 $exploded = explode(':', $exd);
                 $exdate_array[] = trim(end($exploded));
             }
         }
         // This is the local string.
         $exdate_loc = implode(',', $exdate_array);
         $gmt_exdates = array();
         // Now we convert the string to gmt. I must do it here
         // because EXDATE:date1,date2,date3 must be parsed
         if (!empty($exdate_loc)) {
             foreach (explode(',', $exdate_loc) as $date) {
                 $gmt_exdates[] = substr((string) $date, 0, 8);
             }
         }
         $exdate = implode(',', $gmt_exdates);
         // ========================
         // = Latitude & longitude =
         // ========================
         $latitude = $longitude = NULL;
         $geo_tag = $e->getProperty('geo');
         if (is_array($geo_tag)) {
             if (isset($geo_tag['latitude']) && isset($geo_tag['longitude'])) {
                 $latitude = (double) $geo_tag['latitude'];
                 $longitude = (double) $geo_tag['longitude'];
             }
         } else {
             if (!empty($geo_tag) && false !== strpos($geo_tag, ';')) {
                 list($latitude, $longitude) = explode(';', $geo_tag, 2);
                 $latitude = (double) $latitude;
                 $longitude = (double) $longitude;
             }
         }
         unset($geo_tag);
         if (NULL !== $latitude) {
             $data += compact('latitude', 'longitude');
             // Check the input coordinates checkbox, otherwise lat/long data
             // is not present on the edit event page
             $data['show_coordinates'] = 1;
         }
         // ===================
         // = Venue & address =
         // ===================
         $address = $venue = '';
         $location = $e->getProperty('location');
         $matches = array();
         // This regexp matches a venue / address in the format
         // "venue @ address" or "venue - address".
         preg_match('/\\s*(.*\\S)\\s+[\\-@]\\s+(.*)\\s*/', $location, $matches);
         // if there is no match, it's not a combined venue + address
         if (empty($matches)) {
             // if there is a comma, probably it's an address
             if (false === strpos($location, ',')) {
                 $venue = $location;
             } else {
                 $address = $location;
             }
         } else {
             $venue = isset($matches[1]) ? $matches[1] : '';
             $address = isset($matches[2]) ? $matches[2] : '';
         }
         // =====================================================
         // = Set show map status based on presence of location =
         // =====================================================
         if (1 === $do_show_map && NULL === $latitude && empty($address)) {
             $do_show_map = 0;
         }
         // ==================
         // = Cost & tickets =
         // ==================
         $cost = $e->getProperty('X-COST');
         $cost = $cost ? $cost[1] : '';
         $ticket_url = $e->getProperty('X-TICKETS-URL');
         $ticket_url = $ticket_url ? $ticket_url[1] : '';
         // ===============================
         // = Contact name, phone, e-mail =
         // ===============================
         $organizer = $e->getProperty('organizer');
         if ('MAILTO:' === substr($organizer, 0, 7) && false === strpos($organizer, '@')) {
             $organizer = substr($organizer, 7);
         }
         $contact = $e->getProperty('contact');
         $elements = explode(';', $contact, 4);
         foreach ($elements as $el) {
             $el = trim($el);
             // Detect e-mail address.
             if (false !== strpos($el, '@')) {
                 $data['contact_email'] = $el;
             } elseif (false !== strpos($el, '://')) {
                 $data['contact_url'] = $this->_parse_legacy_loggable_url($el);
             } elseif (preg_match('/\\d/', $el)) {
                 $data['contact_phone'] = $el;
             } else {
                 $data['contact_name'] = $el;
             }
         }
         if (!isset($data['contact_name']) || !$data['contact_name']) {
             // If no contact name, default to organizer property.
             $data['contact_name'] = $organizer;
         }
         // Store yet-unsaved values to the $data array.
         $data += array('recurrence_rules' => $rrule, 'exception_rules' => $exrule, 'recurrence_dates' => $rdate, 'exception_dates' => $exdate, 'venue' => $venue, 'address' => $address, 'cost' => $cost, 'ticket_url' => $this->_parse_legacy_loggable_url($ticket_url), 'show_map' => $do_show_map, 'ical_feed_url' => $feed->feed_url, 'ical_source_url' => $e->getProperty('url'), 'ical_organizer' => $organizer, 'ical_contact' => $contact, 'ical_uid' => $e->getProperty('uid'), 'categories' => array_keys($imported_cat), 'tags' => array_keys($imported_tags), 'feed' => $feed, 'post' => array('post_status' => 'publish', 'comment_status' => $comment_status, 'post_type' => AI1EC_POST_TYPE, 'post_author' => 1, 'post_title' => $e->getProperty('summary'), 'post_content' => stripslashes(str_replace('\\n', "\n", $e->getProperty('description')))));
         // Create event object.
         $event = $this->_registry->get('model.event', $data);
         $recurrence = $event->get('recurrence_rules');
         $search = $this->_registry->get('model.search');
         // first let's check by UID
         $matching_event_id = $search->get_matching_event_by_uid_and_url($event->get('ical_uid'), $event->get('ical_feed_url'));
         // if no result, perform the legacy check.
         if (null === $matching_event_id) {
             $matching_event_id = $search->get_matching_event_id($event->get('ical_uid'), $event->get('ical_feed_url'), $event->get('start'), !empty($recurrence));
         }
         if (null === $matching_event_id) {
             // =================================================
             // = Event was not found, so store it and the post =
             // =================================================
             $event->save();
         } else {
             // ======================================================
             // = Event was found, let's store the new event details =
             // ======================================================
             // Update the post
             $post = get_post($matching_event_id);
             if (null !== $post) {
                 $post->post_title = $event->get('post')->post_title;
                 $post->post_content = $event->get('post')->post_content;
                 wp_update_post($post);
                 // Update the event
                 $event->set('post_id', $matching_event_id);
                 $event->set('post', $post);
                 $event->save(true);
             }
         }
         // if the event was already present , unset it from the array so it's not deleted
         unset($events_in_db[$event->get('post_id')]);
         $count++;
     }
     return array('count' => $count, 'events_to_delete' => $events_in_db);
 }
 public function import_ics_data($calendar_id)
 {
     // -------------------------------------
     //	Get some basic info to use later
     // -------------------------------------
     $cbasics = $this->data->calendar_basics();
     $cbasics = $cbasics[$calendar_id];
     $urls = $cbasics['ics_url'];
     if ($urls == '') {
         return FALSE;
     }
     $tz_offset = $cbasics['tz_offset'] != '' ? $cbasics['tz_offset'] : '0000';
     /*
     
     		This shouldn't be happening because DST is only something that
     		would need to be applied when generating the users current local time.
     		If an event were at 7pm EST or EDT, it would still be at 7pm either way.
     		I hate DST.
     
     		if ($tz_offset != '0000' AND ee()->config->item('daylight_savings') == 'y')
     		{
     			$tz_offset += 100;
     		}
     */
     $channel_id = $this->data->channel_is_events_channel();
     $author_id = $cbasics['author_id'];
     // -------------------------------------
     //	Prepare the URLs
     // -------------------------------------
     if (!is_array($urls)) {
         $urls = explode("\n", $urls);
     }
     foreach ($urls as $k => $url) {
         $urls[$k] = trim($url);
     }
     // -------------------------------------
     //	Load iCalCreator
     // -------------------------------------
     if (!class_exists('vcalendar')) {
         require_once CALENDAR_PATH_ASSETS . 'icalcreator/iCalcreator.class.php';
     }
     // -------------------------------------
     //	Load Calendar_datetime
     // -------------------------------------
     if (!class_exists('Calendar_datetime')) {
         require_once CALENDAR_PATH . 'calendar.datetime' . EXT;
     }
     $CDT = new Calendar_datetime();
     $CDT_end = new Calendar_datetime();
     // -------------------------------------
     //	Load Publish
     // -------------------------------------
     if (APP_VER < 2.0) {
         //need to set DSP if not present
         if (!isset($GLOBALS['DSP']) or !is_object($GLOBALS['DSP'])) {
             if (!class_exists('Display')) {
                 require_once PATH_CP . 'cp.display' . EXT;
             }
             $GLOBALS['DSP'] = new Display();
         }
         if (!class_exists('Publish')) {
             require_once PATH_CP . 'cp.publish' . EXT;
         }
         $PB = new Publish();
         $PB->assign_cat_parent = ee()->config->item('auto_assign_cat_parents') == 'n' ? FALSE : TRUE;
     } else {
         ee()->load->library('api');
         ee()->api->instantiate(array('channel_entries', 'channel_categories', 'channel_fields'));
         ee()->api_channel_entries->assign_cat_parent = ee()->config->item('auto_assign_cat_parents') == 'n' ? FALSE : TRUE;
     }
     // -------------------------------------
     //	Tell our extensions that we're running the icalendar import
     // -------------------------------------
     $this->cache['ical'] = TRUE;
     // -------------------------------------
     //	Get already-imported events
     // -------------------------------------
     $imported = $this->data->get_imported_events($calendar_id);
     // -------------------------------------
     //	Don't let EXT drop us early
     // -------------------------------------
     ee()->extensions->in_progress = '';
     // -------------------------------------
     //	Cycle through the URLs
     // -------------------------------------
     foreach ($urls as $url) {
         $ICAL = new vcalendar();
         $ICAL->parse($this->fetch_url($url));
         // -------------------------------------
         //	Iterate among the events
         // -------------------------------------
         while ($event = $ICAL->getComponent('vevent')) {
             // -------------------------------------
             //	Times
             // -------------------------------------
             $hour = isset($event->dtstart['value']['hour']) ? $event->dtstart['value']['hour'] : 00;
             $minute = isset($event->dtstart['value']['min']) ? $event->dtstart['value']['min'] : 00;
             $end_hour = isset($event->dtend['value']['hour']) ? $event->dtend['value']['hour'] : $hour;
             $end_minute = isset($event->dtend['value']['min']) ? $event->dtend['value']['min'] : $minute;
             // -------------------------------------
             //	Last-modified date
             // -------------------------------------
             if (isset($event->lastmodified['value'])) {
                 $lm_date = $event->lastmodified['value']['year'] . $event->lastmodified['value']['month'] . $event->lastmodified['value']['day'] . $event->lastmodified['value']['hour'] . $event->lastmodified['value']['min'];
             } elseif (isset($event->dtstamp['value'])) {
                 $lm_date = $event->dtstamp['value']['year'] . $event->dtstamp['value']['month'] . $event->dtstamp['value']['day'] . $event->dtstamp['value']['hour'] . $event->dtstamp['value']['min'];
             } else {
                 $lm_date = $event->created['value']['year'] . $event->created['value']['month'] . $event->created['value']['day'] . $event->created['value']['hour'] . $event->created['value']['min'];
             }
             // -------------------------------------
             //	Does this event already exist? Do we need to update?
             // -------------------------------------
             if (isset($imported[$event->uid['value']])) {
                 // -------------------------------------
                 //	Has the event been updated? No reason
                 //	to do any work if it's the same old stuff.
                 // -------------------------------------
                 if ($lm_date == $imported[$event->uid['value']]['last_mod']) {
                     continue;
                 } elseif ($lm_date == $imported[$event->uid['value']]['last_mod']) {
                     continue;
                 }
                 $entry_id = $imported[$event->uid['value']]['entry_id'];
             } else {
                 $entry_id = '';
             }
             // -------------------------------------
             //	Adjust CDT
             // -------------------------------------
             $CDT->change_datetime($event->dtstart['value']['year'], $event->dtstart['value']['month'], $event->dtstart['value']['day'], $hour, $minute);
             if (isset($event->dtend['value'])) {
                 $CDT_end->change_datetime($event->dtend['value']['year'], $event->dtend['value']['month'], $event->dtend['value']['day'], $end_hour, $end_minute);
             } else {
                 $CDT_end->change_ymd($CDT->ymd);
                 $CDT_end->change_time($end_hour, $end_minute);
             }
             // -------------------------------------
             //	Adjust to the correct timezone for thie calendar
             // -------------------------------------
             if (!isset($event->dtstart['params']['TZID']) or $event->dtstart['params']['TZID'] == '') {
                 if (isset($event->dtstart['value']['hour'])) {
                     $CDT->add_time($tz_offset);
                     $CDT_end->add_time($tz_offset);
                 } else {
                     $CDT_end->add_day(-1);
                 }
             }
             // -------------------------------------
             //	Variableification
             // -------------------------------------
             $title = isset($event->summary['value']) ? $event->summary['value'] : lang('no_title');
             $summary = (isset($event->description) and is_array($event->description) and isset($event->description[0]['value'])) ? $event->description[0]['value'] : '';
             $location = isset($event->location['value']) ? $event->location['value'] : '';
             $rules = $this->ical_rule_to_calendar_rule($event->rrule);
             $exceptions = array('date' => array());
             if (mb_strlen($title) > 100) {
                 $title = substr($title, 0, 100);
             }
             if (is_array($event->exdate) and !empty($event->exdate)) {
                 $exceptions = $this->ical_exdate_to_calendar_exception($event->exdate);
             }
             $recurs = (is_array($event->rrule) and !empty($event->rrule)) ? 'y' : 'n';
             // -------------------------------------
             //	Fix some linebreak problems
             // -------------------------------------
             $summary = str_replace(array("\r", "\n"), '', $summary);
             $summary = str_replace('\\n', "\n", $summary);
             // -------------------------------------
             //	Set up $_POST
             // -------------------------------------
             $_POST = $post_data = array('site_id' => $this->data->get_site_id(), 'author_id' => $author_id, 'entry_id' => $entry_id, 'weblog_id' => $channel_id, 'channel_id' => $channel_id, 'status' => 'open', 'entry_date' => date('Y-m-d H:i a', ee()->localize->now - 3600 * 24 * 2), 'title' => $title, 'calendar_id' => $calendar_id, 'field_id_' . $this->data->get_field_id(CALENDAR_EVENTS_FIELD_PREFIX . 'summary') => $summary, 'field_id_' . $this->data->get_field_id(CALENDAR_EVENTS_FIELD_PREFIX . 'location') => $location, 'rule_id' => array(), 'start_date' => array($CDT->ymd), 'start_time' => array($CDT->hour . $CDT->minute), 'end_date' => array($CDT_end->ymd), 'end_time' => array($CDT_end->hour . $CDT_end->minute), 'all_day' => !isset($event->dtstart['value']['hour']) ? 'y' : 'n', 'rule_type' => $rules['rule_type'], 'repeat_years' => $rules['repeat_years'], 'repeat_months' => $rules['repeat_months'], 'repeat_weeks' => $rules['repeat_weeks'], 'repeat_days' => $rules['repeat_days'], 'days_of_week' => $rules['days_of_week'], 'relative_dow' => $rules['relative_dow'], 'days_of_month' => $rules['days_of_month'], 'months_of_year' => $rules['months_of_year'], 'end_by' => $rules['end_by'], 'end_after' => $rules['end_after'], 'occurrences' => $exceptions, 'expiration_date' => '', 'comment_expiration_date' => '', 'allow_comments' => 'n');
             // -------------------------------------
             //	Let Publish do its things
             // -------------------------------------
             if (APP_VER < 2.0) {
                 $PB->submit_new_entry(FALSE);
                 //<- LOOK HOW EASY IT USED TO BE >:|
             } else {
                 //EE 1.x doesn't have this field
                 $opt_field = 'field_id_' . $this->data->get_field_id(CALENDAR_EVENTS_FIELD_PREFIX . 'dates_and_options');
                 $_POST[$opt_field] = $calendar_id;
                 $post_data[$opt_field] = $calendar_id;
                 //this worked pre EE 2.1.3, then stopped working? *sigh*
                 //now we have to do all of this mess manually for field
                 //settings before inserting new entries via the API
                 //ee()->api_channel_fields->fetch_custom_channel_fields();
                 //--------------------------------------------
                 //	Check for custom field group
                 //--------------------------------------------
                 $fg_query = ee()->db->query("SELECT field_group\n\t\t\t\t\t\t FROM\texp_channels\n\t\t\t\t\t\t WHERE\tchannel_id = '" . ee()->db->escape_str($channel_id) . "'");
                 if ($fg_query->num_rows() > 0) {
                     $field_group = $fg_query->row('field_group');
                     ee()->lang->loadfile('channel');
                     ee()->lang->loadfile('content');
                     ee()->load->model('field_model');
                     ee()->load->model('channel_model');
                     // Rudimentary handling of custom fields
                     $field_query = ee()->channel_model->get_channel_fields($field_group);
                     $dst_enabled = ee()->session->userdata('daylight_savings');
                     foreach ($field_query->result_array() as $row) {
                         $field_data = '';
                         $field_dt = '';
                         $field_fmt = $row['field_fmt'];
                         // Settings that need to be prepped
                         $settings = array('field_instructions' => trim($row['field_instructions']), 'field_text_direction' => $row['field_text_direction'] == 'rtl' ? 'rtl' : 'ltr', 'field_fmt' => $field_fmt, 'field_dt' => $field_dt, 'field_data' => $field_data, 'field_name' => 'field_id_' . $row['field_id'], 'dst_enabled' => $dst_enabled);
                         $ft_settings = array();
                         if (isset($row['field_settings']) and strlen($row['field_settings'])) {
                             $ft_settings = unserialize(base64_decode($row['field_settings']));
                         }
                         $settings = array_merge($row, $settings, $ft_settings);
                         ee()->api_channel_fields->set_settings($row['field_id'], $settings);
                     }
                 }
                 //now we can do the new entry
                 ee()->api_channel_entries->submit_new_entry($channel_id, $post_data);
             }
             // -------------------------------------
             //	Update the imports table
             // -------------------------------------
             $data = array('calendar_id' => $calendar_id, 'event_id' => $this->cache['ical_event_id'], 'entry_id' => $this->cache['ical_entry_id'], 'uid' => $event->uid['value'], 'last_mod' => $lm_date);
             if ($entry_id != '') {
                 $data['import_id'] = $imported[$event->uid['value']]['import_id'];
                 $this->data->update_imported_event($data);
             } else {
                 //$data['import_id'] = '0';
                 $this->data->add_imported_event($data);
             }
         }
     }
     $this->data->update_ics_updated($calendar_id);
     ee()->extensions->end_script = FALSE;
     ee()->extensions->in_progress = APP_VER < 2.0 ? 'submit_new_entry_end' : 'entry_submission_end';
     return TRUE;
 }
Example #10
0
 public static function toKalenderEvent($iCal, $ownerClass = "iCal", $ownerClassID = "-1")
 {
     $VC = new vcalendar();
     $VC->parse($iCal);
     $event = $VC->getComponent("vevent");
     $dayStart = $event->getProperty("DTSTART");
     $dayEnd = $event->getProperty("DTEND");
     $dayStartTS = strtotime(implode("", $dayStart));
     $dayEndTS = strtotime(implode("", $dayEnd));
     $KE = new KalenderEvent($ownerClass, $ownerClassID, Kalender::formatDay($dayStartTS), Kalender::formatTime($dayStartTS), $event->getProperty("SUMMARY"));
     $KE->UID($event->getProperty("UID"));
     $organizer = $event->getProperty("ORGANIZER", 0, true);
     $organizer["value"] = str_replace("MAILTO:", "", $organizer["value"]);
     $ON = $organizer["value"];
     if (isset($organizer["params"]["CN"])) {
         $ON = $organizer["params"]["CN"];
     }
     $OE = $organizer["value"];
     $KE->organizer($ON, $OE);
     if ($dayStart["hour"] . $dayStart["min"] == "" and $dayEnd["hour"] . $dayEnd["min"] == "") {
         $KE->allDay(true);
     } else {
         $KE->endDay(Kalender::formatDay($dayEndTS));
         $KE->endTime(Kalender::formatTime($dayEndTS));
     }
     return $KE;
 }
Example #11
0


<?php 
ini_set('display_errors', 1);
require_once 'iCalcreator.class.php';
$v = new vcalendar();
/* start parse of local file */
$v->setConfig('directory', 'uploads');
// set directory
$v->setConfig('filename', 'basic.ics');
// set file name
$v->parse();
foreach ($v->components as $component => $info) {
    # get first vevent
    $comp = $v->getComponent("VEVENT");
    //print_r($comp);
    $summary_array = $comp->getProperty("summary", 1, TRUE);
    //$summary_array = $vevent->getProperty("summary", 1, TRUE);
    echo "Event: ", $summary_array["value"], "\n";
    $dtstart_array = $comp->getProperty("dtstart", 1, TRUE);
    //$dtstart_array = $vevent->getProperty("dtstart", 1, TRUE);
    $dtstart = $dtstart_array["value"];
    $startDate = "{$dtstart["year"]}-{$dtstart["month"]}-{$dtstart["day"]}";
    $startTime = "{$dtstart["hour"]}:{$dtstart["min"]}:{$dtstart["sec"]}";
    $dtend_array = $comp->getProperty("dtend", 1, TRUE);
    //$dtend_array = $vevent->getProperty("dtend", 1, TRUE);
    $dtend = $dtend_array["value"];
    $endDate = "{$dtend["year"]}-{$dtend["month"]}-{$dtend["day"]}";
    $endTime = "{$dtend["hour"]}:{$dtend["min"]}:{$dtend["sec"]}";
    echo "start: ", $startDate, "T", $startTime, "\n";
Example #12
0
 $calendar = new vcalendar();
 $calendar->setConfig('unique_id', UNIQUE);
 if (!$calendar->setConfig('directory', CALDIR)) {
     addLogEntry(1, '  ERROR (1) when setting directory \'' . CALDIR . '\', check directory/file permissions!!');
 } elseif (!$calendar->setConfig('filename', TESTFILE)) {
     addLogEntry(1, "  ERROR (2) when setting directory/file '{$dirFile}', check directory/file permissions!!");
 } else {
     $starttime2 = microtime(TRUE);
     $createFileStatus = !$calendar->parse();
     $exec = array(', Parse exec time:', $starttime2, microtime(TRUE));
     if (FALSE !== $createFileStatus) {
         addLogEntry(2, '  FALSE from calendar->parse, i.e. file missing or empty' . $exec[0], $exec[1], $exec[2]);
     } else {
         addLogEntry(3, '  TRUE from calendar->parse' . $exec[0], $exec[1], $exec[2]);
         $starttime2 = microtime(TRUE);
         $comp = $calendar->getComponent('vevent', 1);
         $exec = array(', exec time:', $starttime2, microtime(TRUE));
         if (FALSE === $comp) {
             $createFileStatus = TRUE;
             addLogEntry(2, '  FALSE from calendar->getComponent, no vevent in file' . $exec[0], $exec[1], $exec[2]);
         } else {
             addLogEntry(3, '  TRUE from calendar->getComponent' . $exec[0], $exec[1], $exec[2]);
             $starttime2 = microtime(TRUE);
             $dtstart = $comp->getProperty('dtstart');
             $exec = array(', exec time:', $starttime2, microtime(TRUE));
             if (FALSE === ($dtstart = $comp->getProperty('dtstart'))) {
                 $createFileStatus = TRUE;
                 addLogEntry(2, '  FALSE from (first) getProperty(DTSTART), no DTSTART in vevent component' . $exec[0], $exec[1], $exec[2]);
             } else {
                 $fileDtstartDate = sprintf("%04d%02d%02d", $dtstart['year'], $dtstart['month'], $dtstart['day']);
                 addLogEntry(3, "  {$fileDtstartDate} = (first) getProperty(DTSTART)" . $exec[0], $exec[1], $exec[2]);
/**
 * function iCal2csv
 *
 * Convert iCal file to csv format and send file to browser (default) or save csv file to disk
 * Definition iCal  : rcf2445, http://localhost/work/kigkonsult.se/downloads/index.php#rfc2445
 * Definition csv   : http://en.wikipedia.org/wiki/Comma-separated_values
 * Using iCalcreator: http://localhost/work/kigkonsult.se/downloads/index.php#iCalcreator
 * ical directory/file read/write error OR iCalcreator parse error will be directed to error_log/log
 *
 * @author Kjell-Inge Gustafsson <*****@*****.**>
 * @since 2.0 - 2009-03-27
 * @param string $filename      file to convert (incl. opt. directory)
 * @param array  $conf          opt, default FALSE(=array('del'=>'"','sep'=>',', 'nl'=>'\n'), delimiter, separator and newline characters
 *                              escape sequences will be expanded, '\n' will be used as "\n" etc.
 *                              also map iCal property names to user friendly names, ex. 'DTSTART' => 'startdate'
 *                              also order output columns, ex. 2 => 'DTSTART' (2=first order column, 3 next etc)
 *                              also properties to skip, ex. 'skip' => array( 'CREATED', 'PRIORITY' );
 * @param bool   $save          opt, default FALSE, TRUE=save to disk
 * @param string $diskfilename  opt, filename for file to save or else taken from $filename + 'csv' extension
 * @param object $log           opt, default FALSE (error_log), writes log to file using PEAR LOG or eClog class
 * @return bool                 returns FALSE when error
 */
function iCal2csv($filename, $conf = FALSE, $save = FALSE, $diskfilename = FALSE, $log = FALSE)
{
    if ($log) {
        $timeexec = array('start' => microtime(TRUE));
    }
    $iCal2csv_VERSION = 'iCal2csv 2.0';
    if (!function_exists('fileCheckRead')) {
        require_once 'fileCheck.php';
    }
    if (!class_exists('vcalendar', FALSE)) {
        require_once 'iCalcreator.class.php';
    }
    if ($log) {
        $log->log("{$iCal2csv_VERSION} input={$filename}, conf=" . var_export($conf, TRUE) . ", save={$save}, diskfilename={$diskfilename}", 7);
    }
    $remoteInput = 'http://' == strtolower(substr($filename, 0, 7)) || 'webcal://' == strtolower(substr($filename, 0, 9)) ? TRUE : FALSE;
    // field DELimiter && field SEParator && NewLine character(-s) etc.
    if (!$conf) {
        $conf = array();
    }
    if (!isset($conf['del'])) {
        $conf['del'] = '"';
    }
    if (!isset($conf['sep'])) {
        $conf['sep'] = ',';
    }
    if (!isset($conf['nl'])) {
        $conf['nl'] = "\n";
    }
    foreach ($conf as $key => $value) {
        if ('skip' == $key) {
            foreach ($value as $six => $skipp) {
                $conf['skip'][$six] = strtoupper($skipp);
            }
        } elseif ('2' <= $key && '99' > $key) {
            $conf[$key] = strtoupper($value);
            if ($log) {
                $log->log("{$iCal2csv_VERSION} column {$key} contains " . strtoupper($value), 7);
            }
        } elseif (in_array($key, array('del', 'sep', 'nl'))) {
            $conf[$key] = "{$value}";
        } else {
            $conf[strtoupper($key)] = $value;
            if ($log) {
                $log->log("{$iCal2csv_VERSION} " . strtoupper($key) . " mapped to {$value}", 7);
            }
        }
    }
    /* create path and filename */
    if ($remoteInput) {
        $inputFileParts = parse_url($filename);
        $inputFileParts = array_merge($inputFileParts, pathinfo($inputFileParts['path']));
        if (!$diskfilename) {
            $diskfilename = $inputFileParts['filename'] . '.csv';
        }
    } else {
        if (FALSE === ($filename = fileCheckRead($filename, $log))) {
            if ($log) {
                $log->log("{$iCal2csv_VERSION} (" . number_format(microtime(TRUE) - $timeexec['start'], 5) . ')');
                $log->flush();
            }
            return FALSE;
        }
        $inputFileParts = pathinfo($filename);
        if (!$diskfilename) {
            $diskfilename = $inputFileParts['dirname'] . DIRECTORY_SEPARATOR . $inputFileParts['filename'] . '.csv';
        }
    }
    $outputFileParts = pathinfo($diskfilename);
    if ($save) {
        if (FALSE === ($diskfilename = fileCheckWrite($outputFileParts['dirname'] . DIRECTORY_SEPARATOR . $outputFileParts['basename'], $log))) {
            if ($log) {
                $log->log("{$iCal2csv_VERSION} (" . number_format(microtime(TRUE) - $timeexec['start'], 5) . ')');
                $log->flush();
            }
            return FALSE;
        }
    }
    if ($log) {
        $msg = $iCal2csv_VERSION . ' INPUT FILE:"' . $inputFileParts['dirname'] . DIRECTORY_SEPARATOR . $inputFileParts['basename'] . '"';
        if ($save) {
            $msg .= ' OUTPUT FILE: "' . $outputFileParts['dirname'] . DIRECTORY_SEPARATOR . $outputFileParts['basename'] . '"';
        }
        $log->log($msg, 7);
    }
    /* iCalcreator check, read and parse input iCal file */
    $calendar = new vcalendar();
    $calnl = $calendar->getConfig('nl');
    if ($remoteInput) {
        if (FALSE === $calendar->setConfig('url', $filename)) {
            $msg = $iCal2csv_VERSION . ' ERROR 3 INPUT FILE:"' . $filename . '" iCalcreator: invalid url';
            if ($log) {
                $log->log($msg, 3);
                $log->flush();
            } else {
                error_log($msg);
            }
            return FALSE;
        }
    } else {
        if (FALSE === $calendar->setConfig('directory', $inputFileParts['dirname'])) {
            $msg = $iCal2csv_VERSION . ' ERROR 4 INPUT FILE:"' . $filename . '" iCalcreator: invalid directory: "' . $inputFileParts['dirname'] . '"';
            if ($log) {
                $log->log($msg, 3);
                $log->flush();
            } else {
                error_log($msg);
            }
            return FALSE;
        }
        if (FALSE === $calendar->setConfig('filename', $inputFileParts['basename'])) {
            $msg = $iCal2csv_VERSION . ' ERROR 5 INPUT FILE:"' . $filename . '" iCalcreator: invalid filename: "' . $inputFileParts['basename'] . '"';
            if ($log) {
                $log->log($msg, 3);
                $log->flush();
            } else {
                error_log($msg);
            }
            return FALSE;
        }
    }
    if (FALSE === $calendar->parse()) {
        $msg = $iCal2csv_VERSION . ' ERROR 6 INPUT FILE:"' . $filename . '" iCalcreator parse error';
        if ($log) {
            $log->log($msg, 3);
            $log->flush();
        } else {
            error_log($msg);
        }
        return FALSE;
    }
    if ($log) {
        $timeexec['fileOk'] = microtime(TRUE);
    }
    if (!function_exists('iCaldate2timestamp')) {
        function iCaldate2timestamp($d)
        {
            if (6 > count($d)) {
                return mktime(0, 0, 0, $d['month'], $d['day'], $d['year']);
            } else {
                return mktime($d['hour'], $d['min'], $d['sec'], $d['month'], $d['day'], $d['year']);
            }
        }
    }
    if (!function_exists('fixiCalString')) {
        function fixiCalString($s)
        {
            $s = str_replace('\\,', ',', $s);
            $s = str_replace('\\;', ';', $s);
            $s = str_replace('\\n ', chr(10), $s);
            $s = str_replace('\\\\', '\\', $s);
            return $s;
        }
    }
    /* create output array */
    $rows = array();
    /* info rows */
    $rows[] = array('kigkonsult.se', ICALCREATOR_VERSION, $iCal2csv_VERSION, date('Y-m-d H:i:s'));
    $filename = $remoteInput ? $filename : $inputFileParts['basename'];
    $rows[] = array('iCal input', $filename, 'csv output', $outputFileParts['basename']);
    if ($prop = $calendar->getProperty('CALSCALE')) {
        $rows[] = array('CALSCALE', $prop);
    }
    if ($prop = $calendar->getProperty('METHOD')) {
        $rows[] = array('METHOD', $prop);
    }
    while ($xprop = $calendar->getProperty()) {
        $rows[] = array($xprop[0], $xprop[1]);
    }
    if ($log) {
        $timeexec['infoOk'] = microtime(TRUE);
    }
    /* fix vtimezone property order list */
    $proporder = array();
    foreach ($conf as $key => $value) {
        if ('2' <= $key && '99' > $key) {
            $proporder[$value] = $key;
            if ($log) {
                $log->log("{$iCal2csv_VERSION} {$value} in column {$key}", 7);
            }
        }
    }
    $proporder['TYPE'] = 0;
    $proporder['ORDER'] = 1;
    $props = array('TZID', 'LAST-MODIFIED', 'TZURL', 'DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'TZOFFSETTFROM', 'COMMENT', 'RRULE', 'RDATE', 'TZNAME');
    $pix = 2;
    foreach ($props as $prop) {
        if (isset($proporder[$prop])) {
            continue;
        }
        if (isset($conf['skip']) && in_array($prop, $conf['skip'])) {
            if ($log) {
                $log->log("{$iCal2csv_VERSION} {$prop} removed from output", 7);
            }
            continue;
        }
        while (in_array($pix, $proporder)) {
            $pix++;
        }
        $proporder[$prop] = $pix++;
    }
    /* remove unused properties from and add x-props to property order list */
    $maxpropix = 11;
    if ($maxpropix != count($proporder) - 1) {
        $maxpropix = count($proporder) - 1;
    }
    $compsinfo = $calendar->getConfig('compsinfo');
    $potmp = array();
    $potmp[0] = 'TYPE';
    $potmp[1] = 'ORDER';
    foreach ($compsinfo as $cix => $compinfo) {
        if ('vtimezone' != $compinfo['type']) {
            continue;
        }
        $comp = $calendar->getComponent($compinfo['ordno']);
        foreach ($compinfo['props'] as $propName => $propcnt) {
            if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                $potmp[$proporder[$propName]] = $propName;
            } elseif ('X-PROP' == $propName) {
                while ($xprop = $comp->getProperty()) {
                    if (!in_array($xprop[0], $potmp)) {
                        $maxpropix += 1;
                        $potmp[$maxpropix] = $xprop[0];
                    }
                    // end if
                }
                // end while xprop
            }
            // end X-PROP
        }
        // end $compinfo['props']
        if (isset($compinfo['sub'])) {
            foreach ($compinfo['sub'] as $compinfo2) {
                foreach ($compinfo2['props'] as $propName => $propcnt) {
                    if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                        $potmp[$proporder[$propName]] = $propName;
                    } elseif ('X-PROP' == $propName) {
                        $scomp = $comp->getComponent($compinfo2['ordno']);
                        while ($xprop = $scomp->getProperty()) {
                            if (!in_array($xprop[0], $potmp)) {
                                $maxpropix += 1;
                                $potmp[$maxpropix] = $xprop[0];
                            }
                            // end if
                        }
                        // end while xprop
                    }
                    // end X-PROP
                }
                // end $compinfo['sub']['props']
            }
            // end foreach( $compinfo['sub']
        }
        // end if( isset( $compinfo['sub']
    }
    // end foreach compinfo - vtimezone
    ksort($potmp, SORT_NUMERIC);
    if ('2.6' == substr(ICALCREATOR_VERSION, -3)) {
        foreach ($potmp as $k => $v) {
            // iCalcreator 2.6 bug fix
            if ('TZOFFSETTFROM' == $v) {
                $potmp[$k] = 'TZOFFSETFROM';
            }
        }
    }
    $proporder = array_flip(array_values($potmp));
    if ($log) {
        $log->log("{$iCal2csv_VERSION} zone proporder=" . implode(',', array_flip($proporder)), 7);
    }
    /* create vtimezone info */
    $row = count($rows) - 1;
    if (2 < count($proporder)) {
        $row += 1;
        /* create vtimezone header row */
        foreach ($proporder as $propName => $col) {
            if (isset($conf[$propName])) {
                $rows[$row][$col] = $conf[$propName];
                // check map of userfriendly name to iCal property name
                if ($log) {
                    $log->log("{$iCal2csv_VERSION} header row, col={$col}: {$propName}, replaced by " . $conf[$propName], 7);
                }
            } else {
                $rows[$row][$col] = $propName;
            }
        }
        $allowedProps = array('VTIMEZONE' => array('TZID', 'LAST-MODIFIED', 'TZURL'), 'STANDARD' => array('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'COMMENT', 'RDATE', 'RRULE', 'TZNAME'), 'DAYLIGHT' => array('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'COMMENT', 'RDATE', 'RRULE', 'TZNAME'));
        /* create vtimezone data rows */
        foreach ($compsinfo as $cix => $compinfo) {
            if ('vtimezone' != $compinfo['type']) {
                continue;
            }
            $row += 1;
            foreach ($proporder as $propName => $col) {
                $rows[$row][] = '';
            }
            // set all cells empty
            $rows[$row][$proporder['TYPE']] = $compinfo['type'];
            $rows[$row][$proporder['ORDER']] = $compinfo['ordno'];
            $comp = $calendar->getComponent($compinfo['ordno']);
            foreach ($proporder as $propName => $col) {
                if ('TYPE' == $propName || 'ORDER' == $propName) {
                    continue;
                }
                if ('X-' == substr($propName, 0, 2)) {
                    continue;
                }
                if (!in_array($propName, $allowedProps['VTIMEZONE'])) {
                    // check if component allows property
                    continue;
                }
                if (isset($compinfo['props'][$propName])) {
                    if ('LAST-MODIFIED' == $propName) {
                        $fcn = 'createLastModified';
                    } else {
                        $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                    }
                    if (!method_exists($comp, $fcn)) {
                        $msg = $iCal2csv_VERSION . ' ERROR 7 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')';
                        if ($log) {
                            $log->log($msg, 3);
                        } else {
                            error_log($msg);
                        }
                        continue;
                    }
                    $output = str_replace("{$calnl} ", '', rtrim($comp->{$fcn}()));
                    $output = str_replace($propName . ';', '', $output);
                    $output = str_replace($propName . ':', '', $output);
                    $rows[$row][$proporder[$propName]] = fixiCalString($output);
                }
            }
            // end foreach( $proporder
            if (isset($compinfo['props']['X-PROP'])) {
                while ($xprop = $comp->getProperty()) {
                    $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                    $rows[$row][$proporder[$xprop[0]]] = fixiCalString($output);
                }
            }
            if (isset($compinfo['sub'])) {
                foreach ($compinfo['sub'] as $compinfo2) {
                    $row += 1;
                    foreach ($proporder as $propName => $col) {
                        $rows[$row][] = '';
                    }
                    // set all cells empty
                    $rows[$row][$proporder['TYPE']] = $compinfo2['type'];
                    $rows[$row][$proporder['ORDER']] = $compinfo['ordno'] . ':' . $compinfo2['ordno'];
                    $scomp = $comp->getComponent($compinfo2['ordno']);
                    foreach ($proporder as $propName => $col) {
                        if ('TYPE' == $propName || 'ORDER' == $propName) {
                            continue;
                        }
                        if ('X-' == substr($propName, 0, 2)) {
                            continue;
                        }
                        if (!in_array($propName, $allowedProps[strtoupper($compinfo2['type'])])) {
                            // check if component allows property
                            continue;
                        }
                        if ('2.6' == substr(ICALCREATOR_VERSION, -3) && 'TZOFFSETFROM' == $propName) {
                            $propName = 'TZOFFSETTFROM';
                        }
                        // iCalcreator 2.6 bug fix
                        if (isset($compinfo2['props'][$propName])) {
                            if ('2.6' == substr(ICALCREATOR_VERSION, -3) && 'TZOFFSETTFROM' == $propName) {
                                $propName = 'TZOFFSETFROM';
                            }
                            // iCalcreator 2.6 bug fix
                            $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                            if (!method_exists($scomp, $fcn)) {
                                $msg = $iCal2csv_VERSION . ' ERROR 8 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')';
                                if ($log) {
                                    $log->log($msg, 3);
                                } else {
                                    error_log($msg);
                                }
                                continue;
                            }
                            $output = str_replace("{$calnl} ", '', rtrim($scomp->{$fcn}()));
                            $output = str_replace($propName . ';', '', $output);
                            $output = str_replace($propName . ':', '', $output);
                            $rows[$row][$proporder[$propName]] = fixiCalString($output);
                        }
                    }
                    // end foreach( $proporder
                    if (isset($compinfo2['props']['X-PROP'])) {
                        while ($xprop = $scomp->getProperty()) {
                            $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                            $rows[$row][$proporder[$xprop[0]]] = fixiCalString($output);
                        }
                    }
                }
                // end foreach( $compinfo['sub']
            }
            // end if( isset( $compinfo['sub']['props'] ))
        }
        // end foreach
    }
    // end vtimezone
    if ($log) {
        $timeexec['zoneOk'] = microtime(TRUE);
    }
    $maxColCount = count($proporder);
    /* fix property order list */
    $proporder = array();
    foreach ($conf as $key => $value) {
        if ('2' <= $key && '99' > $key) {
            $proporder[$value] = $key;
            if ($log) {
                $log->log("{$iCal2csv_VERSION} {$value} in column {$key}", 7);
            }
        }
    }
    $proporder['TYPE'] = 0;
    $proporder['ORDER'] = 1;
    $props = array('UID', 'DTSTAMP', 'SUMMARY', 'DTSTART', 'DURATION', 'DTEND', 'DUE', 'RRULE', 'RDATE', 'EXRULE', 'EXDATE', 'DESCRIPTION', 'CATEGORIES', 'ORGANIZER', 'LOCATION', 'RESOURCES', 'CONTACT', 'URL', 'COMMENT', 'PRIORITY', 'ATTENDEE', 'CLASS', 'TRANSP', 'SEQUENCE', 'STATUS', 'COMPLETED', 'CREATED', 'LAST-MODIFIED', 'ACTION', 'TRIGGER', 'REPEAT', 'ATTACH', 'FREEBUSY', 'RELATED-TO', 'REQUEST-STATUS', 'GEO', 'PERCENT-COMPLETE', 'RECURRENCE-ID');
    $pix = 2;
    foreach ($props as $prop) {
        if (isset($proporder[$prop])) {
            continue;
        }
        if (isset($conf['skip']) && in_array($prop, $conf['skip'])) {
            if ($log) {
                $log->log("{$iCal2csv_VERSION} {$prop} removed from output", 7);
            }
            continue;
        }
        while (in_array($pix, $proporder)) {
            $pix++;
        }
        $proporder[$prop] = $pix++;
    }
    /* remove unused properties from and add x-props to property order list */
    if ($maxpropix < count($proporder) - 1) {
        $maxpropix = count($proporder) - 1;
    }
    $potmp = array();
    $potmp[0] = 'TYPE';
    $potmp[1] = 'ORDER';
    //  $potmp[2]                   =  'UID';
    foreach ($compsinfo as $cix => $compinfo) {
        if ('vtimezone' == $compinfo['type']) {
            continue;
        }
        foreach ($compinfo['props'] as $propName => $propcnt) {
            if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                $potmp[$proporder[$propName]] = $propName;
            } elseif ('X-PROP' == $propName) {
                $comp = $calendar->getComponent($compinfo['ordno']);
                while ($xprop = $comp->getProperty()) {
                    if (!in_array($xprop[0], $potmp)) {
                        $maxpropix += 1;
                        $potmp[$maxpropix] = $xprop[0];
                    }
                    // end if
                }
                // while( $xprop
            }
            // end elseif( 'X-PROP'
        }
        // end foreach( $compinfo['props']
        if (isset($compinfo['sub'])) {
            foreach ($compinfo['sub'] as $compinfo2) {
                foreach ($compinfo2['props'] as $propName => $propcnt) {
                    if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                        $potmp[$proporder[$propName]] = $propName;
                    } elseif ('X-PROP' == $propName) {
                        $scomp = $comp->getComponent($compinfo2['ordno']);
                        while ($xprop = $scomp->getProperty()) {
                            if (!in_array($xprop[0], $potmp)) {
                                $maxpropix += 1;
                                $potmp[$maxpropix] = $xprop[0];
                            }
                            // end if
                        }
                        // end while xprop
                    }
                    // end X-PROP
                }
                // end $compinfo['sub']['props']
            }
            // end foreach( $compinfo['sub']
        }
        // end if( isset( $compinfo['sub']
    }
    ksort($potmp, SORT_NUMERIC);
    $proporder = array_flip(array_values($potmp));
    if ($log) {
        $log->log("{$iCal2csv_VERSION} comp proporder=" . implode(',', array_flip($proporder)), 7);
    }
    if ($maxColCount < count($proporder)) {
        $maxColCount = count($proporder);
    }
    /* create header row */
    $row += 1;
    foreach ($proporder as $propName => $col) {
        if (isset($conf[$propName])) {
            $rows[$row][$col] = $conf[$propName];
            // check map of userfriendly name to iCal property name
            if ($log) {
                $log->log("{$iCal2csv_VERSION} header row, col={$col}: {$propName}, replaced by " . $conf[$propName], 7);
            }
        } else {
            $rows[$row][$col] = $propName;
        }
    }
    $allowedProps = array('VEVENT' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTEND', 'DTSTAMP', 'DTSTART', 'DURATION', 'EXDATE', 'RXRULE', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'TRANSP', 'UID', 'URL'), 'VTODO' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'COMPLETED', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART', 'DUE', 'DURATION', 'EXATE', 'EXRULE', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PERCENT', 'PRIORITY', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL'), 'VJOURNAL' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART', 'EXDATE', 'EXRULE', 'LAST-MODIFIED', 'ORGANIZER', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL'), 'VFREEBUSY' => array('ATTENDEE', 'COMMENT', 'CONTACT', 'DTEND', 'DTSTAMP', 'DTSTART', 'DURATION', 'FREEBUSY', 'ORGANIZER', 'UID', 'URL'), 'VALARM' => array('ACTION', 'ATTACH', 'ATTENDEE', 'DESCRIPTION', 'DURATION', 'REPEAT', 'TRANSP', 'TRIGGER'));
    /* create data rows */
    foreach ($compsinfo as $cix => $compinfo) {
        if ('vtimezone' == $compinfo['type']) {
            continue;
        }
        $row += 1;
        foreach ($proporder as $propName => $col) {
            $rows[$row][] = '';
        }
        // set all cells empty
        $rows[$row][$proporder['TYPE']] = $compinfo['type'];
        $rows[$row][$proporder['ORDER']] = $compinfo['ordno'];
        //    $rows[$row][$proporder['UID']]   = $compinfo['uid'];
        $comp = $calendar->getComponent($compinfo['ordno']);
        foreach ($proporder as $propName => $col) {
            if ('TYPE' == $propName || 'ORDER' == $propName) {
                continue;
            }
            if ('X-' == substr($propName, 0, 2)) {
                continue;
            }
            if (!in_array($propName, $allowedProps[strtoupper($compinfo['type'])])) {
                // check if component allows property
                continue;
            }
            if (isset($compinfo['props'][$propName])) {
                switch ($propName) {
                    case 'LAST-MODIFIED':
                        $fcn = 'createLastModified';
                        break;
                    case 'RECURRENCE-ID':
                        $fcn = 'createRecurrenceid';
                        break;
                    case 'RELATED-TO':
                        $fcn = 'createRelatedTo';
                        break;
                    case 'REQUEST-STATUS':
                        $fcn = 'createRequestStatus';
                        break;
                    case 'PERCENT-COMPLETE':
                        $fcn = 'createPercentComplete';
                        break;
                    default:
                        $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                }
                if (!method_exists($comp, $fcn)) {
                    $msg = $iCal2csv_VERSION . ' ERROR 9 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')';
                    if ($log) {
                        $log->log($msg, 3);
                    } else {
                        error_log($msg);
                    }
                    continue;
                }
                $output = str_replace("{$calnl} ", '', rtrim($comp->{$fcn}()));
                $output = str_replace($propName . ';', '', $output);
                $output = str_replace($propName . ':', '', $output);
                $rows[$row][$proporder[$propName]] = fixiCalString($output);
            }
        }
        // end foreach( $proporder
        if (isset($compinfo['props']['X-PROP'])) {
            while ($xprop = $comp->getProperty()) {
                $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                $rows[$row][$proporder[$xprop[0]]] = fixiCalString($output);
            }
        }
        if (isset($compinfo['sub'])) {
            foreach ($compinfo['sub'] as $compinfo2) {
                $row += 1;
                foreach ($proporder as $propName => $col) {
                    $rows[$row][] = '';
                }
                // set all cells empty
                $rows[$row][$proporder['TYPE']] = $compinfo2['type'];
                $rows[$row][$proporder['ORDER']] = $compinfo['ordno'] . ':' . $compinfo2['ordno'];
                $scomp = $comp->getComponent($compinfo2['ordno']);
                foreach ($proporder as $propName => $col) {
                    if ('TYPE' == $propName || 'ORDER' == $propName) {
                        continue;
                    }
                    if ('X-' == substr($propName, 0, 2)) {
                        continue;
                    }
                    if (!in_array($propName, $allowedProps[strtoupper($compinfo2['type'])])) {
                        // check if component allows property
                        continue;
                    }
                    if (isset($compinfo2['props'][$propName])) {
                        $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                        if (!method_exists($scomp, $fcn)) {
                            $msg = $iCal2csv_VERSION . ' ERROR 10 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')';
                            if ($log) {
                                $log->log($msg, 3);
                            } else {
                                error_log($msg);
                            }
                            continue;
                        }
                        $output = str_replace("{$calnl} ", '', rtrim($scomp->{$fcn}()));
                        $output = str_replace($propName . ';', '', $output);
                        $output = str_replace($propName . ':', '', $output);
                        $rows[$row][$proporder[$propName]] = fixiCalString($output);
                    }
                }
                // end foreach( $proporder
                if (isset($compinfo2['props']['X-PROP'])) {
                    while ($xprop = $scomp->getProperty()) {
                        $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                        $rows[$row][$proporder[$xprop[0]]] = fixiCalString($output);
                    }
                }
            }
            // if( isset( $compinfo2['props']['X-PROP']
        }
        // end if( isset( $compinfo['sub']
    }
    // foreach( $compsinfo as
    if ($log) {
        $timeexec['compOk'] = microtime(TRUE);
    }
    /* fix csv format */
    // fields that contain commas, double-quotes, or line-breaks must be quoted,
    // a quote within a field must be escaped with an additional quote immediately preceding the literal quote,
    // space before and after delimiter commas may be trimmed (which is prohibited by RFC 4180)
    // a line break within an element must be preserved.
    // Fields may ALWAYS be enclosed within double-quote characters, whether necessary or not.
    foreach ($rows as $row => $line) {
        for ($col = 0; $col < $maxColCount; $col++) {
            if (!isset($line[$col]) || empty($line[$col])) {
                $rows[$row][$col] = $conf['del'] . $conf['del'];
                continue;
            }
            if (ctype_digit($line[$col])) {
                continue;
            }
            $cell = str_replace($conf['del'], $conf['del'] . $conf['del'], $line[$col]);
            $rows[$row][$col] = $conf['del'] . $cell . $conf['del'];
        }
        $rows[$row] = implode($conf['sep'], $rows[$row]);
    }
    $output = implode($conf['nl'], $rows) . $conf['nl'];
    if ($log) {
        $timeexec['exit'] = microtime(TRUE);
        $msg = "{$iCal2csv_VERSION} '{$filename}'";
        $msg .= ' fileOk:' . number_format($timeexec['fileOk'] - $timeexec['start'], 5);
        $msg .= ' infoOk:' . number_format($timeexec['infoOk'] - $timeexec['fileOk'], 5);
        $msg .= ' zoneOk:' . number_format($timeexec['zoneOk'] - $timeexec['infoOk'], 5);
        $msg .= ' compOk:' . number_format($timeexec['compOk'] - $timeexec['zoneOk'], 5);
        $msg .= ' csvOk:' . number_format($timeexec['exit'] - $timeexec['compOk'], 5);
        $msg .= ' total:' . number_format($timeexec['exit'] - $timeexec['start'], 5) . 'sec';
        $log->log($msg, 7);
        $msg = "{$iCal2csv_VERSION} '{$filename}' (" . count($compsinfo) . ' components) start:' . date('H:i:s', $timeexec['start']);
        $msg .= ' total:' . number_format($timeexec['exit'] - $timeexec['start'], 5) . 'sec';
        if ($save) {
            $msg .= " -> '{$diskfilename}'";
        }
        $msg .= ', size=' . strlen($output);
        $msg .= ', ' . count($rows) . " rows, {$maxColCount} cols";
        $log->log($msg, 6);
    }
    /* save or send the file */
    if ($save) {
        if (FALSE !== file_put_contents($diskfilename, $output)) {
            if ($log) {
                $log->flush();
            }
            return TRUE;
        } else {
            $msg = $iCal2csv_VERSION . ' ERROR 11 INPUT FILE:"' . $filename . '" Invalid write to output file : "' . $diskfilename . '"';
            if ($log) {
                $log->log($msg, 3);
                $log->flush();
            } else {
                error_log($msg);
            }
            return FALSE;
        }
    } else {
        if ($log) {
            $log->flush();
        }
        /** return data, auto gzip */
        $filezise = strlen($output);
        if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
            $output = gzencode($output, 9);
            $filezise = strlen($output);
            header('Content-Encoding: gzip');
            header('Vary: *');
        }
        header('Content-Type: text/csv; charset=utf-8');
        header('Content-Disposition: attachment; filename="' . $outputFileParts['basename'] . '"');
        header('Cache-Control: max-age=10');
        header('Content-Length: ' . $filezise);
        echo $output;
    }
    exit;
}
Example #14
0
/**
 * Import an iCal file into the database
 * @param   array   Course info
 * @return  boolean True on success, false otherwise
 * @deprecated
 */
function agenda_import_ical($course_info, $file)
{
    require_once api_get_path(LIBRARY_PATH) . 'fileUpload.lib.php';
    $charset = api_get_system_encoding();
    $filepath = api_get_path(SYS_ARCHIVE_PATH) . $file['name'];
    if (!@move_uploaded_file($file['tmp_name'], $filepath)) {
        error_log('Problem moving uploaded file: ' . $file['error'] . ' in ' . __FILE__ . ' line ' . __LINE__);
        return false;
    }
    require_once api_get_path(LIBRARY_PATH) . 'icalcreator/iCalcreator.class.php';
    $ical = new vcalendar();
    $ical->setConfig('directory', dirname($filepath));
    $ical->setConfig('filename', basename($filepath));
    $return = $ical->parse();
    //we need to recover: summary, description, dtstart, dtend, organizer, attendee, location (=course name),
    /*
              $ve = $ical->getComponent(VEVENT);
    
              $ttitle	= $ve->getProperty('summary');
              $title	= api_convert_encoding($ttitle,$charset,'UTF-8');
    
              $tdesc	= $ve->getProperty('description');
              $desc	= api_convert_encoding($tdesc,$charset,'UTF-8');
    
              $start_date	= $ve->getProperty('dtstart');
              $start_date_string = $start_date['year'].'-'.$start_date['month'].'-'.$start_date['day'].' '.$start_date['hour'].':'.$start_date['min'].':'.$start_date['sec'];
    
    
              $ts 	 = $ve->getProperty('dtend');
              if ($ts) {
              $end_date_string = $ts['year'].'-'.$ts['month'].'-'.$ts['day'].' '.$ts['hour'].':'.$ts['min'].':'.$ts['sec'];
              } else {
              //Check duration if dtend does not exist
              $duration 	  = $ve->getProperty('duration');
              if ($duration) {
              $duration = $ve->getProperty('duration');
              $duration_string = $duration['year'].'-'.$duration['month'].'-'.$duration['day'].' '.$duration['hour'].':'.$duration['min'].':'.$duration['sec'];
              $start_date_tms = mktime(intval($start_date['hour']), intval($start_date['min']), intval($start_date['sec']), intval($start_date['month']), intval($start_date['day']), intval($start_date['year']));
              //$start_date_tms = mktime(($start_date['hour']), ($start_date['min']), ($start_date['sec']), ($start_date['month']), ($start_date['day']), ($start_date['year']));
              //echo date('d-m-Y - h:i:s', $start_date_tms);
    
              $end_date_string = mktime(intval($start_date['hour']) +$duration['hour'], intval($start_date['min']) + $duration['min'], intval($start_date['sec']) + $duration['sec'], intval($start_date['month']) + $duration['month'], intval($start_date['day'])+$duration['day'], intval($start_date['year']) + $duration['year']);
              $end_date_string = date('Y-m-d H:i:s', $end_date_string);
              //echo date('d-m-Y - h:i:s', $end_date_string);
              }
              }
    
    
              //echo $start_date.' - '.$end_date;
              $organizer	 = $ve->getProperty('organizer');
              $attendee 	 = $ve->getProperty('attendee');
              $course_name = $ve->getProperty('location');
              //insert the event in our database
              $id = agenda_add_item($course_info,$title,$desc,$start_date_string,$end_date_string,$_POST['selectedform']);
    
    
              $repeat = $ve->getProperty('rrule');
              if(is_array($repeat) && !empty($repeat['FREQ'])) {
              $trans = array('DAILY'=>'daily','WEEKLY'=>'weekly','MONTHLY'=>'monthlyByDate','YEARLY'=>'yearly');
              $freq = $trans[$repeat['FREQ']];
              $interval = $repeat['INTERVAL'];
              if(isset($repeat['UNTIL']) && is_array($repeat['UNTIL'])) {
              $until = mktime(23,59,59,$repeat['UNTIL']['month'],$repeat['UNTIL']['day'],$repeat['UNTIL']['year']);
              $res = agenda_add_repeat_item($course_info,$id,$freq,$until,$_POST['selectedform']);
              } */
    $eventcount = 0;
    $message = array();
    $agenda_obj = new Agenda();
    while (true) {
        //we need to recover: summary, description, dtstart, dtend, organizer, attendee, location (=course name)
        $ve = $ical->getComponent('VEVENT', $eventcount);
        if (!$ve) {
            break;
        }
        $ttitle = $ve->getProperty('summary');
        $title = api_convert_encoding($ttitle, $charset, 'UTF-8');
        $tdesc = $ve->getProperty('description');
        $desc = api_convert_encoding($tdesc, $charset, 'UTF-8');
        $start_date = $ve->getProperty('dtstart', false, true);
        if (isset($start_date['params']['VALUE'])) {
            $start_date_value = $start_date['value'];
            if ($start_date['params']['VALUE'] == 'DATE') {
                $start_date_string = $start_date_value['year'] . '-' . $start_date_value['month'] . '-' . $start_date_value['day'] . '';
            } else {
                $start_date_string = $start_date_value['year'] . '-' . $start_date_value['month'] . '-' . $start_date_value['day'] . ' ' . $start_date_value['hour'] . ':' . $start_date_value['min'] . ':' . $start_date_value['sec'];
            }
        } else {
            continue;
        }
        $ts = $ve->getProperty('dtend');
        if ($ts) {
            $end_date = $ve->getProperty('dtend', false, true);
            if (isset($end_date['params']['VALUE'])) {
                $end_date_value = $end_date['value'];
                if ($end_date['params']['VALUE'] == 'DATE') {
                    $end_date_string = $end_date_value['year'] . '-' . $end_date_value['month'] . '-' . $end_date_value['day'] . '';
                } else {
                    $end_date_string = $end_date_value['year'] . '-' . $end_date_value['month'] . '-' . $end_date_value['day'] . ' ' . $end_date_value['hour'] . ':' . $end_date_value['min'] . ':' . $end_date_value['sec'];
                }
            } else {
                //Default behaviour
                $end_date_string = $ts['year'] . '-' . $ts['month'] . '-' . $ts['day'] . ' ' . $ts['hour'] . ':' . $ts['min'] . ':' . $ts['sec'];
            }
        } else {
            //Check duration if dtend does not exist
            $duration = $ve->getProperty('duration');
            if ($duration) {
                $duration = $ve->getProperty('duration');
                $duration_string = $duration['year'] . '-' . $duration['month'] . '-' . $duration['day'] . ' ' . $duration['hour'] . ':' . $duration['min'] . ':' . $duration['sec'];
                $start_date_tms = mktime(intval($start_date['hour']), intval($start_date['min']), intval($start_date['sec']), intval($start_date['month']), intval($start_date['day']), intval($start_date['year']));
                //$start_date_tms = mktime(($start_date['hour']), ($start_date['min']), ($start_date['sec']), ($start_date['month']), ($start_date['day']), ($start_date['year']));
                //echo date('d-m-Y - h:i:s', $start_date_tms);
                $end_date_string = mktime(intval($start_date['hour']) + $duration['hour'], intval($start_date['min']) + $duration['min'], intval($start_date['sec']) + $duration['sec'], intval($start_date['month']) + $duration['month'], intval($start_date['day']) + $duration['day'], intval($start_date['year']) + $duration['year']);
                $end_date_string = api_get_utc_datetime($end_date_string);
                //echo date('d-m-Y - h:i:s', $end_date_string);
            }
        }
        //echo $start_date.' - '.$end_date;
        $organizer = $ve->getProperty('organizer');
        $attendee = $ve->getProperty('attendee');
        $course_name = $ve->getProperty('location');
        //insert the event in our database
        $agenda_obj->type = 'course';
        $all_day = 'false';
        if ($start_date_string == $end_date_string) {
            $all_day = 'true';
        }
        $date = new DateTime($start_date_string);
        $date->add(new DateInterval('P1D'));
        if ($start_date_string == $date->format('Y-m-d h:i:s')) {
            $all_day = 'true';
        }
        $id = $agenda_obj->add_event($start_date_string, $end_date_string, $all_day, $title, $desc, array('everyone'));
        $message[] = " {$title} - " . $start_date_string . " - " . $end_date_string;
        $repeat = $ve->getProperty('rrule');
        if (is_array($repeat) && !empty($repeat['FREQ'])) {
            $trans = array('DAILY' => 'daily', 'WEEKLY' => 'weekly', 'MONTHLY' => 'monthlyByDate', 'YEARLY' => 'yearly');
            $freq = $trans[$repeat['FREQ']];
            $interval = $repeat['INTERVAL'];
            if (isset($repeat['UNTIL']) && is_array($repeat['UNTIL'])) {
                $until = mktime(23, 59, 59, $repeat['UNTIL']['month'], $repeat['UNTIL']['day'], $repeat['UNTIL']['year']);
                $res = agenda_add_repeat_item($course_info, $id, $freq, $until, $attendee);
            }
            //TODO: deal with count
            if (!empty($repeat['COUNT'])) {
                $count = $repeat['COUNT'];
                $res = agenda_add_repeat_item($course_info, $id, $freq, $count, $attendee);
            }
        }
        $eventcount++;
    }
    if (!empty($message)) {
        $message = implode('<br /> ', $message);
    }
    return $message;
}
 public function get_json()
 {
     $event_json = array();
     $filters = $this->in->exists('filters', 'int') ? $this->in->getArray('filters', 'int') : false;
     $range_start = $this->time->fromformat($this->in->get('start', ''), 'Y-m-d');
     $range_end = $this->time->fromformat($this->in->get('end', ''), 'Y-m-d');
     $filterby = $this->in->get('filterby', 'all');
     // parse the feeds
     $feeds = $this->pdh->get('calendars', 'idlist', array('feed', $filters));
     if (is_array($feeds) && count($feeds) > 0) {
         foreach ($feeds as $feed) {
             $feedurl = $this->pdh->get('calendars', 'feed', array($feed));
             if (isValidURL($feedurl)) {
                 require_once $this->root_path . 'libraries/icalcreator/iCalcreator.class.php';
                 $vcalendar = new vcalendar(array('url' => $feedurl));
                 if (TRUE === $vcalendar->parse()) {
                     $vcalendar->sort();
                     while ($comp = $vcalendar->getComponent('vevent')) {
                         $startdate = $comp->getProperty('dtstart', 1);
                         $enddate = $comp->getProperty('dtend', 1);
                         // set the date for the events
                         $allday = isset($enddate['hour']) && isset($startdate['hour']) ? false : true;
                         if ($allday) {
                             $startdate_out = sprintf("%04d", $startdate['year']) . '-' . sprintf("%02d", $startdate['month']) . '-' . sprintf("%02d", $startdate['day']) . ' 00:00';
                             $enddate_out = sprintf("%04d", $enddate['year']) . '-' . sprintf("%02d", $enddate['month']) . '-' . sprintf("%02d", $enddate['day'] - 1) . ' 00:00';
                         } else {
                             $startdate_out = sprintf("%04d", $startdate['year']) . '-' . sprintf("%02d", $startdate['month']) . '-' . sprintf("%02d", $startdate['day']) . ' ' . (isset($startdate['hour']) ? sprintf("%02d", $startdate['hour']) . ':' . sprintf("%02d", $startdate['min']) : '00:00');
                             $enddate_out = sprintf("%04d", $enddate['year']) . '-' . $enddate['month'] . '-' . $enddate['day'] . ' ' . (isset($enddate['hour']) ? $enddate['hour'] . ':' . $enddate['min'] : '00:00');
                         }
                         // build the event colours
                         $eventcolor = $this->pdh->get('calendars', 'color', $feed);
                         $eventcolor_txt = get_brightness($eventcolor) > 130 ? 'black' : 'white';
                         $event_json[] = array('eventid' => $calid, 'title' => $comp->getProperty('summary', 1), 'start' => $startdate_out, 'end' => $enddate_out, 'allDay' => $allday, 'note' => $comp->getProperty('description', 1), 'color' => $eventcolor . ' !important', 'textColor' => $eventcolor_txt . ' !important');
                     }
                 }
             }
         }
     }
     // add the calendar events to the json feed
     $calendars = $this->pdh->get('calendars', 'idlist', array('nofeed', $filters));
     $caleventids = $this->pdh->get('calendar_events', 'id_list', array(false, $range_start, $range_end, false, $filterby));
     if (is_array($caleventids) && count($caleventids) > 0) {
         foreach ($caleventids as $calid) {
             $eventextension = $this->pdh->get('calendar_events', 'extension', array($calid));
             $raidmode = $eventextension['calendarmode'];
             $eventcolor = $this->pdh->get('calendars', 'color', $this->pdh->get('calendar_events', 'calendar_id', array($calid)));
             $eventcolor_txt = get_brightness($eventcolor) > 130 ? 'black' : 'white';
             if (in_array($this->pdh->get('calendar_events', 'calendar_id', array($calid)), $calendars)) {
                 if ($raidmode == 'raid') {
                     // fetch the attendees
                     $attendees_raw = $this->pdh->get('calendar_raids_attendees', 'attendees', array($calid));
                     $attendees = array();
                     if (is_array($attendees_raw)) {
                         foreach ($attendees_raw as $attendeeid => $attendeerow) {
                             $attendees[$attendeerow['signup_status']][$attendeeid] = $attendeerow;
                         }
                     }
                     // Build the guest array
                     $guests = array();
                     if (registry::register('config')->get('calendar_raid_guests') == 1) {
                         $guestarray = registry::register('plus_datahandler')->get('calendar_raids_guests', 'members', array($calid));
                         if (is_array($guestarray)) {
                             foreach ($guestarray as $guest_row) {
                                 $guests[] = $guest_row['name'];
                             }
                         }
                     }
                     // fetch per raid data
                     $raidcal_status = $this->config->get('calendar_raid_status');
                     $rstatusdata = '';
                     if (is_array($raidcal_status)) {
                         foreach ($raidcal_status as $raidcalstat_id) {
                             if ($raidcalstat_id != 4) {
                                 $actcount = isset($attendees[$raidcalstat_id]) ? count($attendees[$raidcalstat_id]) : 0;
                                 if ($raidcalstat_id == 0) {
                                     $actcount += is_array($guests) ? count($guests) : 0;
                                 }
                                 $rstatusdata .= '<div class="raid_status' . $raidcalstat_id . '">' . $this->user->lang(array('raidevent_raid_status', $raidcalstat_id)) . ': ' . $actcount . '</div>';
                             }
                         }
                     }
                     $rstatusdata .= '<div class="raid_status_total">' . $this->user->lang('raidevent_raid_required') . ': ' . (isset($eventextension) ? $eventextension['attendee_count'] : 0) . '</div>';
                     $deadlinedate = $this->pdh->get('calendar_events', 'time_start', array($calid)) - $eventextension['deadlinedate'] * 3600;
                     $deadline = $deadlinedate > $this->time->time || $this->config->get('calendar_raid_allowstatuschange') == '1' && $this->pdh->get('calendar_raids_attendees', 'status', array($calid, $this->user->id)) > 0 && $this->pdh->get('calendar_raids_attendees', 'status', array($calid, $this->user->id)) != 4 && $this->pdh->get('calendar_events', 'time_end', array($calid)) > $this->time->time ? false : true;
                     $deadlineflag = $deadline ? '<i class="fa fa-lock fa-lg" title="' . $this->user->lang('raidevent_raid_deadl_reach') . '"></i>' : '';
                     // Build the JSON
                     $event_json[] = array('type' => 'raid', 'eventid' => $calid, 'editable' => $this->user->check_auth('a_cal_revent_conf', false) || $this->check_permission($calid) ? true : false, 'title' => $this->in->decode_entity($this->pdh->get('calendar_events', 'name', array($calid))), 'url' => $this->routing->build('calendarevent', $this->pdh->get('calendar_events', 'name', array($calid)), $calid), 'start' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_start', array($calid))), 'end' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_end', array($calid))), 'closed' => $this->pdh->get('calendar_events', 'raidstatus', array($calid)) == 1 ? true : false, 'flag' => $deadlineflag . $this->pdh->get('calendar_raids_attendees', 'html_status', array($calid, $this->user->data['user_id'])), 'icon' => $eventextension['raid_eventid'] ? $this->pdh->get('event', 'icon', array($eventextension['raid_eventid'], true)) : '', 'note' => $this->pdh->get('calendar_events', 'notes', array($calid)), 'raidleader' => $eventextension['raidleader'] > 0 ? implode(', ', $this->pdh->aget('member', 'name', 0, array($eventextension['raidleader']))) : '', 'rstatusdata' => $rstatusdata, 'color' => $eventcolor . ' !important', 'textColor' => $eventcolor_txt . ' !important');
                 } else {
                     // check if the event is private
                     if (!$this->pdh->get('calendar_events', 'private_userperm', array($calid))) {
                         continue;
                     }
                     $alldayevents = $this->pdh->get('calendar_events', 'allday', array($calid)) > 0 ? true : false;
                     $event_json[] = array('type' => 'event', 'eventid' => $calid, 'editable' => $this->user->check_auth('a_cal_revent_conf', false) || $this->check_permission($calid) ? true : false, 'url' => $this->routing->build('calendarevent', $this->pdh->get('calendar_events', 'name', array($calid)), $calid) . 'eventdetails', 'title' => $this->pdh->get('calendar_events', 'name', array($calid)), 'start' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_start', array($calid))), 'end' => $this->time->date('Y-m-d H:i', $this->pdh->get('calendar_events', 'time_end', array($calid, $alldayevents))), 'allDay' => $alldayevents, 'note' => $this->pdh->get('calendar_events', 'notes', array($calid)), 'color' => $eventcolor, 'textColor' => $eventcolor_txt, 'isowner' => $this->pdh->get('calendar_events', 'is_owner', array($calid)), 'isinvited' => $this->pdh->get('calendar_events', 'is_invited', array($calid)), 'joinedevent' => $this->pdh->get('calendar_events', 'joined_invitation', array($calid)), 'author' => $this->pdh->get('calendar_events', 'creator', array($calid)), 'attendees' => $this->pdh->get('calendar_events', 'sharedevent_attendees', array($calid)));
                 }
             }
         }
     }
     // birthday calendar
     if ($this->config->get('calendar_show_birthday') && $this->user->check_auth('u_userlist', false)) {
         $birthday_y = $this->time->date('Y', $range_end);
         $birthdays = $this->pdh->get('user', 'birthday_list');
         if (is_array($birthdays)) {
             foreach ($birthdays as $birthday_uid => $birthday_ts) {
                 $birthday_month = $this->time->date('m', $birthday_ts);
                 if ($birthday_month >= $this->time->date('m', $range_start) && $birthday_month <= $this->time->date('m', $range_end)) {
                     $event_json[] = array('type' => 'birthday', 'className' => 'cal_birthday', 'title' => $this->pdh->get('user', 'name', array($birthday_uid)), 'start' => $birthday_y . '-' . $this->time->date('m-d', $birthday_ts), 'end' => $birthday_y . '-' . $this->time->date('m-d', $birthday_ts), 'allDay' => true, 'textColor' => '#000000', 'backgroundColor' => '#E8E8E8', 'borderColor' => '#7F7F7F');
                 }
             }
         }
     }
     // hooks
     if ($this->hooks->isRegistered('calendar')) {
         $arrHooksData = $this->hooks->process('calendar', array('start' => $range_start, 'end' => $range_end), false);
         if (count($arrHooksData) > 0) {
             $event_json = array_merge($arrHooksData, $event_json);
         }
     }
     // Output the array as JSON
     echo json_encode($event_json);
     exit;
 }
 /**
  * add_vcalendar_events_to_db method
  *
  * Process vcalendar instance - add events to database
  *
  * @param vcalendar $v              Calendar to retrieve data from
  * @param stdClass  $feed           Instance of feed (see Ai1ecIcs plugin)
  * @param string    $comment_status WP comment status: 'open' or 'closed'
  * @param int       $do_show_map    Map display status (DB boolean: 0 or 1)
  *
  * @return int Count of events added to database
  */
 public function add_vcalendar_events_to_db(vcalendar $v, $feed, $comment_status, $do_show_map = 0)
 {
     global $ai1ec_events_helper;
     $count = 0;
     $do_show_map = Ai1ec_Number_Utility::db_bool($do_show_map);
     $v->sort();
     // Reverse the sort order, so that RECURRENCE-IDs are listed before the
     // defining recurrence events, and therefore take precedence during
     // caching.
     $v->components = array_reverse($v->components);
     // TODO: select only VEVENT components that occur after, say, 1 month ago.
     // Maybe use $v->selectComponents(), which takes into account recurrence
     // Fetch default timezone in case individual properties don't define it
     $timezone = $v->getProperty('X-WR-TIMEZONE');
     $timezone = $timezone[1];
     // go over each event
     while ($e = $v->getComponent('vevent')) {
         // Event data array.
         $data = array();
         // =====================
         // = Start & end times =
         // =====================
         $start = $e->getProperty('dtstart', 1, true);
         $end = $e->getProperty('dtend', 1, true);
         // For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE value type but no
         // "DTEND" nor "DURATION" property, the event's duration is taken to
         // be one day.  For cases where a "VEVENT" calendar component
         // specifies a "DTSTART" property with a DATE-TIME value type but no
         // "DTEND" property, the event ends on the same calendar date and
         // time of day specified by the "DTSTART" property.
         if (empty($end)) {
             // #1 if duration is present, assign it to end time
             $end = $e->getProperty('duration', 1, true, true);
             if (empty($end)) {
                 // #2 if only DATE value is set for start, set duration to 1 day
                 if (!isset($start['value']['hour'])) {
                     $end = array('year' => $start['value']['year'], 'month' => $start['value']['month'], 'day' => $start['value']['day'] + 1, 'hour' => 0, 'min' => 0, 'sec' => 0, 'tz' => $start['value']['tz']);
                 } else {
                     // #3 set end date to start time
                     $end = $start;
                 }
             }
         }
         // Event is all-day if no time components are defined
         $allday = !isset($start['value']['hour']);
         // Also check the proprietary MS all-day field.
         $ms_allday = $e->getProperty('X-MICROSOFT-CDO-ALLDAYEVENT');
         if (!empty($ms_allday) && $ms_allday[1] == 'TRUE') {
             $allday = true;
         }
         // convert times to GMT UNIX timestamps
         $start = $this->time_array_to_timestamp($start, $timezone);
         $end = $this->time_array_to_timestamp($end, $timezone);
         if (false === $start || false === $end) {
             trigger_error('Failed to parse one or more dates given timezone "' . var_export($timezone, true) . '".', E_USER_WARNING);
             continue;
         }
         // If all-day, and start and end times are equal, then this event has
         // invalid end time (happens sometimes with poorly implemented iCalendar
         // exports, such as in The Event Calendar), so set end time to 1 day
         // after start time.
         if ($allday && $start === $end) {
             $end += 24 * 60 * 60;
         }
         // Due to potential time zone differences (WP time zone vs. feed time
         // zone), must set all-day event start/end dates to midnight of the
         // respective days, in the *local* time zone.
         if ($allday) {
             $start = $ai1ec_events_helper->gmgetdate($start);
             $start = gmmktime(0, 0, 0, $start['mon'], $start['mday'], $start['year']);
             $start = $ai1ec_events_helper->local_to_gmt($start);
             $end = $ai1ec_events_helper->gmgetdate($end);
             $end = gmmktime(0, 0, 0, $end['mon'], $end['mday'], $end['year']);
             $end = $ai1ec_events_helper->local_to_gmt($end);
         }
         $data += compact('start', 'end', 'allday');
         // =======================================
         // = Recurrence rules & recurrence dates =
         // =======================================
         if ($rrule = $e->createRrule()) {
             $rrule = trim(end(explode(':', $rrule)));
         }
         if ($exrule = $e->createExrule()) {
             $exrule = trim(end(explode(':', $exrule)));
         }
         if ($rdate = $e->createRdate()) {
             $rdate = trim(end(explode(':', $rdate)));
         }
         // ===================
         // = Exception dates =
         // ===================
         $exdate_array = array();
         if ($exdates = $e->createExdate()) {
             // We may have two formats:
             // one exdate with many dates ot more EXDATE rules
             $exdates = explode("EXDATE", $exdates);
             foreach ($exdates as $exd) {
                 if (empty($exd)) {
                     continue;
                 }
                 $exdate_array[] = trim(end(explode(':', $exd)));
             }
         }
         // This is the local string.
         $exdate_loc = implode(',', $exdate_array);
         $gmt_exdates = array();
         // Now we convert the string to gmt. I must do it here
         // because EXDATE:date1,date2,date3 must be parsed
         if (!empty($exdate_loc)) {
             foreach (explode(',', $exdate_loc) as $date) {
                 // If the date is > 8 char that's a datetime, we just want the
                 // date part for the exclusion rules
                 if (strlen($date) > 8) {
                     $date = substr($date, 0, 8);
                 }
                 $gmt_exdates[] = $ai1ec_events_helper->exception_dates_to_gmt($date);
             }
         }
         $exdate = implode(',', $gmt_exdates);
         // ========================
         // = Latitude & longitude =
         // ========================
         $latitude = $longitude = NULL;
         $geo_tag = $e->getProperty('geo');
         if (!empty($geo_tag) && false !== strpos(';', $geo_tag)) {
             list($latitude, $longitude) = explode(';', $geo_tag, 2);
             $latitude = (double) $latitude;
             $longitude = (double) $longitude;
         }
         unset($geo_tag);
         if (NULL !== $latitude) {
             $data += compact('latitude', 'longitude');
         }
         // ===================
         // = Venue & address =
         // ===================
         $address = $venue = '';
         $location = $e->getProperty('location');
         $matches = array();
         // This regexp matches a venue / address in the format
         // "venue @ address" or "venue - address".
         preg_match('/\\s*(.*\\S)\\s+[\\-@]\\s+(.*)\\s*/', $location, $matches);
         // if there is no match, it's not a combined venue + address
         if (empty($matches)) {
             // if there is a comma, probably it's an address
             if (false === strpos($location, ',')) {
                 $venue = $location;
             } else {
                 $address = $location;
             }
         } else {
             $venue = isset($matches[1]) ? $matches[1] : '';
             $address = isset($matches[2]) ? $matches[2] : '';
         }
         // =====================================================
         // = Set show map status based on presence of location =
         // =====================================================
         if (1 === $do_show_map && NULL === $latitude && empty($address)) {
             $do_show_map = 0;
         }
         // ==================
         // = Cost & tickets =
         // ==================
         $cost = $e->getProperty('X-COST');
         $cost = $cost ? $cost[1] : '';
         $ticket_url = $e->getProperty('X-TICKETS-URL');
         $ticket_url = $ticket_url ? $ticket_url[1] : '';
         // ===============================
         // = Contact name, phone, e-mail =
         // ===============================
         $organizer = $e->getProperty('organizer');
         $contact = $e->getProperty('contact');
         $elements = explode(';', $contact, 4);
         foreach ($elements as $el) {
             $el = trim($el);
             // Detect e-mail address.
             if (false !== strpos($el, '@')) {
                 $data['contact_email'] = $el;
             } elseif (false !== strpos($el, '://')) {
                 $data['contact_url'] = $el;
             } elseif (preg_match('/\\d/', $el)) {
                 $data['contact_phone'] = $el;
             } else {
                 $data['contact_name'] = $el;
             }
         }
         if (!$data['contact_name']) {
             // If no contact name, default to organizer property.
             $data['contact_name'] = $organizer;
         }
         // Store yet-unsaved values to the $data array.
         $data += array('recurrence_rules' => $rrule, 'exception_rules' => $exrule, 'recurrence_dates' => $rdate, 'exception_dates' => $exdate, 'venue' => $venue, 'address' => $address, 'cost' => $cost, 'ticket_url' => $ticket_url, 'show_map' => $do_show_map, 'ical_feed_url' => $feed->feed_url, 'ical_source_url' => $e->getProperty('url'), 'ical_organizer' => $organizer, 'ical_contact' => $contact, 'ical_uid' => $e->getProperty('uid'), 'categories' => $feed->feed_category, 'tags' => $feed->feed_tags, 'feed' => $feed, 'post' => array('post_status' => 'publish', 'comment_status' => $comment_status, 'post_type' => AI1EC_POST_TYPE, 'post_author' => 1, 'post_title' => $e->getProperty('summary'), 'post_content' => stripslashes(str_replace('\\n', "\n", $e->getProperty('description')))));
         // Create event object.
         $event = new Ai1ec_Event($data);
         // TODO: when singular events change their times in an ICS feed from one
         // import to another, the matching_event_id is null, which is wrong. We
         // want to match that event that previously had a different time.
         // However, we also want the function to NOT return a matching event in
         // the case of recurring events, and different events with different
         // RECURRENCE-IDs... ponder how to solve this.. may require saving the
         // RECURRENCE-ID as another field in the database.
         $matching_event_id = $ai1ec_events_helper->get_matching_event_id($event->ical_uid, $event->ical_feed_url, $event->start, !empty($event->recurrence_rules));
         if (is_null($matching_event_id)) {
             // =================================================
             // = Event was not found, so store it and the post =
             // =================================================
             $event->save();
         } else {
             // ======================================================
             // = Event was found, let's store the new event details =
             // ======================================================
             // Update the post
             $post = get_post($matching_event_id);
             $post->post_title = $event->post->post_title;
             $post->post_content = $event->post->post_content;
             wp_update_post($post);
             // Update the event
             $event->post_id = $matching_event_id;
             $event->post = $post;
             $event->save(true);
             // Delete event's cache
             $ai1ec_events_helper->delete_event_cache($matching_event_id);
         }
         // Regenerate event's cache
         $ai1ec_events_helper->cache_event($event);
         $count++;
     }
     return $count;
 }
Example #17
0
     }
     $calendar .= ">{$i}</option>";
 }
 $calendar .= "  </select>&nbsp;\n\n                    <a href=\"index.php?page=calender&amp;view=list&amp;month={$nextMonth}&amp;year={$year}&amp;menuid={$menuid}\"><img src=\"{$templateinfo['imagedir']}next.png\" title=\"Next Month\" alt=\"Next Month\" border=\"0\"/></a>&nbsp;\n                    <a href=\"index.php?page=calender&amp;view=list&amp;month={$monthnums[$month]}&amp;year={$nextYear}&amp;menuid={$menuid}\"><img src=\"{$templateinfo['imagedir']}last.png\" title=\"Next Year\" alt=\"Next Year\" border=\"0\"/></a>\n                  </div>\n            </form>";
 $days = number_days($monthnum);
 $monthStart = strtotime("{$year}-{$monthnum}-01 00:00:00");
 $monthEnd = strtotime("{$year}-{$monthnum}-{$days} 23:59:59");
 $numcalendar = 0;
 $calitems = $data->select_fetch_all_rows($numcalendar, "calendar_items", "WHERE ((((startdate >= {$monthStart} OR enddate >= {$monthEnd}) AND startdate <= {$monthEnd}) OR (startdate <= {$monthStart} AND enddate >= {$monthStart})) AND allowed=1 AND trash=0) ORDER BY startdate ASC");
 $icalsql = $data->select_query("ical_items");
 $temp2 = $data->select_fetch_one_row("calendar_items", "ORDER BY id DESC", "id");
 $startid = $temp2['id'] + 1;
 while ($temp = $data->fetch_array($icalsql)) {
     $vcalendar = new vcalendar();
     $vcalendar->parse('http://' . $temp['link']);
     while ($vevent = $vcalendar->getComponent()) {
         $startdate = $vevent->getProperty('dtstart');
         $enddate = $vevent->getProperty('dtend');
         if ($startdate['year'] <= $year && $enddate['year'] >= $year && $startdate['month'] <= $monthnum && $enddate['month'] >= $monthnum) {
             $item = array();
             $item['id'] = $startid++;
             $item['summary'] = trim($vevent->getProperty('summary')) . " [{$temp['name']}]";
             $item['detail'] = trim($vevent->getProperty('description'));
             $item['startdate'] = mktime($startdate['hour'], $startdate['min'], 0, $startdate['month'], $startdate['day'], $startdate['year']);
             $item['enddate'] = mktime($enddate['hour'], $enddate['min'], 0, $enddate['month'], $enddate['day'], $enddate['year']);
             $item['groups'] = $temp['groups'];
             $item['colour'] = $temp['colour'];
             $item['ical'] = true;
             $calitems[] = $item;
             $numcalendar++;
         }
Example #18
0
 function GetMessage($folderid, $id, $truncsize, $mimesupport = 0)
 {
     debugLog('CalDAV::GetMessage(' . $folderid . ', ' . $id . ', ..)');
     if (trim($id) == "") {
         return;
     }
     if ($folderid == "calendar") {
         $output = $this->_events[$id]['data'];
     } elseif ($folderid == "tasks") {
         $output = $this->_tasks[$id]['data'];
     } else {
         return;
     }
     //debugLog("CalDAV::Got File ".$id." now parseing ".$output);
     $v = new vcalendar();
     $v->runparse($output);
     $v->sort();
     if ($folderid == "tasks") {
         while ($vtodo = $v->getComponent('vtodo', $vcounter)) {
             $message = $this->converttotask($vtodo, $truncsize);
             $vcounter++;
         }
     } else {
         $vcounter = 1;
         $fullexceptionsarray = array();
         while ($vevent = $v->getComponent('vevent', $vcounter)) {
             $val = $vevent->getProperty("RECURRENCE-ID");
             if ($val === false) {
                 $message = $this->converttoappointment($vevent, $truncsize);
             } else {
                 $tmp = $this->converttoappointment($vevent, $truncsize);
                 $tmp->deleted = "0";
                 //The exceptionstarttime is the ORIGINAL starttime of the event
                 //On Thunderbird this is equal to the RECCURENCE-ID (which is in $val)
                 $tmp->exceptionstarttime = mktime($val['hour'], $val['min'], $val['sec'], $val['month'], $val['day'], $val['year']);
                 unset($tmp->uid);
                 unset($tmp->exceptions);
                 array_push($fullexceptionsarray, $tmp);
                 unset($tmp);
             }
             $vcounter++;
         }
         $message->exceptions = array_merge($message->exceptions, $fullexceptionsarray);
     }
     if ($vtimezone = $v->getComponent('vtimezone')) {
         $message = $this->setoutlooktimezone($message, $vtimezone);
     }
     debugLog("CalDAV::Finsihed Converting " . $id . " now returning");
     return $message;
 }
 public function processFeeds()
 {
     require_once dirname(__FILE__) . '/mxcalendars.ics.class.php';
     $f = $this->modx->newQuery('mxCalendarFeed');
     $f->where(array('active:=' => 1, 'nextrunon:<=' => time()));
     $f->prepare();
     $mxcfeeds = $this->modx->getCollection('mxCalendarFeed', $f);
     if ($this->loggingEnabled) {
         $this->logEvent('feed', 'feeds processor called\\n\\nSQL:\\n' . $f->toSql());
     }
     //$this->modx->setLogLevel(modX::LOG_LEVEL_INFO);
     foreach ($mxcfeeds as $feed) {
         $hadmodifications = 0;
         if ($feed->get('type') == 'ical') {
             $activeUrl = $feed->get('feed');
             $myics = file_get_contents($activeUrl);
             // Cache the response for giggles
             //$this->modx->cacheManager->set('mxcfeed-'.$feed->get('id'),$myics,3600);
             $config = array("unique_id" => 'mxcfeed-' . $feed->get('id') . '-' . time(), "url" => $activeUrl);
             $vcalendar = new vcalendar($config);
             $vcalendar->parse();
             //$this->modx->setLogLevel(modX::LOG_LEVEL_INFO);
             //$this->modx->log(modX::LOG_LEVEL_INFO,'Parsing feed #'.$feed->get('id').' events. ['.$feed->get('feed').']\n\nResponse:\n'.$myics);
             if ($this->loggingEnabled) {
                 $this->logEvent('feed parse', 'Parsing feed #' . $feed->get('id') . ' events. [' . $feed->get('feed') . ']\\n\\nResponse:\\n' . $myics);
             }
             while ($vevent = $vcalendar->getComponent("vevent")) {
                 if ($vevent->dtstart['value']) {
                     $start = mktime($vevent->dtstart['value']['hour'], $vevent->dtstart['value']['min'], $vevent->dtstart['value']['sec'], $vevent->dtstart['value']['month'], $vevent->dtstart['value']['day'], $vevent->dtstart['value']['year']);
                     // one occurrence
                 } else {
                     $start = '';
                 }
                 if ($vevent->dtend['value']) {
                     $end = mktime($vevent->dtend['value']['hour'], $vevent->dtend['value']['min'], $vevent->dtend['value']['sec'], $vevent->dtend['value']['month'], $vevent->dtend['value']['day'], $vevent->dtend['value']['year']);
                 } else {
                     $end = '';
                 }
                 if ($vevent->lastmodified['value']) {
                     $lastchange = mktime($vevent->lastmodified['value']['hour'], $vevent->lastmodified['value']['min'], $vevent->lastmodified['value']['sec'], $vevent->lastmodified['value']['month'], $vevent->lastmodified['value']['day'], $vevent->lastmodified['value']['year']);
                 } else {
                     $lastchange = '';
                 }
                 if ($vevent->created['value']) {
                     $createdDate = mktime($vevent->created['value']['hour'], $vevent->created['value']['min'], $vevent->created['value']['sec'], $vevent->created['value']['month'], $vevent->created['value']['day'], $vevent->created['value']['year']);
                 } else {
                     $createdDate = '';
                 }
                 $description = $vevent->getProperty("description");
                 // one occurrence
                 $location = $vevent->getProperty("location");
                 $title = $vevent->getProperty("summary");
                 $feedEventUID = $vevent->getProperty("uid");
                 //-- Multiple Occurances
                 //while( $comment = $vevent->getProperty( "comment" )) { // MAY occur more than once
                 //   echo json_encode($comment).'<br /><hr /><br />';
                 //}
                 // Output for testing
                 $event = array('title' => $title, 'description' => !empty($description) ? $description : '', 'location_name' => $location, 'startdate' => $start, 'enddate' => $end, 'source' => 'feed', 'lastedit' => $lastchange, 'feeds_id' => $feed->get('id'), 'feeds_uid' => $feedEventUID, 'context' => '', 'categoryid' => $feed->get('defaultcategoryid'), 'createdon' => $createDate, 'repeattype' => 0, 'repeaton' => '', 'repeatfrequency' => 0);
                 //echo 'Title: '.$title.'<br />'.json_encode($event).'<br /><hr><br /><br />';
                 //-- Save the new event
                 if (!empty($feedEventUID)) {
                     $existingEvent = $this->modx->getObject('mxCalendarEvents', array('feeds_uid' => $feedEventUID));
                     if (!is_object($existingEvent)) {
                         $existingEvent = $this->modx->getObject('mxCalendarEvents', array('title' => $title));
                     }
                 } else {
                     $existingEvent = $this->modx->getObject('mxCalendarEvents', array('title' => $title));
                 }
                 if (is_object($existingEvent)) {
                     // Check and modify existing event if modified since last update
                     if ($existingEvent->get('lastedit') <= $lastchange) {
                         // Event has been updated so lets just update all properties
                         $existingEvent->fromArray($event);
                         $existingEvent->save();
                         if ($this->loggingEnabled) {
                             $this->logEvent('feed', 'Update Event (' . $existingEvent->get('id') . ') for feed #' . $feed->get('id') . '\\n\\nEvent JSON:\\n' . json_encode($event));
                         }
                         $hadmodifications++;
                     }
                 } else {
                     // Create the newly found event from the feed
                     $feedEvent = $this->modx->newObject('mxCalendarEvents');
                     $feedEvent->fromArray($event);
                     $feedEvent->save();
                     if ($this->loggingEnabled) {
                         $this->logEvent('feed', 'New Event (' . $feedEvent->get('id') . ') for feed #' . $feed->get('id') . '\\n\\nEvent JSON:\\n' . json_encode($event));
                     }
                     $hadmodifications++;
                 }
             }
             //-- Update the feed next run time
             $nextTime = strtotime('+' . $feed->get('timerint') . ' ' . $feed->get('timermeasurement'));
             $feed->set('lastrunon', time());
             $feed->set('nextrunon', $nextTime);
             $feed->save();
             if ($hadmodifications) {
                 $this->logEvent('feed', 'Parsing feed #' . $feed->get('id') . ' had <strong>' . $hadmodifications . '</strong> event' . ($hadmodifications > 1 ? 's' : '') . ' added/updated [' . $feed->get('feed') . ']');
             } else {
                 $this->logEvent('feed', 'Parsing feed #' . $feed->get('id') . ' had no changes. [' . $feed->get('feed') . ']');
             }
         } else {
             //-- ==================== --//
             //-- Process the XML feed --//
             //-- ==================== --//
             $activeUrl = $feed->get('feed');
             $xmlEvents = file_get_contents($activeUrl);
             $events = new SimpleXMLElement($xmlEvents);
             $idx = 0;
             foreach ($events->event as $event) {
                 if (strtolower($event->timebegin) !== 'all day') {
                     $startDateTime = strtotime($event->date . ' ' . $event->timebegin);
                     $endDateTime = strtotime($event->date . ' ' . str_replace('- ', '', $event->timeend));
                 } else {
                     $startDateTime = strtotime($event->date . ' 00:00:00');
                     $endDateTime = strtotime($event->date . ' 23:59:59');
                 }
                 $lastchange = !empty($event->lastedit) ? $event->lastedit : time();
                 // Output for testing
                 $eventdata = array('title' => $event->title, 'description' => !empty($event->description) ? $event->description : '', 'location_name' => !empty($event->location) ? $event->location : '', 'startdate' => $startDateTime, 'enddate' => $endDateTime, 'source' => 'feed', 'lastedit' => $lastchange, 'feeds_id' => $feed->get('id'), 'feeds_uid' => !empty($event->eventid) ? $event->eventid : '', 'context' => '', 'categoryid' => $feed->get('defaultcategoryid'), 'createdon' => !empty($event->createDate) ? $event->createDate : time(), 'repeattype' => 0, 'repeaton' => '', 'repeatfrequency' => 0);
                 //-- Save the new event
                 if (!empty($event->eventid) && isset($event->eventid)) {
                     $q = $this->modx->newQuery('mxCalendarEvents');
                     $title = (string) $event->title;
                     $feeduid = (string) $event->eventid;
                     $q->where(array('mxCalendarEvents.title' => $title, 'mxCalendarEvents.feeds_id' => $feed->get('id'), 'mxCalendarEvents.feeds_uid' => $feeduid));
                     $q->prepare();
                     //echo 'SQL ['.$event->title.' '.$event->eventid.']: <br />'.$q->toSQL().'<br /><br />';
                     $existingEvent = $this->modx->getObject('mxCalendarEvents', $q);
                     //$existingEvent = $this->modx->getObject('mxCalendarEvents',array());
                 } else {
                     $existingEvent = false;
                 }
                 if (is_object($existingEvent)) {
                     // Check and modify existing event if modified since last update
                     if ($existingEvent->get('lastedit') <= $lastchange) {
                         // Event has been updated so lets just update all properties
                         $existingEvent->fromArray($eventdata);
                         $existingEvent->save();
                         if ($this->loggingEnabled) {
                             $this->logEvent('feed', 'Update Event (' . $existingEvent->get('id') . ')[' . $event->eventid . '] for feed #' . $feed->get('id') . '\\n\\nEvent JSON:\\n' . json_encode($event));
                         }
                         $hadmodifications++;
                     }
                 } else {
                     // Create the newly found event from the feed
                     $feedEvent = $this->modx->newObject('mxCalendarEvents');
                     $feedEvent->fromArray($eventdata);
                     $feedEvent->save();
                     if ($this->loggingEnabled) {
                         $this->logEvent('feed', 'New Event (' . $feedEvent->get('id') . ') for feed #' . $feed->get('id') . '\\n\\nEvent JSON:\\n' . json_encode($event));
                     }
                     $hadmodifications++;
                 }
                 //unset($event);
                 $idx++;
             }
             //-- Update the feed next run time
             $nextTime = strtotime('+' . $feed->get('timerint') . ' ' . $feed->get('timermeasurement'));
             $feed->set('lastrunon', time());
             $feed->set('nextrunon', $nextTime);
             $feed->save();
             if ($hadmodifications) {
                 $this->logEvent('feed', 'Parsing feed #' . $feed->get('id') . ' had <strong>' . $hadmodifications . '</strong> event' . ($hadmodifications > 1 ? 's' : '') . ' added/updated [' . $feed->get('feed') . ']');
             } else {
                 $this->logEvent('feed', 'Parsing feed #' . $feed->get('id') . ' had no changes. [' . $feed->get('feed') . ']');
             }
         }
     }
 }
Example #20
0
 public function import_ics_data($calendar_id, $run_deletes = false)
 {
     // -------------------------------------
     //	this has the potential to take a while
     // -------------------------------------
     set_time_limit(0);
     // -------------------------------------
     //	Get some basic info to use later
     // -------------------------------------
     $tmpl_exists = isset(ee()->TMPL) && is_object(ee()->TMPL);
     $cbasics = $this->data->calendar_basics();
     $cbasics = $cbasics[$calendar_id];
     $urls = $cbasics['ics_url'];
     if ($urls == '') {
         return FALSE;
     }
     $tz_offset = $cbasics['tz_offset'] != '' ? $cbasics['tz_offset'] : '0000';
     // -------------------------------------
     //	delete missing items from update?
     // -------------------------------------
     $delete = ($this->check_yes($this->preference('ics_update_delete_default')) or $tmpl_exists && $this->check_yes(ee()->TMPL->fetch_param('delete_missing')));
     /*
     
     		This shouldn't be happening because DST is only something that
     		would need to be applied when generating the users current local time.
     		If an event were at 7pm EST or EDT, it would still be at 7pm either way.
     		I hate DST.
     
     		if ($tz_offset != '0000' AND ee()->config->item('daylight_savings') == 'y')
     		{
     			$tz_offset += 100;
     		}
     */
     $channel_id = $this->data->channel_is_events_channel();
     $author_id = $cbasics['author_id'];
     // -------------------------------------
     //	Prepare the URLs
     // -------------------------------------
     if (!is_array($urls)) {
         $urls = explode("\n", $urls);
     }
     foreach ($urls as $k => $url) {
         $urls[$k] = trim($url);
     }
     // -------------------------------------
     //	Load iCalCreator
     // -------------------------------------
     if (!class_exists('vcalendar')) {
         require_once 'libraries/icalcreator/iCalcreator.class.php';
     }
     // -------------------------------------
     //	Load Calendar_datetime
     // -------------------------------------
     if (!class_exists('Calendar_datetime')) {
         require_once CALENDAR_PATH . 'calendar.datetime' . EXT;
     }
     $CDT = new Calendar_datetime();
     $CDT_end = new Calendar_datetime();
     // -------------------------------------
     //	Load Publish
     // -------------------------------------
     ee()->load->library('api');
     ee()->api->instantiate(array('channel_entries', 'channel_categories', 'channel_fields'));
     ee()->load->helper('url');
     ee()->api_channel_entries->assign_cat_parent = ee()->config->item('auto_assign_cat_parents') == 'n' ? FALSE : TRUE;
     // -------------------------------------
     //	Tell our extensions that we're running the icalendar import
     // -------------------------------------
     $this->cache['ical'] = TRUE;
     // -------------------------------------
     //	Get already-imported events
     // -------------------------------------
     $imported = $this->data->get_imported_events($calendar_id);
     $imported_not_found = !empty($imported) ? array_combine(array_keys($imported), array_keys($imported)) : array();
     // -------------------------------------
     //	Don't let EXT drop us early
     // -------------------------------------
     ee()->extensions->in_progress = '';
     // -------------------------------------
     //	Cycle through the URLs
     // -------------------------------------
     $errors = array();
     foreach ($urls as $url) {
         $ICAL = new vcalendar();
         $output = $this->fetch_url($url);
         //lets not do horrible things
         if (empty($output)) {
             continue;
         }
         $ICAL->parse($output);
         // -------------------------------------
         //	Iterate among the events
         // -------------------------------------
         while ($event = $ICAL->getComponent('vevent')) {
             // -------------------------------------
             //	Times
             // -------------------------------------
             $hour = isset($event->dtstart['value']['hour']) ? $event->dtstart['value']['hour'] : 00;
             $minute = isset($event->dtstart['value']['min']) ? $event->dtstart['value']['min'] : 00;
             $end_hour = isset($event->dtend['value']['hour']) ? $event->dtend['value']['hour'] : $hour;
             $end_minute = isset($event->dtend['value']['min']) ? $event->dtend['value']['min'] : $minute;
             // -------------------------------------
             //	Last-modified date
             // -------------------------------------
             if (isset($event->lastmodified['value'])) {
                 $lm_date = $event->lastmodified['value']['year'] . $event->lastmodified['value']['month'] . $event->lastmodified['value']['day'] . $event->lastmodified['value']['hour'] . $event->lastmodified['value']['min'];
             } elseif (isset($event->dtstamp['value'])) {
                 $lm_date = $event->dtstamp['value']['year'] . $event->dtstamp['value']['month'] . $event->dtstamp['value']['day'] . $event->dtstamp['value']['hour'] . $event->dtstamp['value']['min'];
             } else {
                 $lm_date = $event->created['value']['year'] . $event->created['value']['month'] . $event->created['value']['day'] . $event->created['value']['hour'] . $event->created['value']['min'];
             }
             // -------------------------------------
             //	Does this event already exist? Do we need to update?
             // -------------------------------------
             if (isset($imported[$event->uid['value']])) {
                 //for what needs to be deleted
                 unset($imported_not_found[$event->uid['value']]);
                 // -------------------------------------
                 //	Has the event been updated? No reason
                 //	to do any work if it's the same old stuff.
                 // -------------------------------------
                 if ($lm_date == $imported[$event->uid['value']]['last_mod']) {
                     continue;
                 }
                 $entry_id = $imported[$event->uid['value']]['entry_id'];
             } else {
                 $entry_id = '';
             }
             // -------------------------------------
             //	Adjust CDT
             // -------------------------------------
             $CDT->change_datetime($event->dtstart['value']['year'], $event->dtstart['value']['month'], $event->dtstart['value']['day'], $hour, $minute);
             if (isset($event->dtend['value'])) {
                 $CDT_end->change_datetime($event->dtend['value']['year'], $event->dtend['value']['month'], $event->dtend['value']['day'], $end_hour, $end_minute);
             } else {
                 $CDT_end->change_ymd($CDT->ymd);
                 $CDT_end->change_time($end_hour, $end_minute);
             }
             // -------------------------------------
             //	Adjust to the correct timezone for thie calendar
             // -------------------------------------
             if (!isset($event->dtstart['params']['TZID']) or $event->dtstart['params']['TZID'] == '') {
                 if (isset($event->dtstart['value']['hour'])) {
                     $CDT->add_time($tz_offset);
                     $CDT_end->add_time($tz_offset);
                 } else {
                     $CDT_end->add_day(-1);
                 }
             }
             // -------------------------------------
             //	Variableification
             // -------------------------------------
             $title = isset($event->summary['value']) ? $event->summary['value'] : lang('no_title');
             $summary = (isset($event->description) and is_array($event->description) and isset($event->description[0]['value'])) ? $event->description[0]['value'] : '';
             $location = isset($event->location['value']) ? $event->location['value'] : '';
             $rules = $this->ical_rule_to_calendar_rule($event->rrule);
             $exceptions = array('date' => array());
             if (mb_strlen($title) > 100) {
                 $title = substr($title, 0, 100);
             }
             if (is_array($event->exdate) and !empty($event->exdate)) {
                 $exceptions = $this->ical_exdate_to_calendar_exception($event->exdate);
             }
             $recurs = (is_array($event->rrule) and !empty($event->rrule)) ? 'y' : 'n';
             // -------------------------------------
             //	Fix some linebreak problems
             // -------------------------------------
             $summary = str_replace(array("\r", "\n"), '', $summary);
             $summary = str_replace('\\n', "\n", $summary);
             // -------------------------------------
             //	Set up $_POST
             // -------------------------------------
             $prefix = CALENDAR_EVENTS_FIELD_PREFIX;
             $sum_fid = $this->data->get_field_id($prefix . 'summary');
             $loc_fid = $this->data->get_field_id($prefix . 'location');
             $dao_fid = $this->data->get_field_id($prefix . 'dates_and_options');
             //lets not be buttwipes
             //will restore old post later
             $old_POST = $_POST;
             //must use $_POST here because many fieldtypoes use their own
             //processing via POST and ignore incoming data
             $_POST = $post_data = array('site_id' => $this->data->get_site_id(), 'author_id' => $author_id, 'entry_id' => $entry_id, 'channel_id' => $channel_id, 'status' => 'open', 'entry_date' => ee()->localize->now - 3600 * 24 * 2, 'title' => $title, 'url_title' => url_title($title), 'calendar_id' => $calendar_id, 'field_id_' . $sum_fid => $summary, 'field_id_' . $loc_fid => $location, 'field_id_' . $dao_fid => $calendar_id, 'rule_id' => array(), 'start_date' => array($CDT->ymd), 'start_time' => array($CDT->hour . $CDT->minute), 'end_date' => array($CDT_end->ymd), 'end_time' => array($CDT_end->hour . $CDT_end->minute), 'all_day' => !isset($event->dtstart['value']['hour']) ? 'y' : 'n', 'rule_type' => $rules['rule_type'], 'repeat_years' => $rules['repeat_years'], 'repeat_months' => $rules['repeat_months'], 'repeat_weeks' => $rules['repeat_weeks'], 'repeat_days' => $rules['repeat_days'], 'days_of_week' => $rules['days_of_week'], 'relative_dow' => $rules['relative_dow'], 'days_of_month' => $rules['days_of_month'], 'months_of_year' => $rules['months_of_year'], 'end_by' => $rules['end_by'], 'end_after' => $rules['end_after'], 'occurrences' => $exceptions, 'expiration_date' => '', 'comment_expiration_date' => '', 'allow_comments' => 'n');
             //--------------------------------------------
             //	Check for custom field group
             //--------------------------------------------
             ee()->api_channel_fields->setup_entry_settings($channel_id, $post_data);
             if ($entry_id) {
                 // -------------------------------------
                 //	get old data and merge
                 // -------------------------------------
                 ee()->load->model('channel_entries_model');
                 //if you don't give it the channel_id it
                 //only selects entry, channel, and author id. lol wtf?
                 $old_data_q = ee()->channel_entries_model->get_entry($entry_id, $channel_id);
                 if ($old_data_q->num_rows() > 0) {
                     $old_data = $old_data_q->row_array();
                     ee()->load->library('calendar_ics_field_update');
                     //prep special cases
                     $old_data = ee()->calendar_ics_field_update->run_prep_fields($old_data);
                     //need to let our new data override old
                     $_POST = $post_data = array_merge($old_data, $post_data);
                 }
                 //fire update and cross fingers
                 $result = ee()->api_channel_entries->update_entry($entry_id, $post_data);
             } else {
                 //now we can do the new entry
                 $result = ee()->api_channel_entries->submit_new_entry($channel_id, $post_data);
             }
             if ($result === FALSE) {
                 //restore old post
                 $_POST = $old_POST;
                 $errors[] = ee()->api_channel_entries->errors;
                 continue;
             }
             // -------------------------------------
             //	Update the imports table
             // -------------------------------------
             /*if (isset($this->cache['ical_event_id']))
             		{*/
             $data = array('calendar_id' => $calendar_id, 'event_id' => $this->cache['ical_event_id'], 'entry_id' => $this->cache['ical_entry_id'], 'uid' => $event->uid['value'], 'last_mod' => $lm_date);
             if ($entry_id != '') {
                 $data['import_id'] = $imported[$event->uid['value']]['import_id'];
                 $this->data->update_imported_event($data);
             } else {
                 //$data['import_id'] = '0';
                 $this->data->add_imported_event($data);
             }
             /*}*/
             //restore old post
             $_POST = $old_POST;
         }
         //END while ($event = $ICAL->getComponent('vevent'))
     }
     //END 	foreach ($urls as $url)
     // -------------------------------------
     //	items to delete
     // -------------------------------------
     if ($delete) {
         $deleted_ids = array();
         foreach ($imported_not_found as $uid => $value) {
             $deleted_ids[] = $imported[$uid]['entry_id'];
         }
         if (!empty($deleted_ids)) {
             ee()->api_channel_entries->delete_entry($deleted_ids);
         }
     }
     $this->data->update_ics_updated($calendar_id);
     ee()->extensions->end_script = FALSE;
     ee()->extensions->in_progress = 'entry_submission_end';
     return TRUE;
 }
Example #21
0
 /**
  * function iCal2xls
  *
  * Convert iCal file to xls format and send file to browser (default) or save xls file to disk
  * Definition iCal  : rcf2445, http://kigkonsult.se/downloads/index.php#rfc
  * Using iCalcreator: http://kigkonsult.se/downloads/index.php#iCalcreator
  * Based on PEAR Spreadsheet_Excel_Writer-0.9.1 (and OLE-1.0.0RC1)
  * to be installed as
  * pear install channel://pear.php.net/OLE-1.0.0RC1
  * pear install channel://pear.php.net/Spreadsheet_Excel_Writer-0.9.1
  *
  * @author Kjell-Inge Gustafsson <*****@*****.**>
  * @since  3.0 - 2011-12-21
  * @param  object $calendar opt. iCalcreator calendar instance
  * @return bool   returns FALSE when error
  */
 public function iCal2xls($calendar = FALSE)
 {
     $timeexec = array('start' => microtime(TRUE));
     if ($this->log) {
         $this->log->log(' ********** START **********', PEAR_LOG_NOTICE);
     }
     /** check input/output directory and filename */
     $inputdirFile = $outputdirFile = '';
     $inputFileParts = $outputFileParts = array();
     $remoteInput = $remoteOutput = FALSE;
     if ($calendar) {
         $inputdirFile = $calendar->getConfig('DIRFILE');
         $inputFileParts = pathinfo($inputdirFile);
         $inputFileParts['dirname'] = realpath($inputFileParts['dirname']);
         if ($this->log) {
             $this->log->log('fileParts:' . var_export($inputFileParts, TRUE), PEAR_LOG_DEBUG);
         }
     } elseif (FALSE === $this->_fixIO('input', 'ics', $inputdirFile, $inputFileParts, $remoteInput)) {
         if ($this->log) {
             $this->log->log(number_format(microtime(TRUE) - $timeexec['start'], 5) . ' sec', PEAR_LOG_ERR);
             $this->log->log("ERROR 2, invalid input ({$inputdirFile})", PEAR_LOG_ERR);
             $this->log->flush();
         }
         return FALSE;
     }
     if (FALSE === $this->_fixIO('output', FALSE, $outputdirFile, $outputFileParts, $remoteOutput)) {
         if (FALSE === $this->setConfig('outputfilename', $inputFileParts['filename'] . '.xls')) {
             if ($this->log) {
                 $this->log->log(number_format(microtime(TRUE) - $timeexec['start'], 5) . ' sec', PEAR_LOG_ERR);
                 $this->log->log('ERROR 3, invalid output (' . $inputFileParts['filename'] . '.csv)', PEAR_LOG_ERR);
                 $this->log->flush();
             }
             return FALSE;
         }
         $outputdirFile = $this->getConfig('outputdirectory') . DIRECTORY_SEPARATOR . $inputFileParts['filename'] . '.xls';
         $outputFileParts = pathinfo($outputdirFile);
         if ($this->log) {
             $this->log->log("output set to '{$outputdirFile}'", PEAR_LOG_INFO);
         }
     }
     if ($this->log) {
         $this->log->log("INPUT..FILE:{$inputdirFile}", PEAR_LOG_NOTICE);
         $this->log->log("OUTPUT.FILE:{$outputdirFile}", PEAR_LOG_NOTICE);
     }
     $save = $this->getConfig('save');
     if ($calendar) {
         $calnl = $calendar->getConfig('nl');
     } else {
         /** iCalcreator set config, read and parse input iCal file */
         $calendar = new vcalendar();
         if (FALSE !== ($unique_id = $this->getConfig('unique_id'))) {
             $calendar->setConfig('unique_id', $unique_id);
         }
         $calnl = $calendar->getConfig('nl');
         if ($remoteInput) {
             if (FALSE === $calendar->setConfig('url', $inputdirFile)) {
                 if ($this->log) {
                     $this->log->log("ERROR 3 INPUT FILE:'{$inputdirFile}' iCalcreator: invalid url", 3);
                 }
                 return FALSE;
             }
         } else {
             if (FALSE === $calendar->setConfig('directory', $inputFileParts['dirname'])) {
                 if ($this->log) {
                     $this->log->log("ERROR 4 INPUT FILE:'{$inputdirFile}' iCalcreator: invalid directory: '" . $inputFileParts['dirname'] . "'", 3);
                     $this->log->flush();
                 }
                 return FALSE;
             }
             if (FALSE === $calendar->setConfig('filename', $inputFileParts['basename'])) {
                 if ($this->log) {
                     $this->log->log("ERROR 5 INPUT FILE:'{$inputdirFile}' iCalcreator: invalid filename: '" . $inputFileParts['basename'] . "'", 3);
                     $this->log->flush();
                 }
                 return FALSE;
             }
         }
         if (FALSE === $calendar->parse()) {
             if ($this->log) {
                 $this->log->log("ERROR 6 INPUT FILE:'{$inputdirFile}' iCalcreator parse error", 3);
                 $this->log->flush();
             }
             return FALSE;
         }
     }
     // end if( !$calendar )
     $timeexec['fileOk'] = microtime(TRUE);
     if (!function_exists('iCaldate2timestamp')) {
         function iCaldate2timestamp($d)
         {
             if (6 > count($d)) {
                 return mktime(0, 0, 0, $d['month'], $d['day'], $d['year']);
             } else {
                 return mktime($d['hour'], $d['min'], $d['sec'], $d['month'], $d['day'], $d['year']);
             }
         }
     }
     if (!function_exists('fixiCalString')) {
         function fixiCalString($s)
         {
             global $calnl;
             $s = str_replace('\\,', ',', $s);
             $s = str_replace('\\;', ';', $s);
             $s = str_replace('\\n ', chr(10), $s);
             $s = str_replace('\\\\', '\\', $s);
             $s = str_replace("{$calnl}", chr(10), $s);
             return utf8_decode($s);
         }
     }
     /** Creating a workbook */
     require_once 'Spreadsheet/Excel/Writer.php';
     if ($save) {
         $workbook = new Spreadsheet_Excel_Writer($outputdirFile);
     } else {
         $workbook = new Spreadsheet_Excel_Writer();
     }
     $workbook->setVersion(8);
     // Use Excel97/2000 Format
     /** opt. sending HTTP headers */
     if (!$save) {
         $workbook->send($outputFileParts['basename']);
     }
     /** Creating a worksheet */
     $worksheet =& $workbook->addWorksheet($inputFileParts['filename']);
     /** fix formats */
     $format_bold =& $workbook->addFormat();
     $format_bold->setBold();
     $timeexec['wrkbkOk'] = microtime(TRUE);
     /** info rows */
     $row = -1;
     $worksheet->writeString(++$row, 0, 'kigkonsult.se', $format_bold);
     $worksheet->writeString($row, 1, ICALCREATOR_VERSION, $format_bold);
     $worksheet->writeString($row, 2, ICALCNVVERSION . ' iCal2xls', $format_bold);
     $worksheet->writeString($row, 3, date('Y-m-d H:i:s'));
     $filename = $remoteInput ? $inputdirFile : $inputFileParts['basename'];
     $worksheet->writeString(++$row, 0, 'iCal input', $format_bold);
     $worksheet->writeString($row, 1, $filename);
     $worksheet->writeString($row, 2, 'xls output', $format_bold);
     $worksheet->writeString($row, 3, $outputFileParts['basename']);
     if (FALSE !== ($prop = $calendar->getProperty('CALSCALE'))) {
         $worksheet->writeString(++$row, 0, 'CALSCALE', $format_bold);
         $worksheet->writeString($row, 1, $prop);
     }
     if (FALSE !== ($prop = $calendar->getProperty('METHOD'))) {
         $worksheet->writeString(++$row, 0, 'METHOD', $format_bold);
         $worksheet->writeString($row, 1, $prop);
     }
     while (FALSE !== ($xprop = $calendar->getProperty())) {
         $worksheet->writeString(++$row, 0, $xprop[0], $format_bold);
         $worksheet->writeString($row, 1, $xprop[1]);
     }
     $timeexec['infoOk'] = microtime(TRUE);
     if (FALSE === ($propsToSkip = $this->getConfig('skip'))) {
         $propsToSkip = array();
     }
     /** fix property order list */
     $proporderOrg = array();
     for ($key = 2; $key < 99; $key++) {
         if (FALSE !== ($value = $this->getConfig($key))) {
             $proporderOrg[$value] = $key;
             if ($this->log) {
                 $this->log->log("{$value} in column {$key}", 7);
             }
         }
     }
     /** fix vtimezone property order list */
     $proporder = $proporderOrg;
     $proporder['TYPE'] = 0;
     $proporder['ORDER'] = 1;
     $props = array('TZID', 'LAST-MODIFIED', 'TZURL', 'DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'COMMENT', 'RRULE', 'RDATE', 'TZNAME');
     $pix = 2;
     foreach ($props as $prop) {
         if (isset($proporder[$prop])) {
             continue;
         }
         if (in_array($prop, $propsToSkip)) {
             if ($this->log) {
                 $this->log->log("'{$prop}' removed from output", 7);
             }
             continue;
         }
         while (in_array($pix, $proporder)) {
             $pix++;
         }
         $proporder[$prop] = $pix++;
     }
     /** remove unused properties from and add x-props to property order list */
     $maxpropix = 11;
     if ($maxpropix != count($proporder) - 1) {
         $maxpropix = count($proporder) - 1;
     }
     $compsinfo = $calendar->getConfig('compsinfo');
     $potmp = array();
     $potmp[0] = 'TYPE';
     $potmp[1] = 'ORDER';
     foreach ($compsinfo as $cix => $compinfo) {
         if ('vtimezone' != $compinfo['type']) {
             continue;
         }
         $comp = $calendar->getComponent($compinfo['ordno']);
         foreach ($compinfo['props'] as $propName => $propcnt) {
             if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                 $potmp[$proporder[$propName]] = $propName;
             } elseif ('X-PROP' == $propName) {
                 while ($xprop = $comp->getProperty()) {
                     if (!in_array($xprop[0], $potmp)) {
                         $maxpropix += 1;
                         $potmp[$maxpropix] = $xprop[0];
                     }
                     // end if
                 }
                 // end while xprop
             }
             // end X-PROP
         }
         // end $compinfo['props']
         if (isset($compinfo['sub'])) {
             foreach ($compinfo['sub'] as $compinfo2) {
                 foreach ($compinfo2['props'] as $propName => $propcnt) {
                     if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                         $potmp[$proporder[$propName]] = $propName;
                     } elseif ('X-PROP' == $propName) {
                         $scomp = $comp->getComponent($compinfo2['ordno']);
                         while ($xprop = $scomp->getProperty()) {
                             if (!in_array($xprop[0], $potmp)) {
                                 $maxpropix += 1;
                                 $potmp[$maxpropix] = $xprop[0];
                             }
                             // end if
                         }
                         // end while xprop
                     }
                     // end X-PROP
                 }
                 // end $compinfo['sub']['props']
             }
             // end foreach( $compinfo['sub']
         }
         // end if( isset( $compinfo['sub']
     }
     // end foreach compinfo - vtimezone
     ksort($potmp, SORT_NUMERIC);
     $proporder = array_flip(array_values($potmp));
     if ($this->log) {
         $this->log->log("timezone proporder=" . implode(',', array_flip($proporder)), 7);
     }
     /** create vtimezone info */
     if (2 < count($proporder)) {
         $row += 1;
         /** create vtimezone header row */
         foreach ($proporder as $propName => $col) {
             if (isset($this->config[$propName])) {
                 $worksheet->writeString($row, $col, $this->config[$propName], $format_bold);
                 // check map of userfriendly name to iCal property name
                 if ($this->log) {
                     $this->log->log("header row, col={$col}: {$propName}, replaced by " . $this->config[$propName], 7);
                 }
             } else {
                 $worksheet->writeString($row, $col, $propName, $format_bold);
             }
         }
         $allowedProps = array('VTIMEZONE' => array('TZID', 'LAST-MODIFIED', 'TZURL'), 'STANDARD' => array('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'COMMENT', 'RDATE', 'RRULE', 'TZNAME'), 'DAYLIGHT' => array('DTSTART', 'TZOFFSETTO', 'TZOFFSETFROM', 'COMMENT', 'RDATE', 'RRULE', 'TZNAME'));
         /** create vtimezone data rows */
         foreach ($compsinfo as $cix => $compinfo) {
             if ('vtimezone' != $compinfo['type']) {
                 continue;
             }
             $row += 1;
             $worksheet->writeString($row, $proporder['TYPE'], $compinfo['type']);
             $worksheet->writeString($row, $proporder['ORDER'], $compinfo['ordno']);
             $comp = $calendar->getComponent($compinfo['ordno']);
             foreach ($proporder as $propName => $col) {
                 if ('TYPE' == $propName || 'ORDER' == $propName) {
                     continue;
                 }
                 if ('X-' == substr($propName, 0, 2)) {
                     continue;
                 }
                 if (!in_array($propName, $allowedProps['VTIMEZONE'])) {
                     // check if component allows property
                     if ($this->log) {
                         $this->log->log("ERROR 7, INPUT FILE:'{$inputdirFile}' iCalcreator: unvalid property for component '" . $compinfo['type'] . "': '{$propName}'", PEAR_LOG_INFO);
                     }
                     continue;
                 }
                 if (isset($compinfo['props'][$propName])) {
                     if ('LAST-MODIFIED' == $propName) {
                         $fcn = 'createLastModified';
                     } else {
                         $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                     }
                     if (!method_exists($comp, $fcn)) {
                         if ($this->log) {
                             $this->log->log('ERROR 8 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')', PEAR_LOG_INFO);
                         }
                         continue;
                     }
                     $output = str_replace("{$calnl} ", '', rtrim($comp->{$fcn}()));
                     $output = str_replace($propName . ';', '', $output);
                     $output = str_replace($propName . ':', '', $output);
                     $worksheet->writeString($row, $proporder[$propName], fixiCalString($output));
                 }
             }
             // end foreach( $proporder
             if (isset($compinfo['props']['X-PROP'])) {
                 while ($xprop = $comp->getProperty()) {
                     $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                     $worksheet->writeString($row, $proporder[$xprop[0]], fixiCalString($output));
                 }
             }
             if (isset($compinfo['sub'])) {
                 foreach ($compinfo['sub'] as $compinfo2) {
                     $row += 1;
                     $worksheet->writeString($row, $proporder['TYPE'], $compinfo2['type']);
                     $worksheet->writeString($row, $proporder['ORDER'], $compinfo['ordno'] . ':' . $compinfo2['ordno']);
                     $scomp = $comp->getComponent($compinfo2['ordno']);
                     foreach ($proporder as $propName => $col) {
                         if ('TYPE' == $propName || 'ORDER' == $propName) {
                             continue;
                         }
                         if ('X-' == substr($propName, 0, 2)) {
                             continue;
                         }
                         if (!in_array($propName, $allowedProps[strtoupper($compinfo2['type'])])) {
                             // check if component allows property
                             if ($this->log) {
                                 $this->log->log("ERROR 9, INPUT FILE:'{$inputdirFile}' iCalcreator: unvalid property for component '" . $compinfo2['type'] . "': '{$propName}'", PEAR_LOG_INFO);
                             }
                             continue;
                         }
                         if (isset($compinfo2['props'][$propName])) {
                             $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                             if (!method_exists($scomp, $fcn)) {
                                 if ($this->log) {
                                     $this->log->log('ERROR 10 INPUT FILE:"' . $filename . '" iCalcreator: unknown property: "' . $propName . '" (' . $fcn . ')', PEAR_LOG_INFO);
                                 }
                                 continue;
                             }
                             $output = str_replace("{$calnl} ", '', rtrim($scomp->{$fcn}()));
                             $output = str_replace($propName . ';', '', $output);
                             $output = str_replace($propName . ':', '', $output);
                             $worksheet->writeString($row, $proporder[$propName], fixiCalString($output));
                         }
                     }
                     // end foreach( $proporder
                     if (isset($compinfo2['props']['X-PROP'])) {
                         while ($xprop = $scomp->getProperty()) {
                             $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                             $worksheet->writeString($row, $proporder[$xprop[0]], fixiCalString($output));
                         }
                     }
                 }
                 // end foreach( $compinfo['sub']
             }
             // end if( isset( $compinfo['sub']['props'] ))
         }
         // end foreach
     }
     // end vtimezone
     $timeexec['zoneOk'] = microtime(TRUE);
     $maxColCount = count($proporder);
     /** fix property order list */
     $proporder = $proporderOrg;
     $proporder['TYPE'] = 0;
     $proporder['ORDER'] = 1;
     $props = array('UID', 'DTSTAMP', 'SUMMARY', 'DTSTART', 'DURATION', 'DTEND', 'DUE', 'RRULE', 'RDATE', 'EXRULE', 'EXDATE', 'DESCRIPTION', 'CATEGORIES', 'ORGANIZER', 'LOCATION', 'RESOURCES', 'CONTACT', 'URL', 'COMMENT', 'PRIORITY', 'ATTENDEE', 'CLASS', 'TRANSP', 'SEQUENCE', 'STATUS', 'COMPLETED', 'CREATED', 'LAST-MODIFIED', 'ACTION', 'TRIGGER', 'REPEAT', 'ATTACH', 'FREEBUSY', 'RELATED-TO', 'REQUEST-STATUS', 'GEO', 'PERCENT-COMPLETE', 'RECURRENCE-ID');
     $pix = 2;
     foreach ($props as $prop) {
         if (isset($proporder[$prop])) {
             continue;
         }
         if (in_array($prop, $propsToSkip)) {
             if ($this->log) {
                 $this->log->log("'{$prop}' removed from output", 7);
             }
             continue;
         }
         while (in_array($pix, $proporder)) {
             $pix++;
         }
         $proporder[$prop] = $pix++;
     }
     /** remove unused properties from and add x-props to property order list */
     if ($maxpropix < count($proporder) - 1) {
         $maxpropix = count($proporder) - 1;
     }
     $potmp = array();
     $potmp[0] = 'TYPE';
     $potmp[1] = 'ORDER';
     //  $potmp[2]                   =  'UID';
     foreach ($compsinfo as $cix => $compinfo) {
         if ('vtimezone' == $compinfo['type']) {
             continue;
         }
         foreach ($compinfo['props'] as $propName => $propcnt) {
             if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                 $potmp[$proporder[$propName]] = $propName;
             } elseif ('X-PROP' == $propName) {
                 $comp = $calendar->getComponent($compinfo['ordno']);
                 while ($xprop = $comp->getProperty()) {
                     if (!in_array($xprop[0], $potmp)) {
                         $maxpropix += 1;
                         $potmp[$maxpropix] = $xprop[0];
                     }
                     // end if
                 }
                 // while( $xprop
             }
             // end elseif( 'X-PROP'
         }
         // end foreach( $compinfo['props']
         if (isset($compinfo['sub'])) {
             foreach ($compinfo['sub'] as $compinfo2) {
                 foreach ($compinfo2['props'] as $propName => $propcnt) {
                     if (!in_array($propName, $potmp) && isset($proporder[$propName])) {
                         $potmp[$proporder[$propName]] = $propName;
                     } elseif ('X-PROP' == $propName) {
                         $scomp = $comp->getComponent($compinfo2['ordno']);
                         while ($xprop = $scomp->getProperty()) {
                             if (!in_array($xprop[0], $potmp)) {
                                 $maxpropix += 1;
                                 $potmp[$maxpropix] = $xprop[0];
                             }
                             // end if
                         }
                         // end while xprop
                     }
                     // end X-PROP
                 }
                 // end $compinfo['sub']['props']
             }
             // end foreach( $compinfo['sub']
         }
         // end if( isset( $compinfo['sub']
     }
     ksort($potmp, SORT_NUMERIC);
     $proporder = array_flip(array_values($potmp));
     if ($this->log) {
         $this->log->log("comp proporder=" . implode(',', array_flip($proporder)), 7);
     }
     if ($maxColCount < count($proporder)) {
         $maxColCount = count($proporder);
     }
     /** create header row */
     $row += 1;
     foreach ($proporder as $propName => $col) {
         if (isset($this->config[$propName])) {
             $worksheet->writeString($row, $col, $this->config[$propName], $format_bold);
             // check map of userfriendly name to iCal property name
             if ($this->log) {
                 $this->log->log("header row, col={$col}: {$propName}, replaced by " . $this->config[$propName], 7);
             }
         } else {
             $worksheet->writeString($row, $col, $propName, $format_bold);
         }
     }
     $allowedProps = array('VEVENT' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTEND', 'DTSTAMP', 'DTSTART', 'DURATION', 'EXDATE', 'RXRULE', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PRIORITY', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'TRANSP', 'UID', 'URL'), 'VTODO' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'COMPLETED', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART', 'DUE', 'DURATION', 'EXDATE', 'EXRULE', 'GEO', 'LAST-MODIFIED', 'LOCATION', 'ORGANIZER', 'PERCENT', 'PRIORITY', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL'), 'VJOURNAL' => array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'CLASS', 'COMMENT', 'CONTACT', 'CREATED', 'DESCRIPTION', 'DTSTAMP', 'DTSTART', 'EXDATE', 'EXRULE', 'LAST-MODIFIED', 'ORGANIZER', 'RDATE', 'RECURRENCE-ID', 'RELATED-TO', 'RRULE', 'REQUEST-STATUS', 'SEQUENCE', 'STATUS', 'SUMMARY', 'UID', 'URL'), 'VFREEBUSY' => array('ATTENDEE', 'COMMENT', 'CONTACT', 'DTEND', 'DTSTAMP', 'DTSTART', 'DURATION', 'FREEBUSY', 'ORGANIZER', 'UID', 'URL'), 'VALARM' => array('ACTION', 'ATTACH', 'ATTENDEE', 'DESCRIPTION', 'DURATION', 'REPEAT', 'SUMMARY', 'TRIGGER'));
     /** create data rows */
     foreach ($compsinfo as $cix => $compinfo) {
         if ('vtimezone' == $compinfo['type']) {
             continue;
         }
         $row += 1;
         $worksheet->writeString($row, $proporder['TYPE'], $compinfo['type']);
         $worksheet->writeString($row, $proporder['ORDER'], $compinfo['ordno']);
         //    $worksheet->write(         $row, $proporder['UID'],   $compinfo['uid'] );
         $comp = $calendar->getComponent($compinfo['ordno']);
         foreach ($proporder as $propName => $col) {
             if ('TYPE' == $propName || 'ORDER' == $propName) {
                 continue;
             }
             if ('X-' == substr($propName, 0, 2)) {
                 continue;
             }
             if (!in_array($propName, $allowedProps[strtoupper($compinfo['type'])])) {
                 // check if component allows property
                 if ($this->log) {
                     $this->log->log("ERROR 11, INPUT FILE:'{$inputdirFile}' iCalcreator: unvalid property for component '" . $compinfo['type'] . "': '{$propName}'", PEAR_LOG_INFO);
                 }
                 continue;
             }
             if (isset($compinfo['props'][$propName])) {
                 switch ($propName) {
                     case 'LAST-MODIFIED':
                         $fcn = 'createLastModified';
                         break;
                     case 'RECURRENCE-ID':
                         $fcn = 'createRecurrenceid';
                         break;
                     case 'RELATED-TO':
                         $fcn = 'createRelatedTo';
                         break;
                     case 'REQUEST-STATUS':
                         $fcn = 'createRequestStatus';
                         break;
                     case 'PERCENT-COMPLETE':
                         $fcn = 'createPercentComplete';
                         break;
                     default:
                         $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                 }
                 if (!method_exists($comp, $fcn)) {
                     if ($this->log) {
                         $this->log->log("ERROR 12 INPUT FILE:'{$filename}' iCalcreator: unknown property: '{$propName}' ({$fcn})", PEAR_LOG_INFO);
                     }
                     continue;
                 }
                 $output = str_replace("{$calnl} ", '', rtrim($comp->{$fcn}()));
                 $output = str_replace($propName . ';', '', $output);
                 $output = str_replace($propName . ':', '', $output);
                 $worksheet->writeString($row, $proporder[$propName], fixiCalString($output));
             }
         }
         // end foreach( $proporder
         if (isset($compinfo['props']['X-PROP'])) {
             while ($xprop = $comp->getProperty()) {
                 $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                 $worksheet->writeString($row, $proporder[$xprop[0]], fixiCalString($output));
             }
         }
         if (isset($compinfo['sub'])) {
             foreach ($compinfo['sub'] as $compinfo2) {
                 $row += 1;
                 $worksheet->writeString($row, $proporder['TYPE'], $compinfo2['type']);
                 $worksheet->writeString($row, $proporder['ORDER'], $compinfo['ordno'] . ':' . $compinfo2['ordno']);
                 $scomp = $comp->getComponent($compinfo2['ordno']);
                 foreach ($proporder as $propName => $col) {
                     if ('TYPE' == $propName || 'ORDER' == $propName) {
                         continue;
                     }
                     if ('X-' == substr($propName, 0, 2)) {
                         continue;
                     }
                     if (!in_array($propName, $allowedProps[strtoupper($compinfo2['type'])])) {
                         // check if component allows property
                         if ($this->log) {
                             $this->log->log("ERROR 13, INPUT FILE:'{$inputdirFile}' iCalcreator: unvalid property for component '" . $compinfo2['type'] . "': '{$propName}'", PEAR_LOG_INFO);
                         }
                         continue;
                     }
                     if (isset($compinfo2['props'][$propName])) {
                         $fcn = 'create' . strtoupper(substr($propName, 0, 1)) . strtolower(substr($propName, 1));
                         if (!method_exists($scomp, $fcn)) {
                             if ($this->log) {
                                 $this->log->log("ERROR 14 INPUT FILE:'{$filename}' iCalcreator: unknown property: '{$propName}' ({$fcn})", PEAR_LOG_INFO);
                             }
                             continue;
                         }
                         $output = str_replace("{$calnl} ", '', rtrim($scomp->{$fcn}()));
                         $output = str_replace($propName . ';', '', $output);
                         $output = str_replace($propName . ':', '', $output);
                         $worksheet->writeString($row, $proporder[$propName], fixiCalString($output));
                     }
                     // end if( isset( $compinfo2['props'][$propName]
                 }
                 // end foreach( $proporder
                 if (isset($compinfo2['props']['X-PROP'])) {
                     while ($xprop = $scomp->getProperty()) {
                         $output = str_replace("{$calnl} ", '', rtrim($xprop[1]));
                         $output = str_replace('\\n ', chr(10), $output);
                         $worksheet->writeString($row, $proporder[$xprop[0]], fixiCalString($output));
                     }
                 }
                 // end if( isset( $compinfo2['props']['X-PROP']
             }
             // end foreach( $compinfo['sub']
         }
         // end if( isset( $compinfo['sub']
     }
     // foreach( $compsinfo as
     if ($this->log) {
         $timeexec['exit'] = microtime(TRUE);
         $msg = "'{$filename}'";
         $msg .= ' fileOk:' . number_format($timeexec['fileOk'] - $timeexec['start'], 5);
         $msg .= ' wrkbkOk:' . number_format($timeexec['wrkbkOk'] - $timeexec['fileOk'], 5);
         $msg .= ' infoOk:' . number_format($timeexec['infoOk'] - $timeexec['wrkbkOk'], 5);
         $msg .= ' zoneOk:' . number_format($timeexec['zoneOk'] - $timeexec['infoOk'], 5);
         $msg .= ' compOk:' . number_format($timeexec['exit'] - $timeexec['zoneOk'], 5);
         $msg .= ' total:' . number_format($timeexec['exit'] - $timeexec['start'], 5) . 'sec';
         $msg .= ', ' . ($row + 1) . " rows, {$maxColCount} cols";
         $this->log->log($msg, PEAR_LOG_DEBUG);
         $msg = "'{$filename}' (" . count($compsinfo) . ' components) start:' . date('H:i:s', $timeexec['start']);
         $msg .= ' total:' . number_format($timeexec['exit'] - $timeexec['start'], 5) . 'sec';
         if ($save) {
             $msg .= " saved as '{$outputdirFile}'";
         } else {
             $msg .= " redirected as '" . $outputFileParts['basename'] . "'";
         }
         $this->log->log($msg, PEAR_LOG_NOTICE);
     }
     /** Close and, opt., send the file */
     if ($this->log) {
         $this->log->flush();
     }
     $workbook->close();
     return TRUE;
 }
Example #22
0
$v = new vcalendar($config);
$v->parse();
$timezone_calendar = $v->getProperty('X-WR-TIMEZONE');
$export_timezone = false;
if ($timezone_calendar[1]) {
    $export_timezone = $timezone_calendar[1];
}
$event_calendar_times = elgg_get_plugin_setting('times', 'event_calendar');
$event_calendar_region_display = elgg_get_plugin_setting('region_display', 'event_calendar');
$event_calendar_type_display = elgg_get_plugin_setting('type_display', 'event_calendar');
$event_calendar_more_required = elgg_get_plugin_setting('more_required', 'event_calendar');
// for now, turn off the more_required setting during import
elgg_set_plugin_setting('more_required', 'no', 'event_calendar');
$created = array();
// an array to hold all of the created events
while ($vevent = $v->getComponent()) {
    if ($vevent instanceof vevent) {
        $dtstart = $vevent->getProperty('dtstart');
        $dtend = $vevent->getProperty('dtend');
        if (empty($dtstart['hour'])) {
            $dtstart['hour'] = 0;
        }
        if (empty($dtstart['min'])) {
            $dtstart['min'] = 0;
        }
        if ($dtend && empty($dtend['hour'])) {
            $dtend['hour'] = 0;
        }
        if ($dtend && empty($dtend['min'])) {
            $dtend['min'] = 0;
        }