mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 08:38:54 +01:00
* Calendar/CalDAV/eSync: exceptions show up in calendars of participants only participating in exceptions not whole recuring event (requires a DB update for existing events!)
This commit is contained in:
parent
ffbd475f35
commit
0b62d3ea4a
@ -435,7 +435,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
if (!($info = $this->resource_info($uid))) continue;
|
if (!($info = $this->resource_info($uid))) continue;
|
||||||
|
|
||||||
if ($status == 'X') continue; // dont include deleted participants
|
if (in_array($status, array('X','E'))) continue; // dont include deleted participants
|
||||||
|
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||||
* @author Christian Binder <christian-AT-jaytraxx.de>
|
* @author Christian Binder <christian-AT-jaytraxx.de>
|
||||||
* @author Joerg Lehrke <jlehrke@noc.de>
|
* @author Joerg Lehrke <jlehrke@noc.de>
|
||||||
* @copyright (c) 2005-13 by RalfBecker-At-outdoor-training.de
|
* @copyright (c) 2005-14 by RalfBecker-At-outdoor-training.de
|
||||||
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
|
||||||
* @version $Id$
|
* @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
|
* 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!
|
* read or search methods, but influence the ctag of the deleted users calendar!
|
||||||
*
|
*
|
||||||
|
* DB-model uses egw_cal_user.cal_status='E' for participants only participating in exceptions of recurring
|
||||||
|
* events, so whole recurring event get found for these participants too!
|
||||||
|
*
|
||||||
* All update methods not take care to update modification time of (evtl. existing) series master too,
|
* 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.
|
* to force an etag, ctag and sync-token change! Methods not doing that are private to this class.
|
||||||
*
|
*
|
||||||
@ -283,7 +286,7 @@ class calendar_so
|
|||||||
foreach($this->db->select($this->user_table,'*',array(
|
foreach($this->db->select($this->user_table,'*',array(
|
||||||
'cal_id' => $ids,
|
'cal_id' => $ids,
|
||||||
'cal_recur_date' => $recur_date,
|
'cal_recur_date' => $recur_date,
|
||||||
"cal_status != 'X'",
|
"cal_status NOT IN ('X','E')",
|
||||||
),__LINE__,__FILE__,false,'ORDER BY cal_user_type DESC,cal_recur_date ASC,'.self::STATUS_SORT,'calendar') as $row) // DESC puts users before resources and contacts
|
),__LINE__,__FILE__,false,'ORDER BY cal_user_type DESC,cal_recur_date ASC,'.self::STATUS_SORT,'calendar') as $row) // DESC puts users before resources and contacts
|
||||||
{
|
{
|
||||||
// combine all participant data in uid and status values
|
// combine all participant data in uid and status values
|
||||||
@ -461,12 +464,18 @@ class calendar_so
|
|||||||
*/
|
*/
|
||||||
function &search($start,$end,$users,$cat_id=0,$filter='all',$offset=False,$num_rows=0,array $params=array(),$remove_rejected_by_user=null)
|
function &search($start,$end,$users,$cat_id=0,$filter='all',$offset=False,$num_rows=0,array $params=array(),$remove_rejected_by_user=null)
|
||||||
{
|
{
|
||||||
//error_log(__METHOD__.'('.($start ? date('Y-m-d H:i',$start) : '').','.($end ? date('Y-m-d H:i',$end) : '').','.array2string($users).','.array2string($cat_id).",'$filter',".array2string($offset).",$num_rows,".array2string($params).') '.function_backtrace());
|
error_log(__METHOD__.'('.($start ? date('Y-m-d H:i',$start) : '').','.($end ? date('Y-m-d H:i',$end) : '').','.array2string($users).','.array2string($cat_id).",'$filter',".array2string($offset).",$num_rows,".array2string($params).') '.function_backtrace());
|
||||||
|
|
||||||
$cols = self::get_columns('calendar', $this->cal_table);
|
|
||||||
$cols[0] = $this->db->to_varchar($this->cal_table.'.cal_id');
|
|
||||||
$cols = isset($params['cols']) ? $params['cols'] : "$this->repeats_table.recur_type,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,range_end AS recur_enddate,".implode(',',$cols).",cal_start,cal_end,$this->user_table.cal_recur_date";
|
|
||||||
|
|
||||||
|
if (isset($params['cols']))
|
||||||
|
{
|
||||||
|
$cols = $params['cols'];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$all_cols = self::get_columns('calendar', $this->cal_table);
|
||||||
|
$all_cols[0] = $this->db->to_varchar($this->cal_table.'.cal_id');
|
||||||
|
$cols = "$this->repeats_table.recur_type,$this->repeats_table.recur_interval,$this->repeats_table.recur_data,range_end AS recur_enddate,".implode(',',$all_cols).",cal_start,cal_end,$this->user_table.cal_recur_date";
|
||||||
|
}
|
||||||
$where = array();
|
$where = array();
|
||||||
if (is_array($params['query']))
|
if (is_array($params['query']))
|
||||||
{
|
{
|
||||||
@ -557,27 +566,42 @@ class calendar_so
|
|||||||
break;
|
break;
|
||||||
case 'showonlypublic':
|
case 'showonlypublic':
|
||||||
$where['cal_public'] = 1;
|
$where['cal_public'] = 1;
|
||||||
$where[] = "$this->user_table.cal_status NOT IN ('R','X')"; break;
|
$where[] = "$this->user_table.cal_status NOT IN ('R','X','E')";
|
||||||
|
break;
|
||||||
case 'deleted':
|
case 'deleted':
|
||||||
$where[] = 'cal_deleted IS NOT NULL'; break;
|
$where[] = 'cal_deleted IS NOT NULL';
|
||||||
|
break;
|
||||||
case 'unknown':
|
case 'unknown':
|
||||||
$where[] = "$this->user_table.cal_status='U'"; break;
|
$where[] = "$this->user_table.cal_status='U'";
|
||||||
|
break;
|
||||||
case 'not-unknown':
|
case 'not-unknown':
|
||||||
$where[] = "$this->user_table.cal_status NOT IN ('U','X')"; break;
|
$where[] = "$this->user_table.cal_status NOT IN ('U','X','E')";
|
||||||
|
break;
|
||||||
case 'accepted':
|
case 'accepted':
|
||||||
$where[] = "$this->user_table.cal_status='A'"; break;
|
$where[] = "$this->user_table.cal_status='A'";
|
||||||
|
break;
|
||||||
case 'tentative':
|
case 'tentative':
|
||||||
$where[] = "$this->user_table.cal_status='T'"; break;
|
$where[] = "$this->user_table.cal_status='T'";
|
||||||
|
break;
|
||||||
case 'rejected':
|
case 'rejected':
|
||||||
$where[] = "$this->user_table.cal_status='R'"; break;
|
$where[] = "$this->user_table.cal_status='R'";
|
||||||
|
break;
|
||||||
case 'delegated':
|
case 'delegated':
|
||||||
$where[] = "$this->user_table.cal_status='D'"; break;
|
$where[] = "$this->user_table.cal_status='D'";
|
||||||
|
break;
|
||||||
case 'all':
|
case 'all':
|
||||||
case 'owner':
|
case 'owner':
|
||||||
$where[] = "$this->user_table.cal_status!='X'"; break;
|
$where[] = "$this->user_table.cal_status NOT IN ('X','E')";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
if ($params['enum_recuring']) // regular UI
|
||||||
|
{
|
||||||
|
$where[] = "$this->user_table.cal_status NOT IN ('R','X','E')";
|
||||||
|
}
|
||||||
|
else // CalDAV / eSync / iCal need to include 'E' = exceptions
|
||||||
|
{
|
||||||
$where[] = "$this->user_table.cal_status NOT IN ('R','X')";
|
$where[] = "$this->user_table.cal_status NOT IN ('R','X')";
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -699,14 +723,14 @@ class calendar_so
|
|||||||
array('range_start AS cal_start','range_end AS cal_end'), $selects[$key]['cols']);
|
array('range_start AS cal_start','range_end AS cal_end'), $selects[$key]['cols']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!isset($param['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
if (!isset($params['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
||||||
|
|
||||||
$this->total = $this->db->union($selects,__LINE__,__FILE__)->NumRows();
|
$this->total = $this->db->union($selects,__LINE__,__FILE__)->NumRows();
|
||||||
|
|
||||||
// restore original cols / selects
|
// restore original cols / selects
|
||||||
$selects = $save_selects; unset($save_selects);
|
$selects = $save_selects; unset($save_selects);
|
||||||
}
|
}
|
||||||
if (!isset($param['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
if (!isset($params['cols'])) self::get_union_selects($selects,$start,$end,$users,$cat_id,$filter,$params['query'],$params['users']);
|
||||||
|
|
||||||
$rs = $this->db->union($selects,__LINE__,__FILE__,$params['order'],$offset,$num_rows);
|
$rs = $this->db->union($selects,__LINE__,__FILE__,$params['order'],$offset,$num_rows);
|
||||||
}
|
}
|
||||||
@ -770,7 +794,7 @@ class calendar_so
|
|||||||
// 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;
|
||||||
$utcal_id_view = " (SELECT * FROM ".$this->user_table." WHERE cal_id IN (".implode(',',$ids).")".
|
$utcal_id_view = " (SELECT * FROM ".$this->user_table." WHERE cal_id IN (".implode(',',$ids).")".
|
||||||
($filter != 'everything' ? " AND cal_status!='X'" : '').") utcalid ";
|
($filter != 'everything' ? " AND cal_status NOT IN ('X','E')" : '').") utcalid ";
|
||||||
//$utrecurdate_view = " (select * from ".$this->user_table." where cal_recur_date in (".implode(',',array_unique($recur_dates)).")) utrecurdates ";
|
//$utrecurdate_view = " (select * from ".$this->user_table." where cal_recur_date in (".implode(',',array_unique($recur_dates)).")) utrecurdates ";
|
||||||
foreach($this->db->select($utcal_id_view,'*',array(
|
foreach($this->db->select($utcal_id_view,'*',array(
|
||||||
//'cal_id' => array_unique($ids),
|
//'cal_id' => array_unique($ids),
|
||||||
@ -1089,6 +1113,9 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
|
|
||||||
$event['cal_category'] = implode(',',$categories);
|
$event['cal_category'] = implode(',',$categories);
|
||||||
|
|
||||||
|
// make sure recurring events never reference to an other recurrent event
|
||||||
|
if ($event['recur_type'] != MCAL_RECUR_NONE) $event['cal_reference'] = 0;
|
||||||
|
|
||||||
if ($cal_id)
|
if ($cal_id)
|
||||||
{
|
{
|
||||||
// query old recurrance information, before updating main table, where recur_endate is now stored
|
// query old recurrance information, before updating main table, where recur_endate is now stored
|
||||||
@ -1161,6 +1188,33 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
$this->db->delete($this->repeats_table,array(
|
$this->db->delete($this->repeats_table,array(
|
||||||
'cal_id' => $cal_id),
|
'cal_id' => $cal_id),
|
||||||
__LINE__,__FILE__,'calendar');
|
__LINE__,__FILE__,'calendar');
|
||||||
|
|
||||||
|
// add exception marker to master, so participants added to exceptions *only* get found
|
||||||
|
if ($event['cal_reference'])
|
||||||
|
{
|
||||||
|
$master_participants = array();
|
||||||
|
foreach($this->db->select($this->user_table, 'cal_user_type,cal_user_id', array(
|
||||||
|
'cal_id' => $event['cal_reference'],
|
||||||
|
'cal_recur_date' => 0,
|
||||||
|
"cal_status != 'X'", // deleted need to be replaced with exception marker too
|
||||||
|
), __LINE__, __FILE__, 'calendar') as $row)
|
||||||
|
{
|
||||||
|
$master_participants[] = self::combine_user($row['cal_user_type'], $row['cal_user_id']);
|
||||||
|
}
|
||||||
|
foreach(array_diff(array_keys((array)$event['cal_participants']), $master_participants) as $uid)
|
||||||
|
{
|
||||||
|
$user_type = $user_id = null;
|
||||||
|
self::split_user($uid, $user_type, $user_id);
|
||||||
|
$this->db->insert($this->user_table, array(
|
||||||
|
'cal_status' => 'E',
|
||||||
|
), array(
|
||||||
|
'cal_id' => $event['cal_reference'],
|
||||||
|
'cal_recur_date' => 0,
|
||||||
|
'cal_user_type' => $user_type,
|
||||||
|
'cal_user_id' => $user_id,
|
||||||
|
), __LINE__, __FILE__, 'calendar');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // write information about recuring event, if recur_type is present in the array
|
else // write information about recuring event, if recur_type is present in the array
|
||||||
{
|
{
|
||||||
@ -1615,9 +1669,9 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
'cal_user_id' => $ids,
|
'cal_user_id' => $ids,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
$where[1] = '('.implode(' OR ',$to_or).')';
|
$where[] = '('.implode(' OR ',$to_or).')';
|
||||||
|
$where[] = "cal_status!='E'"; // do NOT delete exception marker
|
||||||
$this->db->update($this->user_table,array('cal_status'=>'X'),$where,__LINE__,__FILE__,'calendar');
|
$this->db->update($this->user_table,array('cal_status'=>'X'),$where,__LINE__,__FILE__,'calendar');
|
||||||
unset($where[1]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
$setup_info['calendar']['name'] = 'calendar';
|
$setup_info['calendar']['name'] = 'calendar';
|
||||||
$setup_info['calendar']['version'] = '14.1';
|
$setup_info['calendar']['version'] = '14.1.001';
|
||||||
$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';
|
||||||
|
@ -2296,3 +2296,37 @@ function calendar_upgrade1_9_011()
|
|||||||
{
|
{
|
||||||
return $GLOBALS['setup_info']['calendar']['currentver'] = '14.1';
|
return $GLOBALS['setup_info']['calendar']['currentver'] = '14.1';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add pseudo-participants with status 'E' to all recurrence-masters of exceptions with participants not in master
|
||||||
|
*
|
||||||
|
* This allows CalDAV and eSync to find the recurring events efficient in calendars of these participants.
|
||||||
|
*
|
||||||
|
* Also fix recurring events containing a reference to an other master, created when an exception is made a recurring event.
|
||||||
|
*
|
||||||
|
* @return type
|
||||||
|
*/
|
||||||
|
function calendar_upgrade14_1()
|
||||||
|
{
|
||||||
|
$GLOBALS['egw_setup']->db->query(
|
||||||
|
"UPDATE egw_cal
|
||||||
|
SET cal_reference=0,cal_etag=cal_etag+1,cal_modifier=0,cal_modified=".time().
|
||||||
|
"WHERE cal_reference != 0 AND cal_id IN (SELECT cal_id FROM egw_cal_repeats)", __LINE__, __FILE__);
|
||||||
|
|
||||||
|
foreach($GLOBALS['egw_setup']->db->query(
|
||||||
|
"SELECT DISTINCT master.cal_id,egw_cal_user.cal_user_type,egw_cal_user.cal_user_id,'E' AS cal_status
|
||||||
|
FROM egw_cal_user
|
||||||
|
JOIN egw_cal ON egw_cal_user.cal_id=egw_cal.cal_id
|
||||||
|
JOIN egw_cal master ON egw_cal.cal_reference=master.cal_id
|
||||||
|
WHERE egw_cal_user.cal_recur_date=0 AND
|
||||||
|
(cal_user_type,cal_user_id) NOT IN (
|
||||||
|
SELECT master_user.cal_user_type,master_user.cal_user_id
|
||||||
|
FROM egw_cal_user master_user
|
||||||
|
WHERE master_user.cal_recur_date=0 AND master_user.cal_id=master.cal_id
|
||||||
|
)
|
||||||
|
ORDER BY master.cal_id DESC", __LINE__, __FILE__, 0, -1, false, egw_db::FETCH_ASSOC) as $row)
|
||||||
|
{
|
||||||
|
$GLOBALS['egw_setup']->db->insert('egw_cal_user', $row, false, __LINE__, __FILE__, 'calendar');
|
||||||
|
}
|
||||||
|
return $GLOBALS['setup_info']['calendar']['currentver'] = '14.1.001';
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user