no more querying of recurrences for etag of series master, as all update methods now update modification time of series master for recurrenc-exceptions

This commit is contained in:
Ralf Becker 2013-02-26 08:48:50 +00:00
parent 1202ccb0d1
commit 32751c69b6
3 changed files with 40 additions and 64 deletions

View File

@ -1918,14 +1918,14 @@ class calendar_bo
/**
* Get the etag for an entry
*
* As all update routines (incl. set_status and add/delete alarms) update (series master) modified timestamp,
* we do NOT need any special handling for series master anymore
*
* @param array|int|string $event array with event or cal_id, or cal_id:recur_date for virtual exceptions
* @param string &$schedule_tag=null on return schedule-tag (egw_cal.cal_id:egw_cal.cal_etag, no participant modifications!)
* @param boolean $client_share_uid_excpetions Does client understand exceptions to be included in VCALENDAR component of series master sharing its UID
* @param boolean $master_only=false only take into account recurrance masters
* (for ActiveSync which does not support different participants/status on recurrences/exceptions!)
* @return string|boolean string with etag or false
*/
function get_etag($entry, &$schedule_tag=null, $client_share_uid_excpetions=true,$master_only=false)
function get_etag($entry, &$schedule_tag=null)
{
if (!is_array($entry))
{
@ -1936,35 +1936,6 @@ class calendar_bo
$etag = $schedule_tag = $entry['id'].':'.$entry['etag'];
$etag .= ':'.$entry['modified'];
// include exception etags into our own etag, if exceptions are included
if ($client_share_uid_excpetions && //!empty($entry['uid']) &&
$entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception'])
{
foreach($this->so->get_cal_data(array(
'cal_reference' => $entry['id'],
), 'cal_id,cal_reference,cal_etag,cal_modified'.(!$master_only ? ',cal_user_modified' : '')) as $recurrence)
{
$recurrence = egw_db::strip_array_keys($data, 'cal_');
if ($recurrence['reference'] && $recurrence['id'] != $entry['id']) // ignore series master
{
// modified need to be max from modified and user_modified
if (!$master_only && $recurrence['modified'] < $recurrence['user_modified'])
{
$recurrence['modified'] = $recurrence['user_modified'];
}
$exception_etag = $this->get_etag($recurrence);
// if $master_only, only add cal_etag, not max. user modification date
if ($master_only) list(,$exception_etag) = explode(':',$exception_etag);
$exception_etags .= ':'.$exception_etag;
}
}
if ($exception_etags)
{
$etag .= ':'.md5($exception_etags); // limit size, as there can be many exceptions
}
//error_log(__METHOD__."($entry[id]: $entry[title]) returning $etag ".function_backtrace());
}
//error_log(__METHOD__ . "($entry[id],$client_share_uid_excpetions) entry=".array2string($entry)." --> etag=$etag");
return $etag;
}

View File

@ -1755,7 +1755,7 @@ class calendar_boupdate extends calendar_bo
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar', $cal_id, 'modify', $this->now);
return $this->so->save_alarm($cal_id,$alarm, $this->now);
return $this->so->save_alarm($cal_id,$alarm);
}
/**
@ -1775,7 +1775,7 @@ class calendar_boupdate extends calendar_bo
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar', $cal_id, 'modify', $this->now);
return $this->so->delete_alarm($id, $this->now);
return $this->so->delete_alarm($id);
}
/**

View File

@ -7,7 +7,7 @@
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
* @author Christian Binder <christian-AT-jaytraxx.de>
* @author Joerg Lehrke <jlehrke@noc.de>
* @copyright (c) 2005-11 by RalfBecker-At-outdoor-training.de
* @copyright (c) 2005-13 by RalfBecker-At-outdoor-training.de
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @version $Id$
*/
@ -68,6 +68,9 @@ define('WEEK_s',7*DAY_s);
* DB-model uses egw_cal_user.cal_status='X' for participants who got deleted. They never get returned by
* read or search methods, but influence the ctag of the deleted users calendar!
*
* All update methods not take care to update modification time of (evtl. existing) series master too,
* to force an etag, ctag and sync-token change! Methods not doing that are private to this class.
*
* range_start/_end in main-table contains start and end of whole event series (range_end is NULL for unlimited recuring events),
* saving the need to always join dates table, to query non-enumerating recuring events (like CalDAV or ActiveSync does).
* This effectivly stores MIN(cal_start) and MAX(cal_end) permanently as column in main-table and improves speed tremendiously
@ -1321,7 +1324,7 @@ ORDER BY cal_user_type, cal_usre_id
{
continue; // pgoerzen: don't add alarm in the past
}
$this->save_alarm($cal_id,$alarm);
$this->save_alarm($cal_id, $alarm, false); // false: not update modified, we do it anyway
}
}
if (is_null($etag))
@ -1683,13 +1686,7 @@ ORDER BY cal_user_type, cal_usre_id
// update modified and modifier in main table
if (($ret = $this->db->affected_rows()))
{
$this->updateModified($cal_id);
// if event is an exception: update modified of master, to force etag, ctag and sync-token change
if (($master_id = $this->db->select($this->cal_table, 'cal_reference', array('cal_id' => $cal_id), __LINE__, __FILE__)->fetchColumn()))
{
$this->updateModified($master_id);
}
$this->updateModified($cal_id, true); // true = update series master too
}
//error_log(__METHOD__."($cal_id,$user_type,$user_id,$status,$recur_date) = $ret");
return $ret;
@ -1770,6 +1767,9 @@ ORDER BY cal_user_type, cal_usre_id
$this->delete_alarms($cal_id);
// update timestamp of series master, updates own timestamp too, which does not hurt ;-)
$this->updateModified($cal_id, true);
foreach($this->all_tables as $table)
{
$this->db->delete($table,array('cal_id'=>$cal_id),__LINE__,__FILE__,'calendar');
@ -1859,10 +1859,10 @@ ORDER BY cal_user_type, cal_usre_id
*
* @param int $cal_id Id of the calendar-entry
* @param array $alarm array with fields: text, owner, enabled, ..
* @param timestamp $now=0 timestamp for modification of related event
* @param boolean $update_modified=true call update modified, default true
* @return string id of the alarm
*/
function save_alarm($cal_id, $alarm, $now=0)
function save_alarm($cal_id, $alarm, $update_modified=true)
{
//echo "<p>save_alarm(cal_id=$cal_id, alarm="; print_r($alarm); echo ")</p>\n";
//error_log(__METHOD__."(.$cal_id,$now,".array2string($alarm).')');
@ -1890,21 +1890,20 @@ ORDER BY cal_user_type, cal_usre_id
}
// update the modification information of the related event
if (!$now) $now = time();
$modifier = $GLOBALS['egw_info']['user']['account_id'];
$this->db->update($this->cal_table, array('cal_modified' => $now, 'cal_modifier' => $modifier),
array('cal_id' => $cal_id), __LINE__, __FILE__, 'calendar');
if ($update_modified) $this->updateModified($cal_id, true);
return $id;
}
/**
* delete all alarms of a calendar-entry
* Delete all alarms of a calendar-entry
*
* Does not update timestamps of series master, therefore private!
*
* @param int $cal_id Id of the calendar-entry
* @return int number of alarms deleted
*/
function delete_alarms($cal_id)
private function delete_alarms($cal_id)
{
$alarms = $this->read_alarms($cal_id);
@ -1919,19 +1918,15 @@ ORDER BY cal_user_type, cal_usre_id
* delete one alarms identified by its id
*
* @param string $id alarm-id is a string of 'cal:'.$cal_id.':'.$alarm_nr, it is used as the job-id too
* @param timestamp $now=0 timestamp for modification of related event
* @return int number of alarms deleted
*/
function delete_alarm($id, $now=0)
function delete_alarm($id)
{
// update the modification information of the related event
list(,$cal_id) = explode(':',$id);
if ($cal_id)
{
if (!$now) $now = time();
$modifier = $GLOBALS['egw_info']['user']['account_id'];
$this->db->update($this->cal_table, array('cal_modified' => $now, 'cal_modifier' => $modifier),
array('cal_id' => $cal_id), __LINE__, __FILE__, 'calendar');
$this->updateModified($cal_id, true);
}
return $this->async->cancel_timer($id);
}
@ -2453,19 +2448,29 @@ ORDER BY cal_user_type, cal_usre_id
}
/**
* Udates the modification timestamp
* Updates the modification timestamp to force an etag, ctag and sync-token change
*
* @param id event id
* @param time new timestamp, default current (server-)time
* @param modifier uid of the modifier, default current user
* @param int $id event id
* @param int|boolean $update_master=false id of series master or true, to update series master too
* @param int $time=null new timestamp, default current (server-)time
* @param int $modifier=null uid of the modifier, default current user
*/
function updateModified($id, $time=null, $modifier=null)
function updateModified($id, $update_master=false, $time=null, $modifier=null)
{
if (is_null($time)) $time = time();
if (is_null($time) || !$time) $time = time();
if (is_null($modifier)) $modifier = $GLOBALS['egw_info']['user']['account_id'];
$this->db->update($this->cal_table,
array('cal_modified' => $time, 'cal_modifier' => $modifier),
array('cal_id' => $id), __LINE__,__FILE__, 'calendar');
// if event is an exception: update modified of master, to force etag, ctag and sync-token change
if ($update_master)
{
if ($update_master !== true || ($update_master = $this->db->select($this->cal_table, 'cal_reference', array('cal_id' => $id), __LINE__, __FILE__)->fetchColumn()))
{
$this->updateModified($update_master, false, $time, $modifier);
}
}
}
}