/** * 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; }
/** * set calendar component property trigger * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.16.21 - 2013-06-23 * @param mixed $year * @param mixed $month * @param int $day * @param int $week * @param int $hour * @param int $min * @param int $sec * @param bool $relatedStart * @param bool $before * @param array $params * @uses calendarComponent::getConfig() * @uses calendarComponent::$trigger * @uses iCalUtilityFunctions::_setParams() * @uses iCalUtilityFunctions::_isArrayTimestampDate() * @uses iCalUtilityFunctions::_timestamp2date() * @uses iCalUtilityFunctions::_strdate2date() * @uses iCalUtilityFunctions::_duration2arr() * @return bool */ function setTrigger($year, $month = null, $day = null, $week = FALSE, $hour = FALSE, $min = FALSE, $sec = FALSE, $relatedStart = TRUE, $before = TRUE, $params = FALSE) { if (empty($year) && (empty($month) || is_array($month)) && empty($day) && empty($week) && empty($hour) && empty($min) && empty($sec)) { if ($this->getConfig('allowEmpty')) { $this->trigger = array('value' => '', 'params' => iCalUtilityFunctions::_setParams($month)); return TRUE; } else { return FALSE; } } if (iCalUtilityFunctions::_isArrayTimestampDate($year)) { // timestamp UTC $params = iCalUtilityFunctions::_setParams($month); $date = iCalUtilityFunctions::_timestamp2date($year, 7); foreach ($date as $k => $v) { ${$k} = $v; } } elseif (is_array($year) && (is_array($month) || empty($month))) { $params = iCalUtilityFunctions::_setParams($month); if (!(array_key_exists('year', $year) && array_key_exists('month', $year) && array_key_exists('day', $year))) { // when this must be a duration if (isset($params['RELATED']) && 'END' == strtoupper($params['RELATED'])) { $relatedStart = FALSE; } else { $relatedStart = array_key_exists('relatedStart', $year) && TRUE !== $year['relatedStart'] ? FALSE : TRUE; } $before = array_key_exists('before', $year) && TRUE !== $year['before'] ? FALSE : TRUE; } $SSYY = array_key_exists('year', $year) ? $year['year'] : null; $month = array_key_exists('month', $year) ? $year['month'] : null; $day = array_key_exists('day', $year) ? $year['day'] : null; $week = array_key_exists('week', $year) ? $year['week'] : null; $hour = array_key_exists('hour', $year) ? $year['hour'] : 0; //null; $min = array_key_exists('min', $year) ? $year['min'] : 0; //null; $sec = array_key_exists('sec', $year) ? $year['sec'] : 0; //null; $year = $SSYY; } elseif (is_string($year) && (is_array($month) || empty($month))) { // duration or date in a string $params = iCalUtilityFunctions::_setParams($month); if (in_array($year[0], array('P', '+', '-'))) { // duration $relatedStart = isset($params['RELATED']) && 'END' == strtoupper($params['RELATED']) ? FALSE : TRUE; $before = '-' == $year[0] ? TRUE : FALSE; if ('P' != $year[0]) { $year = substr($year, 1); } $date = iCalUtilityFunctions::_durationStr2arr($year); } else { // date $date = iCalUtilityFunctions::_strdate2date($year, 7); } unset($year, $month, $day, $date['unparsedtext']); if (empty($date)) { $sec = 0; } else { foreach ($date as $k => $v) { ${$k} = $v; } } } else { // single values in function input parameters $params = iCalUtilityFunctions::_setParams($params); } if (!empty($year) && !empty($month) && !empty($day)) { // date $params['VALUE'] = 'DATE-TIME'; $hour = $hour ? $hour : 0; $min = $min ? $min : 0; $sec = $sec ? $sec : 0; $this->trigger = array('params' => $params); $this->trigger['value'] = array('year' => $year, 'month' => $month, 'day' => $day, 'hour' => $hour, 'min' => $min, 'sec' => $sec, 'tz' => 'Z'); return TRUE; } elseif (empty($year) && empty($month) && (!empty($week) || 0 == $week || (!empty($day) || 0 == $day) || (!empty($hour) || 0 == $hour) || (!empty($min) || 0 == $min) || (!empty($sec) || 0 == $sec))) { unset($params['RELATED']); // set at output creation (END only) unset($params['VALUE']); // 'DURATION' default $this->trigger = array('params' => $params); $this->trigger['value'] = array(); if (!empty($week)) { $this->trigger['value']['week'] = $week; } if (!empty($day)) { $this->trigger['value']['day'] = $day; } if (!empty($hour)) { $this->trigger['value']['hour'] = $hour; } if (!empty($min)) { $this->trigger['value']['min'] = $min; } if (!empty($sec)) { $this->trigger['value']['sec'] = $sec; } if (empty($this->trigger['value'])) { $this->trigger['value']['sec'] = 0; $before = FALSE; } else { $this->trigger['value'] = iCalUtilityFunctions::_duration2arr($this->trigger['value']); } $relatedStart = FALSE !== $relatedStart ? TRUE : FALSE; $before = FALSE !== $before ? TRUE : FALSE; $this->trigger['value']['relatedStart'] = $relatedStart; $this->trigger['value']['before'] = $before; return TRUE; } return FALSE; }
/** * convert format for input date (UTC) to internal date with parameters * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @since 2.14.4 - 2012-10-06 * @param mixed $year * @param mixed $month optional * @param int $day optional * @param int $hour optional * @param int $min optional * @param int $sec optional * @param array $params optional * @return array */ public static function _setDate2($year, $month = FALSE, $day = FALSE, $hour = FALSE, $min = FALSE, $sec = FALSE, $params = FALSE) { $input = null; iCalUtilityFunctions::_strDate2arr($year); if (iCalUtilityFunctions::_isArrayDate($year)) { $input['value'] = iCalUtilityFunctions::_chkDateArr($year, 7); if (isset($input['value']['year']) && 100 > $input['value']['year']) { $input['value']['year'] += 2000; } $input['params'] = iCalUtilityFunctions::_setParams($month, array('VALUE' => 'DATE-TIME')); if (isset($input['value']['tz']) && 'Z' != $input['value']['tz'] && iCalUtilityFunctions::_isOffset($input['value']['tz'])) { $d = $input['value']; $strdate = sprintf('%04d-%02d-%02d %02d:%02d:%02d %s', $d['year'], $d['month'], $d['day'], $d['hour'], $d['min'], $d['sec'], $d['tz']); $input['value'] = iCalUtilityFunctions::_strdate2date($strdate, 7); unset($input['value']['unparsedtext']); } } elseif (iCalUtilityFunctions::_isArrayTimestampDate($year)) { $year['tz'] = 'UTC'; $input['value'] = iCalUtilityFunctions::_timestamp2date($year, 7); $input['params'] = iCalUtilityFunctions::_setParams($month, array('VALUE' => 'DATE-TIME')); } elseif (8 <= strlen(trim($year))) { // ex. 2006-08-03 10:12:18 $input['value'] = iCalUtilityFunctions::_strdate2date($year, 7); unset($input['value']['unparsedtext']); $input['params'] = iCalUtilityFunctions::_setParams($month, array('VALUE' => 'DATE-TIME')); } else { $input['value'] = array('year' => $year, 'month' => $month, 'day' => $day, 'hour' => $hour, 'min' => $min, 'sec' => $sec); if (isset($tz)) { $input['value']['tz'] = $tz; } if (isset($tz) && iCalUtilityFunctions::_isOffset($tz) || isset($input['params']['TZID']) && iCalUtilityFunctions::_isOffset($input['params']['TZID'])) { if (!isset($tz) && isset($input['params']['TZID']) && iCalUtilityFunctions::_isOffset($input['params']['TZID'])) { $input['value']['tz'] = $input['params']['TZID']; } unset($input['params']['TZID']); $strdate = iCalUtilityFunctions::_date2strdate($input['value'], 7); $input['value'] = iCalUtilityFunctions::_strdate2date($strdate, 7); unset($input['value']['unparsedtext']); } $input['params'] = iCalUtilityFunctions::_setParams($params, array('VALUE' => 'DATE-TIME')); } $parno = iCalUtilityFunctions::_existRem($input['params'], 'VALUE', 'DATE-TIME', 7); // remove default if (!isset($input['value']['hour'])) { $input['value']['hour'] = 0; } if (!isset($input['value']['min'])) { $input['value']['min'] = 0; } if (!isset($input['value']['sec'])) { $input['value']['sec'] = 0; } $input['value']['tz'] = 'Z'; return $input; }
/** * step date, return updated date, array and timpstamp * * @author Kjell-Inge Gustafsson, kigkonsult <*****@*****.**> * @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; } } }
/** * 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); } } }
/** * 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); }