Changeset View
Changeset View
Standalone View
Standalone View
plugins/libkolab/lib/kolab_format_xcal.php
Show First 20 Lines • Show All 111 Lines • ▼ Show 20 Lines | public function to_array($data = array()) | ||||
$status_map = array_flip($this->status_map); | $status_map = array_flip($this->status_map); | ||||
$object += array( | $object += array( | ||||
'sequence' => intval($this->obj->sequence()), | 'sequence' => intval($this->obj->sequence()), | ||||
'title' => $this->obj->summary(), | 'title' => $this->obj->summary(), | ||||
'location' => $this->obj->location(), | 'location' => $this->obj->location(), | ||||
'description' => $this->obj->description(), | 'description' => $this->obj->description(), | ||||
'url' => $this->obj->url(), | 'url' => $this->obj->url(), | ||||
'status' => $status_map[$this->obj->status()], | 'status' => $status_map[$this->obj->status()] ?? null, | ||||
'priority' => $this->obj->priority(), | 'priority' => $this->obj->priority(), | ||||
'categories' => self::vector2array($this->obj->categories()), | 'categories' => self::vector2array($this->obj->categories()), | ||||
'start' => self::php_datetime($this->obj->start()), | 'start' => self::php_datetime($this->obj->start()), | ||||
); | ); | ||||
if (method_exists($this->obj, 'comment')) { | if (method_exists($this->obj, 'comment')) { | ||||
$object['comment'] = $this->obj->comment(); | $object['comment'] = $this->obj->comment(); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 211 Lines • ▼ Show 20 Lines | public function set(&$object) | ||||
} | } | ||||
$this->obj->setSequence(intval($object['sequence'])); | $this->obj->setSequence(intval($object['sequence'])); | ||||
if ($object['sequence'] > $old_sequence) { | if ($object['sequence'] > $old_sequence) { | ||||
$reschedule = true; | $reschedule = true; | ||||
} | } | ||||
$this->obj->setSummary($object['title']); | $this->obj->setSummary($object['title']); | ||||
$this->obj->setLocation($object['location']); | $this->obj->setLocation($object['location'] ?? null); | ||||
$this->obj->setDescription($object['description']); | $this->obj->setDescription($object['description']); | ||||
$this->obj->setPriority($object['priority']); | $this->obj->setPriority($object['priority']); | ||||
$this->obj->setCategories(self::array2vector($object['categories'])); | $this->obj->setCategories(self::array2vector($object['categories'] ?? null)); | ||||
$this->obj->setUrl(strval($object['url'])); | $this->obj->setUrl(strval($object['url'] ?? null)); | ||||
if (method_exists($this->obj, 'setComment')) { | if (method_exists($this->obj, 'setComment')) { | ||||
$this->obj->setComment($object['comment']); | $this->obj->setComment($object['comment'] ?? null); | ||||
} | } | ||||
// process event attendees | // process event attendees | ||||
$attendees = new vectorattendee; | $attendees = new vectorattendee; | ||||
foreach ((array)$object['attendees'] as $i => $attendee) { | foreach ((array)($object['attendees'] ?? []) as $i => $attendee) { | ||||
if ($attendee['role'] == 'ORGANIZER') { | if ($attendee['role'] == 'ORGANIZER') { | ||||
$object['organizer'] = $attendee; | $object['organizer'] = $attendee; | ||||
} | } | ||||
else if ($attendee['email'] != $object['organizer']['email']) { | else if ($attendee['email'] != $object['organizer']['email']) { | ||||
$cr = new ContactReference(ContactReference::EmailReference, $attendee['email']); | $cr = new ContactReference(ContactReference::EmailReference, $attendee['email']); | ||||
$cr->setName($attendee['name']); | $cr->setName($attendee['name']); | ||||
// set attendee RSVP if missing | // set attendee RSVP if missing | ||||
Show All 38 Lines | public function set(&$object) | ||||
$this->obj->setAttendees($attendees); | $this->obj->setAttendees($attendees); | ||||
if ($object['organizer']) { | if ($object['organizer']) { | ||||
$organizer = new ContactReference(ContactReference::EmailReference, $object['organizer']['email']); | $organizer = new ContactReference(ContactReference::EmailReference, $object['organizer']['email']); | ||||
$organizer->setName($object['organizer']['name']); | $organizer->setName($object['organizer']['name']); | ||||
$this->obj->setOrganizer($organizer); | $this->obj->setOrganizer($organizer); | ||||
} | } | ||||
if ($object['start'] instanceof DateTimeInterface) { | if (($object['start'] ?? null) instanceof DateTimeInterface) { | ||||
$start_tz = $object['start']->getTimezone(); | $start_tz = $object['start']->getTimezone(); | ||||
} | } | ||||
// save recurrence rule | // save recurrence rule | ||||
$rr = new RecurrenceRule; | $rr = new RecurrenceRule; | ||||
$rr->setFrequency(RecurrenceRule::FreqNone); | $rr->setFrequency(RecurrenceRule::FreqNone); | ||||
if ($object['recurrence'] && !empty($object['recurrence']['FREQ'])) { | if (($object['recurrence'] ?? null) && !empty($object['recurrence']['FREQ'])) { | ||||
$freq = $object['recurrence']['FREQ']; | $freq = $object['recurrence']['FREQ']; | ||||
$bysetpos = explode(',', $object['recurrence']['BYSETPOS']); | $bysetpos = explode(',', $object['recurrence']['BYSETPOS']); | ||||
$rr->setFrequency($this->rrule_type_map[$freq]); | $rr->setFrequency($this->rrule_type_map[$freq]); | ||||
if ($object['recurrence']['INTERVAL']) | if ($object['recurrence']['INTERVAL']) | ||||
$rr->setInterval(intval($object['recurrence']['INTERVAL'])); | $rr->setInterval(intval($object['recurrence']['INTERVAL'])); | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | public function set(&$object) | ||||
foreach ((array)$object['recurrence']['RDATE'] as $rdate) | foreach ((array)$object['recurrence']['RDATE'] as $rdate) | ||||
$rdates->push(self::get_datetime($rdate, null, true, $start_tz)); | $rdates->push(self::get_datetime($rdate, null, true, $start_tz)); | ||||
$this->obj->setRecurrenceDates($rdates); | $this->obj->setRecurrenceDates($rdates); | ||||
} | } | ||||
// save alarm(s) | // save alarm(s) | ||||
$valarms = new vectoralarm; | $valarms = new vectoralarm; | ||||
$valarm_hashes = array(); | $valarm_hashes = array(); | ||||
if ($object['valarms']) { | if ($object['valarms'] ?? null) { | ||||
foreach ($object['valarms'] as $valarm) { | foreach ($object['valarms'] as $valarm) { | ||||
if (!array_key_exists($valarm['action'], $this->alarm_type_map)) { | if (!array_key_exists($valarm['action'], $this->alarm_type_map)) { | ||||
continue; // skip unknown alarm types | continue; // skip unknown alarm types | ||||
} | } | ||||
// Get rid of duplicates, some CalDAV clients can set them | // Get rid of duplicates, some CalDAV clients can set them | ||||
$hash = serialize($valarm); | $hash = serialize($valarm); | ||||
if (in_array($hash, $valarm_hashes)) { | if (in_array($hash, $valarm_hashes)) { | ||||
▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | public function set(&$object) | ||||
// ignore | // ignore | ||||
} | } | ||||
} | } | ||||
$valarms->push($alarm); | $valarms->push($alarm); | ||||
} | } | ||||
} | } | ||||
// legacy support | // legacy support | ||||
else if ($object['alarms']) { | else if ($object['alarms'] ?? null) { | ||||
list($offset, $type) = explode(":", $object['alarms']); | list($offset, $type) = explode(":", $object['alarms']); | ||||
if ($type == 'EMAIL' && !empty($object['_owner'])) { // email alarms implicitly go to event owner | if ($type == 'EMAIL' && !empty($object['_owner'])) { // email alarms implicitly go to event owner | ||||
$recipients = new vectorcontactref; | $recipients = new vectorcontactref; | ||||
$recipients->push(new ContactReference(ContactReference::EmailReference, $object['_owner'])); | $recipients->push(new ContactReference(ContactReference::EmailReference, $object['_owner'])); | ||||
$alarm = new Alarm($object['title'], strval($object['description']), $recipients); | $alarm = new Alarm($object['title'], strval($object['description']), $recipients); | ||||
} | } | ||||
else { // default: display alarm | else { // default: display alarm | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | abstract class kolab_format_xcal extends kolab_format | ||||
* @return array List of words to save in cache | * @return array List of words to save in cache | ||||
*/ | */ | ||||
public function get_words($obj = null) | public function get_words($obj = null) | ||||
{ | { | ||||
$data = ''; | $data = ''; | ||||
$object = $obj ?: $this->data; | $object = $obj ?: $this->data; | ||||
foreach (self::$fulltext_cols as $colname) { | foreach (self::$fulltext_cols as $colname) { | ||||
list($col, $field) = explode(':', $colname); | list($col, $field) = array_pad(explode(':', $colname), 2, null); | ||||
if ($field) { | if ($field) { | ||||
$a = array(); | $a = array(); | ||||
foreach ((array)$object[$col] as $attr) | foreach ((array)($object[$col] ?? []) as $attr) | ||||
$a[] = $attr[$field]; | $a[] = $attr[$field]; | ||||
$val = join(' ', $a); | $val = join(' ', $a); | ||||
} | } | ||||
else { | else { | ||||
$val = is_array($object[$col]) ? join(' ', $object[$col]) : $object[$col]; | $val = is_array($object[$col] ?? null) ? join(' ', $object[$col]) : $object[$col] ?? null; | ||||
} | } | ||||
if (strlen($val)) | if (strlen($val)) | ||||
$data .= $val . ' '; | $data .= $val . ' '; | ||||
} | } | ||||
$words = rcube_utils::normalize_string($data, true); | $words = rcube_utils::normalize_string($data, true); | ||||
// collect words from recurrence exceptions | // collect words from recurrence exceptions | ||||
if (is_array($object['exceptions'])) { | if (is_array($object['exceptions'] ?? null)) { | ||||
foreach ($object['exceptions'] as $exception) { | foreach ($object['exceptions'] as $exception) { | ||||
$words = array_merge($words, $this->get_words($exception)); | $words = array_merge($words, $this->get_words($exception)); | ||||
} | } | ||||
} | } | ||||
return array_unique($words); | return array_unique($words); | ||||
} | } | ||||
/** | /** | ||||
* Callback for kolab_storage_cache to get object specific tags to cache | * Callback for kolab_storage_cache to get object specific tags to cache | ||||
* | * | ||||
* @return array List of tags to save in cache | * @return array List of tags to save in cache | ||||
*/ | */ | ||||
public function get_tags($obj = null) | public function get_tags($obj = null) | ||||
{ | { | ||||
$tags = array(); | $tags = array(); | ||||
$object = $obj ?: $this->data; | $object = $obj ?: $this->data; | ||||
if (!empty($object['valarms'])) { | if (!empty($object['valarms'] ?? null)) { | ||||
$tags[] = 'x-has-alarms'; | $tags[] = 'x-has-alarms'; | ||||
} | } | ||||
// create tags reflecting participant status | // create tags reflecting participant status | ||||
if (is_array($object['attendees'])) { | if (is_array($object['attendees'] ?? null)) { | ||||
foreach ($object['attendees'] as $attendee) { | foreach ($object['attendees'] as $attendee) { | ||||
if (!empty($attendee['email']) && !empty($attendee['status'])) | if (!empty($attendee['email']) && !empty($attendee['status'])) | ||||
$tags[] = 'x-partstat:' . $attendee['email'] . ':' . strtolower($attendee['status']); | $tags[] = 'x-partstat:' . $attendee['email'] . ':' . strtolower($attendee['status']); | ||||
} | } | ||||
} | } | ||||
// collect tags from recurrence exceptions | // collect tags from recurrence exceptions | ||||
if (is_array($object['exceptions'])) { | if (is_array($object['exceptions'] ?? null)) { | ||||
foreach ($object['exceptions'] as $exception) { | foreach ($object['exceptions'] as $exception) { | ||||
$tags = array_merge($tags, $this->get_tags($exception)); | $tags = array_merge($tags, $this->get_tags($exception)); | ||||
} | } | ||||
} | } | ||||
if (!empty($object['status'])) { | if (!empty($object['status'])) { | ||||
$tags[] = 'x-status:' . strtolower($object['status']); | $tags[] = 'x-status:' . strtolower($object['status']); | ||||
} | } | ||||
Show All 13 Lines | abstract class kolab_format_xcal extends kolab_format | ||||
{ | { | ||||
$reschedule = false; | $reschedule = false; | ||||
if (!is_array($old)) { | if (!is_array($old)) { | ||||
$old = $this->data['uid'] ? $this->data : $this->to_array(); | $old = $this->data['uid'] ? $this->data : $this->to_array(); | ||||
} | } | ||||
foreach ($this->_scheduling_properties ?: self::$scheduling_properties as $prop) { | foreach ($this->_scheduling_properties ?: self::$scheduling_properties as $prop) { | ||||
$a = $old[$prop]; | $a = $old[$prop] ?? null; | ||||
$b = $object[$prop]; | $b = $object[$prop] ?? null; | ||||
if ($object['allday'] | if (($object['allday'] ?? false) | ||||
&& ($prop == 'start' || $prop == 'end') | && ($prop == 'start' || $prop == 'end') | ||||
&& $a instanceof DateTimeInterface | && $a instanceof DateTimeInterface | ||||
&& $b instanceof DateTimeInterface | && $b instanceof DateTimeInterface | ||||
) { | ) { | ||||
$a = $a->format('Y-m-d'); | $a = $a->format('Y-m-d'); | ||||
$b = $b->format('Y-m-d'); | $b = $b->format('Y-m-d'); | ||||
} | } | ||||
if ($prop == 'recurrence' && is_array($a) && is_array($b)) { | if ($prop == 'recurrence' && is_array($a) && is_array($b)) { | ||||
▲ Show 20 Lines • Show All 44 Lines • Show Last 20 Lines |