/** * Returns a new block-object for the section/data-pair. The list * of returned objects is: * * vcalendar => SG_iCal_VCalendar * vtimezone => SG_iCal_VTimeZone * vevent => SG_iCal_VEvent * * => ArrayObject * * @param $ical SG_iCalReader The reader this section/data-pair belongs to * @param $section string * @param SG_iCal_Line[] */ public static function factory(SG_iCal $ical, $section, $data) { switch ($section) { case "vcalendar": require_once dirname(__FILE__) . '/../blocks/SG_iCal_VCalendar.php'; return new SG_iCal_VCalendar(SG_iCal_Line::Remove_Line($data), $ical); case "vtimezone": require_once dirname(__FILE__) . '/../blocks/SG_iCal_VTimeZone.php'; return new SG_iCal_VTimeZone(SG_iCal_Line::Remove_Line($data), $ical); case "vevent": require_once dirname(__FILE__) . '/../blocks/SG_iCal_VEvent.php'; return new SG_iCal_VEvent($data, $ical); default: return new ArrayObject(SG_iCal_Line::Remove_Line((array) $data)); } }
/** * Parses the feed found in content and calls storeSection to store * parsed data * @param string $content * @param SG_iCal $ical */ private static function _Parse($content, SG_iCal $ical) { $main_sections = array('vevent', 'vjournal', 'vtodo', 'vtimezone', 'vcalendar'); $array_idents = array('exdate', 'rdate'); $sections = array(); $section = ''; $current_data = array(); foreach ($content as $line) { $line = new SG_iCal_Line($line); if ($line->isBegin()) { // New block of data, $section = new block $section = strtolower($line->getData()); $sections[] = strtolower($line->getData()); } elseif ($line->isEnd()) { // End of block of data ($removed = just ended block, $section = new top-block) $removed = array_pop($sections); $section = end($sections); if (array_search($removed, $main_sections) !== false) { self::StoreSection($removed, $current_data[$removed], $ical); $current_data[$removed] = array(); } } else { // Data line foreach ($main_sections as $s) { // Loops though the main sections if (array_search($s, $sections) !== false) { // This section is in the main section if ($section == $s) { // It _is_ the main section else if (in_array($line->getIdent(), $array_idents)) { //exdate could appears more that once $current_data[$s][$line->getIdent()][] = $line; } else { $current_data[$s][$line->getIdent()] = $line; } } else { // Sub section $current_data[$s][$section][$line->getIdent()] = $line; } break; } } } } $current_data = array(); }
/** * Constructs a new SG_iCal_VEvent. Needs the SG_iCalReader * supplied so it can query for timezones. * @param SG_iCal_Line[] $data * @param SG_iCalReader $ical */ public function __construct($data, SG_iCal $ical) { $this->uid = $data['uid']->getData(); unset($data['uid']); if (isset($data['rrule'])) { $this->recurrence = new SG_iCal_Recurrence($data['rrule']); unset($data['rrule']); } if (isset($data['exrule'])) { $this->recurex = new SG_iCal_Recurrence($data['exrule']); unset($data['exrule']); } if (isset($data['dtstart'])) { $this->start = $this->getTimestamp($data['dtstart'], $ical); unset($data['dtstart']); } if (isset($data['dtend'])) { $this->end = $this->getTimestamp($data['dtend'], $ical); unset($data['dtend']); } elseif (isset($data['duration'])) { $dur = new SG_iCal_Duration($data['duration']->getData()); $this->end = $this->start + $dur->getDuration(); unset($data['duration']); } //google cal set dtend as end of initial event (duration) if (isset($this->recurrence)) { //if there is a recurrence rule //exclusions if (isset($data['exdate'])) { foreach ($data['exdate'] as $exdate) { foreach ($exdate->getDataAsArray() as $ts) { $this->excluded[] = strtotime($ts); } } unset($data['exdate']); } //additions if (isset($data['rdate'])) { foreach ($data['rdate'] as $rdate) { foreach ($rdate->getDataAsArray() as $ts) { $this->added[] = strtotime($ts); } } unset($data['rdate']); } $until = $this->recurrence->getUntil(); $count = $this->recurrence->getCount(); //check if there is either 'until' or 'count' set if ($until) { //ok.. } elseif ($count) { //if count is set, then figure out the last occurrence and set that as the end date $this->getFrequency(); $until = $this->freq->lastOccurrence($this->start); } else { //forever... limit to 3 years $this->recurrence->setUntil('+3 years'); $until = $this->recurrence->getUntil(); } //date_default_timezone_set( xx ) needed ?; $this->laststart = strtotime($until); $this->lastend = $this->laststart + $this->getDuration(); } $imports = array('summary', 'description', 'location'); foreach ($imports as $import) { if (isset($data[$import])) { $this->{$import} = $data[$import]->getData(); unset($data[$import]); } } if (isset($this->previous_tz)) { date_default_timezone_set($this->previous_tz); } $this->data = SG_iCal_Line::Remove_Line($data); }
/** * Creates an recurrence object with a passed in line. Parses the line. * @param object $line an SG_iCal_Line object which will be parsed to get the * desired information. */ public function __construct(SG_iCal_Line $line) { $this->parseLine($line->getData()); }
/** * Converts recurrence rule to array of string of dates. * * @param string $rule RUle. * * @return array Array of dates or empty array. * @throws Ai1ec_Bootstrap_Exception */ protected function get_date_array_from_rule($rule) { if ('RDATE' !== substr($rule, 0, 5) && 'EXDATE' !== substr($rule, 0, 6)) { return array(); } $line = new SG_iCal_Line('RRULE:' . $rule); $dates = $line->getDataAsArray(); $dates_as_strings = array(); foreach ($dates as $date) { $date = str_replace(array('RDATE=', 'EXDATE='), '', $date); $date = $this->_registry->get('date.time', $date); $dates_as_strings[] = $date->format('m/d/Y'); } return $dates_as_strings; }
/** * Calculates the timestamp from a DT line. * @param $line SG_iCal_Line * @return int */ private function getTimestamp(SG_iCal_Line $line, SG_iCal $ical) { $ts = strtotime($line->getData()); if (isset($line['tzid'])) { $tz = $ical->getTimeZoneInfo($line['tzid']); $offset = $tz->getOffset($ts); $ts = strtotime(date('D, d M Y H:i:s', $ts) . ' ' . $offset); } return $ts; }