From c6b0f825d92411129be55906f508dfc47f515de5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lehrke?= Date: Sat, 26 Jun 2010 15:58:33 +0000 Subject: [PATCH] Fix SyncML replace and recur_enddate issue --- calendar/inc/class.calendar_ical.inc.php | 149 ++++++----------------- calendar/inc/class.calendar_so.inc.php | 28 +++-- 2 files changed, 52 insertions(+), 125 deletions(-) diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index f41389e841..3bd314fa25 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -615,6 +615,8 @@ class calendar_ical extends calendar_boupdate $rrule = $rriter->generate_rrule($version); if ($event['recur_enddate']) { + $length = $event['end'] - $event['start']; + $rrule['UNTIL']->modify($length . ' second'); if (!$tzid || $version != '1.0') { if (!isset(self::$tz_cache['UTC'])) @@ -1052,6 +1054,7 @@ class calendar_ical extends calendar_boupdate function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0, $principalURL='', $user=null, $charset=null) { $this->events_imported = 0; + $replace = $delete_exceptions= false; if (!is_array($this->supportedFields)) $this->setSupportedFields(); @@ -1065,6 +1068,7 @@ class calendar_ical extends calendar_boupdate { if (count($events) == 1) { + $replace = $recur_date == 0; $events[0]['id'] = $cal_id; if (!is_null($etag)) $events[0]['etag'] = (int) $etag; if ($recur_date) $events[0]['recurrence'] = $recur_date; @@ -1120,43 +1124,42 @@ class calendar_ical extends calendar_boupdate . array2string($event)."\n",3,$this->logfile); } - /* - if ($event['recur_type'] != MCAL_RECUR_NONE) + $updated_id = false; + + if ($replace) { - // Adjust the event start -- no exceptions before and at the start - $length = $event['end'] - $event['start']; - $rriter = calendar_rrule::event2rrule($event, false); - $rriter->rewind(); - if (!$rriter->valid()) continue; // completely disolved into exceptions - - $newstart = egw_time::to($rriter->current, 'server'); - if ($newstart != $event['start']) + $event_info['type'] = $event['recur_type'] == MCAL_RECUR_NONE ? + 'SINGLE' : 'SERIES-MASTER'; + $event_info['acl_edit'] = $this->check_perms(EGW_ACL_EDIT, $cal_id); + if (($event_info['stored_event'] = $this->read($cal_id, 0, false, 'server')) && + $event_info['stored_event']['recur_type'] != MCAL_RECUR_NONE && + ($event_info['stored_event']['recur_type'] != $event['recur_type'] + || $event_info['stored_event']['recur_interval'] != $event['recur_interval'] + || $event_info['stored_event']['recur_data'] != $event['recur_data'] + || $event_info['stored_event']['start'] != $event['start'])) { - // leading exceptions skiped - $event['start'] = $newstart; - $event['end'] = $newstart + $length; - } - - $exceptions = $event['recur_exception']; - foreach($exceptions as $key => $day) - { - // remove leading exceptions - if ($day <= $event['start']) + // handle the old exceptions + $recur_exceptions = $this->so->get_related($event_info['stored_event']['uid']); + foreach ($recur_exceptions as $id) { - if ($this->log) + if ($delete_exceptions) { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '(): event SERIES-MASTER skip leading exception ' . - $day . "\n",3,$this->logfile); + $this->delete($id); + } + else + { + if (!($exception = $this->read($id))) continue; + $exception['uid'] = common::generate_uid('calendar', $id); + $exception['reference'] = $exception['recurrence'] = 0; + $this->update($exception, true); } - unset($exceptions[$key]); } } - $event['recur_exception'] = $exceptions; } - */ - $updated_id = false; - $event_info = $this->get_event_info($event); + else + { + $event_info = $this->get_event_info($event); + } // common adjustments for existing events if (is_array($event_info['stored_event'])) @@ -1471,55 +1474,7 @@ class calendar_ical extends calendar_boupdate if (is_array($days)) { $recur_exceptions = array(); - /* - if (!isset($days[$event_info['stored_event']['start']]) && - $event_info['stored_event']['start'] < $event['start']) - { - // We started with a pseudo exception and moved the - // event start therefore to the future; let's try to go back - $exceptions = $this->so->get_recurrence_exceptions($event_info['stored_event'], $this->tzid, 0, 0, 'rrule'); - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."(START ADJUSTMENT):\n" . - array2string($exceptions)."\n",3,$this->logfile); - } - $startdate = $event_info['stored_event']['start']; - $length = $event['end'] - $event['start']; - $rriter = calendar_rrule::event2rrule($event_info['stored_event'], false); - $rriter->rewind(); - do - { - // start is a pseudo excpetion for sure - $rriter->next_no_exception(); - $day = $this->date2ts($rriter->current()); - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '(): event SERIES-MASTER try leading pseudo exception ' . - $day . "\n",3,$this->logfile); - } - if ($day >= $event['start']) break; - if (!isset($exceptions[$day])) - { - // all leading occurrences have to be exceptions; - // if not -> no restore - if ($this->log) - { - error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. - '(): event SERIES-MASTER pseudo exception series broken at ' . - $rriter->current() . "!\n",3,$this->logfile); - } - $startdate = $event['start']; - $recur_exceptions = array(); - break; - } - $recur_exceptions[] = $day; - } while ($rriter->valid()); - - $event['start'] = $startdate; - $event['end'] = $startdate + $length; - } */ - + foreach ($event['recur_exception'] as $recur_exception) { if (isset($days[$recur_exception])) @@ -1592,43 +1547,7 @@ class calendar_ical extends calendar_boupdate array_unique(array_merge($event_info['master_event']['recur_exception'], array($event['recurrence']))); } - /* - // Adjust the event start -- must not be an exception - $length = $event_info['master_event']['end'] - $event_info['master_event']['start']; - $rriter = calendar_rrule::event2rrule($event_info['master_event'], false); - $rriter->rewind(); - if ($rriter->valid()) - { - $newstart = egw_time::to($rriter->current, 'server'); - foreach($event_info['master_event']['recur_exception'] as $key => $day) - { - // remove leading exceptions - if ($day < $newstart) - { - if (($foundEvents = $this->find_event( - array('uid' => $event_info['master_event']['uid'], - 'recurrence' => $day), 'exact')) && - ($eventId = array_shift($foundEvents)) && - ($exception = read($eventId, 0, 'server'))) - { - // Unlink this exception - unset($exception['uid']); - $this->update($exception, true); - } - if ($event['recurrence'] == $day) - { - // Unlink this exception - unset($event['uid']); - } - unset($event_info['master_event']['recur_exception'][$key]); - } - } - } - if ($event_info['master_event']['start'] < $newstart) - { - $event_info['master_event']['start'] = $newstart; - $event_info['master_event']['end'] = $newstart + $length; - }*/ + $event['reference'] = $event_info['master_event']['id']; $event['category'] = $event_info['master_event']['category']; $event['owner'] = $event_info['master_event']['owner']; diff --git a/calendar/inc/class.calendar_so.inc.php b/calendar/inc/class.calendar_so.inc.php index 9bc7bce4ba..5b0fe85e32 100644 --- a/calendar/inc/class.calendar_so.inc.php +++ b/calendar/inc/class.calendar_so.inc.php @@ -914,8 +914,23 @@ ORDER BY cal_user_type, cal_usre_id $this->db->update($this->cal_table, array('cal_uid' => $event['cal_uid']), array('cal_id' => $event['cal_id']),__LINE__,__FILE__,'calendar'); } - // write information about recuring event, if recur_type is present in the array - if ($event['recur_type'] != MCAL_RECUR_NONE) + + if ($event['recur_type'] == MCAL_RECUR_NONE) + { + $this->db->delete($this->dates_table,array( + 'cal_id' => $cal_id), + __LINE__,__FILE__,'calendar'); + + // delete all user-records, with recur-date != 0 + $this->db->delete($this->user_table,array( + 'cal_id' => $cal_id, 'cal_recur_date != 0'), + __LINE__,__FILE__,'calendar'); + + $this->db->delete($this->repeats_table,array( + 'cal_id' => $cal_id), + __LINE__,__FILE__,'calendar'); + } + else // write information about recuring event, if recur_type is present in the array { // fetch information about the currently saved (old) event $old_min = (int) $this->db->select($this->dates_table,'MIN(cal_start)',array('cal_id'=>$cal_id),__LINE__,__FILE__,false,'','calendar')->fetchColumn(); @@ -1024,14 +1039,7 @@ ORDER BY cal_user_type, cal_usre_id // write the repeats table $event['recur_exception'] = empty($event['recur_exception']) ? null : implode(',',$event['recur_exception']); unset($event[0]); // unset the 'etag=etag+1', as it's not in the repeats table - if($event['recur_type'] != MCAL_RECUR_NONE) - { - $this->db->insert($this->repeats_table,$event,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar'); - } - else - { - $this->db->delete($this->repeats_table,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar'); - } + $this->db->insert($this->repeats_table,$event,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar'); } // update start- and endtime if present in the event-array, evtl. we need to move all recurrences if (isset($event['cal_start']) && isset($event['cal_end']))