Example #1
0
 /**
  * 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());