Read/write event recurrence rules and alarms
This commit is contained in:
parent
ec04074a46
commit
87b474eab7
1 changed files with 192 additions and 9 deletions
|
@ -39,6 +39,31 @@ class kolab_format_event extends kolab_format
|
|||
'CHAIR' => kolabformat::Chair,
|
||||
);
|
||||
|
||||
private $rrule_type_map = array(
|
||||
'MINUTELY' => RecurrenceRule::Minutely,
|
||||
'HOURLY' => RecurrenceRule::Hourly,
|
||||
'DAILY' => RecurrenceRule::Daily,
|
||||
'WEEKLY' => RecurrenceRule::Weekly,
|
||||
'MONTHLY' => RecurrenceRule::Monthly,
|
||||
'YEARLY' => RecurrenceRule::Yearly,
|
||||
);
|
||||
|
||||
private $weekday_map = array(
|
||||
'MO' => kolabformat::Monday,
|
||||
'TU' => kolabformat::Tuesday,
|
||||
'WE' => kolabformat::Wednesday,
|
||||
'TH' => kolabformat::Thursday,
|
||||
'FR' => kolabformat::Friday,
|
||||
'SA' => kolabformat::Saturday,
|
||||
'SU' => kolabformat::Sunday,
|
||||
);
|
||||
|
||||
private $alarm_type_map = array(
|
||||
'DISPLAY' => Alarm::DisplayAlarm,
|
||||
'EMAIL' => Alarm::EMailAlarm,
|
||||
'AUDIO' => Alarm::AudioAlarm,
|
||||
);
|
||||
|
||||
private $status_map = array(
|
||||
'UNKNOWN' => kolabformat::PartNeedsAction,
|
||||
'NEEDS-ACTION' => kolabformat::PartNeedsAction,
|
||||
|
@ -116,7 +141,6 @@ class kolab_format_event extends kolab_format
|
|||
// do the hard work of setting object values
|
||||
$this->obj->setStart(self::get_datetime($object['start'], null, $object['allday']));
|
||||
$this->obj->setEnd(self::get_datetime($object['end'], null, $object['allday']));
|
||||
|
||||
$this->obj->setSummary($object['title']);
|
||||
$this->obj->setLocation($object['location']);
|
||||
$this->obj->setDescription($object['description']);
|
||||
|
@ -149,21 +173,109 @@ class kolab_format_event extends kolab_format
|
|||
$att->setRole($this->role_map[$attendee['role']] ? $this->role_map[$attendee['role']] : kolabformat::Required);
|
||||
$att->setRSVP((bool)$attendee['rsvp']);
|
||||
|
||||
if ($att->isValid())
|
||||
if ($att->isValid()) {
|
||||
$attendees->push($att);
|
||||
}
|
||||
else {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Invalid event attendee: " . json_encode($attendee),
|
||||
), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->obj->setOrganizer($organizer);
|
||||
$this->obj->setAttendees($attendees);
|
||||
|
||||
// TODO: save recurrence rule
|
||||
// save recurrence rule
|
||||
if ($object['recurrence']) {
|
||||
$rr = new RecurrenceRule;
|
||||
$rr->setFrequency($this->rrule_type_map[$object['recurrence']['FREQ']]);
|
||||
|
||||
// TODO: save alarm
|
||||
if ($object['recurrence']['INTERVAL'])
|
||||
$rr->setInterval(intval($object['recurrence']['INTERVAL']));
|
||||
|
||||
if ($object['recurrence']['BYDAY']) {
|
||||
$byday = new vectordaypos;
|
||||
foreach (explode(',', $object['recurrence']['BYDAY']) as $day) {
|
||||
$occurrence = 0;
|
||||
if (preg_match('/^([\d-]+)([A-Z]+)$/', $day, $m)) {
|
||||
$occurrence = intval($m[1]);
|
||||
$day = $m[2];
|
||||
}
|
||||
if (isset($this->weekday_map[$day]))
|
||||
$byday->push(new DayPos($occurrence, $this->weekday_map[$day]));
|
||||
}
|
||||
$rr->setByday($byday);
|
||||
}
|
||||
|
||||
if ($object['recurrence']['BYMONTHDAY']) {
|
||||
$bymday = new vectori;
|
||||
foreach (explode(',', $object['recurrence']['BYMONTHDAY']) as $day)
|
||||
$bymday->push(intval($day));
|
||||
$rr->setBymonthday($bymday);
|
||||
}
|
||||
|
||||
if ($object['recurrence']['BYMONTH']) {
|
||||
$bymonth = new vectori;
|
||||
foreach (explode(',', $object['recurrence']['BYMONTH']) as $month)
|
||||
$bymonth->push(intval($month));
|
||||
$rr->setBymonth($bymonth);
|
||||
}
|
||||
|
||||
if ($object['recurrence']['COUNT'])
|
||||
$rr->setCount(intval($object['recurrence']['COUNT']));
|
||||
else if ($object['recurrence']['UNTIL'])
|
||||
$rr->setEnd(self::get_datetime($object['recurrence']['UNTIL'], null, true));
|
||||
|
||||
if ($rr->isValid()) {
|
||||
$this->obj->setRecurrenceRule($rr);
|
||||
|
||||
// add exception dates (only if recurrence rule is valid)
|
||||
$exdates = new vectordatetime;
|
||||
foreach ((array)$object['recurrence']['EXDATE'] as $exdate)
|
||||
$exdates->push(self::get_datetime($exdate, null, true));
|
||||
$this->obj->setExceptionDates($exdates);
|
||||
}
|
||||
else {
|
||||
raise_error(array(
|
||||
'code' => 600, 'type' => 'php',
|
||||
'file' => __FILE__, 'line' => __LINE__,
|
||||
'message' => "Invalid event recurrence rule: " . json_encode($object['recurrence']),
|
||||
), true);
|
||||
}
|
||||
}
|
||||
|
||||
// save alarm
|
||||
$valarms = new vectoralarm;
|
||||
if ($object['alarms']) {
|
||||
$alarm = new Alarm;
|
||||
list($duration, $type) = explode(":", $object['alarms']);
|
||||
|
||||
list($offset, $type) = explode(":", $object['alarms']);
|
||||
|
||||
if ($type == 'EMAIL') { // email alarms implicitly go to event owner
|
||||
$recipients = new vectorcontactref;
|
||||
$recipients->push(new ContactReference(ContactReference::EmailReference, $object['_owner']));
|
||||
$alarm = new Alarm($object['title'], strval($object['description']), $recipients);
|
||||
}
|
||||
else { // default: display alarm
|
||||
$alarm = new Alarm($object['title']);
|
||||
}
|
||||
|
||||
if (preg_match('/^@(\d+)/', $offset, $d)) {
|
||||
$alarm->setStart(self::get_datetime($d[1]));
|
||||
}
|
||||
else if (preg_match('/^([-+]?)(\d+)([SMHDW])/', $offset, $d)) {
|
||||
$days = $hours = $minutes = $seconds = 0;
|
||||
switch ($d[3]) {
|
||||
case 'W': $days = 7*intval($d[2]); break;
|
||||
case 'D': $days = intval($d[2]); break;
|
||||
case 'H': $hours = intval($d[2]); break;
|
||||
case 'M': $minutes = intval($d[2]); break;
|
||||
case 'S': $seconds = intval($d[2]); break;
|
||||
}
|
||||
$alarm->setRelativeStart(new Duration($days, $hours, $minutes, $seconds, $d[1] == '-'), $d[1] == '-' ? kolabformat::Start : kolabformat::End);
|
||||
}
|
||||
|
||||
$valarms->push($alarm);
|
||||
}
|
||||
$this->obj->setAlarms($valarms);
|
||||
|
@ -243,7 +355,77 @@ class kolab_format_event extends kolab_format
|
|||
);
|
||||
}
|
||||
|
||||
// TODO: hanlde recurrence rules, alarms and attachments
|
||||
// read recurrence rule
|
||||
if (($rr = $this->obj->recurrenceRule()) && $rr->isValid()) {
|
||||
$rrule_type_map = array_flip($this->rrule_type_map);
|
||||
$object['recurrence'] = array('FREQ' => $rrule_type_map[$rr->frequency()]);
|
||||
|
||||
if ($intvl = $rr->interval())
|
||||
$object['recurrence']['INTERVAL'] = $intvl;
|
||||
|
||||
if (($count = $rr->count()) && $count > 0) {
|
||||
$object['recurrence']['COUNT'] = $count;
|
||||
}
|
||||
else if ($until = self::php_datetime($rr->end())) {
|
||||
$until->setTime($object['start']->format('G'), $object['start']->format('i'), 0);
|
||||
$object['recurrence']['UNTIL'] = $until->format('U');
|
||||
}
|
||||
|
||||
if (($byday = $rr->byday()) && $byday->size()) {
|
||||
$weekday_map = array_flip($this->weekday_map);
|
||||
$weekdays = array();
|
||||
for ($i=0; $i < $byday->size(); $i++) {
|
||||
$daypos = $byday->get($i);
|
||||
$prefix = $daypos->occurence();
|
||||
$weekdays[] = ($prefix ? $prefix : '') . $weekday_map[$daypos->weekday()];
|
||||
}
|
||||
$object['recurrence']['BYDAY'] = join(',', $weekdays);
|
||||
}
|
||||
|
||||
if (($bymday = $rr->bymonthday()) && $bymday->size()) {
|
||||
$object['recurrence']['BYMONTHDAY'] = join(',', self::vector2array($bymday));
|
||||
}
|
||||
|
||||
if (($bymonth = $rr->bymonth()) && $bymonth->size()) {
|
||||
$object['recurrence']['BYMONTH'] = join(',', self::vector2array($bymonth));
|
||||
}
|
||||
|
||||
if ($exceptions = $this->obj->exceptionDates()) {
|
||||
for ($i=0; $i < $exceptions->size(); $i++) {
|
||||
if ($exdate = self::php_datetime($exceptions->get($i)))
|
||||
$object['recurrence']['EXDATE'][] = $exdate->format('U');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// read alarm
|
||||
$valarms = $this->obj->alarms();
|
||||
$alarm_types = array_flip($this->alarm_type_map);
|
||||
for ($i=0; $i < $valarms->size(); $i++) {
|
||||
$alarm = $valarms->get($i);
|
||||
$type = $alarm_types[$alarm->type()];
|
||||
|
||||
if ($type == 'DISPLAY' || $type == 'EMAIL') { // only DISPLAY and EMAIL alarms are supported
|
||||
if ($start = self::php_datetime($alarm->start())) {
|
||||
$object['alarms'] = '@' . $start->format('U');
|
||||
}
|
||||
else if ($offset = $alarm->relativeStart()) {
|
||||
$value = $alarm->relativeTo() == kolabformat::End ? '+' : '-';
|
||||
if ($w = $offset->weeks()) $value .= $w . 'W';
|
||||
else if ($d = $offset->days()) $value .= $d . 'D';
|
||||
else if ($h = $offset->hours()) $value .= $h . 'H';
|
||||
else if ($m = $offset->minutes()) $value .= $m . 'M';
|
||||
else if ($s = $offset->seconds()) $value .= $s . 'S';
|
||||
else continue;
|
||||
|
||||
$object['alarms'] = $value;
|
||||
}
|
||||
$object['alarms'] .= ':' . $type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: handle attachments
|
||||
|
||||
$this->data = $object;
|
||||
return $this->data;
|
||||
|
@ -260,7 +442,8 @@ class kolab_format_event extends kolab_format
|
|||
$start_time = date('H:i:s', $rec['start-date']);
|
||||
$allday = $rec['_is_all_day'] || ($start_time == '00:00:00' && $start_time == date('H:i:s', $rec['end-date']));
|
||||
|
||||
if ($allday) { // in Roundcube all-day events go from 12:00 to 13:00
|
||||
// in Roundcube all-day events go from 12:00 to 13:00
|
||||
if ($allday) {
|
||||
$now = new DateTime('now', self::$timezone);
|
||||
$gmt_offset = $now->getOffset();
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue