mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 00:29:38 +01:00
Fix various synchronization issues (SyncML & CalDAV)
This commit is contained in:
parent
8204d84ca5
commit
21ccdd5f28
@ -95,6 +95,7 @@ class calendar_bo
|
|||||||
'R' => 'Rejected',
|
'R' => 'Rejected',
|
||||||
'T' => 'Tentative',
|
'T' => 'Tentative',
|
||||||
'U' => 'No Response',
|
'U' => 'No Response',
|
||||||
|
'D' => 'Delegated',
|
||||||
'G' => 'Group invitation',
|
'G' => 'Group invitation',
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
@ -1349,6 +1350,9 @@ class calendar_bo
|
|||||||
case 'U': // no response = unknown
|
case 'U': // no response = unknown
|
||||||
$status = html::image('calendar','cnr-pending',$this->verbose_status[$status]);
|
$status = html::image('calendar','cnr-pending',$this->verbose_status[$status]);
|
||||||
break;
|
break;
|
||||||
|
case 'D': // delegated
|
||||||
|
$status = html::image('calendar','forward',$this->verbose_status[$status]);
|
||||||
|
break;
|
||||||
case 'G': // group invitation
|
case 'G': // group invitation
|
||||||
// Todo: Image, seems not to be used
|
// Todo: Image, seems not to be used
|
||||||
$status = '('.$this->verbose_status[$status].')';
|
$status = '('.$this->verbose_status[$status].')';
|
||||||
|
@ -20,6 +20,7 @@ define('MSG_TENTATIVE',4);
|
|||||||
define('MSG_ACCEPTED',5);
|
define('MSG_ACCEPTED',5);
|
||||||
define('MSG_ALARM',6);
|
define('MSG_ALARM',6);
|
||||||
define('MSG_DISINVITE',7);
|
define('MSG_DISINVITE',7);
|
||||||
|
define('MSG_DELEGATED',8);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class to access AND manipulate all calendar data (business object)
|
* Class to access AND manipulate all calendar data (business object)
|
||||||
@ -493,7 +494,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
|
|
||||||
// the following switch falls through all cases, as each included the following too
|
// the following switch falls through all cases, as each included the following too
|
||||||
//
|
//
|
||||||
$msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE;
|
$msg_is_response = $msg_type == MSG_REJECTED || $msg_type == MSG_ACCEPTED || $msg_type == MSG_TENTATIVE || $msg_type == MSG_DELEGATED;
|
||||||
|
|
||||||
switch($ru = $part_prefs['calendar']['receive_updates'])
|
switch($ru = $part_prefs['calendar']['receive_updates'])
|
||||||
{
|
{
|
||||||
@ -619,6 +620,12 @@ class calendar_boupdate extends calendar_bo
|
|||||||
$msgtype = '"calendar";';
|
$msgtype = '"calendar";';
|
||||||
$method = 'REPLY';
|
$method = 'REPLY';
|
||||||
break;
|
break;
|
||||||
|
case MSG_DELEGATED:
|
||||||
|
$action = lang('Delegated');
|
||||||
|
$msg = 'Response';
|
||||||
|
$msgtype = '"calendar";';
|
||||||
|
$method = 'REPLY';
|
||||||
|
break;
|
||||||
case MSG_ALARM:
|
case MSG_ALARM:
|
||||||
$action = lang('Alarm');
|
$action = lang('Alarm');
|
||||||
$msg = 'Alarm';
|
$msg = 'Alarm';
|
||||||
@ -825,8 +832,16 @@ class calendar_boupdate extends calendar_bo
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// invalidate the read-cache if it contains the event we store now
|
if ($event['id'])
|
||||||
if ($event['id'] && $event['id'] == self::$cached_event['id']) self::$cached_event = array();
|
{
|
||||||
|
// invalidate the read-cache if it contains the event we store now
|
||||||
|
if ($event['id'] == self::$cached_event['id']) self::$cached_event = array();
|
||||||
|
$old_event = $this->read($event['id'], $event['recurrence'], false, 'server');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$old_event = null;
|
||||||
|
}
|
||||||
|
|
||||||
$save_event = $event;
|
$save_event = $event;
|
||||||
// we run all dates through date2ts, to adjust to server-time and the possible date-formats
|
// we run all dates through date2ts, to adjust to server-time and the possible date-formats
|
||||||
@ -858,8 +873,6 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
$set_recurrences = false;
|
$set_recurrences = false;
|
||||||
$set_recurrences_start = 0;
|
$set_recurrences_start = 0;
|
||||||
$old_event = $this->read($event['id'], $event['recurrence']);
|
|
||||||
|
|
||||||
if (($cal_id = $this->so->save($event,$set_recurrences,$set_recurrences_start,0,$event['etag'])) && $set_recurrences && $event['recur_type'] != MCAL_RECUR_NONE)
|
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;
|
||||||
@ -1062,7 +1075,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
"($cal_id, $uid, $status, $recur_date)");
|
"($cal_id, $uid, $status, $recur_date)");
|
||||||
}
|
}
|
||||||
$old_event = $this->read($cal_id, $recur_date);
|
$old_event = $this->read($cal_id, $recur_date, false, 'server');
|
||||||
if (($Ok = $this->so->set_status($cal_id,is_numeric($uid)?'u':$uid[0],is_numeric($uid)?$uid:substr($uid,1),$status,$recur_date ? $this->date2ts($recur_date,true) : 0,$role)))
|
if (($Ok = $this->so->set_status($cal_id,is_numeric($uid)?'u':$uid[0],is_numeric($uid)?$uid:substr($uid,1),$status,$recur_date ? $this->date2ts($recur_date,true) : 0,$role)))
|
||||||
{
|
{
|
||||||
if ($updateTS) $GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'modify',time());
|
if ($updateTS) $GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'modify',time());
|
||||||
@ -1071,6 +1084,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
'R' => MSG_REJECTED,
|
'R' => MSG_REJECTED,
|
||||||
'T' => MSG_TENTATIVE,
|
'T' => MSG_TENTATIVE,
|
||||||
'A' => MSG_ACCEPTED,
|
'A' => MSG_ACCEPTED,
|
||||||
|
'D' => MSG_DELEGATED,
|
||||||
);
|
);
|
||||||
if (isset($status2msg[$status]))
|
if (isset($status2msg[$status]))
|
||||||
{
|
{
|
||||||
@ -1080,7 +1094,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Update history
|
// Update history
|
||||||
if (!is_array($event)) $event = $this->read($cal_id);
|
$event = $this->read($cal_id, $recur_date, false, 'server');
|
||||||
$tracking = new calendar_tracking($this);
|
$tracking = new calendar_tracking($this);
|
||||||
$tracking->track($event, $old_event);
|
$tracking->track($event, $old_event);
|
||||||
|
|
||||||
@ -1098,8 +1112,6 @@ class calendar_boupdate extends calendar_bo
|
|||||||
*/
|
*/
|
||||||
function delete($cal_id,$recur_date=0,$ignore_acl=false)
|
function delete($cal_id,$recur_date=0,$ignore_acl=false)
|
||||||
{
|
{
|
||||||
$event = $this->read($cal_id,$recur_date);
|
|
||||||
|
|
||||||
if (!($event = $this->read($cal_id,$recur_date)) ||
|
if (!($event = $this->read($cal_id,$recur_date)) ||
|
||||||
!$ignore_acl && !$this->check_perms(EGW_ACL_DELETE,$event))
|
!$ignore_acl && !$this->check_perms(EGW_ACL_DELETE,$event))
|
||||||
{
|
{
|
||||||
@ -1111,10 +1123,6 @@ class calendar_boupdate extends calendar_bo
|
|||||||
{
|
{
|
||||||
$this->so->delete($cal_id);
|
$this->so->delete($cal_id);
|
||||||
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'delete',time());
|
$GLOBALS['egw']->contenthistory->updateTimeStamp('calendar',$cal_id,'delete',time());
|
||||||
|
|
||||||
// Update history
|
|
||||||
$tracking = new calendar_tracking($this);
|
|
||||||
$tracking->track($event, $event, null, true);
|
|
||||||
|
|
||||||
// delete all links to the event
|
// delete all links to the event
|
||||||
egw_link::unlink(0,'calendar',$cal_id);
|
egw_link::unlink(0,'calendar',$cal_id);
|
||||||
@ -1448,6 +1456,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
{
|
{
|
||||||
$matchingEvents = array();
|
$matchingEvents = array();
|
||||||
$query = array();
|
$query = array();
|
||||||
|
$recur_date = 0;
|
||||||
|
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
@ -1459,17 +1468,12 @@ class calendar_boupdate extends calendar_bo
|
|||||||
{
|
{
|
||||||
if (isset($event['recurrence']))
|
if (isset($event['recurrence']))
|
||||||
{
|
{
|
||||||
$recur_date = $event['recurrence'];
|
$recur_date = $this->date2usertime($event['recurrence']);
|
||||||
}
|
}
|
||||||
else
|
elseif (isset($event['start']))
|
||||||
{
|
{
|
||||||
$recur_date = $event['start'];
|
$recur_date = $this->date2usertime($event['start']);
|
||||||
}
|
}
|
||||||
$recur_date = $this->date2usertime($recur_date);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$recur_date = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($event['id'])
|
if ($event['id'])
|
||||||
@ -1501,13 +1505,14 @@ class calendar_boupdate extends calendar_bo
|
|||||||
return $matchingEvents;
|
return $matchingEvents;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($filter == 'exact' || $filter == 'check') return array();
|
if ($filter == 'exact') return array();
|
||||||
}
|
}
|
||||||
unset($event['id']);
|
unset($event['id']);
|
||||||
|
|
||||||
if ($filter == 'master')
|
if ($filter == 'master')
|
||||||
{
|
{
|
||||||
$query[] = 'recur_type!='. MCAL_RECUR_NONE;
|
$query[] = 'recur_type!='. MCAL_RECUR_NONE;
|
||||||
|
$query['cal_recurrence'] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// only query calendars of users, we have READ-grants from
|
// only query calendars of users, we have READ-grants from
|
||||||
@ -1611,7 +1616,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
'(' . $event['uid'] . ')[EventUID]');
|
'(' . $event['uid'] . ')[EventUID]');
|
||||||
}
|
}
|
||||||
if (isset($event['recurrence']))
|
if ($filter != 'master' && isset($event['recurrence']))
|
||||||
{
|
{
|
||||||
$query['cal_recurrence'] = $event['recurrence'];
|
$query['cal_recurrence'] = $event['recurrence'];
|
||||||
}
|
}
|
||||||
@ -1637,17 +1642,17 @@ class calendar_boupdate extends calendar_bo
|
|||||||
|
|
||||||
foreach($foundEvents as $egwEvent)
|
foreach($foundEvents as $egwEvent)
|
||||||
{
|
{
|
||||||
if (in_array($egwEvent['id'], $matchingEvents)) continue;
|
|
||||||
|
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
'[FOUND]: ' . array2string($egwEvent));
|
'[FOUND]: ' . array2string($egwEvent));
|
||||||
}
|
}
|
||||||
|
if (in_array($egwEvent['id'], $matchingEvents)) continue;
|
||||||
|
|
||||||
if ($filter == 'chec' && !empty($event['uid']))
|
if (in_array($filter, array('exact', 'master')) && !empty($event['uid']))
|
||||||
{
|
{
|
||||||
$matchingEvents[] = $egwEvent['id']; // UID found
|
$matchingEvents[] = $egwEvent['id']; // UID found
|
||||||
|
if ($filter = 'master') break;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1849,6 +1854,7 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$matchingEvents[] = $egwEvent['id']; // exact match
|
$matchingEvents[] = $egwEvent['id']; // exact match
|
||||||
|
if ($filter = 'master') break;
|
||||||
}
|
}
|
||||||
// append pseudos as last entries
|
// append pseudos as last entries
|
||||||
$matchingEvents = array_merge($matchingEvents, $pseudos);
|
$matchingEvents = array_merge($matchingEvents, $pseudos);
|
||||||
@ -1942,20 +1948,24 @@ class calendar_boupdate extends calendar_bo
|
|||||||
in_array($event['recurrence'], $master_event['recur_exception']))
|
in_array($event['recurrence'], $master_event['recur_exception']))
|
||||||
{
|
{
|
||||||
$type = 'SERIES-PSEUDO-EXCEPTION'; // could also be a real one
|
$type = 'SERIES-PSEUDO-EXCEPTION'; // could also be a real one
|
||||||
$recurrence_event = $event;
|
$recurrence_event = $master_event;
|
||||||
|
$recurrence_event['start'] = $event['recurrence'];
|
||||||
|
$recurrence_event['end'] -= $master_event['start'] - $event['recurrence'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
elseif (in_array($event['start'], $master_event['recur_exception']))
|
elseif (in_array($event['start'], $master_event['recur_exception']))
|
||||||
{
|
{
|
||||||
$type='SERIES-PSEUDO-EXCEPTION'; // new pseudo exception?
|
$type='SERIES-PSEUDO-EXCEPTION'; // new pseudo exception?
|
||||||
$recurrence_event = $event;
|
$recurrence_event = $master_event;
|
||||||
|
$recurrence_event['start'] = $event['start'];
|
||||||
|
$recurrence_event['end'] -= $master_event['start'] - $event['start'];
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// try to find a suitable pseudo exception date
|
// try to find a suitable pseudo exception date
|
||||||
$egw_rrule = calendar_rrule::event2rrule($master_event, false);
|
$egw_rrule = calendar_rrule::event2rrule($master_event, false);
|
||||||
$egw_rrule->rewind();
|
$egw_rrule->current = clone $egw_rrule->time;
|
||||||
while ($egw_rrule->valid())
|
while ($egw_rrule->valid())
|
||||||
{
|
{
|
||||||
$occurrence = egw_time::to($egw_rrule->current(), 'server');
|
$occurrence = egw_time::to($egw_rrule->current(), 'server');
|
||||||
@ -1967,7 +1977,9 @@ class calendar_boupdate extends calendar_bo
|
|||||||
if ($event['start'] == $occurrence)
|
if ($event['start'] == $occurrence)
|
||||||
{
|
{
|
||||||
$type = 'SERIES-PSEUDO-EXCEPTION'; // let's try a pseudo exception
|
$type = 'SERIES-PSEUDO-EXCEPTION'; // let's try a pseudo exception
|
||||||
$recurrence_event = $event;
|
$recurrence_event = $master_event;
|
||||||
|
$recurrence_event['start'] = $occurrence;
|
||||||
|
$recurrence_event['end'] -= $master_event['start'] - $occurrence;
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
if (isset($event['recurrence']) && $event['recurrence'] == $occurrence)
|
if (isset($event['recurrence']) && $event['recurrence'] == $occurrence)
|
||||||
@ -2077,4 +2089,4 @@ class calendar_boupdate extends calendar_bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -110,10 +110,12 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
'daywise' => false,
|
'daywise' => false,
|
||||||
'date_format' => 'server',
|
'date_format' => 'server',
|
||||||
);
|
);
|
||||||
|
/*
|
||||||
if ($this->client_shared_uid_exceptions)
|
if ($this->client_shared_uid_exceptions)
|
||||||
{
|
{
|
||||||
$cal_filters['query']['cal_reference'] = 0;
|
$cal_filters['query']['cal_reference'] = 0;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
// process REPORT filters or multiget href's
|
// process REPORT filters or multiget href's
|
||||||
if (($id || $options['root']['name'] != 'propfind') && !$this->_report_filters($options,$cal_filters,$id))
|
if (($id || $options['root']['name'] != 'propfind') && !$this->_report_filters($options,$cal_filters,$id))
|
||||||
{
|
{
|
||||||
@ -137,8 +139,17 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
if ($events)
|
if ($events)
|
||||||
{
|
{
|
||||||
// get all max user modified times at once
|
// get all max user modified times at once
|
||||||
foreach($events as &$event)
|
foreach($events as $k => &$event)
|
||||||
{
|
{
|
||||||
|
if ($this->client_shared_uid_exceptions &&
|
||||||
|
$event['reference'] &&
|
||||||
|
($master = $this->bo->read($event['reference'], 0, false, 'server')) &&
|
||||||
|
array_search($event['recurrence'], $master['recur_exception']) !== false)
|
||||||
|
{
|
||||||
|
// this exception will be handled with the series master
|
||||||
|
unset($events[$k]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$ids[] = $event['id'];
|
$ids[] = $event['id'];
|
||||||
}
|
}
|
||||||
$max_user_modified = $this->bo->so->max_user_modified($ids);
|
$max_user_modified = $this->bo->so->max_user_modified($ids);
|
||||||
@ -350,22 +361,28 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
*/
|
*/
|
||||||
private static function &get_series($uid,calendar_bo $bo=null)
|
private static function &get_series($uid,calendar_bo $bo=null)
|
||||||
{
|
{
|
||||||
if (is_null($bo)) $bo = new calendar_bo();
|
if (is_null($bo)) $bo = new calendar_bopdate();
|
||||||
|
|
||||||
|
if (!($masterId = array_shift($bo->find_event(array('uid' => $uid), 'master')))
|
||||||
|
|| !($master = $bo->read($masterId, 0, false, 'server')))
|
||||||
|
{
|
||||||
|
return array(); // should never happen
|
||||||
|
}
|
||||||
|
|
||||||
|
$exceptions = $master['recur_exception'];
|
||||||
|
|
||||||
$events =& $bo->search(array(
|
$events =& $bo->search(array(
|
||||||
'query' => array('cal_uid' => $uid),
|
'query' => array('cal_uid' => $uid),
|
||||||
'daywise' => false,
|
'daywise' => false,
|
||||||
'date_format' => 'server',
|
'date_format' => 'server',
|
||||||
));
|
));
|
||||||
$master = null;
|
$events = array_merge(array($master), $events);
|
||||||
foreach($events as $k => &$recurrence)
|
foreach($events as $k => &$recurrence)
|
||||||
{
|
{
|
||||||
if (!isset($master)) // first event is always the series master
|
//error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
{
|
// "($uid)[$k]:" . array2string($recurrence));
|
||||||
$master =& $events[$k];
|
if (!$k) continue; // nothing to change
|
||||||
//error_log('master: '.array2string($master));
|
|
||||||
continue; // nothing to change
|
|
||||||
}
|
|
||||||
if ($recurrence['id'] != $master['id']) // real exception
|
if ($recurrence['id'] != $master['id']) // real exception
|
||||||
{
|
{
|
||||||
//error_log('real exception: '.array2string($recurrence));
|
//error_log('real exception: '.array2string($recurrence));
|
||||||
@ -373,9 +390,9 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
// at least Lightning "understands" EXDATE as exception from what's included
|
// at least Lightning "understands" EXDATE as exception from what's included
|
||||||
// in the whole resource / VCALENDAR component
|
// in the whole resource / VCALENDAR component
|
||||||
// not removing it causes Lightning to remove the exception itself
|
// not removing it causes Lightning to remove the exception itself
|
||||||
if (($k = array_search($recurrence['recurrence'],$master['recur_exception'])) !== false)
|
if (($e = array_search($recurrence['recurrence'],$exceptions)) !== false)
|
||||||
{
|
{
|
||||||
unset($master['recur_exception'][$k]);
|
unset($exceptions[$e]);
|
||||||
}
|
}
|
||||||
continue; // nothing to change
|
continue; // nothing to change
|
||||||
}
|
}
|
||||||
@ -386,13 +403,14 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
unset($events[$k]); // no exception --> remove it
|
unset($events[$k]); // no exception --> remove it
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// this is a virtual excetion now (no extra event/cal_id in DB)
|
// this is a virtual exception now (no extra event/cal_id in DB)
|
||||||
//error_log('virtual exception: '.array2string($recurrence));
|
//error_log('virtual exception: '.array2string($recurrence));
|
||||||
$recurrence['recurrence'] = $recurrence['start'];
|
$recurrence['recurrence'] = $recurrence['start'];
|
||||||
$recurrence['reference'] = $master['id'];
|
$recurrence['reference'] = $master['id'];
|
||||||
$recurrence['recur_type'] = MCAL_RECUR_NONE; // is set, as this is a copy of the master
|
$recurrence['recur_type'] = MCAL_RECUR_NONE; // is set, as this is a copy of the master
|
||||||
// not for included exceptions (Lightning): $master['recur_exception'][] = $recurrence['start'];
|
// not for included exceptions (Lightning): $master['recur_exception'][] = $recurrence['start'];
|
||||||
}
|
}
|
||||||
|
$events[0]['recur_exception'] = $exceptions;
|
||||||
return $events;
|
return $events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -416,10 +434,12 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
return $event;
|
return $event;
|
||||||
}
|
}
|
||||||
$handler = $this->_get_handler();
|
$handler = $this->_get_handler();
|
||||||
if (!is_numeric($id) && ($foundEntries = $handler->find_event($options['content'], 'check')))
|
|
||||||
|
if (!is_numeric($id) && ($foundEntries = $handler->find_event($options['content'], 'exact')))
|
||||||
{
|
{
|
||||||
$id = array_shift($foundEntries);
|
$id = array_shift($foundEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!($cal_id = $handler->importVCal($options['content'],is_numeric($id) ? $id : -1,
|
if (!($cal_id = $handler->importVCal($options['content'],is_numeric($id) ? $id : -1,
|
||||||
self::etag2value($this->http_if_match))))
|
self::etag2value($this->http_if_match))))
|
||||||
{
|
{
|
||||||
@ -448,14 +468,15 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
static function fix_series(array &$events)
|
static function fix_series(array &$events)
|
||||||
{
|
{
|
||||||
foreach($events as $n => $event) error_log(__METHOD__." $n before: ".array2string($event));
|
foreach($events as $n => $event) error_log(__METHOD__." $n before: ".array2string($event));
|
||||||
$master =& $events[0];
|
//$master =& $events[0];
|
||||||
|
|
||||||
$bo = new calendar_boupdate();
|
$bo = new calendar_boupdate();
|
||||||
|
|
||||||
// get array with orginal recurrences indexed by recurrence-id
|
// get array with orginal recurrences indexed by recurrence-id
|
||||||
$org_recurrences = array();
|
$org_recurrences = $exceptions = array();
|
||||||
foreach(self::get_series($master['uid'],$bo) as $event)
|
foreach(self::get_series($events[0]['uid'],$bo) as $k => $event)
|
||||||
{
|
{
|
||||||
|
if (!$k) $master = $event;
|
||||||
if ($event['recurrence'])
|
if ($event['recurrence'])
|
||||||
{
|
{
|
||||||
$org_recurrences[$event['recurrence']] = $event;
|
$org_recurrences[$event['recurrence']] = $event;
|
||||||
@ -463,9 +484,15 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
}
|
}
|
||||||
|
|
||||||
// assign cal_id's to already existing recurrences and evtl. re-add recur_exception to master
|
// assign cal_id's to already existing recurrences and evtl. re-add recur_exception to master
|
||||||
foreach($events as &$recurrence)
|
foreach($events as $k => &$recurrence)
|
||||||
{
|
{
|
||||||
if ($recurrence['id'] || !$recurrence['recurrence']) continue; // master
|
if (!$recurrence['recurrence'])
|
||||||
|
{
|
||||||
|
// master
|
||||||
|
$recurrence['id'] = $master['id'];
|
||||||
|
$master =& $events[$k];
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
// from now on we deal with exceptions
|
// from now on we deal with exceptions
|
||||||
$org_recurrence = $org_recurrences[$recurrence['recurrence']];
|
$org_recurrence = $org_recurrences[$recurrence['recurrence']];
|
||||||
@ -478,12 +505,13 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
if ($recurrence['id'] != $master['id'])
|
if ($recurrence['id'] != $master['id'])
|
||||||
{
|
{
|
||||||
error_log(__METHOD__.'() re-adding recur_exception '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence']));
|
error_log(__METHOD__.'() re-adding recur_exception '.$recurrence['recurrence'].' = '.date('Y-m-d H:i:s',$recurrence['recurrence']));
|
||||||
$master['recur_exception'][] = $recurrence['recurrence'];
|
$exceptions[] = $recurrence['recurrence'];
|
||||||
}
|
}
|
||||||
// remove recurrence to be able to detect deleted exceptions
|
// remove recurrence to be able to detect deleted exceptions
|
||||||
unset($org_recurrences[$recurrence['recurrence']]);
|
unset($org_recurrences[$recurrence['recurrence']]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
$master['recur_exception'] = array_merge($exceptions, $master['recur_exception']);
|
||||||
|
|
||||||
// delete not longer existing recurrences
|
// delete not longer existing recurrences
|
||||||
foreach($org_recurrences as $org_recurrence)
|
foreach($org_recurrences as $org_recurrence)
|
||||||
|
@ -41,6 +41,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
'A' => 'ACCEPTED',
|
'A' => 'ACCEPTED',
|
||||||
'R' => 'DECLINED',
|
'R' => 'DECLINED',
|
||||||
'T' => 'TENTATIVE',
|
'T' => 'TENTATIVE',
|
||||||
|
'D' => 'DELEGATED'
|
||||||
);
|
);
|
||||||
/**
|
/**
|
||||||
* @var array conversation of the participant status ical => egw
|
* @var array conversation of the participant status ical => egw
|
||||||
@ -51,6 +52,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
'ACCEPTED' => 'A',
|
'ACCEPTED' => 'A',
|
||||||
'DECLINED' => 'R',
|
'DECLINED' => 'R',
|
||||||
'TENTATIVE' => 'T',
|
'TENTATIVE' => 'T',
|
||||||
|
'DELEGATED' => 'D',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -227,7 +229,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
"() User does not have the permission to read event $_id.\n",
|
'() User does not have the permission to read event ' . $event['id']. "\n",
|
||||||
3,$this->logfile);
|
3,$this->logfile);
|
||||||
}
|
}
|
||||||
return -1; // Permission denied
|
return -1; // Permission denied
|
||||||
@ -238,8 +240,8 @@ class calendar_ical extends calendar_boupdate
|
|||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
"() Event $_id not found.\n",
|
"() Event $event not found.\n",
|
||||||
3,$this->logfile);
|
3, $this->logfile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@ -342,15 +344,21 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE');
|
$horde_vtimezone->parsevCalendar($vtimezone,'VTIMEZONE');
|
||||||
// DTSTART must be in local time!
|
// DTSTART must be in local time!
|
||||||
$standard = $horde_vtimezone->findComponent('STANDARD');
|
$standard = $horde_vtimezone->findComponent('STANDARD');
|
||||||
$dtstart = $standard->getAttribute('DTSTART');
|
if (is_a($standard, 'Horde_iCalendar'))
|
||||||
$dtstart = new egw_time($dtstart, egw_time::$server_timezone);
|
{
|
||||||
$dtstart->setTimezone(self::$tz_cache[$tzid]);
|
$dtstart = $standard->getAttribute('DTSTART');
|
||||||
$standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false);
|
$dtstart = new egw_time($dtstart, egw_time::$server_timezone);
|
||||||
|
$dtstart->setTimezone(self::$tz_cache[$tzid]);
|
||||||
|
$standard->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false);
|
||||||
|
}
|
||||||
$daylight = $horde_vtimezone->findComponent('DAYLIGHT');
|
$daylight = $horde_vtimezone->findComponent('DAYLIGHT');
|
||||||
$dtstart = $daylight->getAttribute('DTSTART');
|
if (is_a($daylight, 'Horde_iCalendar'))
|
||||||
$dtstart = new egw_time($dtstart, egw_time::$server_timezone);
|
{
|
||||||
$dtstart->setTimezone(self::$tz_cache[$tzid]);
|
$dtstart = $daylight->getAttribute('DTSTART');
|
||||||
$daylight->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false);
|
$dtstart = new egw_time($dtstart, egw_time::$server_timezone);
|
||||||
|
$dtstart->setTimezone(self::$tz_cache[$tzid]);
|
||||||
|
$daylight->setAttribute('DTSTART', $dtstart->format('Ymd\THis'), array(), false);
|
||||||
|
}
|
||||||
$vcal->addComponent($horde_vtimezone);
|
$vcal->addComponent($horde_vtimezone);
|
||||||
$vtimezones_added[] = $tzid;
|
$vtimezones_added[] = $tzid;
|
||||||
}
|
}
|
||||||
@ -396,6 +404,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
sort($exceptions);
|
sort($exceptions);
|
||||||
}
|
}
|
||||||
$event['recur_exception'] = $exceptions;
|
$event['recur_exception'] = $exceptions;
|
||||||
|
/*
|
||||||
// Adjust the event start -- must not be an exception
|
// Adjust the event start -- must not be an exception
|
||||||
$length = $event['end'] - $event['start'];
|
$length = $event['end'] - $event['start'];
|
||||||
$rriter = calendar_rrule::event2rrule($event, false, $tzid);
|
$rriter = calendar_rrule::event2rrule($event, false, $tzid);
|
||||||
@ -415,13 +424,21 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
// the series dissolved completely into exceptions
|
// the series dissolved completely into exceptions
|
||||||
continue;
|
continue;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($egwSupportedFields as $icalFieldName => $egwFieldName)
|
foreach ($egwSupportedFields as $icalFieldName => $egwFieldName)
|
||||||
{
|
{
|
||||||
if (!isset($this->supportedFields[$egwFieldName])) continue;
|
if (!isset($this->supportedFields[$egwFieldName]))
|
||||||
|
{
|
||||||
|
if ($this->log)
|
||||||
|
{
|
||||||
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
|
'(' . $event['id'] . ") [$icalFieldName] not supported\n",
|
||||||
|
3,$this->logfile);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
$values[$icalFieldName] = array();
|
$values[$icalFieldName] = array();
|
||||||
switch ($icalFieldName)
|
switch ($icalFieldName)
|
||||||
{
|
{
|
||||||
@ -928,11 +945,30 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
||||||
|
|
||||||
if (!($events = $this->icaltoegw($_vcalData,$cal_id,$etag,$recur_date)))
|
if (!($events = $this->icaltoegw($_vcalData)))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($cal_id > 0)
|
||||||
|
{
|
||||||
|
if (count($events) == 1)
|
||||||
|
{
|
||||||
|
$events[0]['id'] = $cal_id;
|
||||||
|
if (!is_null($etag)) $events[0]['etag'] = (int) $etag;
|
||||||
|
if ($recur_date) $events[0]['recurrence'] = $recur_date;
|
||||||
|
}
|
||||||
|
elseif (($foundEvent = $this->find_event(array('id' => $cal_id), 'exact')) &&
|
||||||
|
($eventId = array_shift($foundEvent)) &&
|
||||||
|
($egwEvent = $this->read($eventId)))
|
||||||
|
{
|
||||||
|
foreach ($events as $k => $event)
|
||||||
|
{
|
||||||
|
if (!isset($event['uid'])) $events[$k]['uid'] = $egwEvent['uid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// check if we are importing an event series with exceptions in CalDAV
|
// check if we are importing an event series with exceptions in CalDAV
|
||||||
// only first event / series master get's cal_id from URL
|
// only first event / series master get's cal_id from URL
|
||||||
// other events are exceptions and need to be checked if they are new
|
// other events are exceptions and need to be checked if they are new
|
||||||
@ -947,13 +983,18 @@ class calendar_ical extends calendar_boupdate
|
|||||||
foreach ($events as $event)
|
foreach ($events as $event)
|
||||||
{
|
{
|
||||||
if ($this->so->isWholeDay($event)) $event['whole_day'] = true;
|
if ($this->so->isWholeDay($event)) $event['whole_day'] = true;
|
||||||
|
if (is_array($event['category']))
|
||||||
|
{
|
||||||
|
$event['category'] = $this->find_or_add_categories($event['category'],
|
||||||
|
isset($event['id']) ? $event['id'] : -1);
|
||||||
|
}
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
array2string($event)."\n",3,$this->logfile);
|
array2string($event)."\n",3,$this->logfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
||||||
{
|
{
|
||||||
// Adjust the event start -- no exceptions before and at the start
|
// Adjust the event start -- no exceptions before and at the start
|
||||||
@ -987,7 +1028,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
$event['recur_exception'] = $exceptions;
|
$event['recur_exception'] = $exceptions;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
$updated_id = false;
|
$updated_id = false;
|
||||||
$event_info = $this->get_event_info($event);
|
$event_info = $this->get_event_info($event);
|
||||||
|
|
||||||
@ -1066,11 +1107,11 @@ class calendar_ical extends calendar_boupdate
|
|||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
|
||||||
"() Restore status for $uid\n",3,$this->logfile);
|
"() Restore status for $uid\n",3,$this->logfile);
|
||||||
}
|
}
|
||||||
$event['participants']['uid'] = $event_info['stored_event']['participants'][$uid];
|
$event['participants'][$uid] = $event_info['stored_event']['participants'][$uid];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$event['participants']['uid'] = calendar_so::combine_status('U');
|
$event['participants'][$uid] = calendar_so::combine_status('U');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1271,7 +1312,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
if (is_array($days))
|
if (is_array($days))
|
||||||
{
|
{
|
||||||
$recur_exceptions = array();
|
$recur_exceptions = array();
|
||||||
|
/*
|
||||||
if (!isset($days[$event_info['stored_event']['start']]) &&
|
if (!isset($days[$event_info['stored_event']['start']]) &&
|
||||||
$event_info['stored_event']['start'] < $event['start'])
|
$event_info['stored_event']['start'] < $event['start'])
|
||||||
{
|
{
|
||||||
@ -1318,7 +1359,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
$event['start'] = $startdate;
|
$event['start'] = $startdate;
|
||||||
$event['end'] = $startdate + $length;
|
$event['end'] = $startdate + $length;
|
||||||
}
|
} */
|
||||||
|
|
||||||
foreach ($event['recur_exception'] as $recur_exception)
|
foreach ($event['recur_exception'] as $recur_exception)
|
||||||
{
|
{
|
||||||
@ -1363,7 +1404,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$event_info['master_event']['recur_exception'] =
|
$event_info['master_event']['recur_exception'] =
|
||||||
array_unique(array_merge($event_info['master_event']['recur_exception'],
|
array_unique(array_merge($event_info['master_event']['recur_exception'],
|
||||||
array($event['recurrence'])));
|
array($event['recurrence'])));
|
||||||
|
/*
|
||||||
// Adjust the event start -- must not be an exception
|
// Adjust the event start -- must not be an exception
|
||||||
$length = $event_info['master_event']['end'] - $event_info['master_event']['start'];
|
$length = $event_info['master_event']['end'] - $event_info['master_event']['start'];
|
||||||
$rriter = calendar_rrule::event2rrule($event_info['master_event'], false);
|
$rriter = calendar_rrule::event2rrule($event_info['master_event'], false);
|
||||||
@ -1376,6 +1417,21 @@ class calendar_ical extends calendar_boupdate
|
|||||||
// remove leading exceptions
|
// remove leading exceptions
|
||||||
if ($day < $newstart)
|
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]);
|
unset($event_info['master_event']['recur_exception'][$key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1384,14 +1440,14 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
$event_info['master_event']['start'] = $newstart;
|
$event_info['master_event']['start'] = $newstart;
|
||||||
$event_info['master_event']['end'] = $newstart + $length;
|
$event_info['master_event']['end'] = $newstart + $length;
|
||||||
$event_to_store = $event_info['master_event']; // prevent the master_event from being changed by the update method
|
}*/
|
||||||
$this->server2usertime($event_to_store);
|
|
||||||
$this->update($event_to_store, true);
|
|
||||||
unset($event_to_store);
|
|
||||||
}
|
|
||||||
$event['reference'] = $event_info['master_event']['id'];
|
$event['reference'] = $event_info['master_event']['id'];
|
||||||
$event['category'] = $event_info['master_event']['category'];
|
$event['category'] = $event_info['master_event']['category'];
|
||||||
$event['owner'] = $event_info['master_event']['owner'];
|
$event['owner'] = $event_info['master_event']['owner'];
|
||||||
|
$event_to_store = $event_info['master_event']; // prevent the master_event from being changed by the update method
|
||||||
|
$this->server2usertime($event_to_store);
|
||||||
|
$this->update($event_to_store, true);
|
||||||
|
unset($event_to_store);
|
||||||
}
|
}
|
||||||
|
|
||||||
$event_to_store = $event; // prevent $event from being changed by update method
|
$event_to_store = $event; // prevent $event from being changed by update method
|
||||||
@ -1864,7 +1920,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function icaltoegw($_vcalData, $cal_id=-1, $etag=null, $recur_date=0)
|
function icaltoegw($_vcalData)
|
||||||
{
|
{
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
@ -1906,7 +1962,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
{
|
{
|
||||||
if (is_a($component, 'Horde_iCalendar_vevent'))
|
if (is_a($component, 'Horde_iCalendar_vevent'))
|
||||||
{
|
{
|
||||||
if (($event = $this->vevent2egw($component, $version, $this->supportedFields, $cal_id)))
|
if (($event = $this->vevent2egw($component, $version, $this->supportedFields)))
|
||||||
{
|
{
|
||||||
//common adjustments
|
//common adjustments
|
||||||
if ($this->productManufacturer == '' && $this->productName == ''
|
if ($this->productManufacturer == '' && $this->productName == ''
|
||||||
@ -1943,11 +1999,6 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']);
|
date_default_timezone_set($GLOBALS['egw_info']['server']['server_timezone']);
|
||||||
|
|
||||||
// if cal_id, etag or recur_date is given, use/set it for 1. event
|
|
||||||
if ($cal_id > 0) $events[0]['id'] = $cal_id;
|
|
||||||
if (!is_null($etag)) $events[0]['etag'] = (int) $etag;
|
|
||||||
if ($recur_date) $events[0]['recurrence'] = $recur_date;
|
|
||||||
|
|
||||||
return $events;
|
return $events;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1957,11 +2008,10 @@ class calendar_ical extends calendar_boupdate
|
|||||||
* @param array $component VEVENT
|
* @param array $component VEVENT
|
||||||
* @param string $version vCal version (1.0/2.0)
|
* @param string $version vCal version (1.0/2.0)
|
||||||
* @param array $supportedFields supported fields of the device
|
* @param array $supportedFields supported fields of the device
|
||||||
* @param int $cal_id id of existing event in the content (only used to merge categories)
|
|
||||||
*
|
*
|
||||||
* @return array|boolean event on success, false on failure
|
* @return array|boolean event on success, false on failure
|
||||||
*/
|
*/
|
||||||
function vevent2egw(&$component, $version, $supportedFields, $cal_id=-1)
|
function vevent2egw(&$component, $version, $supportedFields)
|
||||||
{
|
{
|
||||||
if (!is_a($component, 'Horde_iCalendar_vevent')) return false;
|
if (!is_a($component, 'Horde_iCalendar_vevent')) return false;
|
||||||
|
|
||||||
@ -2353,7 +2403,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
case 'CATEGORIES':
|
case 'CATEGORIES':
|
||||||
if ($attributes['value'])
|
if ($attributes['value'])
|
||||||
{
|
{
|
||||||
$vcardData['category'] = $this->find_or_add_categories(explode(',',$attributes['value']), $cal_id);
|
$vcardData['category'] = explode(',', $attributes['value']);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2369,6 +2419,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
if (isset($attributes['params']['STATUS']))
|
if (isset($attributes['params']['STATUS']))
|
||||||
{
|
{
|
||||||
$status = $this->status_ical2egw[strtoupper($attributes['params']['STATUS'])];
|
$status = $this->status_ical2egw[strtoupper($attributes['params']['STATUS'])];
|
||||||
|
if (empty($status)) $status = 'X';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -2599,8 +2650,6 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
|
if ($this->calendarOwner) $event['owner'] = $this->calendarOwner;
|
||||||
|
|
||||||
if ($cal_id > 0) $event['id'] = $cal_id;
|
|
||||||
|
|
||||||
if ($this->log)
|
if ($this->log)
|
||||||
{
|
{
|
||||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||||
@ -2613,7 +2662,15 @@ class calendar_ical extends calendar_boupdate
|
|||||||
|
|
||||||
function search($_vcalData, $contentID=null, $relax=false)
|
function search($_vcalData, $contentID=null, $relax=false)
|
||||||
{
|
{
|
||||||
if (($events = $this->icaltoegw($_vcalData,!is_null($contentID) ? $contentID : -1)))
|
if (is_null($contentID))
|
||||||
|
{
|
||||||
|
$eventId = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$eventId = $contentID;
|
||||||
|
}
|
||||||
|
if (($events = $this->icaltoegw($_vcalData)))
|
||||||
{
|
{
|
||||||
// this function only supports searching a single event
|
// this function only supports searching a single event
|
||||||
if (count($events) == 1)
|
if (count($events) == 1)
|
||||||
@ -2621,6 +2678,7 @@ class calendar_ical extends calendar_boupdate
|
|||||||
$filter = $relax ? 'relax' : 'check';
|
$filter = $relax ? 'relax' : 'check';
|
||||||
$event = array_shift($events);
|
$event = array_shift($events);
|
||||||
if ($this->so->isWholeDay($event)) $event['whole_day'] = true;
|
if ($this->so->isWholeDay($event)) $event['whole_day'] = true;
|
||||||
|
$event['category'] = $this->find_or_add_categories($event['category'], $eventId);
|
||||||
if ($contentID) $event['id'] = $contentID;
|
if ($contentID) $event['id'] = $contentID;
|
||||||
return $this->find_event($event, $filter);
|
return $this->find_event($event, $filter);
|
||||||
}
|
}
|
||||||
|
@ -430,6 +430,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
if ($event['recur_type'] != MCAL_RECUR_NONE)
|
||||||
{
|
{
|
||||||
// Adjust the event start -- no exceptions before and at the start
|
// Adjust the event start -- no exceptions before and at the start
|
||||||
@ -462,7 +463,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$event['recur_exception'] = $exceptions;
|
$event['recur_exception'] = $exceptions;
|
||||||
}
|
} */
|
||||||
|
|
||||||
if ($recur_date) $event['recurrence'] = $recur_date;
|
if ($recur_date) $event['recurrence'] = $recur_date;
|
||||||
$event_info = $this->get_event_info($event);
|
$event_info = $this->get_event_info($event);
|
||||||
@ -684,7 +685,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
$event_info['master_event']['recur_exception'] =
|
$event_info['master_event']['recur_exception'] =
|
||||||
array_unique(array_merge($event_info['master_event']['recur_exception'],
|
array_unique(array_merge($event_info['master_event']['recur_exception'],
|
||||||
array($event['recurrence'])));
|
array($event['recurrence'])));
|
||||||
|
/*
|
||||||
// Adjust the event start -- must not be an exception
|
// Adjust the event start -- must not be an exception
|
||||||
$length = $event_info['master_event']['end'] - $event_info['master_event']['start'];
|
$length = $event_info['master_event']['end'] - $event_info['master_event']['start'];
|
||||||
$rriter = calendar_rrule::event2rrule($event_info['master_event'], false);
|
$rriter = calendar_rrule::event2rrule($event_info['master_event'], false);
|
||||||
@ -709,7 +710,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
$this->server2usertime($event_to_store);
|
$this->server2usertime($event_to_store);
|
||||||
$this->update($event_to_store, true);
|
$this->update($event_to_store, true);
|
||||||
unset($event_to_store);
|
unset($event_to_store);
|
||||||
}
|
} */
|
||||||
$event['reference'] = $event_info['master_event']['id'];
|
$event['reference'] = $event_info['master_event']['id'];
|
||||||
$event['category'] = $event_info['master_event']['category'];
|
$event['category'] = $event_info['master_event']['category'];
|
||||||
$event['owner'] = $event_info['master_event']['owner'];
|
$event['owner'] = $event_info['master_event']['owner'];
|
||||||
@ -914,6 +915,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
array2string($exceptions)."\n",3,$this->logfile);
|
array2string($exceptions)."\n",3,$this->logfile);
|
||||||
}
|
}
|
||||||
$event['recur_exception'] = $exceptions;
|
$event['recur_exception'] = $exceptions;
|
||||||
|
/*
|
||||||
// Adjust the event start -- must not be an exception
|
// Adjust the event start -- must not be an exception
|
||||||
$length = $event['end'] - $event['start'];
|
$length = $event['end'] - $event['start'];
|
||||||
$rriter = calendar_rrule::event2rrule($event, false, $tzid);
|
$rriter = calendar_rrule::event2rrule($event, false, $tzid);
|
||||||
@ -927,7 +929,7 @@ class calendar_sif extends calendar_boupdate
|
|||||||
// remove leading exceptions
|
// remove leading exceptions
|
||||||
if ($day <= $event['start']) unset($exceptions[$key]);
|
if ($day <= $event['start']) unset($exceptions[$key]);
|
||||||
}
|
}
|
||||||
$event['recur_exception'] = $exceptions;
|
$event['recur_exception'] = $exceptions; */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->uidExtension)
|
if ($this->uidExtension)
|
||||||
|
@ -44,6 +44,7 @@ define('REJECTED',0);
|
|||||||
define('NO_RESPONSE',1);
|
define('NO_RESPONSE',1);
|
||||||
define('TENTATIVE',2);
|
define('TENTATIVE',2);
|
||||||
define('ACCEPTED',3);
|
define('ACCEPTED',3);
|
||||||
|
define('DELEGATED',4);
|
||||||
|
|
||||||
define('HOUR_s',60*60);
|
define('HOUR_s',60*60);
|
||||||
define('DAY_s',24*HOUR_s);
|
define('DAY_s',24*HOUR_s);
|
||||||
@ -188,6 +189,18 @@ class calendar_so
|
|||||||
$this->db->update($this->cal_table, array('cal_uid' => $event['uid']),
|
$this->db->update($this->cal_table, array('cal_uid' => $event['uid']),
|
||||||
array('cal_id' => $event['id']),__LINE__,__FILE__,'calendar');
|
array('cal_id' => $event['id']),__LINE__,__FILE__,'calendar');
|
||||||
}
|
}
|
||||||
|
if ((int) $recur_date == 0 &&
|
||||||
|
$event['recur_type'] != MCAL_RECUR_NONE &&
|
||||||
|
!empty($event['recur_exception']))
|
||||||
|
{
|
||||||
|
sort($event['recur_exception']);
|
||||||
|
if ($event['recur_exception'][0] < $event['start'])
|
||||||
|
{
|
||||||
|
// leading exceptions => move start and end
|
||||||
|
$event['end'] -= $event['start'] - $event['recur_exception'][0];
|
||||||
|
$event['start'] = $event['recur_exception'][0];
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we have a real recurance, if not set $recur_date=0
|
// check if we have a real recurance, if not set $recur_date=0
|
||||||
@ -377,6 +390,8 @@ class calendar_so
|
|||||||
$where[] = "cal_status='T'"; break;
|
$where[] = "cal_status='T'"; break;
|
||||||
case 'rejected':
|
case 'rejected':
|
||||||
$where[] = "cal_status='R'"; break;
|
$where[] = "cal_status='R'"; break;
|
||||||
|
case 'delegated':
|
||||||
|
$where[] = "cal_status='D'"; break;
|
||||||
case 'all':
|
case 'all':
|
||||||
case 'owner':
|
case 'owner':
|
||||||
break;
|
break;
|
||||||
@ -649,6 +664,8 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
$minimum_uid_length = 8;
|
$minimum_uid_length = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$old_min = $old_duration = 0;
|
||||||
|
|
||||||
//echo '<p>'.__METHOD__.'('.array2string($event).",$change_since) event="; _debug_array($event);
|
//echo '<p>'.__METHOD__.'('.array2string($event).",$change_since) event="; _debug_array($event);
|
||||||
//error_log(__METHOD__.'('.array2string($event).",$set_recurrences,$change_since,$etag)");
|
//error_log(__METHOD__.'('.array2string($event).",$set_recurrences,$change_since,$etag)");
|
||||||
|
|
||||||
@ -827,7 +844,7 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
// 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']))
|
||||||
{
|
{
|
||||||
$this->move($cal_id,$event['cal_start'],$event['cal_end'],!$cal_id ? false : $change_since);
|
$this->move($cal_id,$event['cal_start'],$event['cal_end'],!$cal_id ? false : $change_since, $old_min, $old_min + $old_duration);
|
||||||
}
|
}
|
||||||
// update participants if present in the event-array
|
// update participants if present in the event-array
|
||||||
if (isset($event['cal_participants']))
|
if (isset($event['cal_participants']))
|
||||||
@ -1157,7 +1174,8 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
REJECTED => 'R',
|
REJECTED => 'R',
|
||||||
NO_RESPONSE => 'U',
|
NO_RESPONSE => 'U',
|
||||||
TENTATIVE => 'T',
|
TENTATIVE => 'T',
|
||||||
ACCEPTED => 'A'
|
ACCEPTED => 'A',
|
||||||
|
DELEGATED => 'D'
|
||||||
);
|
);
|
||||||
if (!(int)$cal_id || !(int)$user_id && $user_type != 'e')
|
if (!(int)$cal_id || !(int)$user_id && $user_type != 'e')
|
||||||
{
|
{
|
||||||
@ -1581,7 +1599,7 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
* @param int $start=0 if != 0: startdate of the search/list (servertime)
|
* @param int $start=0 if != 0: startdate of the search/list (servertime)
|
||||||
* @param int $end=0 if != 0: enddate of the search/list (servertime)
|
* @param int $end=0 if != 0: enddate of the search/list (servertime)
|
||||||
* @param string $filter='all' string filter-name: all (not rejected),
|
* @param string $filter='all' string filter-name: all (not rejected),
|
||||||
* accepted, unknown, tentative, rejected,
|
* accepted, unknown, tentative, rejected, delegated
|
||||||
* rrule return array of remote exceptions in servertime
|
* rrule return array of remote exceptions in servertime
|
||||||
* tz_rrule/tz_only, return (only by) timezone transition affected entries
|
* tz_rrule/tz_only, return (only by) timezone transition affected entries
|
||||||
* map return array of dates with no pseudo exception
|
* map return array of dates with no pseudo exception
|
||||||
@ -1607,15 +1625,46 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
$remote = in_array($filter, array('tz_rrule', 'rrule'));
|
$remote = in_array($filter, array('tz_rrule', 'rrule'));
|
||||||
|
|
||||||
$egw_rrule = calendar_rrule::event2rrule($event, false);
|
$egw_rrule = calendar_rrule::event2rrule($event, false);
|
||||||
$egw_rrule->rewind();
|
$egw_rrule->current = clone $egw_rrule->time;
|
||||||
if ($expand_all)
|
if ($expand_all)
|
||||||
{
|
{
|
||||||
unset($event['recur_excpetion']);
|
unset($event['recur_excpetion']);
|
||||||
$remote_rrule = calendar_rrule::event2rrule($event, false, $tz_id);
|
$remote_rrule = calendar_rrule::event2rrule($event, false, $tz_id);
|
||||||
$remote_rrule->rewind();
|
$remote_rrule->current = clone $remote_rrule->time;
|
||||||
}
|
}
|
||||||
while ($egw_rrule->valid())
|
while ($egw_rrule->valid())
|
||||||
{
|
{
|
||||||
|
while ($egw_rrule->exceptions &&
|
||||||
|
in_array($egw_rrule->current->format('Ymd'),$egw_rrule->exceptions))
|
||||||
|
{
|
||||||
|
if (in_array($filter, array('map','tz_map','rrule','tz_rrule')))
|
||||||
|
{
|
||||||
|
// real exception
|
||||||
|
$locts = (int)egw_time::to($egw_rrule->current(),'server');
|
||||||
|
if ($expand_all)
|
||||||
|
{
|
||||||
|
$remts = (int)egw_time::to($remote_rrule->current(),'server');
|
||||||
|
if ($remote)
|
||||||
|
{
|
||||||
|
$days[$locts]= $remts;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$days[$remts]= $locts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$days[$locts]= $locts;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($expand_all)
|
||||||
|
{
|
||||||
|
$remote_rrule->next_no_exception();
|
||||||
|
}
|
||||||
|
$egw_rrule->next_no_exception();
|
||||||
|
if (!$egw_rrule->valid()) return $days;
|
||||||
|
}
|
||||||
$day = $egw_rrule->current();
|
$day = $egw_rrule->current();
|
||||||
$locts = (int)egw_time::to($day,'server');
|
$locts = (int)egw_time::to($day,'server');
|
||||||
$tz_exception = ($filter == 'tz_rrule');
|
$tz_exception = ($filter == 'tz_rrule');
|
||||||
@ -1659,7 +1708,6 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
// '() status exception: ' . $day->format('Ymd\THis'));
|
// '() status exception: ' . $day->format('Ymd\THis'));
|
||||||
if ($expand_all)
|
if ($expand_all)
|
||||||
{
|
{
|
||||||
$remts = (int)egw_time::to($remote_day,'server');
|
|
||||||
if ($filter == 'tz_only')
|
if ($filter == 'tz_only')
|
||||||
{
|
{
|
||||||
unset($days[$remts]);
|
unset($days[$remts]);
|
||||||
@ -1699,40 +1747,11 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
do
|
if ($expand_all)
|
||||||
{
|
{
|
||||||
$egw_rrule->next_no_exception();
|
$remote_rrule->next_no_exception();
|
||||||
$day = $egw_rrule->current();
|
|
||||||
if ($expand_all)
|
|
||||||
{
|
|
||||||
$remote_rrule->next_no_exception();
|
|
||||||
$remts = (int)egw_time::to($remote_rrule->current(),'server');
|
|
||||||
}
|
|
||||||
$exception = $egw_rrule->exceptions &&
|
|
||||||
in_array($day->format('Ymd'),$egw_rrule->exceptions);
|
|
||||||
if (in_array($filter, array('map','tz_map','rrule','tz_rrule'))
|
|
||||||
&& $exception)
|
|
||||||
{
|
|
||||||
// real exception
|
|
||||||
$locts = (int)egw_time::to($day,'ts');
|
|
||||||
if ($expand_all)
|
|
||||||
{
|
|
||||||
if ($remote)
|
|
||||||
{
|
|
||||||
$days[$locts]= $remts;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$days[$remts]= $locts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$days[$locts]= $locts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while ($exception);
|
$egw_rrule->next_no_exception();
|
||||||
}
|
}
|
||||||
return $days;
|
return $days;
|
||||||
}
|
}
|
||||||
@ -1831,6 +1850,13 @@ ORDER BY cal_user_type, cal_usre_id
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 'delegated':
|
||||||
|
if ($status != 'D')
|
||||||
|
{
|
||||||
|
unset($participants[$uid]);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'default':
|
case 'default':
|
||||||
if ($status == 'R')
|
if ($status == 'R')
|
||||||
{
|
{
|
||||||
|
@ -146,7 +146,7 @@ class calendar_ui
|
|||||||
$this->accountsel = $GLOBALS['egw']->uiaccountsel;
|
$this->accountsel = $GLOBALS['egw']->uiaccountsel;
|
||||||
|
|
||||||
$this->categories = new categories($this->user,'calendar');
|
$this->categories = new categories($this->user,'calendar');
|
||||||
|
|
||||||
$this->common_prefs = &$GLOBALS['egw_info']['user']['preferences']['common'];
|
$this->common_prefs = &$GLOBALS['egw_info']['user']['preferences']['common'];
|
||||||
$this->cal_prefs = &$GLOBALS['egw_info']['user']['preferences']['calendar'];
|
$this->cal_prefs = &$GLOBALS['egw_info']['user']['preferences']['calendar'];
|
||||||
$this->bo->check_set_default_prefs();
|
$this->bo->check_set_default_prefs();
|
||||||
@ -708,6 +708,7 @@ class calendar_ui
|
|||||||
'accepted' => array(lang('Accepted'), lang('Show only accepted events')),
|
'accepted' => array(lang('Accepted'), lang('Show only accepted events')),
|
||||||
'unknown' => array(lang('Invitations'), lang('Show only invitations, not yet accepted or rejected')),
|
'unknown' => array(lang('Invitations'), lang('Show only invitations, not yet accepted or rejected')),
|
||||||
'tentative' => array(lang('Tentative'), lang('Show only tentative accepted events')),
|
'tentative' => array(lang('Tentative'), lang('Show only tentative accepted events')),
|
||||||
|
'delegated' => array(lang('Delegated'), lang('Show only delegated events')),
|
||||||
'rejected' => array(lang('Rejected'),lang('Show only rejected events')),
|
'rejected' => array(lang('Rejected'),lang('Show only rejected events')),
|
||||||
'owner' => array(lang('Owner too'),lang('Show also events just owned by selected user')),
|
'owner' => array(lang('Owner too'),lang('Show also events just owned by selected user')),
|
||||||
'all' => array(lang('All incl. rejected'),lang('Show all status incl. rejected events')),
|
'all' => array(lang('All incl. rejected'),lang('Show all status incl. rejected events')),
|
||||||
|
BIN
calendar/templates/default/images/forward.gif
Normal file
BIN
calendar/templates/default/images/forward.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 319 B |
BIN
calendar/templates/default/images/forward.png
Normal file
BIN
calendar/templates/default/images/forward.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 494 B |
Loading…
Reference in New Issue
Block a user