/** * Create instances of a recurring event * * @param array Hash array with event properties * @param object DateTime Start date of the recurrence window * @param object DateTime End date of the recurrence window * @param string ID of a specific recurring event instance * @return array List of recurring event instances */ public function get_recurring_events($event, $start, $end = null, $event_id = null) { $object = $event['_formatobj']; if (!$object) { $rec = $this->storage->get_object($event['id']); $object = $rec['_formatobj']; } if (!is_object($object)) { return array(); } // determine a reasonable end date if none given if (!$end) { switch ($event['recurrence']['FREQ']) { case 'YEARLY': $intvl = 'P100Y'; break; case 'MONTHLY': $intvl = 'P20Y'; break; default: $intvl = 'P10Y'; break; } $end = clone $event['start']; $end->add(new DateInterval($intvl)); } // add recurrence exceptions to output $i = 0; $events = array(); $exdates = array(); $futuredata = array(); if (is_array($event['recurrence']['EXCEPTIONS'])) { // copy the recurrence rule from the master event (to be used in the UI) $recurrence_rule = $event['recurrence']; unset($recurrence_rule['EXCEPTIONS'], $recurrence_rule['EXDATE']); foreach ($event['recurrence']['EXCEPTIONS'] as $exception) { $rec_event = $this->_to_rcube_event($exception); $rec_event['id'] = $event['uid'] . '-' . ++$i; $rec_event['recurrence_id'] = $event['uid']; $rec_event['recurrence'] = $recurrence_rule; $rec_event['_instance'] = $i; $rec_event['isexception'] = 1; $events[] = $rec_event; // found the specifically requested instance, exiting... if ($rec_event['id'] == $event_id) { $this->events[$rec_event['id']] = $rec_event; return $events; } // remember this exception's date $exdate = $rec_event['start']->format('Y-m-d'); $exdates[$exdate] = $rec_event['id']; if ($rec_event['thisandfuture']) { $futuredata[$exdate] = $rec_event; } } } // use libkolab to compute recurring events if (class_exists('kolabcalendaring')) { $recurrence = new kolab_date_recurrence($object); } else { // fallback to local recurrence implementation require_once $this->cal->home . '/lib/calendar_recurrence.php'; $recurrence = new calendar_recurrence($this->cal, $event); } while ($next_event = $recurrence->next_instance()) { // skip if there's an exception at this date $datestr = $next_event['start']->format('Y-m-d'); if ($exdates[$datestr]) { // use this event data for future recurring instances if ($futuredata[$datestr]) { $overlay_data = $futuredata[$datestr]; } continue; } // add to output if in range $rec_id = $event['uid'] . '-' . ++$i; if ($next_event['start'] <= $end && $next_event['end'] >= $start || $event_id && $rec_id == $event_id) { $rec_event = $this->_to_rcube_event($next_event); if ($overlay_data) { // copy data from a 'this-and-future' exception $this->_merge_event_data($rec_event, $overlay_data); } $rec_event['id'] = $rec_id; $rec_event['recurrence_id'] = $event['uid']; $rec_event['_instance'] = $i; unset($rec_event['_attendees']); $events[] = $rec_event; if ($rec_id == $event_id) { $this->events[$rec_id] = $rec_event; break; } } else { if ($next_event['start'] > $end) { // stop loop if out of range break; } } // avoid endless recursion loops if ($i > 1000) { break; } } return $events; }
/** * */ private function get_recurrence_count($event, $dtstart) { // use libkolab to compute recurring events if (class_exists('kolabcalendaring') && $event['_formatobj']) { $recurrence = new kolab_date_recurrence($event['_formatobj']); } else { // fallback to local recurrence implementation require_once $this->cal->home . '/lib/calendar_recurrence.php'; $recurrence = new calendar_recurrence($this->cal, $event); } $count = 0; while (($next_event = $recurrence->next_instance()) && $next_event['start'] <= $dtstart && $count < 1000) { $count++; } return $count; }
/** * Create instances of a recurring event * * @param array Hash array with event properties * @param object DateTime Start date of the recurrence window * @param object DateTime End date of the recurrence window * @return array List of recurring event instances */ public function get_recurring_events($event, $start, $end = null) { $events = array(); if ($event['recurrence']) { // include library class require_once dirname(__FILE__) . '/../lib/calendar_recurrence.php'; $rcmail = rcmail::get_instance(); $recurrence = new calendar_recurrence($rcmail->plugins->get_plugin('calendar'), $event); // determine a reasonable end date if none given if (!$end) { switch ($event['recurrence']['FREQ']) { case 'YEARLY': $intvl = 'P100Y'; break; case 'MONTHLY': $intvl = 'P20Y'; break; default: $intvl = 'P10Y'; break; } $end = clone $event['start']; $end->add(new DateInterval($intvl)); } $i = 0; while ($next_event = $recurrence->next_instance()) { $next_event['uid'] = $event['uid'] . '-' . ++$i; // add to output if in range if ($next_event['start'] <= $end && $next_event['end'] >= $start) { $next_event['id'] = $next_event['uid']; $next_event['recurrence_id'] = $event['uid']; $next_event['_instance'] = $i; $events[] = $next_event; } else { if ($next_event['start'] > $end) { // stop loop if out of range break; } } // avoid endless recursion loops if ($i > 1000) { break; } } } return $events; }