/** * Example taken from http://www.kanzaki.com/docs/ical/rrule.html */ public function testUntil() { $rule = new RecurrenceRule(); $rule->setFreq(RecurrenceRule::FREQ_DAILY); $rule->setInterval(null); $rule->setUntil(new \DateTime('1997-12-24')); $this->assertEquals('FREQ=DAILY;UNTIL=19971224T000000Z', $rule->getEscapedValue()); }
/** * @param $Until timestamp Date to generate occurrences up to. * @param $EventId * - integer Event id. * - FALSE all events. * @return int Number of occurrences created. * * This should be called periodically with an increased @a $Until. * * This should be called for new recurring events before being published */ function EventsGenerateRecurrences($Until, $EventId = FALSE) { if ($this->mReadOnly) { throw new Exception(self::$cReadOnlyMessage); } // Initial query to get the events $bind_data = array(); $sql_select_events = ' SELECT events.event_id, events.event_name, ' . $this->recurrence_model->SqlSelectRecurrenceRule() . ' FROM events INNER JOIN recurrence_rules ON events.event_recurrence_rule_id = recurrence_rules.recurrence_rule_id WHERE events.event_deleted = 0 AND ( events.event_recurrence_updated_until < FROM_UNIXTIME(?) OR events.event_recurrence_updated_until IS NULL)'; $bind_data[] = $Until; if (FALSE !== $EventId) { $sql_select_events .= ' AND event.event_id = ?'; $bind_data[] = $EventId; } // Perform the query now $query = $this->db->query($sql_select_events, $bind_data); // Return values $occurrences_created = 0; $events_generated = 0; $events_mutexed = 0; $mutexes_stolen = 0; // foreach event if ($query->num_rows() > 0) { $events = $query->result_array(); foreach ($events as $event) { // Query to set the event recurrence mutex and timestamp // Note that affected_rows will only be 1 if // the event exists AND // the mutex isn't already set, // OR timestamp is NULL, // OR timestamp is more than an hour in the past // I.E. the mutex is lost after 5 minutes $sql_set_mutex = ' UPDATE events SET events.event_recurrence_mutex = 1, events.event_timestamp = CURRENT_TIMESTAMP() WHERE events.event_id = ? AND ( events.event_recurrence_mutex = 0 OR events.event_timestamp = NULL OR events.event_timestamp < DATE_SUB(CURRENT_TIMESTAMP(), INTERVAL 5 MINUTE))'; $set_mutex_bind_data = array($event['event_id']); // Query to uset the event recurrence mutex // Note that if it is already uset, affected_rows will be 0 $sql_unset_mutex_failure = ' UPDATE events SET events.event_recurrence_mutex = 0 WHERE events.event_id = ?'; $unset_mutex_bind_data_fail = array($event['event_id']); $sql_unset_mutex_success = ' UPDATE events SET events.event_recurrence_mutex = 0, events.event_recurrence_updated_until = FROM_UNIXTIME(?) WHERE events.event_id = ?'; $unset_mutex_bind_data_success = array($Until, $event['event_id']); // Get the mutex $this->db->query($sql_set_mutex, $set_mutex_bind_data); // if we managed to get the mutex if ($this->db->affected_rows() > 0) { // get previous update time $sql_get_update = ' SELECT UNIX_TIMESTAMP(events.event_recurrence_updated_until) AS previous_update FROM events WHERE events.event_id = ?'; $query_get_update = $this->db->query($sql_get_update, $event['event_id']); if ($query_get_update->num_rows() == 1) { $previous_update = $query_get_update->row()->previous_update; if ($previous_update < time()) { $previous_update = time(); } // find recurrences between event.until and $Until $event['recurrence_rule_offset_minutes'] = 0; $recurrence_rule = new RecurrenceRule($event); $recurrences = $recurrence_rule->FindTimes($previous_update, $Until); if (count($recurrences) > 0) { // save occurrences and update event.until to $Until $occurrence_data = array(); foreach ($recurrences as $when => $value) { $occurrence_data[] = array('state' => 'published', 'time_associated' => TRUE, 'ends_late' => FALSE, 'start' => $when, 'end' => strtotime('+1day', $when)); } //$this->messages->AddDumpMessage('data',$occurrence_data); $occurrences_created += $this->OccurrencesAdd($event['event_id'], $occurrence_data); } ++$events_generated; // Signal the mutex $this->db->query($sql_unset_mutex_success, $unset_mutex_bind_data_success); } else { // Signal the mutex $this->db->query($sql_unset_mutex_failure, $unset_mutex_bind_data_fail); } if ($this->db->affected_rows() === 0) { ++$mutexes_stolen; } } else { ++$events_mutexed; } } } return array($occurrences_created, $events_generated, $events_mutexed, $mutexes_stolen); }
assertcontains($xml, '<duration>-PT6H30M</duration>', "Alarm::setRelativeStart(Duration)"); assertcontains($xml, '<trigger><date-time>2012-07-30T20:30:00Z</date-time>', "Alarm::setStart()"); assertcontains($xml, '<trigger><parameters><related><text>START</text>', "Alarm relative to Start"); assertcontains($xml, '<valarm><properties><action><text>EMAIL</text>', "Email alarm"); assertcontains($xml, '<attendee><cal-address>mailto:%3Calarms%40kolab.org%3E</cal-address>', "Email alarm attendee"); $e1 = kolabformat::readEvent($xml, false); assertequal($xml, kolabformat::writeEvent($e1), "kolabformat::readEvent() => kolabformat::writeEvent()"); $s = $e1->start(); assertequal(sprintf('%d-%d-%d', $s->year(), $s->month(), $s->day()), '2012-7-31', "Event::start()"); $r = $e1->recurrenceRule(); assertequal($r->frequency(), RecurrenceRule::Minutely, "RecurrenceRule::frequency()"); assertequal($r->bysecond()->size(), 2, "RecurrenceRule::bysecond()"); assertequal($e1->exceptionDates()->size(), 1, "Read Event::exceptionDates()"); $va = $e1->alarms(); assertequal($va->size(), 2, "Event::alarms()"); $rr = new RecurrenceRule(); $rr->setFrequency(RecurrenceRule::Monthly); $byday = new vectordaypos(); $byday->push(new DayPos(2, kolabformat::Monday)); $byday->push(new DayPos(-1, kolabformat::Friday)); $rr->setByday($byday); $e1->setRecurrenceRule($rr); $xml = kolabformat::writeEvent($e1); #print $xml; assertcontains($xml, '<byday>2MO</byday><byday>-1FR</byday>', "Recurrence by weekday"); $att1 = new Attendee(new ContactReference("*****@*****.**")); $att1->setPartStat(kolabformat::PartDelegated); $att2 = new Attendee(new ContactReference("*****@*****.**")); $att1->setPartStat(kolabformat::PartNeedsAction); $vdelegatees = new vectorcontactref(); $vdelegatees->push($att2->contact());