manually insert or truncate the recurrences when changing enddate. recurrences rebuild (and stati reset) is now minimized to the following cases: move startdate/enddate, change recur_type, change recur_interval

This commit is contained in:
Christian Binder 2009-08-10 09:24:39 +00:00
parent ae855c4979
commit 77de24e563
3 changed files with 77 additions and 48 deletions

View File

@ -16,10 +16,6 @@ if (!defined('ACL_TYPE_IDENTIFER')) // used to mark ACL-values for the debug_mes
define('ACL_TYPE_IDENTIFER','***ACL***'); define('ACL_TYPE_IDENTIFER','***ACL***');
} }
define('HOUR_s',60*60);
define('DAY_s',24*HOUR_s);
define('WEEK_s',7*DAY_s);
/** /**
* Gives read access to the calendar, but all events the user is not participating are private! * Gives read access to the calendar, but all events the user is not participating are private!
* Used by addressbook. * Used by addressbook.

View File

@ -715,10 +715,13 @@ class calendar_boupdate extends calendar_bo
} }
} }
$set_recurrences = false; $set_recurrences = false;
if (($cal_id = $this->so->save($event,$set_recurrences,0,$event['etag'])) && $set_recurrences && $event['recur_type'] != MCAL_RECUR_NONE) $set_recurrences_start = 0;
if (($cal_id = $this->so->save($event,$set_recurrences,$set_recurrences_start,0,$event['etag'])) && $set_recurrences && $event['recur_type'] != MCAL_RECUR_NONE)
{ {
$save_event['id'] = $cal_id; $save_event['id'] = $cal_id;
$this->set_recurrences($save_event, 0); // unset participants to enforce the default stati for all added recurrences
unset($save_event['participants']);
$this->set_recurrences($save_event, $set_recurrences_start);
} }
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,$event['id'] ? 'modify' : 'add',time()); $GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,$event['id'] ? 'modify' : 'add',time());

View File

@ -44,6 +44,10 @@ define('NO_RESPONSE',1);
define('TENTATIVE',2); define('TENTATIVE',2);
define('ACCEPTED',3); define('ACCEPTED',3);
define('HOUR_s',60*60);
define('DAY_s',24*HOUR_s);
define('WEEK_s',7*DAY_s);
/** /**
* Class to store all calendar data (storage object) * Class to store all calendar data (storage object)
* *
@ -498,11 +502,12 @@ ORDER BY cal_user_type, cal_usre_id
* *
* @param array $event * @param array $event
* @param boolean &$set_recurrences on return: true if the recurrences need to be written, false otherwise * @param boolean &$set_recurrences on return: true if the recurrences need to be written, false otherwise
* @param int &$set_recurrences_start=0 on return: time from which on the recurrences should be rebuilt, default 0=all
* @param int $change_since=0 time from which on the repetitions should be changed, default 0=all * @param int $change_since=0 time from which on the repetitions should be changed, default 0=all
* @param int &$etag etag=null etag to check or null, on return new etag * @param int &$etag etag=null etag to check or null, on return new etag
* @return boolean|int false on error, 0 if etag does not match, cal_id otherwise * @return boolean|int false on error, 0 if etag does not match, cal_id otherwise
*/ */
function save($event,&$set_recurrences,$change_since=0,&$etag=null) function save($event,&$set_recurrences,&$set_recurrences_start=0,$change_since=0,&$etag=null)
{ {
if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length'])) if (isset($GLOBALS['egw_info']['user']['preferences']['syncml']['minimum_uid_length']))
{ {
@ -577,17 +582,34 @@ ORDER BY cal_user_type, cal_usre_id
$old_repeats = $this->db->select($this->repeats_table,'*',array('cal_id' => $cal_id),__LINE__,__FILE__,false,'','calendar')->fetch(); $old_repeats = $this->db->select($this->repeats_table,'*',array('cal_id' => $cal_id),__LINE__,__FILE__,false,'','calendar')->fetch();
$old_exceptions = $old_repeats['recur_exception'] ? explode(',',$old_repeats['recur_exception']) : array(); $old_exceptions = $old_repeats['recur_exception'] ? explode(',',$old_repeats['recur_exception']) : array();
if (isset($event['recur_exception']) && is_array($event['recur_exception']) && count($event['recur_exception'])) $event['recur_exception'] = is_array($event['recur_exception']) ? $event['recur_exception'] : array();
// re-check: did so much recurrence data change that we have to rebuild it from scratch?
if (!$set_recurrences)
{ {
// added and existing exceptions: delete the execeptions from the user and dates table, it could be the first time $set_recurrences = (isset($event['cal_start']) && (int)$old_min != (int) $event['cal_start']) ||
$this->db->delete($this->user_table,array('cal_id' => $cal_id,'cal_recur_date' => $event['recur_exception']),__LINE__,__FILE__,'calendar'); $event['recur_type'] != $old_repeats['recur_type'] || $event['recur_data'] != $old_repeats['recur_data'] ||
$this->db->delete($this->dates_table,array('cal_id' => $cal_id,'cal_start' => $event['recur_exception']),__LINE__,__FILE__,'calendar'); (int)$event['recur_interval'] != (int)$old_repeats['recur_interval'];
}
if ($set_recurrences)
{
// too much recurrence data has changed, we have to do a rebuild from scratch
// delete all, but the lowest dates record
$this->db->delete($this->dates_table,array(
'cal_id' => $cal_id,
'cal_start > '.(int)$old_min,
),__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');
} }
else else
{ {
$event['recur_exception'] = array(); // we adjust some possibly changed recurrences manually
}
// deleted exceptions: re-insert recurrences into the user and dates table // deleted exceptions: re-insert recurrences into the user and dates table
if(count($deleted_exceptions = array_diff($old_exceptions,$event['recur_exception']))) if(count($deleted_exceptions = array_diff($old_exceptions,$event['recur_exception'])))
{ {
@ -605,16 +627,38 @@ ORDER BY cal_user_type, cal_usre_id
} }
} }
if (!$set_recurrences) // check if recurrence enddate was adjusted
if(isset($event['recur_enddate']))
{ {
// check if the recurrence-information changed // recurrences need to be truncated
$set_recurrences = (isset($event['cal_start']) && (int)$old_min != (int) $event['cal_start']) || if((int)$event['recur_enddate'] > 0 &&
$event['recur_type'] != $old_repeats['recur_type'] || $event['recur_data'] != $old_repeats['recur_data'] || ((int)$old_repeats['recur_enddate'] == 0 || (int)$old_repeats['recur_enddate'] > (int)$event['recur_enddate'])
(int)$event['recur_interval'] != (int)$old_repeats['recur_interval'] || )
$event['recur_enddate'] != $old_repeats['recur_enddate']; {
// ToDo jaytraxx: manually handle recur_enddate change without recurrences rebuild $this->db->delete($this->user_table,array('cal_id' => $cal_id,'cal_recur_date > '.($event['recur_enddate'] + 1*DAY_s)),__LINE__,__FILE__,'calendar');
$this->db->delete($this->dates_table,array('cal_id' => $cal_id,'cal_start > '.($event['recur_enddate'] + 1*DAY_s)),__LINE__,__FILE__,'calendar');
} }
// recurrences need to be expanded
if(((int)$event['recur_enddate'] == 0 && (int)$old_repeats['recur_enddate'] > 0)
|| ((int)$event['recur_enddate'] > 0 && (int)$old_repeats['recur_enddate'] > 0 && (int)$old_repeats['recur_enddate'] < (int)$event['recur_enddate'])
)
{
$set_recurrences = true;
$set_recurrences_start = ($old_repeats['recur_enddate'] + 1*DAY_s);
}
}
// truncate recurrences by given exceptions
if (count($event['recur_exception']))
{
// added and existing exceptions: delete the execeptions from the user and dates table, it could be the first time
$this->db->delete($this->user_table,array('cal_id' => $cal_id,'cal_recur_date' => $event['recur_exception']),__LINE__,__FILE__,'calendar');
$this->db->delete($this->dates_table,array('cal_id' => $cal_id,'cal_start' => $event['recur_exception']),__LINE__,__FILE__,'calendar');
}
}
// write the repeats table
$event['recur_exception'] = empty($event['recur_exception']) ? null : implode(',',$event['recur_exception']); $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 unset($event[0]); // unset the 'etag=etag+1', as it's not in the repeats table
if($event['recur_type'] != MCAL_RECUR_NONE) if($event['recur_type'] != MCAL_RECUR_NONE)
@ -625,20 +669,6 @@ ORDER BY cal_user_type, cal_usre_id
{ {
$this->db->delete($this->repeats_table,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar'); $this->db->delete($this->repeats_table,array('cal_id' => $cal_id),__LINE__,__FILE__,'calendar');
} }
if ($set_recurrences)
{
// delete all, but the lowest dates record
$this->db->delete($this->dates_table,array(
'cal_id' => $cal_id,
'cal_start > '.(int)$old_min,
),__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');
}
} }
// update start- and endtime if present in the event-array, evtl. we need to move all recurrences // 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'])) if (isset($event['cal_start']) && isset($event['cal_end']))