Provide access to exception instances outside of a recurring event context (#4722)
This commit is contained in:
parent
1c590d3969
commit
31ad93a62e
3 changed files with 83 additions and 12 deletions
|
@ -96,11 +96,15 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
$status = $this->status_map[$object['status']];
|
$status = $this->status_map[$object['status']];
|
||||||
$this->obj->setStatus($status);
|
$this->obj->setStatus($status);
|
||||||
|
|
||||||
// save recurrence exceptions
|
// save (recurrence) exceptions
|
||||||
if (is_array($object['recurrence']) && is_array($object['recurrence']['EXCEPTIONS'])) {
|
if (is_array($object['recurrence']) && is_array($object['recurrence']['EXCEPTIONS']) && !isset($object['exceptions'])) {
|
||||||
|
$object['exceptions'] = $object['recurrence']['EXCEPTIONS'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_array($object['exceptions'])) {
|
||||||
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
|
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
|
||||||
$vexceptions = new vectorevent;
|
$vexceptions = new vectorevent;
|
||||||
foreach((array)$object['recurrence']['EXCEPTIONS'] as $i => $exception) {
|
foreach ($object['exceptions'] as $i => $exception) {
|
||||||
$exevent = new kolab_format_event;
|
$exevent = new kolab_format_event;
|
||||||
$exevent->set(($compacted = $this->compact_exception($exception, $object))); // only save differing values
|
$exevent->set(($compacted = $this->compact_exception($exception, $object))); // only save differing values
|
||||||
|
|
||||||
|
@ -118,11 +122,17 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
$vexceptions->push($exevent->obj);
|
$vexceptions->push($exevent->obj);
|
||||||
|
|
||||||
// write cleaned-up exception data back to memory/cache
|
// write cleaned-up exception data back to memory/cache
|
||||||
$object['recurrence']['EXCEPTIONS'][$i] = $this->expand_exception($exevent->data, $object);
|
$object['exceptions'][$i] = $this->expand_exception($exevent->data, $object);
|
||||||
}
|
}
|
||||||
$this->obj->setExceptions($vexceptions);
|
$this->obj->setExceptions($vexceptions);
|
||||||
|
|
||||||
|
// link with recurrence.EXCEPTIONS for compatibility
|
||||||
|
if (is_array($object['recurrence'])) {
|
||||||
|
$object['recurrence']['EXCEPTIONS'] = &$object['exceptions'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ($object['recurrence_date'] && $object['recurrence_date'] instanceof DateTime) {
|
|
||||||
|
if ($object['recurrence_date'] && $object['recurrence_date'] instanceof DateTime) {
|
||||||
$this->obj->setRecurrenceID(self::get_datetime($object['recurrence_date'], null, $object['allday']), (bool)$object['thisandfuture']);
|
$this->obj->setRecurrenceID(self::get_datetime($object['recurrence_date'], null, $object['allday']), (bool)$object['thisandfuture']);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +204,7 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
$object['recurrence_date'] = self::php_datetime($this->obj->recurrenceID());
|
$object['recurrence_date'] = self::php_datetime($this->obj->recurrenceID());
|
||||||
}
|
}
|
||||||
// read exception event objects
|
// read exception event objects
|
||||||
else if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
|
if (($exceptions = $this->obj->exceptions()) && is_object($exceptions) && $exceptions->size()) {
|
||||||
$recurrence_exceptions = array();
|
$recurrence_exceptions = array();
|
||||||
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
|
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
|
||||||
for ($i=0; $i < $exceptions->size(); $i++) {
|
for ($i=0; $i < $exceptions->size(); $i++) {
|
||||||
|
@ -215,12 +225,53 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$object['recurrence']['EXCEPTIONS'] = $recurrence_exceptions;
|
$object['exceptions'] = $recurrence_exceptions;
|
||||||
|
|
||||||
|
// also link with recurrence.EXCEPTIONS for compatibility
|
||||||
|
if (is_array($object['recurrence'])) {
|
||||||
|
$object['recurrence']['EXCEPTIONS'] = &$object['exceptions'];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->data = $object;
|
return $this->data = $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for a single instance from a recurrence series or stored subcomponents
|
||||||
|
*
|
||||||
|
* @param mixed The recurrence-id of the requested instance, either as string or a DateTime object
|
||||||
|
* @return array Event data as hash array or null if not found
|
||||||
|
*/
|
||||||
|
public function get_instance($recurrence_id)
|
||||||
|
{
|
||||||
|
$result = null;
|
||||||
|
$object = $this->to_array();
|
||||||
|
|
||||||
|
$recurrence_id_format = $object['allday'] ? 'Ymd' : 'Ymd\THis';
|
||||||
|
$instance_id = $recurrence_id instanceof DateTime ? $recurrence_id->format($recurrence_id_format) : strval($recurrence_id);
|
||||||
|
|
||||||
|
if ($object['recurrence_date'] instanceof DateTime) {
|
||||||
|
if ($object['recurrence_date']->format($recurrence_id_format) == $instance_id) {
|
||||||
|
$result = $object;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$result && is_array($object['exceptions'])) {
|
||||||
|
foreach ($object['exceptions'] as $exception) {
|
||||||
|
if ($exception['_instance'] == $instance_id) {
|
||||||
|
$result = $exception;
|
||||||
|
$result['isexception'] = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: compute instances from recurrence rule and return the matching instance
|
||||||
|
// clone from plugins/calendar/drivers/kolab/kolab_calendar::get_recurring_events()
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback for kolab_storage_cache to get object specific tags to cache
|
* Callback for kolab_storage_cache to get object specific tags to cache
|
||||||
*
|
*
|
||||||
|
@ -262,8 +313,10 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
*/
|
*/
|
||||||
private function expand_exception($exception, $master)
|
private function expand_exception($exception, $master)
|
||||||
{
|
{
|
||||||
|
$is_recurring = !empty($master['recurrence']);
|
||||||
|
|
||||||
foreach ($master as $prop => $value) {
|
foreach ($master as $prop => $value) {
|
||||||
if (empty($exception[$prop]) && !empty($value)) {
|
if (empty($exception[$prop]) && !empty($value) && ($is_recurring || in_array($prop, array('uid','organizer','_attachments')))) {
|
||||||
$exception[$prop] = $value;
|
$exception[$prop] = $value;
|
||||||
if ($prop == 'recurrence') {
|
if ($prop == 'recurrence') {
|
||||||
unset($exception[$prop]['EXCEPTIONS']);
|
unset($exception[$prop]['EXCEPTIONS']);
|
||||||
|
|
|
@ -597,8 +597,8 @@ abstract class kolab_format_xcal extends kolab_format
|
||||||
$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['recurrence']) && $object['recurrence']['EXCEPTIONS']) {
|
if (is_array($object['exceptions'])) {
|
||||||
foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
|
foreach ($object['exceptions'] as $exception) {
|
||||||
$words = array_merge($words, $this->get_words($exception));
|
$words = array_merge($words, $this->get_words($exception));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -629,8 +629,8 @@ abstract class kolab_format_xcal extends kolab_format
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect tags from recurrence exceptions
|
// collect tags from recurrence exceptions
|
||||||
if (is_array($object['recurrence']) && $object['recurrence']['EXCEPTIONS']) {
|
if (is_array($object['exceptions'])) {
|
||||||
foreach((array)$object['recurrence']['EXCEPTIONS'] as $exception) {
|
foreach ($object['exceptions'] as $exception) {
|
||||||
$tags = array_merge($tags, $this->get_tags($exception));
|
$tags = array_merge($tags, $this->get_tags($exception));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,24 @@ class kolab_storage_cache_event extends kolab_storage_cache
|
||||||
$sql_data['dtend'] = $dtend->format(self::DB_DATE_FORMAT);
|
$sql_data['dtend'] = $dtend->format(self::DB_DATE_FORMAT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extend start/end dates to spawn all exceptions
|
||||||
|
if (is_array($object['exceptions'])) {
|
||||||
|
foreach ($object['exceptions'] as $exception) {
|
||||||
|
if (is_a($exception['start'], 'DateTime')) {
|
||||||
|
$exstart = $exception['start']->format(self::DB_DATE_FORMAT);
|
||||||
|
if ($exstart < $sql_data['dtstart']) {
|
||||||
|
$sql_data['dtstart'] = $exstart;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (is_a($exception['end'], 'DateTime')) {
|
||||||
|
$exend = $exception['end']->format(self::DB_DATE_FORMAT);
|
||||||
|
if ($exend > $sql_data['dtend']) {
|
||||||
|
$sql_data['dtend'] = $exend;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return $sql_data;
|
return $sql_data;
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue