mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-23 16:33:17 +01:00
* Calendar/CalDAV/eSync: tracking participant status changes now in modified date and user of calendar entry (main table), fixes sometimes not synced status changes and simplifies code a lot
This commit is contained in:
parent
5486b8a03f
commit
41470de3b4
@ -631,7 +631,6 @@ class calendar_bo
|
|||||||
'owner' => $event['owner'],
|
'owner' => $event['owner'],
|
||||||
'recur_type' => MCAL_RECUR_NONE,
|
'recur_type' => MCAL_RECUR_NONE,
|
||||||
'etag' => $event['etag'],
|
'etag' => $event['etag'],
|
||||||
'max_user_modified' => $event['max_user_modified'],
|
|
||||||
'participants' => array_intersect_key($event['participants'],array_flip($allowed_participants)),
|
'participants' => array_intersect_key($event['participants'],array_flip($allowed_participants)),
|
||||||
'public'=> 0,
|
'public'=> 0,
|
||||||
'category' => $event['category'], // category is visible anyway, eg. by using planner by cat
|
'category' => $event['category'], // category is visible anyway, eg. by using planner by cat
|
||||||
@ -803,11 +802,11 @@ class calendar_bo
|
|||||||
$time->setTime(23, 59, 59);
|
$time->setTime(23, 59, 59);
|
||||||
$event['recur_enddate'] = egw_time::to($time, $date_format);
|
$event['recur_enddate'] = egw_time::to($time, $date_format);
|
||||||
}
|
}
|
||||||
$timestamps = array('modified','created','max_user_modified');
|
$timestamps = array('modified','created');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$timestamps = array('start','end','modified','created','recur_enddate','recurrence','max_user_modified');
|
$timestamps = array('start','end','modified','created','recur_enddate','recurrence');
|
||||||
}
|
}
|
||||||
// we convert here from the server-time timestamps to user-time and (optional) to a different date-format!
|
// we convert here from the server-time timestamps to user-time and (optional) to a different date-format!
|
||||||
foreach ($timestamps as $ts)
|
foreach ($timestamps as $ts)
|
||||||
@ -1931,18 +1930,8 @@ class calendar_bo
|
|||||||
if (!$this->check_perms(EGW_ACL_FREEBUSY, $entry, 0, 'server')) return false;
|
if (!$this->check_perms(EGW_ACL_FREEBUSY, $entry, 0, 'server')) return false;
|
||||||
$entry = $this->read($entry, $recur_date, true, 'server');
|
$entry = $this->read($entry, $recur_date, true, 'server');
|
||||||
}
|
}
|
||||||
$etag = $schedule_tag = $entry['id'].':'.$entry['etag'];
|
$etag = $schedule_tag = $entry['id'].':'.$entry['etag'].':'.$entry['modified'];
|
||||||
|
|
||||||
// use new MAX(modification date) of egw_cal_user table (deals with virtual exceptions too)
|
|
||||||
if (isset($entry['max_user_modified']))
|
|
||||||
{
|
|
||||||
$modified = max($entry['max_user_modified'], $entry['modified']);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$modified = max($this->so->max_user_modified($entry['id'],false,$master_only), $entry['modified']);
|
|
||||||
}
|
|
||||||
$etag .= ':' . $modified;
|
|
||||||
// include exception etags into our own etag, if exceptions are included
|
// include exception etags into our own etag, if exceptions are included
|
||||||
if ($client_share_uid_excpetions && !empty($entry['uid']) &&
|
if ($client_share_uid_excpetions && !empty($entry['uid']) &&
|
||||||
$entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception'])
|
$entry['recur_type'] != MCAL_RECUR_NONE && $entry['recur_exception'])
|
||||||
|
@ -232,7 +232,7 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
$props = array(
|
$props = array(
|
||||||
'getcontenttype' => $this->agent != 'kde' ? 'text/calendar; charset=utf-8; component=VEVENT' : 'text/calendar',
|
'getcontenttype' => $this->agent != 'kde' ? 'text/calendar; charset=utf-8; component=VEVENT' : 'text/calendar',
|
||||||
'getetag' => '"'.$etag.'"',
|
'getetag' => '"'.$etag.'"',
|
||||||
'getlastmodified' => max($event['modified'], $event['max_user_modified']),
|
'getlastmodified' => $event['modified'],
|
||||||
);
|
);
|
||||||
if ($this->use_schedule_tag)
|
if ($this->use_schedule_tag)
|
||||||
{
|
{
|
||||||
@ -1215,15 +1215,17 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
}
|
}
|
||||||
$props['supported-calendar-component-set'] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,
|
$props['supported-calendar-component-set'] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,
|
||||||
'supported-calendar-component-set',$supported_components);
|
'supported-calendar-component-set',$supported_components);
|
||||||
$props['supported-report-set'] = HTTP_WebDAV_Server::mkprop('supported-report-set',array(
|
$props['supported-report-set'] = array(
|
||||||
HTTP_WebDAV_Server::mkprop('supported-report',array(
|
'calendar-query' => HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-query',''))),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-query',''))))),
|
||||||
|
'calendar-multiget' => HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget',''))),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget',''))))),
|
||||||
|
'free-busy-query' => HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'free-busy-query',''))),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'free-busy-query',''))))),
|
||||||
))));
|
);
|
||||||
$props['supported-calendar-data'] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-data',array(
|
$props['supported-calendar-data'] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-data',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-data', array('content-type' => 'text/calendar', 'version'=> '2.0')),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-data', array('content-type' => 'text/calendar', 'version'=> '2.0')),
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-data', array('content-type' => 'text/x-calendar', 'version'=> '1.0'))));
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-data', array('content-type' => 'text/x-calendar', 'version'=> '1.0'))));
|
||||||
|
@ -856,11 +856,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
$attributes['CREATED'] = $event['created'] ? $event['created'] : $event['modified'];
|
$attributes['CREATED'] = $event['created'] ? $event['created'] : $event['modified'];
|
||||||
}
|
}
|
||||||
if ($event['max_user_modified'])
|
if ($event['modified'])
|
||||||
{
|
|
||||||
$attributes['LAST-MODIFIED'] = max($event['modified'], $event['max_user_modified']);
|
|
||||||
}
|
|
||||||
elseif ($event['modified'])
|
|
||||||
{
|
{
|
||||||
$attributes['LAST-MODIFIED'] = $event['modified'];
|
$attributes['LAST-MODIFIED'] = $event['modified'];
|
||||||
}
|
}
|
||||||
|
@ -241,7 +241,6 @@ class calendar_so
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$need_max_user_modified = array();
|
|
||||||
// participants, if a recur_date give, we read that recurance, plus the one users from the default entry with recur_date=0
|
// participants, if a recur_date give, we read that recurance, plus the one users from the default entry with recur_date=0
|
||||||
// sorting by cal_recur_date ASC makes sure recurence status always overwrites series status
|
// sorting by cal_recur_date ASC makes sure recurence status always overwrites series status
|
||||||
foreach($this->db->select($this->user_table,'*',array(
|
foreach($this->db->select($this->user_table,'*',array(
|
||||||
@ -256,23 +255,6 @@ class calendar_so
|
|||||||
|
|
||||||
$events[$row['cal_id']]['participants'][$uid] = $status;
|
$events[$row['cal_id']]['participants'][$uid] = $status;
|
||||||
$events[$row['cal_id']]['participant_types'][$row['cal_user_type']][$row['cal_user_id']] = $status;
|
$events[$row['cal_id']]['participant_types'][$row['cal_user_type']][$row['cal_user_id']] = $status;
|
||||||
|
|
||||||
if ($events[$row['cal_id']]['recur_type'])
|
|
||||||
{
|
|
||||||
$need_max_user_modified[$row['cal_id']] = $row['cal_id'];
|
|
||||||
}
|
|
||||||
elseif (($modified = $this->db->from_timestamp($row['cal_user_modified'])) > $events[$row['cal_id']]['max_user_modified'])
|
|
||||||
{
|
|
||||||
$events[$row['cal_id']]['max_user_modified'] = $modified;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// max_user_modified for recurring events has to include all recurrences, above code only querys $recur_date!
|
|
||||||
if ($need_max_user_modified)
|
|
||||||
{
|
|
||||||
foreach($this->max_user_modified($need_max_user_modified) as $id => $modified)
|
|
||||||
{
|
|
||||||
$events[$id]['max_user_modified'] = $modified;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// custom fields
|
// custom fields
|
||||||
@ -297,44 +279,6 @@ class calendar_so
|
|||||||
return $events;
|
return $events;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get maximum modification time of participant data of given event(s)
|
|
||||||
*
|
|
||||||
* This includes ALL recurences of an event series
|
|
||||||
*
|
|
||||||
* @param int|array $ids one or multiple cal_id's
|
|
||||||
* @param boolean $return_maximum=false if true return only the maximum, even for multiple ids
|
|
||||||
* @param boolean $master_only=false only check recurance master (egw_cal_user.recur_date=0)
|
|
||||||
* @return int|array (array of) modification timestamp(s)
|
|
||||||
*/
|
|
||||||
function max_user_modified($ids, $return_maximum=false, $master_only=false)
|
|
||||||
{
|
|
||||||
if (!is_array($ids)) $return_maximum = true;
|
|
||||||
|
|
||||||
$where = array('cal_id' => $ids);
|
|
||||||
if ($master_only) $where['cal_recur_date'] = 0;
|
|
||||||
|
|
||||||
if ($return_maximum)
|
|
||||||
{
|
|
||||||
if (($etags = $this->db->select($this->user_table,'MAX(cal_user_modified)',$where,
|
|
||||||
__LINE__,__FILE__,false,'','calendar')->fetchColumn()))
|
|
||||||
{
|
|
||||||
$etags = $this->db->from_timestamp($etags);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$etags = array();
|
|
||||||
foreach($this->db->select($this->user_table,'cal_id,MAX(cal_user_modified) AS user_etag',$where,
|
|
||||||
__LINE__,__FILE__,false,'GROUP BY cal_id','calendar') as $row)
|
|
||||||
{
|
|
||||||
$etags[$row['cal_id']] = $this->db->from_timestamp($row['user_etag']);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//error_log(__METHOD__.'('.array2string($ids).', '.array2string($return_maximum).', '.array2string($master_only).') = '.array2string($etags).' '.function_backtrace());
|
|
||||||
return $etags;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get maximum modification time of events for given participants and optional owned by them
|
* Get maximum modification time of events for given participants and optional owned by them
|
||||||
*
|
*
|
||||||
@ -347,6 +291,10 @@ class calendar_so
|
|||||||
*/
|
*/
|
||||||
function get_ctag($users, $owner_too=false,$master_only=false)
|
function get_ctag($users, $owner_too=false,$master_only=false)
|
||||||
{
|
{
|
||||||
|
static $ctags = array(); // some per-request caching
|
||||||
|
$signature = serialize(func_get_args());
|
||||||
|
if (isset($ctags[$signature])) return $ctags[$signature];
|
||||||
|
|
||||||
$where = array(
|
$where = array(
|
||||||
'cal_user_type' => 'u',
|
'cal_user_type' => 'u',
|
||||||
'cal_user_id' => $users,
|
'cal_user_id' => $users,
|
||||||
@ -367,14 +315,8 @@ class calendar_so
|
|||||||
'cal_owner' => $users,
|
'cal_owner' => $users,
|
||||||
),')');
|
),')');
|
||||||
}
|
}
|
||||||
if (($data = $this->db->select($this->user_table,array(
|
return $ctags[$signature] = $this->db->select($this->user_table,'MAX(cal_modified) AS max_modified',
|
||||||
'MAX(cal_user_modified) AS max_user_modified',
|
$where,__LINE__,__FILE__,false,'','calendar',0,'JOIN egw_cal ON egw_cal.cal_id=egw_cal_user.cal_id')->fetchColumn();
|
||||||
'MAX(cal_modified) AS max_modified',
|
|
||||||
),$where,__LINE__,__FILE__,false,'','calendar',0,'JOIN egw_cal ON egw_cal.cal_id=egw_cal_user.cal_id')->fetch()))
|
|
||||||
{
|
|
||||||
$data = max($this->db->from_timestamp($data['max_user_modified']),$data['max_modified']);
|
|
||||||
}
|
|
||||||
return $data;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -729,7 +671,6 @@ class calendar_so
|
|||||||
{
|
{
|
||||||
$ids = array_unique($ids);
|
$ids = array_unique($ids);
|
||||||
|
|
||||||
$need_max_user_modified = array();
|
|
||||||
// now ready all users with the given cal_id AND (cal_recur_date=0 or the fitting recur-date)
|
// now ready all users with the given cal_id AND (cal_recur_date=0 or the fitting recur-date)
|
||||||
// This will always read the first entry of each recuring event too, we eliminate it later
|
// This will always read the first entry of each recuring event too, we eliminate it later
|
||||||
$recur_dates[] = 0;
|
$recur_dates[] = 0;
|
||||||
@ -762,16 +703,6 @@ class calendar_so
|
|||||||
|
|
||||||
// set data, if recurrence is requested
|
// set data, if recurrence is requested
|
||||||
if (isset($events[$id])) $events[$id]['participants'][$uid] = $status;
|
if (isset($events[$id])) $events[$id]['participants'][$uid] = $status;
|
||||||
|
|
||||||
// fill max_user_modified:
|
|
||||||
if (!$params['master_only'] && $events[$id]['recur_type'])
|
|
||||||
{
|
|
||||||
$need_max_user_modified[$id] = $id;
|
|
||||||
}
|
|
||||||
elseif (isset($events[$id]) && ($modified = $this->db->from_timestamp($row['cal_user_modified'])) > $events[$id]['max_user_modified'])
|
|
||||||
{
|
|
||||||
$events[$id]['max_user_modified'] = $modified;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// query recurrance exceptions, if needed
|
// query recurrance exceptions, if needed
|
||||||
if (!$params['enum_recuring'])
|
if (!$params['enum_recuring'])
|
||||||
@ -787,14 +718,6 @@ class calendar_so
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// max_user_modified for recurring events has to include all recurrences, above code only querys $recur_date!
|
|
||||||
if (!$params['enum_recuring'] && $need_max_user_modified)
|
|
||||||
{
|
|
||||||
foreach($this->max_user_modified($need_max_user_modified) as $id => $modified)
|
|
||||||
{
|
|
||||||
$events[$id]['max_user_modified'] = $modified;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//custom fields are not shown in the regular views, so we only query them, if explicitly required
|
//custom fields are not shown in the regular views, so we only query them, if explicitly required
|
||||||
if (!is_null($params['cfs']))
|
if (!is_null($params['cfs']))
|
||||||
{
|
{
|
||||||
@ -1651,7 +1574,11 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
if (!is_null($role) && $role != 'REQ-PARTICIPANT') $set['cal_role'] = $role;
|
if (!is_null($role) && $role != 'REQ-PARTICIPANT') $set['cal_role'] = $role;
|
||||||
$this->db->insert($this->user_table,$set,$where,__LINE__,__FILE__,'calendar');
|
$this->db->insert($this->user_table,$set,$where,__LINE__,__FILE__,'calendar');
|
||||||
}
|
}
|
||||||
$ret = $this->db->affected_rows();
|
// update modified and modifier in main table
|
||||||
|
if (($ret = $this->db->affected_rows()))
|
||||||
|
{
|
||||||
|
$this->updateModified($cal_id, time(), $GLOBALS['egw_info']['user']['account_id']);
|
||||||
|
}
|
||||||
//error_log(__METHOD__."($cal_id,$user_type,$user_id,$status,$recur_date) = $ret");
|
//error_log(__METHOD__."($cal_id,$user_type,$user_id,$status,$recur_date) = $ret");
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$setup_info['calendar']['name'] = 'calendar';
|
$setup_info['calendar']['name'] = 'calendar';
|
||||||
$setup_info['calendar']['version'] = '1.9.008';
|
$setup_info['calendar']['version'] = '1.9.009';
|
||||||
$setup_info['calendar']['app_order'] = 3;
|
$setup_info['calendar']['app_order'] = 3;
|
||||||
$setup_info['calendar']['enable'] = 1;
|
$setup_info['calendar']['enable'] = 1;
|
||||||
$setup_info['calendar']['index'] = 'calendar.calendar_uiviews.index';
|
$setup_info['calendar']['index'] = 'calendar.calendar_uiviews.index';
|
||||||
|
@ -2212,9 +2212,9 @@ function calendar_upgrade1_9_007()
|
|||||||
{
|
{
|
||||||
foreach(array('egw_cal_repeats','egw_cal_dates','egw_cal_user','egw_cal_extra') as $table)
|
foreach(array('egw_cal_repeats','egw_cal_dates','egw_cal_user','egw_cal_extra') as $table)
|
||||||
{
|
{
|
||||||
$GLOBALS['egw_setup']->db->query("DELETE FROM $table WHERE cal_id IN (SELECT cal_id FROM egw_cal WHERE range_start=0 OR range_start IS NULL)");
|
$GLOBALS['egw_setup']->db->query("DELETE FROM $table WHERE cal_id IN (SELECT cal_id FROM egw_cal WHERE range_start=0 OR range_start IS NULL)", __LINE__, __FILE__);
|
||||||
}
|
}
|
||||||
$GLOBALS['egw_setup']->db->query("DELETE FROM egw_cal WHERE range_start=0 OR range_start IS NULL");
|
$GLOBALS['egw_setup']->db->query("DELETE FROM egw_cal WHERE range_start=0 OR range_start IS NULL", __LINE__, __FILE__);
|
||||||
|
|
||||||
// now we can remove temporary default of 0 from range_start and set it NOT NULL
|
// now we can remove temporary default of 0 from range_start and set it NOT NULL
|
||||||
$GLOBALS['egw_setup']->oProc->AlterColumn('egw_cal','range_start',array(
|
$GLOBALS['egw_setup']->oProc->AlterColumn('egw_cal','range_start',array(
|
||||||
@ -2227,10 +2227,21 @@ function calendar_upgrade1_9_007()
|
|||||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.9.008';
|
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.9.008';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* UPDATE cal_modified to contain maximum of cal_user_modified and current cal_modified, to get a single modification date per calendar-entry
|
||||||
|
*/
|
||||||
|
function calendar_upgrade1_9_008()
|
||||||
|
{
|
||||||
|
$max_user_modified = 'SELECT '.$GLOBALS['egw_setup']->db->unix_timestamp('MAX(cal_user_modified)').' FROM egw_cal_user WHERE egw_cal.cal_id=egw_cal_user.cal_id';
|
||||||
|
$GLOBALS['egw_setup']->db->query("UPDATE egw_cal SET cal_modified=($max_user_modified) WHERE cal_modified < ($max_user_modified)", __LINE__, __FILE__);
|
||||||
|
|
||||||
|
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.9.009';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add cal_rrule columns, drop egw_cal_repeats table
|
* Add cal_rrule columns, drop egw_cal_repeats table
|
||||||
*/
|
*/
|
||||||
/*function calendar_upgrade1_9_008()
|
/*function calendar_upgrade1_9_009()
|
||||||
{
|
{
|
||||||
$GLOBALS['egw_setup']->oProc->AddColumn('egw_cal','cal_rrule',array(
|
$GLOBALS['egw_setup']->oProc->AddColumn('egw_cal','cal_rrule',array(
|
||||||
'type' => 'varchar',
|
'type' => 'varchar',
|
||||||
@ -2255,6 +2266,6 @@ function calendar_upgrade1_9_007()
|
|||||||
}
|
}
|
||||||
$GLOBALS['egw_setup']->oProc->DropTable('egw_cal_repeats');
|
$GLOBALS['egw_setup']->oProc->DropTable('egw_cal_repeats');
|
||||||
|
|
||||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.9.009';
|
return $GLOBALS['setup_info']['calendar']['currentver'] = '1.9.010';
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user