public function export(array $arguments, array $params = array()) { $c = new vcalendar(); $c->setProperty('calscale', 'GREGORIAN'); $c->setProperty('method', 'PUBLISH'); // if no post id are specified do not export those properties // as they would create a new calendar in outlook. // a user reported this in AIOEC-982 and said this would fix it if (true === $arguments['do_not_export_as_calendar']) { $c->setProperty('X-WR-CALNAME', get_bloginfo('name')); $c->setProperty('X-WR-CALDESC', get_bloginfo('description')); } $c->setProperty('X-FROM-URL', home_url()); // Timezone setup $tz = $this->_registry->get('date.timezone')->get_default_timezone(); if ($tz) { $c->setProperty('X-WR-TIMEZONE', $tz); $tz_xprops = array('X-LIC-LOCATION' => $tz); iCalUtilityFunctions::createTimezone($c, $tz, $tz_xprops); } $this->_taxonomy_model = $this->_registry->get('model.taxonomy'); $post_ids = array(); foreach ($arguments['events'] as $event) { $post_ids[] = $event->get('post_id'); } $this->_taxonomy_model->update_meta($post_ids); foreach ($arguments['events'] as $event) { $c = $this->_insert_event_in_calendar($event, $c, true, $params); } $str = ltrim($c->createCalendar()); return $str; }
/** * get component property value/params * * if property has multiply values, consequtive function calls are needed * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.9.3 - 2011-05-18 * @param string $propName, optional * @param int @propix, optional, if specific property is wanted in case of multiply occurences * @param bool $inclParam=FALSE * @param bool $specform=FALSE * @return mixed */ function getProperty($propName = FALSE, $propix = FALSE, $inclParam = FALSE, $specform = FALSE) { if ($this->_notExistProp($propName)) { return FALSE; } $propName = $propName ? strtoupper($propName) : 'X-PROP'; if (in_array($propName, array('ATTACH', 'ATTENDEE', 'CATEGORIES', 'COMMENT', 'CONTACT', 'DESCRIPTION', 'EXDATE', 'EXRULE', 'FREEBUSY', 'RDATE', 'RELATED-TO', 'RESOURCES', 'RRULE', 'REQUEST-STATUS', 'TZNAME', 'X-PROP'))) { if (!$propix) { $propix = isset($this->propix[$propName]) ? $this->propix[$propName] + 2 : 1; } $this->propix[$propName] = --$propix; } switch ($propName) { case 'ACTION': if (!empty($this->action['value'])) { return $inclParam ? $this->action : $this->action['value']; } break; case 'ATTACH': while (is_array($this->attach) && !isset($this->attach[$propix]) && 0 < count($this->attach) && $propix < end(array_keys($this->attach))) { $propix++; } if (!isset($this->attach[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->attach[$propix] : $this->attach[$propix]['value']; break; case 'ATTENDEE': while (is_array($this->attendee) && !isset($this->attendee[$propix]) && 0 < count($this->attendee) && $propix < end(array_keys($this->attendee))) { $propix++; } if (!isset($this->attendee[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->attendee[$propix] : $this->attendee[$propix]['value']; break; case 'CATEGORIES': while (is_array($this->categories) && !isset($this->categories[$propix]) && 0 < count($this->categories) && $propix < end(array_keys($this->categories))) { $propix++; } if (!isset($this->categories[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->categories[$propix] : $this->categories[$propix]['value']; break; case 'CLASS': if (!empty($this->class['value'])) { return $inclParam ? $this->class : $this->class['value']; } break; case 'COMMENT': while (is_array($this->comment) && !isset($this->comment[$propix]) && 0 < count($this->comment) && $propix < end(array_keys($this->comment))) { $propix++; } if (!isset($this->comment[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->comment[$propix] : $this->comment[$propix]['value']; break; case 'COMPLETED': if (!empty($this->completed['value'])) { return $inclParam ? $this->completed : $this->completed['value']; } break; case 'CONTACT': while (is_array($this->contact) && !isset($this->contact[$propix]) && 0 < count($this->contact) && $propix < end(array_keys($this->contact))) { $propix++; } if (!isset($this->contact[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->contact[$propix] : $this->contact[$propix]['value']; break; case 'CREATED': if (!empty($this->created['value'])) { return $inclParam ? $this->created : $this->created['value']; } break; case 'DESCRIPTION': while (is_array($this->description) && !isset($this->description[$propix]) && 0 < count($this->description) && $propix < end(array_keys($this->description))) { $propix++; } if (!isset($this->description[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->description[$propix] : $this->description[$propix]['value']; break; case 'DTEND': if (!empty($this->dtend['value'])) { return $inclParam ? $this->dtend : $this->dtend['value']; } break; case 'DTSTAMP': if (in_array($this->objName, array('valarm', 'vtimezone', 'standard', 'daylight'))) { return; } if (!isset($this->dtstamp['value'])) { $this->_makeDtstamp(); } return $inclParam ? $this->dtstamp : $this->dtstamp['value']; break; case 'DTSTART': if (!empty($this->dtstart['value'])) { return $inclParam ? $this->dtstart : $this->dtstart['value']; } break; case 'DUE': if (!empty($this->due['value'])) { return $inclParam ? $this->due : $this->due['value']; } break; case 'DURATION': if (!isset($this->duration['value'])) { return FALSE; } $value = $specform && isset($this->dtstart['value']) && isset($this->duration['value']) ? iCalUtilityFunctions::_duration2date($this->dtstart['value'], $this->duration['value']) : $this->duration['value']; return $inclParam ? array('value' => $value, 'params' => $this->duration['params']) : $value; break; case 'EXDATE': while (is_array($this->exdate) && !isset($this->exdate[$propix]) && 0 < count($this->exdate) && $propix < end(array_keys($this->exdate))) { $propix++; } if (!isset($this->exdate[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->exdate[$propix] : $this->exdate[$propix]['value']; break; case 'EXRULE': while (is_array($this->exrule) && !isset($this->exrule[$propix]) && 0 < count($this->exrule) && $propix < end(array_keys($this->exrule))) { $propix++; } if (!isset($this->exrule[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->exrule[$propix] : $this->exrule[$propix]['value']; break; case 'FREEBUSY': while (is_array($this->freebusy) && !isset($this->freebusy[$propix]) && 0 < count($this->freebusy) && $propix < end(array_keys($this->freebusy))) { $propix++; } if (!isset($this->freebusy[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->freebusy[$propix] : $this->freebusy[$propix]['value']; break; case 'GEO': if (!empty($this->geo['value'])) { return $inclParam ? $this->geo : $this->geo['value']; } break; case 'LAST-MODIFIED': if (!empty($this->lastmodified['value'])) { return $inclParam ? $this->lastmodified : $this->lastmodified['value']; } break; case 'LOCATION': if (!empty($this->location['value'])) { return $inclParam ? $this->location : $this->location['value']; } break; case 'ORGANIZER': if (!empty($this->organizer['value'])) { return $inclParam ? $this->organizer : $this->organizer['value']; } break; case 'PERCENT-COMPLETE': if (!empty($this->percentcomplete['value']) || isset($this->percentcomplete['value']) && '0' == $this->percentcomplete['value']) { return $inclParam ? $this->percentcomplete : $this->percentcomplete['value']; } break; case 'PRIORITY': if (!empty($this->priority['value']) || isset($this->priority['value']) && '0' == $this->priority['value']) { return $inclParam ? $this->priority : $this->priority['value']; } break; case 'RDATE': while (is_array($this->rdate) && !isset($this->rdate[$propix]) && 0 < count($this->rdate) && $propix < end(array_keys($this->rdate))) { $propix++; } if (!isset($this->rdate[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->rdate[$propix] : $this->rdate[$propix]['value']; break; case 'RECURRENCE-ID': if (!empty($this->recurrenceid['value'])) { return $inclParam ? $this->recurrenceid : $this->recurrenceid['value']; } break; case 'RELATED-TO': while (is_array($this->relatedto) && !isset($this->relatedto[$propix]) && 0 < count($this->relatedto) && $propix < end(array_keys($this->relatedto))) { $propix++; } if (!isset($this->relatedto[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->relatedto[$propix] : $this->relatedto[$propix]['value']; break; case 'REPEAT': if (!empty($this->repeat['value']) || isset($this->repeat['value']) && '0' == $this->repeat['value']) { return $inclParam ? $this->repeat : $this->repeat['value']; } break; case 'REQUEST-STATUS': while (is_array($this->requeststatus) && !isset($this->requeststatus[$propix]) && 0 < count($this->requeststatus) && $propix < end(array_keys($this->requeststatus))) { $propix++; } if (!isset($this->requeststatus[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->requeststatus[$propix] : $this->requeststatus[$propix]['value']; break; case 'RESOURCES': while (is_array($this->resources) && !isset($this->resources[$propix]) && 0 < count($this->resources) && $propix < end(array_keys($this->resources))) { $propix++; } if (!isset($this->resources[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->resources[$propix] : $this->resources[$propix]['value']; break; case 'RRULE': while (is_array($this->rrule) && !isset($this->rrule[$propix]) && 0 < count($this->rrule) && $propix < end(array_keys($this->rrule))) { $propix++; } if (!isset($this->rrule[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->rrule[$propix] : $this->rrule[$propix]['value']; break; case 'SEQUENCE': if (isset($this->sequence['value']) && (isset($this->sequence['value']) && '0' <= $this->sequence['value'])) { return $inclParam ? $this->sequence : $this->sequence['value']; } break; case 'STATUS': if (!empty($this->status['value'])) { return $inclParam ? $this->status : $this->status['value']; } break; case 'SUMMARY': if (!empty($this->summary['value'])) { return $inclParam ? $this->summary : $this->summary['value']; } break; case 'TRANSP': if (!empty($this->transp['value'])) { return $inclParam ? $this->transp : $this->transp['value']; } break; case 'TRIGGER': if (!empty($this->trigger['value'])) { return $inclParam ? $this->trigger : $this->trigger['value']; } break; case 'TZID': if (!empty($this->tzid['value'])) { return $inclParam ? $this->tzid : $this->tzid['value']; } break; case 'TZNAME': while (is_array($this->tzname) && !isset($this->tzname[$propix]) && 0 < count($this->tzname) && $propix < end(array_keys($this->tzname))) { $propix++; } if (!isset($this->tzname[$propix])) { unset($this->propix[$propName]); return FALSE; } return $inclParam ? $this->tzname[$propix] : $this->tzname[$propix]['value']; break; case 'TZOFFSETFROM': if (!empty($this->tzoffsetfrom['value'])) { return $inclParam ? $this->tzoffsetfrom : $this->tzoffsetfrom['value']; } break; case 'TZOFFSETTO': if (!empty($this->tzoffsetto['value'])) { return $inclParam ? $this->tzoffsetto : $this->tzoffsetto['value']; } break; case 'TZURL': if (!empty($this->tzurl['value'])) { return $inclParam ? $this->tzurl : $this->tzurl['value']; } break; case 'UID': if (in_array($this->objName, array('valarm', 'vtimezone', 'standard', 'daylight'))) { return FALSE; } if (empty($this->uid['value'])) { $this->_makeuid(); } return $inclParam ? $this->uid : $this->uid['value']; break; case 'URL': if (!empty($this->url['value'])) { return $inclParam ? $this->url : $this->url['value']; } break; default: if ($propName != 'X-PROP') { if (!isset($this->xprop[$propName])) { return FALSE; } return $inclParam ? array($propName, $this->xprop[$propName]) : array($propName, $this->xprop[$propName]['value']); } else { if (empty($this->xprop)) { return FALSE; } $xpropno = 0; foreach ($this->xprop as $xpropkey => $xpropvalue) { if ($propix == $xpropno) { return $inclParam ? array($xpropkey, $this->xprop[$xpropkey]) : array($xpropkey, $this->xprop[$xpropkey]['value']); } else { $xpropno++; } } return FALSE; // not found ?? } } return FALSE; }
private static function date2timestamp($datetime, $tz = null) { if (!isset($datetime['hour'])) { $datetime['hour'] = '0'; } if (!isset($datetime['min'])) { $datetime['min'] = '0'; } if (!isset($datetime['sec'])) { $datetime['sec'] = '0'; } foreach ($datetime as $dkey => $dvalue) { if ('tz' != $dkey) { $datetime[$dkey] = (int) $dvalue; } } if ($tz) { $datetime['tz'] = $tz; } $offset = isset($datetime['tz']) && '' < trim($datetime['tz']) ? iCalUtilityFunctions::_tz2offset($datetime['tz']) : 0; return gmmktime($datetime['hour'], $datetime['min'], $datetime['sec'] + $offset, $datetime['month'], $datetime['day'], $datetime['year']); }
/** * creates formatted output for calendar component property * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.21.11 - 2015-03-31 * @param string $label property name * @param string $attributes property attributes * @param string $content property content (optional) * @uses iCalBase::$format * @uses iCalBase::$elementStart1 * @uses iCalBase::$xcaldecl * @uses iCalBase::$intAttrDelimiter * @uses iCalBase::$attributeDelimiter * @uses iCalBase::_createElement() * @uses iCalBase::$elementStart2 * @uses iCalBase::$nl * @uses iCalBase::$valueInit * @uses iCalUtilityFunctions::_size75() * @uses iCalBase::$elementEnd1 * @uses iCalBase::$elementEnd2 * @access protected * @return string */ protected function _createElement($label, $attributes = null, $content = FALSE) { switch ($this->format) { case 'xcal': $label = strtolower($label); break; default: $label = strtoupper($label); break; } $output = $this->elementStart1 . $label; $categoriesAttrLang = null; $attachInlineBinary = FALSE; $attachfmttype = null; if ('xcal' == $this->format && 'x-' == substr($label, 0, 2)) { $this->xcaldecl[] = array('xmldecl' => 'ELEMENT', 'ref' => $label, 'type2' => '(#PCDATA)'); } if (!empty($attributes)) { $attributes = trim($attributes); if ('xcal' == $this->format) { $attributes2 = explode($this->intAttrDelimiter, $attributes); $attributes = null; foreach ($attributes2 as $aix => $attribute) { $attrKVarr = explode('=', $attribute); if (empty($attrKVarr[0])) { continue; } if (!isset($attrKVarr[1])) { $attrValue = $attrKVarr[0]; $attrKey = $aix; } elseif (2 == count($attrKVarr)) { $attrKey = strtolower($attrKVarr[0]); $attrValue = $attrKVarr[1]; } else { $attrKey = strtolower($attrKVarr[0]); unset($attrKVarr[0]); $attrValue = implode('=', $attrKVarr); } if ('attach' == $label && in_array($attrKey, array('fmttype', 'encoding', 'value'))) { $attachInlineBinary = TRUE; if ('fmttype' == $attrKey) { $attachfmttype = $attrKey . '=' . $attrValue; } continue; } elseif ('categories' == $label && 'language' == $attrKey) { $categoriesAttrLang = $attrKey . '=' . $attrValue; } else { $attributes .= empty($attributes) ? ' ' : $this->attributeDelimiter . ' '; $attributes .= !empty($attrKey) ? $attrKey . '=' : null; if ('"' == substr($attrValue, 0, 1) && '"' == substr($attrValue, -1)) { $attrValue = substr($attrValue, 1, strlen($attrValue) - 2); $attrValue = str_replace('"', '', $attrValue); } $attributes .= '"' . htmlspecialchars($attrValue) . '"'; } } } else { $attributes = str_replace($this->intAttrDelimiter, $this->attributeDelimiter, $attributes); } } if ('xcal' == $this->format && ('attach' == $label && !$attachInlineBinary || in_array($label, array('tzurl', 'url')))) { $pos = strrpos($content, "/"); $docname = $pos !== false ? substr($content, 1 - strlen($content) + $pos) : $content; $this->xcaldecl[] = array('xmldecl' => 'ENTITY', 'uri' => $docname, 'ref' => 'SYSTEM', 'external' => $content, 'type' => 'NDATA', 'type2' => 'BINERY'); $attributes .= empty($attributes) ? ' ' : $this->attributeDelimiter . ' '; $attributes .= 'uri="' . $docname . '"'; $content = null; if ('attach' == $label) { $attributes = str_replace($this->attributeDelimiter, $this->intAttrDelimiter, $attributes); $content = $this->nl . $this->_createElement('extref', $attributes, null); $attributes = null; } } elseif ('xcal' == $this->format && 'attach' == $label && $attachInlineBinary) { $content = $this->nl . $this->_createElement('b64bin', $attachfmttype, $content); // max one attribute } $output .= $attributes; if (!$content && '0' != $content) { switch ($this->format) { case 'xcal': $output .= ' /'; $output .= $this->elementStart2 . $this->nl; return $output; break; default: $output .= $this->elementStart2 . $this->valueInit; return iCalUtilityFunctions::_size75($output, $this->nl); break; } } $output .= $this->elementStart2; $output .= $this->valueInit . $content; switch ($this->format) { case 'xcal': return $output . $this->elementEnd1 . $label . $this->elementEnd2; break; default: return iCalUtilityFunctions::_size75($output, $this->nl); break; } }
public function generate_ical() { $eventdata = $this->pdh->get('calendar_events', 'data', array($this->url_id)); require $this->root_path . 'libraries/icalcreator/iCalcreator.class.php'; $v = new vcalendar(); $v->setConfig('unique_id', $this->config->get('server_name')); $v->setProperty('x-wr-calname', sprintf(registry::fetch('user')->lang('icalfeed_name'), registry::register('config')->get('guildtag'))); $v->setProperty('X-WR-CALDESC', registry::fetch('user')->lang('icalfeed_description')); // set the timezone - required by some clients $timezone = registry::register('config')->get('timezone'); $v->setProperty("X-WR-TIMEZONE", $timezone); iCalUtilityFunctions::createTimezone($v, $timezone, array("X-LIC-LOCATION" => $timezone)); // Generate the vevents... $e = new vevent(); $e->setProperty('dtstart', array("timestamp" => $eventdata['timestamp_start'] . 'Z')); $e->setProperty('dtend', array("timestamp" => $eventdata['timestamp_end'] . 'Z')); $e->setProperty('dtstamp', array("timestamp" => $this->time->time)); $e->setProperty('summary', $this->pdh->get('event', 'name', array($eventdata['extension']['raid_eventid']))); $e->setProperty('description', $eventdata['notes']); $e->setProperty('class', 'PUBLIC'); $e->setProperty('categories', 'PERSONAL'); $v->setComponent($e); // Save or Output the ICS File.. if ($icsfile == true) { $v->setConfig('filename', $icsfile); $v->saveCalendar(); } else { header('Content-type: text/calendar; charset=utf-8;'); header('Content-Disposition: filename=raidevent-' . $eventdata['timestamp_start'] . '.ics'); echo $v->createCalendar(); exit; } }
if (version_compare(JVERSION, '3.0', 'ge')) { $offset = $config->get('offset'); } else { $offset = $config->getValue('config.offset'); } $dateTimeZone = new DateTimeZone($offset); $dateTime = new DateTime("now", $dateTimeZone); $timeOffset = $dateTimeZone->getOffset($dateTime); $timezone = $timeOffset / 3600; $tz = 'UTC'; $v->setProperty('method', 'PUBLISH'); $v->setProperty('X-WR-CALDESC', ''); $v->setProperty('X-WR-TIMEZONE', $tz); $xprops = array('X-LIC-LOCATION' => $tz); if (version_compare(PHP_VERSION, '5.3.0') >= 0) { iCalUtilityFunctions::createTimezone($v, $tz, $xprops); } $stamp = $this->data; $get_date = ''; $href = '#'; $start_Datetime = ''; $start_Date = ''; $end_Datetime = ''; $end_Date = ''; foreach ($stamp->items as $item) { $s_dates = $item->dates; $single_dates = unserialize($s_dates); if (JRequest::getVar('date', '')) { $var_one_date = JRequest::getVar('date'); $one_ex = explode('-', $var_one_date); $get_one_date = $one_ex['0'] . '-' . $one_ex['1'] . '-' . $one_ex['2'] . ' ' . $one_ex['3'] . ':' . $one_ex['4'] . ':00';
/** * transforms a dateTime from a timezone to another using PHP DateTime and DateTimeZone class (PHP >= PHP 5.2.0) * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.15.1 - 2012-10-17 * @param mixed $date, date to alter * @param string $tzFrom, PHP valid 'from' timezone * @param string $tzTo, PHP valid 'to' timezone, default 'UTC' * @param string $format, date output format, default 'Ymd\THis' * @return bool */ public static function transformDateTime(&$date, $tzFrom, $tzTo = 'UTC', $format = 'Ymd\\THis') { if (is_array($date) && isset($date['timestamp'])) { try { $d = new DateTime("@{$date['timestamp']}"); // set UTC date $d->setTimezone(new DateTimeZone($tzFrom)); // convert to 'from' date } catch (Exception $e) { return FALSE; } } else { if (iCalUtilityFunctions::_isArrayDate($date)) { if (isset($date['tz'])) { unset($date['tz']); } $date = iCalUtilityFunctions::_date2strdate(iCalUtilityFunctions::_chkDateArr($date)); } if ('Z' == substr($date, -1)) { $date = substr($date, 0, strlen($date) - 2); } try { $d = new DateTime($date, new DateTimeZone($tzFrom)); } catch (Exception $e) { return FALSE; } } try { $d->setTimezone(new DateTimeZone($tzTo)); } catch (Exception $e) { return FALSE; } $date = $d->format($format); return TRUE; }
case 'icalfeed': // the permissions for the single modules $permissions = array('calendar' => 'po_calendarevent'); $modulename = registry::register('input')->get('module', ''); // check for permission $userid = registry::fetch('user')->getUserIDfromExchangeKey(registry::register('input')->get('key', '')); if (isset($permissions[$modulename]) && registry::fetch('user')->check_auth($permissions[$modulename], false, $userid)) { require $eqdkp_root_path . 'libraries/icalcreator/iCalcreator.class.php'; $v = new vcalendar(); $v->setConfig('unique_id', registry::register('config')->get('server_name')); $v->setProperty('x-wr-calname', sprintf(registry::fetch('user')->lang('icalfeed_name'), registry::register('config')->get('guildtag'))); $v->setProperty('X-WR-CALDESC', registry::fetch('user')->lang('icalfeed_description')); // set the timezone - required by some clients $timezone = registry::register('config')->get('timezone'); $v->setProperty("X-WR-TIMEZONE", $timezone); iCalUtilityFunctions::createTimezone($v, $timezone, array("X-LIC-LOCATION" => $timezone)); switch ($modulename) { case 'calendar': $eventtypes = registry::register('input')->get('type', 'raids'); switch ($eventtypes) { case 'raids': $eventsfilter = true; break; case 'all': $eventsfilter = false; break; case 'appointments': $eventsfilter = 'appointments'; break; } $caleventids = registry::register('plus_datahandler')->get('calendar_events', 'id_list', array($eventsfilter, registry::register('time')->createRepeatableEvents(registry::register('time')->time, -30)));
/** * step date, return updated date, array and timpstamp * * @author Kjell-Inge Gustafsson <*****@*****.**> * @since 2.4.16 - 2008-10-18 * @param array $date, date to step * @param int $timestamp * @param array $step, default array( 'day' => 1 ) * @return void */ public static function _stepdate(&$date, &$timestamp, $step = array('day' => 1)) { foreach ($step as $stepix => $stepvalue) { $date[$stepix] += $stepvalue; } $timestamp = iCalUtilityFunctions::_date2timestamp($date); $date = iCalUtilityFunctions::_timestamp2date($timestamp, 6); foreach ($date as $k => $v) { if (ctype_digit($v)) { $date[$k] = (int) $v; } } }
function display($tpl = null) { // Get a reference of the page instance in joomla $document = JFactory::getDocument(); $model = $this->getModel(); $project = $model->getProject(); //$config = $model->getTemplateConfig($this->getName()); if (isset($project)) { $this->project = $project; } $this->overallconfig = $model->getOverallConfig(); $this->config = $this->overallconfig; $this->matches = $model->getMatches(); $this->teams = $model->getTeamsFromMatches($this->matches); // load a class that handles ical formats. require_once JLG_PATH_SITE . DS . 'helpers' . DS . 'iCalcreator.class.php'; // create a new calendar instance $v = new vcalendar(); foreach ($this->matches as $match) { $hometeam = $this->teams[$match->team1]; $home = sprintf('%s', $hometeam->name); $guestteam = $this->teams[$match->team2]; $guest = sprintf('%s', $guestteam->name); $summary = $match->project_name . ': ' . $home . ' - ' . $guest; // check if match gots a date, if not it will not be included in ical if ($match->match_date) { $totalMatchTime = isset($project) ? $project->halftime * ($project->game_parts - 1) + $project->game_regular_time : 90; $start = JoomleagueHelper::getMatchStartTimestamp($match, 'Y-m-d H:i:s'); $end = JoomleagueHelper::getMatchEndTimestamp($match, $totalMatchTime, 'Y-m-d H:i:s'); // check if exist a playground in match or team or club $stringlocation = ''; $stringname = ''; if (!empty($match->playground_id)) { $stringlocation = $match->playground_address . ", " . $match->playground_zipcode . " " . $match->playground_city; $stringname = $match->playground_name; } elseif (!empty($match->team_playground_id)) { $stringlocation = $match->team_playground_address . ", " . $match->team_playground_zipcode . " " . $match->team_playground_city; $stringname = $match->team_playground_name; } elseif (!empty($match->club_playground_id)) { $stringlocation = $match->club_playground_address . ", " . $match->club_playground_zipcode . " " . $match->club_playground_city; $stringname = $match->club_playground_name; } $location = $stringlocation; //if someone want to insert more in description here is the place $description = $stringname; // create an event and insert it in calendar $vevent = new vevent(); $timezone = JoomleagueHelper::getMatchTimezone($match); $vevent->setProperty("dtstart", $start, array("TZID" => $timezone)); $vevent->setProperty("dtend", $end, array("TZID" => $timezone)); $vevent->setProperty('LOCATION', $location); $vevent->setProperty('summary', $summary); $vevent->setProperty('description', $description); $v->setComponent($vevent); } } $v->setProperty("X-WR-TIMEZONE", $timezone); $xprops = array("X-LIC-LOCATION" => $timezone); iCalUtilityFunctions::createTimezone($v, $timezone, $xprops); $v->returnCalendar(); //$debugstr = $v->createCalendar(); //echo "<pre>"; //echo $debugstr; // exit before display // parent::display( $tpl ); }
} if (!$events) { register_error(elgg_echo('event_calendar:no_events_found')); forward(REFERER); } $events = event_calendar_flatten_event_structure($events); $timezone = date_default_timezone_get(); //get_plugin_setting('timezone', 'event_connector'); $config = array('UNIQUE_ID' => elgg_get_site_url(), 'FILENAME' => 'Calendar.ics', 'TZID' => $timezone); $v = new vcalendar($config); $v->setProperty('method', 'PUBLISH'); $v->setProperty("X-WR-TIMEZONE", date_default_timezone_get()); $v->setProperty("calscale", "GREGORIAN"); $v->setProperty("version", "2.0"); $v->setProperty("X-WR-CALNAME", elgg_get_logged_in_user_entity()->username . "Calendar"); iCalUtilityFunctions::createTimezone($v, $timezone); foreach ($events as $event) { //set default beginning and ending time $hb = 8; $he = 18; $mb = $me = $sb = $se = 0; if ($event->start_time) { $hb = (int) ($event->start_time / 60); $mb = $event->start_time % 60; } if ($event->end_time) { $he = (int) ($event->end_time / 60); $me = $event->end_time % 60; } $vevent = $v->newComponent('vevent'); if (!isset($event->end_date)) {
/** * parse iCal text/file into vcalendar, components, properties and parameters * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.21.12 - 2014-03-10 * @param mixed $unparsedtext strict rfc2445 formatted, single property string or array of property strings * @param resource $context PHP resource context * @uses iCalUtilityFunctions::convEolChar() * @uses vcalendar::getConfig() * @uses vcalendar::$components * @uses calendarComponent::copy() * @uses vevent::construct() * @uses vfreebusy::construct() * @uses vjournal::construct() * @uses vtodo::construct() * @uses vtimezone::construct() * @uses vcalendar::$unparsed * @uses iCalUtilityFunctions::_splitContent() * @uses iCalUtilityFunctions::_strunrep() * @uses vcalendar::setProperty() * @uses calendarComponent::$unparsed * @uses calendarComponent::parse() * @return bool FALSE if error occurs during parsing */ function parse($unparsedtext = FALSE, $context = null) { $nl = $this->getConfig('nl'); if (FALSE === $unparsedtext || empty($unparsedtext)) { /* directory+filename is set previously via setConfig url or directory+filename */ if (FALSE === ($file = $this->getConfig('url'))) { if (FALSE === ($file = $this->getConfig('dirfile'))) { return FALSE; } /* err 1 */ if (!is_file($file)) { return FALSE; } /* err 2 */ if (!is_readable($file)) { return FALSE; } /* err 3 */ } /* READ FILE */ if (!empty($context) && filter_var($file, FILTER_VALIDATE_URL) && FALSE === ($rows = file_get_contents($file, FALSE, $context))) { return FALSE; } elseif (FALSE === ($rows = file_get_contents($file))) { return FALSE; } /* err 5 */ } elseif (is_array($unparsedtext)) { $rows = implode('\\n' . $nl, $unparsedtext); } else { $rows =& $unparsedtext; } /* fix line folding */ $rows = iCalUtilityFunctions::convEolChar($rows, $nl); /* skip leading (empty/invalid) lines (and remove leading BOM chars etc) */ foreach ($rows as $lix => $line) { if (FALSE !== stripos($line, 'BEGIN:VCALENDAR')) { $rows[$lix] = 'BEGIN:VCALENDAR'; break; } unset($rows[$lix]); } $rcnt = count($rows); if (3 > $rcnt) { /* err 10 */ return FALSE; } /* skip trailing empty lines and ensure an end row */ $lix = array_keys($rows); $lix = end($lix); while (3 < $lix) { $tst = trim($rows[$lix]); if ('\\n' == $tst || empty($tst)) { unset($rows[$lix]); $lix--; continue; } if (FALSE === stripos($rows[$lix], 'END:VCALENDAR')) { $rows[] = 'END:VCALENDAR'; } else { $rows[$lix] = 'END:VCALENDAR'; } break; } $comp =& $this; $calsync = $compsync = 0; /* identify components and update unparsed data within component */ $config = $this->getConfig(); $endtxt = array('END:VE', 'END:VF', 'END:VJ', 'END:VT'); foreach ($rows as $lix => $line) { if ('BEGIN:VCALENDAR' == strtoupper(substr($line, 0, 15))) { $calsync++; continue; } elseif ('END:VCALENDAR' == strtoupper(substr($line, 0, 13))) { if (0 < $compsync) { $this->components[] = $comp->copy(); } $compsync--; $calsync--; break; } elseif (1 != $calsync) { return FALSE; } elseif (in_array(strtoupper(substr($line, 0, 6)), $endtxt)) { $this->components[] = $comp->copy(); $compsync--; continue; } if ('BEGIN:VEVENT' == strtoupper(substr($line, 0, 12))) { $comp = new vevent($config); $compsync++; } elseif ('BEGIN:VFREEBUSY' == strtoupper(substr($line, 0, 15))) { $comp = new vfreebusy($config); $compsync++; } elseif ('BEGIN:VJOURNAL' == strtoupper(substr($line, 0, 14))) { $comp = new vjournal($config); $compsync++; } elseif ('BEGIN:VTODO' == strtoupper(substr($line, 0, 11))) { $comp = new vtodo($config); $compsync++; } elseif ('BEGIN:VTIMEZONE' == strtoupper(substr($line, 0, 15))) { $comp = new vtimezone($config); $compsync++; } else { /* update component with unparsed data */ $comp->unparsed[] = $line; } } // end foreach( $rows as $line ) unset($config, $endtxt); /* parse data for calendar (this) object */ if (isset($this->unparsed) && is_array($this->unparsed) && 0 < count($this->unparsed)) { /* concatenate property values spread over several lines */ $propnames = array('calscale', 'method', 'prodid', 'version', 'x-'); $proprows = array(); for ($i = 0; $i < count($this->unparsed); $i++) { // concatenate lines $line = rtrim($this->unparsed[$i], $nl); while (isset($this->unparsed[$i + 1]) && !empty($this->unparsed[$i + 1]) && ' ' == $this->unparsed[$i + 1][0]) { $line .= rtrim(substr($this->unparsed[++$i], 1), $nl); } $proprows[] = $line; } foreach ($proprows as $line) { if ('\\n' == substr($line, -2)) { $line = substr($line, 0, -2); } /* get property name */ $propname = ''; $cix = 0; while (FALSE !== ($char = substr($line, $cix, 1))) { if (in_array($char, array(':', ';'))) { break; } else { $propname .= $char; } $cix++; } /* skip non standard property names */ if ('x-' != strtolower(substr($propname, 0, 2)) && !in_array(strtolower($propname), $propnames)) { continue; } /* ignore version/prodid properties */ if (in_array(strtolower($propname), array('version', 'prodid'))) { continue; } /* rest of the line is opt.params and value */ $line = substr($line, $cix); /* separate attributes from value */ iCalUtilityFunctions::_splitContent($line, $propAttr); /* update Property */ if (FALSE !== strpos($line, ',')) { $content = array(0 => ''); $cix = $lix = 0; while (FALSE !== substr($line, $lix, 1)) { if (0 < $lix && ',' == $line[$lix] && "\\" != $line[$lix - 1]) { $cix++; $content[$cix] = ''; } else { $content[$cix] .= $line[$lix]; } $lix++; } if (1 < count($content)) { foreach ($content as $cix => $contentPart) { $content[$cix] = iCalUtilityFunctions::_strunrep($contentPart); } $this->setProperty($propname, $content, $propAttr); continue; } else { $line = reset($content); } $line = iCalUtilityFunctions::_strunrep($line); } $this->setProperty($propname, rtrim($line, ".."), $propAttr); } // end - foreach( $this->unparsed.. . } // end - if( is_array( $this->unparsed.. . unset($unparsedtext, $rows, $this->unparsed, $proprows); /* parse Components */ if (is_array($this->components) && 0 < count($this->components)) { $ckeys = array_keys($this->components); foreach ($ckeys as $ckey) { if (!empty($this->components[$ckey]) && !empty($this->components[$ckey]->unparsed)) { $this->components[$ckey]->parse(); } } } else { return FALSE; } /* err 91 or something.. . */ return TRUE; }
public function ical_feed() { global $wp_query; if (!have_posts()) { $wp_query->set_404(); $wp_query->max_num_pages = 0; header('Content-Type: text/html; charset=' . get_option('blog_charset'), true); locate_template('404.php', true); die; } $display_format = ''; if (isset($_GET['format'])) { $display_format = strtolower($_GET['format']); } if ($display_format == 'xml') { nocache_headers(); header('Content-Type: text/xml; charset=' . get_option('blog_charset'), true); } if ($display_format == 'json') { nocache_headers(); header('Content-Type: application/json; charset=' . get_option('blog_charset'), true); } //TODO: Add filters for these things $calendar_name = get_bloginfo('name') . ' Events'; $calendar_description = 'Events found on ' . get_site_url(); $timezone = get_option('timezone_string'); // define time zone $args = array('unique_id' => get_site_url(), 'TZID' => $timezone); $v = new vcalendar($args); // create a new calendar instance $v->setProperty('method', 'PUBLISH'); // required of some calendar software $v->setProperty('x-wr-calname', $calendar_name); // required of some calendar software $v->setProperty('X-WR-CALDESC', $calendar_description); // required of some calendar software $v->setProperty('X-WR-TIMEZONE', $timezone); // required of some calendar software $xprops = array('X-LIC-LOCATION' => $timezone); // required of some calendar software iCalUtilityFunctions::createTimezone($v, $timezone, $xprops); // create timezone component(-s) opt. 1 based on present date while (have_posts()) { the_post(); $event_id = get_the_ID(); $event = get_post($event_id); $event_date = sc_get_event_date($event_id); $event_time = sc_get_event_time($event_id); $event_start = strtotime($event_date . ' ' . $event_time['start']); $event_end = strtotime($event_date . ' ' . $event_time['end']); $event_location = ''; if (function_exists('sc_get_event_address')) { $event_location = sc_get_event_address(); } $event_description = apply_filters('sc_ical_event_description', get_the_content(), $event); $event_description = sc_html2plain($event_description); $vevent =& $v->newComponent('vevent'); // create an event calendar component $start = array('year' => date('Y', $event_start), 'month' => date('n', $event_start), 'day' => date('j', $event_start), 'hour' => date('G', $event_start), 'min' => date('i', $event_start), 'sec' => date('s', $event_start)); $vevent->setProperty('dtstart', $start); $end = array('year' => date('Y', $event_end), 'month' => date('n', $event_end), 'day' => date('j', $event_end), 'hour' => date('G', $event_end), 'min' => date('i', $event_end), 'sec' => date('s', $event_end)); $vevent->setProperty('dtend', $end); $vevent->setProperty('LOCATION', $event_location); // property name - case independent if (function_exists('sc_get_the_organizer')) { $organizer_details = sc_get_the_organizer($event_id); $organizer_details = array_filter($organizer_details); if (isset($organizer_details['name']) && isset($organizer_details['email'])) { $organizer_args = array('CN' => $organizer_details['name']); $x_params = array('Phone', 'Website'); foreach ($x_params as $param) { $lowercase_param = strtolower($param); if (isset($organizer_details[$lowercase_param])) { $arg_key = 'X-' . $param; $val = $organizer_details[$lowercase_param]; $organizer_args[$arg_key] = $val; } } $vevent->setProperty('organizer', $organizer_details['email'], $organizer_args); } } $vevent->setProperty('summary', $event->post_title); $vevent->setProperty('description', $event_description); } // all calendar components are described in rfc5545 // a complete method list in iCalcreator manual iCalUtilityFunctions::createTimezone($v, $timezone, $xprops); // create timezone component(-s) opt. 2 // based on all start dates in events (i.e. dtstart) if ($display_format == 'xml') { echo iCal2XML($v); exit; } if ($display_format == 'json') { $xml = simplexml_load_string(iCal2XML($v)); echo json_encode($xml); exit; } $v->returnCalendar(); // redirect calendar file to browser exit; }
/** * Create list of recurrent instances. * * @param Ai1ec_Event $event Event to generate instances for. * @param array $event_instance First instance contents. * @param int $_start Timestamp of first occurence. * @param int $tif Timestamp of last occurence. * @param int $duration Event duration in seconds. * @param string $timezone Target timezone. * * @return array List of event instances. */ public function create_instances_by_recurrence(Ai1ec_Event $event, array $event_instance, $_start, $tif, $duration, $timezone) { $recurrence_parser = $this->_registry->get('recurrence.rule'); $evs = array(); $startdate = array('timestamp' => $_start, 'tz' => $timezone); $enddate = array('timestamp' => $tif, 'tz' => $timezone); $start = $event_instance['start']; $wdate = $startdate = iCalUtilityFunctions::_timestamp2date($startdate, 6); $enddate = iCalUtilityFunctions::_timestamp2date($enddate, 6); $exclude_dates = array(); $recurrence_dates = array(); if ($event->get('exception_rules')) { // creat an array for the rules $exception_rules = $recurrence_parser->build_recurrence_rules_array($event->get('exception_rules')); $exception_rules = iCalUtilityFunctions::_setRexrule($exception_rules); $result = array(); // The first array is the result and it is passed by reference iCalUtilityFunctions::_recur2date($exclude_dates, $exception_rules, $wdate, $startdate, $enddate); } $recurrence_rules = $recurrence_parser->build_recurrence_rules_array($event->get('recurrence_rules')); $recurrence_rules = iCalUtilityFunctions::_setRexrule($recurrence_rules); iCalUtilityFunctions::_recur2date($recurrence_dates, $recurrence_rules, $wdate, $startdate, $enddate); $recurrence_dates = array_keys($recurrence_dates); // Add the instances foreach ($recurrence_dates as $date) { // The arrays are in the form timestamp => true so an isset call is what we need if (isset($exclude_dates[$date])) { continue; } $event_instance['start'] = $date; $event_instance['end'] = $date + $duration; $excluded = false; // Check if exception dates match this occurence if ($exception_dates = $event->get('exception_dates')) { $match_exdates = $this->date_match_exdates($date, $exception_dates, $timezone); if ($match_exdates) { $excluded = true; } } // Add event only if it is not excluded if (false === $excluded) { $evs[] = $event_instance; } } return $evs; }
/** * return initialized calendar tool class for ics export * * @return object */ static function getCalendarTool() { require_once JPATH_SITE . '/components/com_jem/classes/iCalcreator.class.php'; $timezone_name = JemHelper::getTimeZoneName(); $config = JFactory::getConfig(); $sitename = $config->get('sitename'); $config = array("unique_id" => $sitename, "TZID" => $timezone_name); $vcal = new vcalendar($config); if (!file_exists(JPATH_SITE . '/cache/com_jem')) { jimport('joomla.filesystem.folder'); JFolder::create(JPATH_SITE . '/cache/com_jem'); } $vcal->setConfig('directory', JPATH_SITE . '/cache/com_jem'); $vcal->setProperty("calscale", "GREGORIAN"); $vcal->setProperty('method', 'PUBLISH'); $vcal->setProperty("X-WR-TIMEZONE", $timezone_name); $vcal->setProperty("x-wr-calname", "Calendar"); $vcal->setProperty("X-WR-CALDESC", "Calendar Description"); $xprops = array("X-LIC-LOCATION" => $timezone_name); if ($timezone_name != 'UTC') { iCalUtilityFunctions::createTimezone($vcal, $timezone_name, $xprops); } return $vcal; }
/** * transforms a dateTime from a timezone to another using PHP DateTime and DateTimeZone class (PHP >= PHP 5.2.0) * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.11.14 - 2012-01-24 * @param mixed $date, date to alter * @param string $tzFrom, PHP valid old timezone * @param string $tzTo, PHP valid new timezone, default 'UTC' * @param string $format, date output format, default 'Ymd\THis' * @return bool */ public static function transformDateTime(&$date, $tzFrom, $tzTo = 'UTC', $format = 'Ymd\\THis') { if (!class_exists('DateTime') || !class_exists('DateTimeZone')) { return FALSE; } if (is_array($date) && isset($date['timestamp'])) { $timestamp = $date['timestamp']; } elseif (iCalUtilityFunctions::_isArrayDate($date)) { if (isset($date['tz'])) { unset($date['tz']); } $date = iCalUtilityFunctions::_format_date_time(iCalUtilityFunctions::_date_time_array($date)); if ('Z' == substr($date, -1)) { $date = substr($date, 0, strlen($date) - 2); } if (FALSE === ($timestamp = strtotime($date))) { return FALSE; } } elseif (FALSE === ($timestamp = @strtotime($date))) { return FALSE; } try { $d = new DateTime(date('Y-m-d H:i:s', $timestamp), new DateTimeZone($tzFrom)); $d->setTimezone(new DateTimeZone($tzTo)); } catch (Exception $e) { return FALSE; } $date = $d->format($format); return TRUE; }
/** * Returns an array containing time zone data from vtimezone standard/daylight instances * * @param object $vtzc an iCalcreator calendar standard/daylight instance * @return array time zone data; array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname) * */ function expandTimezoneDates($vtzc) { $tzdates = array(); // prepare time zone "description" to attach to each change $tzbefore = array(); $tzbefore['offsetHis'] = $vtzc->getProperty('tzoffsetfrom'); $tzbefore['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzbefore['offsetHis']); if ('-' != substr((string) $tzbefore['offsetSec'], 0, 1) && '+' != substr((string) $tzbefore['offsetSec'], 0, 1)) { $tzbefore['offsetSec'] = '+' . $tzbefore['offsetSec']; } $tzafter = array(); $tzafter['offsetHis'] = $vtzc->getProperty('tzoffsetto'); $tzafter['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzafter['offsetHis']); if ('-' != substr((string) $tzafter['offsetSec'], 0, 1) && '+' != substr((string) $tzafter['offsetSec'], 0, 1)) { $tzafter['offsetSec'] = '+' . $tzafter['offsetSec']; } if (FALSE === ($tzafter['tzname'] = $vtzc->getProperty('tzname'))) { $tzafter['tzname'] = $tzafter['offsetHis']; } // find out where to start from $dtstart = $vtzc->getProperty('dtstart'); $dtstarttimestamp = mktime($dtstart['hour'], $dtstart['min'], $dtstart['sec'], $dtstart['month'], $dtstart['day'], $dtstart['year']); if (!isset($dtstart['unparsedtext'])) { // ?? $dtstart['unparsedtext'] = sprintf('%04d%02d%02dT%02d%02d%02d', $dtstart['year'], $dtstart['month'], $dtstart['day'], $dtstart['hour'], $dtstart['min'], $dtstart['sec']); } if ($dtstarttimestamp == 0) { // it seems that the dtstart string may not have parsed correctly // let's set a timestamp starting from 1902, using the time part of the original string // so that the time will change at the right time of day // at worst we'll get midnight again $origdtstartsplit = explode('T', $dtstart['unparsedtext']); $dtstarttimestamp = strtotime("19020101", 0); $dtstarttimestamp = strtotime($origdtstartsplit[1], $dtstarttimestamp); } // the date (in dtstart and opt RDATE/RRULE) is ALWAYS LOCAL (not utc!!), adjust from 'utc' to 'local' timestamp $diff = -1 * $tzbefore['offsetSec']; $dtstarttimestamp += $diff; // add this (start) change to the array of changes $tzdates[] = array('timestamp' => $dtstarttimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter); $datearray = getdate($dtstarttimestamp); // save original array to use time parts, because strtotime (used below) apparently loses the time $changetime = $datearray; // generate dates according to an RRULE line $rrule = $vtzc->getProperty('rrule'); if (is_array($rrule)) { if ($rrule['FREQ'] == 'YEARLY') { // calculate transition dates starting from DTSTART $offsetchangetimestamp = $dtstarttimestamp; // calculate transition dates until 10 years in the future $stoptimestamp = strtotime("+10 year", time()); // if UNTIL is set, calculate until then (however far ahead) if (isset($rrule['UNTIL']) && $rrule['UNTIL'] != '') { $stoptimestamp = mktime($rrule['UNTIL']['hour'], $rrule['UNTIL']['min'], $rrule['UNTIL']['sec'], $rrule['UNTIL']['month'], $rrule['UNTIL']['day'], $rrule['UNTIL']['year']); } $count = 0; $stopcount = isset($rrule['COUNT']) ? $rrule['COUNT'] : 0; $daynames = array('SU' => 'Sunday', 'MO' => 'Monday', 'TU' => 'Tuesday', 'WE' => 'Wednesday', 'TH' => 'Thursday', 'FR' => 'Friday', 'SA' => 'Saturday'); // repeat so long as we're between DTSTART and UNTIL, or we haven't prepared COUNT dates while ($offsetchangetimestamp < $stoptimestamp && ($stopcount == 0 || $count < $stopcount)) { // break up the timestamp into its parts $datearray = getdate($offsetchangetimestamp); if (isset($rrule['BYMONTH']) && $rrule['BYMONTH'] != 0) { // set the month $datearray['mon'] = $rrule['BYMONTH']; } if (isset($rrule['BYMONTHDAY']) && $rrule['BYMONTHDAY'] != 0) { // set specific day of month $datearray['mday'] = $rrule['BYMONTHDAY']; } elseif (is_array($rrule['BYDAY'])) { // find the Xth WKDAY in the month // the starting point for this process is the first of the month set above $datearray['mday'] = 1; // turn $datearray as it is now back into a timestamp $offsetchangetimestamp = mktime($datearray['hours'], $datearray['minutes'], $datearray['seconds'], $datearray['mon'], $datearray['mday'], $datearray['year']); if ($rrule['BYDAY'][0] > 0) { // to find Xth WKDAY in month, we find last WKDAY in month before // we do that by finding first WKDAY in this month and going back one week // then we add X weeks (below) $offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']], $offsetchangetimestamp); $offsetchangetimestamp = strtotime("-1 week", $offsetchangetimestamp); } else { // to find Xth WKDAY before the end of the month, we find the first WKDAY in the following month // we do that by going forward one month and going to WKDAY there // then we subtract X weeks (below) $offsetchangetimestamp = strtotime("+1 month", $offsetchangetimestamp); $offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']], $offsetchangetimestamp); } // now move forward or back the appropriate number of weeks, into the month we want $offsetchangetimestamp = strtotime($rrule['BYDAY'][0] . " week", $offsetchangetimestamp); $datearray = getdate($offsetchangetimestamp); } // convert the date parts back into a timestamp, setting the time parts according to the // original time data which we stored $offsetchangetimestamp = mktime($changetime['hours'], $changetime['minutes'], $changetime['seconds'] + $diff, $datearray['mon'], $datearray['mday'], $datearray['year']); // add this change to the array of changes $tzdates[] = array('timestamp' => $offsetchangetimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter); // update counters (timestamp and count) $offsetchangetimestamp = strtotime("+" . (isset($rrule['INTERVAL']) && $rrule['INTERVAL'] != 0 ? $rrule['INTERVAL'] : 1) . " year", $offsetchangetimestamp); $count += 1; } } } // generate dates according to RDATE lines while ($rdates = $vtzc->getProperty('rdate')) { if (is_array($rdates)) { foreach ($rdates as $rdate) { // convert the explicit change date to a timestamp $offsetchangetimestamp = mktime($rdate['hour'], $rdate['min'], $rdate['sec'] + $diff, $rdate['month'], $rdate['day'], $rdate['year']); // add this change to the array of changes $tzdates[] = array('timestamp' => $offsetchangetimestamp, 'tzbefore' => $tzbefore, 'tzafter' => $tzafter); } } } return $tzdates; }
/** * cache_event function * * Creates a new entry in the cache table for each date that the event appears * (and does not already have an explicit RECURRENCE-ID instance, given its * iCalendar UID). * * @param Ai1ec_Event $event Event to generate cache table for * * @return void **/ public function cache_event(Ai1ec_Event &$event) { global $wpdb; // Convert event timestamps to local for correct calculations of // recurrence. Need to also remove PHP timezone offset for each date for // SG_iCal to calculate correct recurring instances. $event->start = $this->gmt_to_local($event->start) - date('Z', $event->start); $event->end = $this->gmt_to_local($event->end) - date('Z', $event->end); $evs = array(); $e = array('post_id' => $event->post_id, 'start' => $event->start, 'end' => $event->end); $duration = $event->getDuration(); // Timestamp of today date + 3 years (94608000 seconds) $tif = Ai1ec_Time_Utility::current_time(true) + 94608000; // Always cache initial instance $evs[] = $e; $_start = $event->start; $_end = $event->end; if ($event->recurrence_rules) { $start = $event->start; $wdate = $startdate = iCalUtilityFunctions::_timestamp2date($_start, 6); $enddate = iCalUtilityFunctions::_timestamp2date($tif, 6); $exclude_dates = array(); $recurrence_dates = array(); if ($event->exception_rules) { // creat an array for the rules $exception_rules = $this->build_recurrence_rules_array($event->exception_rules); $exception_rules = iCalUtilityFunctions::_setRexrule($exception_rules); $result = array(); // The first array is the result and it is passed by reference iCalUtilityFunctions::_recur2date($exclude_dates, $exception_rules, $wdate, $startdate, $enddate); } $recurrence_rules = $this->build_recurrence_rules_array($event->recurrence_rules); $recurrence_rules = iCalUtilityFunctions::_setRexrule($recurrence_rules); iCalUtilityFunctions::_recur2date($recurrence_dates, $recurrence_rules, $wdate, $startdate, $enddate); // Add the instances foreach ($recurrence_dates as $date => $bool) { // The arrays are in the form timestamp => true so an isset call is what we need if (isset($exclude_dates[$date])) { continue; } $e['start'] = $date; $e['end'] = $date + $duration; $excluded = false; // Check if exception dates match this occurence if ($event->exception_dates) { if ($this->date_match_exdates($date, $event->exception_dates)) { $excluded = true; } } // Add event only if it is not excluded if ($excluded == false) { $evs[] = $e; } } } // Make entries unique (sometimes recurrence generator creates duplicates?) $evs_unique = array(); foreach ($evs as $ev) { $evs_unique[md5(serialize($ev))] = $ev; } foreach ($evs_unique as $e) { // Find out if this event instance is already accounted for by an // overriding 'RECURRENCE-ID' of the same iCalendar feed (by comparing the // UID, start date, recurrence). If so, then do not create duplicate // instance of event. $start = $this->local_to_gmt($e['start']) - date('Z', $e['start']); $matching_event_id = $event->ical_uid ? $this->get_matching_event_id($event->ical_uid, $event->ical_feed_url, $start, false, $event->post_id) : NULL; // If no other instance was found if (NULL === $matching_event_id) { $start = getdate($e['start']); $end = getdate($e['end']); $this->insert_event_in_cache_table($e); } } return Ai1ec_Events_List_Helper::get_instance()->clean_post_cache($event->post_id); }
/** * Create list of recurrent instances. * * @param Ai1ec_Event $event Event to generate instances for. * @param array $event_instance First instance contents. * @param int $_start Timestamp of first occurence. * @param int $duration Event duration in seconds. * @param string $timezone Target timezone. * * @return array List of event instances. */ public function create_instances_by_recurrence(Ai1ec_Event $event, array $event_instance, $_start, $duration, $timezone) { $restore_timezone = date_default_timezone_get(); $recurrence_parser = $this->_registry->get('recurrence.rule'); $events = array(); $start = $event_instance['start']; $wdate = $startdate = $enddate = $this->_parsed_date_array($_start, $timezone); $enddate['year'] = $enddate['year'] + 3; $exclude_dates = array(); $recurrence_dates = array(); if ($recurrence_dates = $event->get('recurrence_dates')) { $recurrence_dates = $this->_populate_recurring_dates($recurrence_dates, $startdate, $timezone); } if ($exception_dates = $event->get('exception_dates')) { $exclude_dates = $this->_populate_recurring_dates($exception_dates, $startdate, $timezone); } if ($event->get('exception_rules')) { // creat an array for the rules $exception_rules = $recurrence_parser->build_recurrence_rules_array($event->get('exception_rules')); unset($exception_rules['EXDATE']); if (!empty($exception_rules)) { $exception_rules = iCalUtilityFunctions::_setRexrule($exception_rules); $result = array(); date_default_timezone_set($timezone); // The first array is the result and it is passed by reference iCalUtilityFunctions::_recur2date($exclude_dates, $exception_rules, $wdate, $startdate, $enddate); date_default_timezone_set($restore_timezone); } } $recurrence_rules = $recurrence_parser->build_recurrence_rules_array($event->get('recurrence_rules')); $recurrence_rules = iCalUtilityFunctions::_setRexrule($recurrence_rules); if ($recurrence_rules) { date_default_timezone_set($timezone); iCalUtilityFunctions::_recur2date($recurrence_dates, $recurrence_rules, $wdate, $startdate, $enddate); date_default_timezone_set($restore_timezone); } if (!is_array($recurrence_dates)) { $recurrence_dates = array(); } $recurrence_dates = array_keys($recurrence_dates); // Add the instances foreach ($recurrence_dates as $timestamp) { // The arrays are in the form timestamp => true so an isset call is what we need if (!isset($exclude_dates[$timestamp])) { $event_instance['start'] = $timestamp; $event_instance['end'] = $timestamp + $duration; $events[$timestamp] = $event_instance; } } return $events; }
/** * Add a VTIMEZONE using the specified TZID * If VTIMEZONE was already added, do nothing * * @param iCalcomponent * @param string Timezone id to add * @param array (Optional) result from get_timezones() * @return Used TZID, even when it was not added */ function add_vtimezone(&$resource, $tzid, $timezones = array()) { if ($tzid != 'UTC' && !isset($timezones[$tzid])) { $res = iCalUtilityFunctions::createTimezone($resource, $tzid, array('X-LIC-LOCATION' => $tzid)); if ($res === FALSE) { $this->CI->extended_logs->message('ERROR', "Couldn't create vtimezone with tzid=" . $tzid . ' Defaulting to UTC'); $tzid = 'UTC'; } } return $tzid; }
/** * parse component unparsed data into properties * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.20.3 - 2015-03-05 * @param mixed $unparsedtext strict rfc2445 formatted, single property string or array of strings * @uses calendarComponent::getConfig() * @uses iCalUtilityFunctions::convEolChar() * @uses calendarComponent::$unparsed * @uses calendarComponent::$components * @uses calendarComponent::copy() * @uses iCalUtilityFunctions::_splitContent() * @uses calendarComponent::setProperty() * @uses iCalUtilityFunctions::_strunrep() * @uses calendarComponent::parse() * @return bool FALSE if error occurs during parsing */ function parse($unparsedtext = null) { $nl = $this->getConfig('nl'); if (!empty($unparsedtext)) { if (is_array($unparsedtext)) { $unparsedtext = implode('\\n' . $nl, $unparsedtext); } $unparsedtext = iCalUtilityFunctions::convEolChar($unparsedtext, $nl); } elseif (!isset($this->unparsed)) { $unparsedtext = array(); } else { $unparsedtext = $this->unparsed; } /* skip leading (empty/invalid) lines */ foreach ($unparsedtext as $lix => $line) { if (FALSE !== ($pos = stripos($line, 'BEGIN:'))) { $unparsedtext[$lix] = substr($unparsedtext[$lix], $pos); break; } $tst = trim($line); if ('\\n' == $tst || empty($tst)) { unset($unparsedtext[$lix]); } } $this->unparsed = array(); $comp =& $this; $config = $this->getConfig(); $compsync = $subsync = 0; foreach ($unparsedtext as $lix => $line) { if ('END:VALARM' == strtoupper(substr($line, 0, 10))) { if (1 != $subsync) { return FALSE; } $this->components[] = $comp->copy(); $subsync--; } elseif ('END:DAYLIGHT' == strtoupper(substr($line, 0, 12))) { if (1 != $subsync) { return FALSE; } $this->components[] = $comp->copy(); $subsync--; } elseif ('END:STANDARD' == strtoupper(substr($line, 0, 12))) { if (1 != $subsync) { return FALSE; } array_unshift($this->components, $comp->copy()); $subsync--; } elseif ('END:' == strtoupper(substr($line, 0, 4))) { // end:<component> if (1 != $compsync) { return FALSE; } if (0 < $subsync) { $this->components[] = $comp->copy(); } $compsync--; break; /* skip trailing empty lines */ } elseif ('BEGIN:VALARM' == strtoupper(substr($line, 0, 12))) { $comp = new valarm($config); $subsync++; } elseif ('BEGIN:STANDARD' == strtoupper(substr($line, 0, 14))) { $comp = new vtimezone('standard', $config); $subsync++; } elseif ('BEGIN:DAYLIGHT' == strtoupper(substr($line, 0, 14))) { $comp = new vtimezone('daylight', $config); $subsync++; } elseif ('BEGIN:' == strtoupper(substr($line, 0, 6))) { // begin:<component> $compsync++; } else { $comp->unparsed[] = $line; } } if (0 < $subsync) { $this->components[] = $comp->copy(); } unset($config); /* concatenate property values spread over several lines */ $lastix = -1; $propnames = array('action', 'attach', 'attendee', 'categories', 'comment', 'completed', 'contact', 'class', 'created', 'description', 'dtend', 'dtstart', 'dtstamp', 'due', 'duration', 'exdate', 'exrule', 'freebusy', 'geo', 'last-modified', 'location', 'organizer', 'percent-complete', 'priority', 'rdate', 'recurrence-id', 'related-to', 'repeat', 'request-status', 'resources', 'rrule', 'sequence', 'status', 'summary', 'transp', 'trigger', 'tzid', 'tzname', 'tzoffsetfrom', 'tzoffsetto', 'tzurl', 'uid', 'url', 'x-'); $proprows = array(); for ($i = 0; $i < count($this->unparsed); $i++) { // concatenate lines $line = rtrim($this->unparsed[$i], $nl); while (isset($this->unparsed[$i + 1]) && !empty($this->unparsed[$i + 1]) && ' ' == $this->unparsed[$i + 1][0]) { $line .= rtrim(substr($this->unparsed[++$i], 1), $nl); } $proprows[] = $line; } /* parse each property 'line' */ foreach ($proprows as $line) { if ('\\n' == substr($line, -2)) { $line = substr($line, 0, -2); } /* get propname */ $propname = null; $cix = 0; while (isset($line[$cix])) { if (in_array($line[$cix], array(':', ';'))) { break; } else { $propname .= $line[$cix]; } $cix++; } if ('x-' == substr($propname, 0, 2) || 'X-' == substr($propname, 0, 2)) { $propname2 = $propname; $propname = 'X-'; } if (!in_array(strtolower($propname), $propnames)) { // skip non standard property names continue; } /* rest of the line is opt.params and value */ $line = substr($line, $cix); /* separate attributes from value */ iCalUtilityFunctions::_splitContent($line, $propAttr); /* call setProperty( $propname.. . */ switch (strtoupper($propname)) { case 'ATTENDEE': foreach ($propAttr as $pix => $attr) { if (!in_array(strtoupper($pix), array('MEMBER', 'DELEGATED-TO', 'DELEGATED-FROM'))) { continue; } $attr2 = explode(',', $attr); if (1 < count($attr2)) { $propAttr[$pix] = $attr2; } } $this->setProperty($propname, $line, $propAttr); break; case 'CATEGORIES': case 'RESOURCES': if (FALSE !== strpos($line, ',')) { $content = array(0 => ''); $cix = $lix = 0; while (FALSE !== substr($line, $lix, 1)) { if (',' == $line[$lix] && "\\" != $line[$lix - 1]) { $cix++; $content[$cix] = ''; } else { $content[$cix] .= $line[$lix]; } $lix++; } if (1 < count($content)) { $content = array_values($content); foreach ($content as $cix => $contentPart) { $content[$cix] = iCalUtilityFunctions::_strunrep($contentPart); } $this->setProperty($propname, $content, $propAttr); break; } else { $line = reset($content); } } case 'COMMENT': case 'CONTACT': case 'DESCRIPTION': case 'LOCATION': case 'SUMMARY': if (empty($line)) { $propAttr = null; } $this->setProperty($propname, iCalUtilityFunctions::_strunrep($line), $propAttr); break; case 'REQUEST-STATUS': $values = explode(';', $line, 3); $values[1] = !isset($values[1]) ? null : iCalUtilityFunctions::_strunrep($values[1]); $values[2] = !isset($values[2]) ? null : iCalUtilityFunctions::_strunrep($values[2]); $this->setProperty($propname, $values[0], $values[1], $values[2], $propAttr); break; case 'FREEBUSY': $fbtype = isset($propAttr['FBTYPE']) ? $propAttr['FBTYPE'] : ''; // force setting default, if missing unset($propAttr['FBTYPE']); $values = explode(',', $line); foreach ($values as $vix => $value) { $value2 = explode('/', $value); if (1 < count($value2)) { $values[$vix] = $value2; } } $this->setProperty($propname, $fbtype, $values, $propAttr); break; case 'GEO': $value = explode(';', $line, 2); if (2 > count($value)) { $value[1] = null; } $this->setProperty($propname, $value[0], $value[1], $propAttr); break; case 'EXDATE': $values = !empty($line) ? explode(',', $line) : null; $this->setProperty($propname, $values, $propAttr); break; case 'RDATE': if (empty($line)) { $this->setProperty($propname, $line, $propAttr); break; } $values = explode(',', $line); foreach ($values as $vix => $value) { $value2 = explode('/', $value); if (1 < count($value2)) { $values[$vix] = $value2; } } $this->setProperty($propname, $values, $propAttr); break; case 'EXRULE': case 'RRULE': $values = explode(';', $line); $recur = array(); foreach ($values as $value2) { if (empty($value2)) { continue; } // ;-char in ending position ??? $value3 = explode('=', $value2, 2); $rulelabel = strtoupper($value3[0]); switch ($rulelabel) { case 'BYDAY': $value4 = explode(',', $value3[1]); if (1 < count($value4)) { foreach ($value4 as $v5ix => $value5) { $value6 = array(); $dayno = $dayname = null; $value5 = trim((string) $value5); if (ctype_alpha(substr($value5, -1)) && ctype_alpha(substr($value5, -2, 1))) { $dayname = substr($value5, -2, 2); if (2 < strlen($value5)) { $dayno = substr($value5, 0, strlen($value5) - 2); } } if ($dayno) { $value6[] = $dayno; } if ($dayname) { $value6['DAY'] = $dayname; } $value4[$v5ix] = $value6; } } else { $value4 = array(); $dayno = $dayname = null; $value5 = trim((string) $value3[1]); if (ctype_alpha(substr($value5, -1)) && ctype_alpha(substr($value5, -2, 1))) { $dayname = substr($value5, -2, 2); if (2 < strlen($value5)) { $dayno = substr($value5, 0, strlen($value5) - 2); } } if ($dayno) { $value4[] = $dayno; } if ($dayname) { $value4['DAY'] = $dayname; } } $recur[$rulelabel] = $value4; break; default: $value4 = explode(',', $value3[1]); if (1 < count($value4)) { $value3[1] = $value4; } $recur[$rulelabel] = $value3[1]; break; } // end - switch $rulelabel } // end - foreach( $values.. . $this->setProperty($propname, $recur, $propAttr); break; case 'X-': $propname = isset($propname2) ? $propname2 : $propname; unset($propname2); case 'ACTION': case 'CLASSIFICATION': case 'STATUS': case 'TRANSP': case 'UID': case 'TZID': case 'RELATED-TO': case 'TZNAME': $line = iCalUtilityFunctions::_strunrep($line); default: $this->setProperty($propname, $line, $propAttr); break; } // end switch( $propname.. . } // end - foreach( $proprows.. . unset($unparsedtext, $this->unparsed, $proprows); if (isset($this->components) && is_array($this->components) && 0 < count($this->components)) { $ckeys = array_keys($this->components); foreach ($ckeys as $ckey) { if (!empty($this->components[$ckey]) && !empty($this->components[$ckey]->unparsed)) { $this->components[$ckey]->parse(); } } } return TRUE; }
/** * cache_event function * * Creates a new entry in the cache table for each date that the event appears * (and does not already have an explicit RECURRENCE-ID instance, given its * iCalendar UID). * * @param object $event Event to generate cache table for * * @return void **/ function cache_event(&$event) { global $wpdb; // Convert event's timestamps to local for correct calculations of // recurrence. Need to also remove PHP timezone offset for each date for // SG_iCal to calculate correct recurring instances. $event->start = $this->gmt_to_local($event->start) - date('Z', $event->start); $event->end = $this->gmt_to_local($event->end) - date('Z', $event->end); $evs = array(); $e = array('post_id' => $event->post_id, 'start' => $event->start, 'end' => $event->end); $duration = $event->getDuration(); // Timestamp of today's date + 3 years $tif = Ai1ec_Time_Utility::current_time(true) + 94608000; //94 608 000 = 3 years in seconds // Always cache initial instance $evs[] = $e; $_start = $event->start; $_end = $event->end; if ($event->recurrence_rules) { $start = $event->start; $wdate = $startdate = iCalUtilityFunctions::_timestamp2date($_start, 6); $enddate = iCalUtilityFunctions::_timestamp2date($tif, 6); $exclude_dates = array(); $recurrence_dates = array(); if ($event->exception_rules) { // creat an array for the rules $exception_rules = $this->build_recurrence_rules_array($event->exception_rules); $exception_rules = iCalUtilityFunctions::_setRexrule($exception_rules); $result = array(); // The first array is the result and it's passed by reference iCalUtilityFunctions::_recur2date($exclude_dates, $exception_rules, $wdate, $startdate, $enddate); } $recurrence_rules = $this->build_recurrence_rules_array($event->recurrence_rules); $recurrence_rules = iCalUtilityFunctions::_setRexrule($recurrence_rules); iCalUtilityFunctions::_recur2date($recurrence_dates, $recurrence_rules, $wdate, $startdate, $enddate); // Add the instances foreach ($recurrence_dates as $date => $bool) { // The arrays are in the form timestamp => true so an isset call is what we need if (isset($exclude_dates[$date])) { continue; } $e['start'] = $date; $e['end'] = $date + $duration; $excluded = false; // Check if exception dates match this occurence if ($event->exception_dates) { if ($this->date_match_exdates($date, $event->exception_dates)) { $excluded = true; } } // Add event only if it is not excluded if ($excluded == false) { $evs[] = $e; } } } foreach ($evs as $e) { // Find out if this event instance is already accounted for by an // overriding 'RECURRENCE-ID' of the same iCalendar feed (by comparing the // UID, start date, recurrence). If so, then do not create duplicate // instance of event. $matching_event_id = $event->ical_uid ? $this->get_matching_event_id($event->ical_uid, $event->ical_feed_url, $start = $this->local_to_gmt($e['start']) - date('Z', $e['start']), false, $event->post_id) : null; // If no other instance was found if (is_null($matching_event_id)) { $start = getdate($e['start']); $end = getdate($e['end']); /* // Commented out for now // If event spans a day and end time is not midnight, or spans more than // a day, then create instance for each spanning day if( ( $start['mday'] != $end['mday'] && ( $end['hours'] || $end['minutes'] || $end['seconds'] ) ) || $e['end'] - $e['start'] > 60 * 60 * 24 ) { $this->create_cache_table_entries( $e ); // Else cache single instance of event } else { $this->insert_event_in_cache_table( $e ); } */ $this->insert_event_in_cache_table($e); } } }
/** * Generate ical file content * * @param $who user ID * @param $who_group group ID * @param $limititemtype itemtype only display this itemtype (default '') * * @return icalendar string **/ static function generateIcal($who, $who_group, $limititemtype = '') { global $CFG_GLPI; if ($who === 0 && $who_group === 0) { return false; } include_once GLPI_ROOT . "/lib/icalcreator/iCalcreator.class.php"; $v = new vcalendar(); if (!empty($CFG_GLPI["version"])) { $v->setConfig('unique_id', "GLPI-Planning-" . trim($CFG_GLPI["version"])); } else { $v->setConfig('unique_id', "GLPI-Planning-UnknownVersion"); } $tz = date_default_timezone_get(); $v->setConfig('TZID', $tz); $v->setProperty("method", "PUBLISH"); $v->setProperty("version", "2.0"); $v->setProperty("X-WR-TIMEZONE", $tz); $xprops = array("X-LIC-LOCATION" => $tz); iCalUtilityFunctions::createTimezone($v, $tz, $xprops); $v->setProperty("x-wr-calname", "GLPI-" . $who . "-" . $who_group); $v->setProperty("calscale", "GREGORIAN"); $interv = array(); $begin = time() - MONTH_TIMESTAMP * 12; $end = time() + MONTH_TIMESTAMP * 12; $begin = date("Y-m-d H:i:s", $begin); $end = date("Y-m-d H:i:s", $end); $params = array('who' => $who, 'who_group' => $who_group, 'begin' => $begin, 'end' => $end); $interv = array(); if (empty($limititemtype)) { foreach ($CFG_GLPI['planning_types'] as $itemtype) { $interv = array_merge($interv, $itemtype::populatePlanning($params)); } } else { $interv = $limititemtype::populatePlanning($params); } if (count($interv) > 0) { foreach ($interv as $key => $val) { $vevent = new vevent(); //initiate EVENT if (isset($val['itemtype'])) { if (isset($val[getForeignKeyFieldForItemType($val['itemtype'])])) { $vevent->setProperty("uid", $val['itemtype'] . "#" . $val[getForeignKeyFieldForItemType($val['itemtype'])]); } else { $vevent->setProperty("uid", "Other#" . $key); } } else { $vevent->setProperty("uid", "Other#" . $key); } $vevent->setProperty("dstamp", $val["begin"]); $vevent->setProperty("dtstart", $val["begin"]); $vevent->setProperty("dtend", $val["end"]); if (isset($val["tickets_id"])) { $vevent->setProperty("summary", sprintf(__('Ticket #%1$s %2$s'), $val["tickets_id"], $val["name"])); } else { if (isset($val["name"])) { $vevent->setProperty("summary", $val["name"]); } } if (isset($val["content"])) { $text = $val["content"]; // be sure to replace nl by \r\n $text = preg_replace("/<br( [^>]*)?" . ">/i", "\r\n", $text); $text = Html::clean($text); $vevent->setProperty("description", $text); } else { if (isset($val["name"])) { $text = $val["name"]; // be sure to replace nl by \r\n $text = preg_replace("/<br( [^>]*)?" . ">/i", "\r\n", $text); $text = Html::clean($text); $vevent->setProperty("description", $text); } } if (isset($val["url"])) { $vevent->setProperty("url", $val["url"]); } $v->setComponent($vevent); } } $v->sort(); // $v->parse(); return $v->returnCalendar(); }
/** * Create calendar * Adds timezone component, when not already done * * @see http://kigkonsult.se/iCalcreator/docs/using.html#createTimezone * * @return string */ public function createCalendar() { // add timezone component if ($this->timezone && $this->getComponent('VTIMEZONE') === false) { $xprops = array('X-LIC-LOCATION' => $this->timezone); \iCalUtilityFunctions::createTimezone($this, $this->timezone, $xprops); } return parent::createCalendar(); }
/** * export_events function * * Export events * * @return void **/ function export_events() { global $ai1ec_events_helper, $ai1ec_exporter_helper, $ai1ec_localization_helper; $ai1ec_cat_ids = !empty($_REQUEST['ai1ec_cat_ids']) ? $_REQUEST['ai1ec_cat_ids'] : false; $ai1ec_tag_ids = !empty($_REQUEST['ai1ec_tag_ids']) ? $_REQUEST['ai1ec_tag_ids'] : false; $ai1ec_post_ids = !empty($_REQUEST['ai1ec_post_ids']) ? $_REQUEST['ai1ec_post_ids'] : false; if (!empty($_REQUEST['lang'])) { $ai1ec_localization_helper->set_language($_REQUEST['lang']); } $filter = array(); if ($ai1ec_cat_ids) { $filter['cat_ids'] = explode(',', $ai1ec_cat_ids); } if ($ai1ec_tag_ids) { $filter['tag_ids'] = explode(',', $ai1ec_tag_ids); } if ($ai1ec_post_ids) { $filter['post_ids'] = explode(',', $ai1ec_post_ids); } // when exporting events by post_id, do not look up the event's start/end date/time $start = $ai1ec_post_ids !== false ? false : Ai1ec_Time_Utility::current_time(true) - 24 * 60 * 60; // Include any events ending today $end = false; $c = new vcalendar(); $c->setProperty('calscale', 'GREGORIAN'); $c->setProperty('method', 'PUBLISH'); $c->setProperty('X-WR-CALNAME', get_bloginfo('name')); $c->setProperty('X-WR-CALDESC', get_bloginfo('description')); $c->setProperty('X-FROM-URL', home_url()); // Timezone setup $tz = Ai1ec_Meta::get_option('timezone_string'); if ($tz) { $c->setProperty('X-WR-TIMEZONE', $tz); $tz_xprops = array('X-LIC-LOCATION' => $tz); iCalUtilityFunctions::createTimezone($c, $tz, $tz_xprops); } $events = $ai1ec_events_helper->get_matching_events($start, $end, $filter); foreach ($events as $event) { $ai1ec_exporter_helper->insert_event_in_calendar($event, $c, $export = true); } $str = ltrim($c->createCalendar()); header('Content-type: text/calendar; charset=utf-8'); echo $str; exit; }
/** * Add children to a SimpleXMLelement * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.18.10 - 2013-09-04 * @param object $parent reference to a SimpleXMLelement node * @param string $name new element node name * @param string $type content type, subelement(-s) name * @param string $content new subelement content * @param array $params new element 'attributes' * @uses iCalUtilityFunctions::_duration2str() * @uses iCalUtilityFunctions::_geo2str2() * @uses iCalUtilityFunctions::$geoLatFmt * @uses iCalUtilityFunctions::$geoLongFmt * @return void */ function _addXMLchild(&$parent, $name, $type, $content, $params = array()) { static $fmtYmd = '%04d-%02d-%02d'; static $fmtYmdHis = '%04d-%02d-%02dT%02d:%02d:%02d'; /** create new child node */ $name = strtolower($name); $child = $parent->addChild($name); if (!empty($params)) { $parameters = $child->addChild('parameters'); foreach ($params as $param => $parVal) { if ('VALUE' == $param) { continue; } $param = strtolower($param); if ('x-' == substr($param, 0, 2)) { $p1 = $parameters->addChild($param); $p2 = $p1->addChild('unknown', htmlspecialchars($parVal)); } else { $p1 = $parameters->addChild($param); switch ($param) { case 'altrep': case 'dir': $ptype = 'uri'; break; case 'delegated-from': case 'delegated-to': case 'member': case 'sent-by': $ptype = 'cal-address'; break; case 'rsvp': $ptype = 'boolean'; break; default: $ptype = 'text'; break; } if (is_array($parVal)) { foreach ($parVal as $pV) { $p2 = $p1->addChild($ptype, htmlspecialchars($pV)); } } else { $p2 = $p1->addChild($ptype, htmlspecialchars($parVal)); } } } } // end if( !empty( $params )) if (empty($content) && '0' != $content || !is_array($content) && ('-' != substr($content, 0, 1) && 0 > $content)) { return; } /** store content */ switch ($type) { case 'binary': $v = $child->addChild($type, $content); break; case 'boolean': break; case 'cal-address': $v = $child->addChild($type, $content); break; case 'date': if (array_key_exists('year', $content)) { $content = array($content); } foreach ($content as $date) { $str = sprintf($fmtYmd, (int) $date['year'], (int) $date['month'], (int) $date['day']); $v = $child->addChild($type, $str); } break; case 'date-time': if (array_key_exists('year', $content)) { $content = array($content); } foreach ($content as $dt) { if (!isset($dt['hour'])) { $dt['hour'] = 0; } if (!isset($dt['min'])) { $dt['min'] = 0; } if (!isset($dt['sec'])) { $dt['sec'] = 0; } $str = sprintf($fmtYmdHis, (int) $dt['year'], (int) $dt['month'], (int) $dt['day'], (int) $dt['hour'], (int) $dt['min'], (int) $dt['sec']); if (isset($dt['tz']) && 'Z' == $dt['tz']) { $str .= 'Z'; } $v = $child->addChild($type, $str); } break; case 'duration': $output = 'trigger' == $name && FALSE !== $content['before'] ? '-' : ''; $v = $child->addChild($type, $output . iCalUtilityFunctions::_duration2str($content)); break; case 'geo': if (!empty($content)) { $v1 = $child->addChild('latitude', iCalUtilityFunctions::_geo2str2($content['latitude'], iCalUtilityFunctions::$geoLatFmt)); $v1 = $child->addChild('longitude', iCalUtilityFunctions::_geo2str2($content['longitude'], iCalUtilityFunctions::$geoLongFmt)); } break; case 'integer': $v = $child->addChild($type, (string) $content); break; case 'period': if (!is_array($content)) { break; } foreach ($content as $period) { $v1 = $child->addChild($type); $str = sprintf($fmtYmdHis, (int) $period[0]['year'], (int) $period[0]['month'], (int) $period[0]['day'], (int) $period[0]['hour'], (int) $period[0]['min'], (int) $period[0]['sec']); if (isset($period[0]['tz']) && 'Z' == $period[0]['tz']) { $str .= 'Z'; } $v2 = $v1->addChild('start', $str); if (array_key_exists('year', $period[1])) { $str = sprintf($fmtYmdHis, (int) $period[1]['year'], (int) $period[1]['month'], (int) $period[1]['day'], (int) $period[1]['hour'], (int) $period[1]['min'], (int) $period[1]['sec']); if (isset($period[1]['tz']) && 'Z' == $period[1]['tz']) { $str .= 'Z'; } $v2 = $v1->addChild('end', $str); } else { $v2 = $v1->addChild('duration', iCalUtilityFunctions::_duration2str($period[1])); } } break; case 'recur': $content = array_change_key_case($content); foreach ($content as $rulelabel => $rulevalue) { switch ($rulelabel) { case 'until': if (isset($rulevalue['hour'])) { $str = sprintf($fmtYmdHis, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'], (int) $rulevalue['hour'], (int) $rulevalue['min'], (int) $rulevalue['sec']) . 'Z'; } else { $str = sprintf($fmtYmd, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day']); } $v = $child->addChild($rulelabel, $str); break; case 'bysecond': case 'byminute': case 'byhour': case 'bymonthday': case 'byyearday': case 'byweekno': case 'bymonth': case 'bysetpos': if (is_array($rulevalue)) { foreach ($rulevalue as $vix => $valuePart) { $v = $child->addChild($rulelabel, $valuePart); } } else { $v = $child->addChild($rulelabel, $rulevalue); } break; case 'byday': if (isset($rulevalue['DAY'])) { $str = isset($rulevalue[0]) ? $rulevalue[0] : ''; $str .= $rulevalue['DAY']; $p = $child->addChild($rulelabel, $str); } else { foreach ($rulevalue as $valuePart) { if (isset($valuePart['DAY'])) { $str = isset($valuePart[0]) ? $valuePart[0] : ''; $str .= $valuePart['DAY']; $p = $child->addChild($rulelabel, $str); } else { $p = $child->addChild($rulelabel, $valuePart); } } } break; case 'freq': case 'count': case 'interval': case 'wkst': default: $p = $child->addChild($rulelabel, $rulevalue); break; } // end switch( $rulelabel ) } // end foreach( $content as $rulelabel => $rulevalue ) break; case 'rstatus': $v = $child->addChild('code', number_format((double) $content['statcode'], 2, '.', '')); $v = $child->addChild('description', htmlspecialchars($content['text'])); if (isset($content['extdata'])) { $v = $child->addChild('data', htmlspecialchars($content['extdata'])); } break; case 'text': if (!is_array($content)) { $content = array($content); } foreach ($content as $part) { $v = $child->addChild($type, htmlspecialchars($part)); } break; case 'time': break; case 'uri': $v = $child->addChild($type, $content); break; case 'utc-offset': if (in_array(substr($content, 0, 1), array('-', '+'))) { $str = substr($content, 0, 1); $content = substr($content, 1); } else { $str = '+'; } $str .= substr($content, 0, 2) . ':' . substr($content, 2, 2); if (4 < strlen($content)) { $str .= ':' . substr($content, 4); } $v = $child->addChild($type, $str); break; case 'unknown': default: if (is_array($content)) { $content = implode('', $content); } $v = $child->addChild('unknown', htmlspecialchars($content)); break; } }