Fix CalDAV group invitation issue

This commit is contained in:
Jörg Lehrke 2010-06-28 05:12:04 +00:00
parent 9265095371
commit 69fcef79aa

View File

@ -433,27 +433,6 @@ 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
$length = $event['end'] - $event['start'];
$rriter = calendar_rrule::event2rrule($event, false, $tzid);
$rriter->rewind();
if ($rriter->valid())
{
$event['start'] = egw_time::to($rriter->current, 'server');
$event['end'] = $event['start'] + $length;
foreach($exceptions as $key => $day)
{
// remove leading exceptions
if ($day <= $event['start']) unset($exceptions[$key]);
}
$event['recur_exception'] = $exceptions;
}
else
{
// the series dissolved completely into exceptions
continue;
}*/
} }
foreach ($egwSupportedFields as $icalFieldName => $egwFieldName) foreach ($egwSupportedFields as $icalFieldName => $egwFieldName)
@ -472,8 +451,12 @@ class calendar_ical extends calendar_boupdate
switch ($icalFieldName) switch ($icalFieldName)
{ {
case 'ATTENDEE': case 'ATTENDEE':
$attendees = count($event['participants']);
foreach ((array)$event['participants'] as $uid => $status) foreach ((array)$event['participants'] as $uid => $status)
{ {
calendar_so::split_status($status, $quantity, $role);
if ($attendees == 1 &&
$uid == $this->user && $status == 'A') continue;
if (!($info = $this->resource_info($uid))) continue; if (!($info = $this->resource_info($uid))) continue;
if ($this->log) if ($this->log)
{ {
@ -492,16 +475,15 @@ class calendar_ical extends calendar_boupdate
{ {
$participantURL = empty($info['email']) ? '' : 'MAILTO:' . $info['email']; $participantURL = empty($info['email']) ? '' : 'MAILTO:' . $info['email'];
} }
calendar_so::split_status($status, $quantity, $role); // RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U
$rsvp = $status == 'U' ? 'TRUE' : 'FALSE';
if ($role == 'CHAIR') if ($role == 'CHAIR')
{ {
$organizerURL = $participantURL; $organizerURL = $participantURL;
$rsvp = '';
$organizerCN = $participantCN; $organizerCN = $participantCN;
$organizerUID = ($info['type'] != 'e' ? $uid : ''); $organizerUID = ($info['type'] != 'e' ? $uid : '');
} }
$attributes['ATTENDEE'][] = $participantURL;
// RSVP={TRUE|FALSE} // resonse expected, not set in eGW => status=U
$rsvp = $status == 'U' ? 'TRUE' : 'FALSE';
// PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm. // PARTSTAT={NEEDS-ACTION|ACCEPTED|DECLINED|TENTATIVE|DELEGATED|COMPLETED|IN-PROGRESS} everything from delegated is NOT used by eGW atm.
$status = $this->status_egw2ical[$status]; $status = $this->status_egw2ical[$status];
// CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN} // CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN}
@ -509,6 +491,27 @@ class calendar_ical extends calendar_boupdate
{ {
case 'g': case 'g':
$cutype = 'GROUP'; $cutype = 'GROUP';
if ($this->productManufacturer == 'groupdav')
{
$participantURL = 'invalid:nomail';
$cutype = 'INDIVIDUAL';
}
$members = $GLOBALS['egw']->accounts->members($uid, true);
if (!isset($event['participants'][$this->user]) && in_array($this->user, $members))
{
$user = $this->resource_info($this->user);
$attributes['ATTENDEE'][] = 'MAILTO:' . $user['email'];
$parameters['ATTENDEE'][] = array(
'CN' => $user['name'],
'ROLE' => 'REQ-PARTICIPANT',
'PARTSTAT' => 'NEEDS-ACTION',
'CUTYPE' => 'INDIVIDUAL',
'RSVP' => 'TRUE',
'X-EGROUPWARE-UID' => $this->user,
'EMAIL' => $user['email'],
);
$event['participants'][$this->user] = true;
}
break; break;
case 'r': case 'r':
$cutype = 'RESOURCE'; $cutype = 'RESOURCE';
@ -523,14 +526,17 @@ class calendar_ical extends calendar_boupdate
break; break;
}; };
// ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT|X-*} // ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT|X-*}
$parameters['ATTENDEE'][] = array( $options = array();
'CN' => $participantCN, if (!empty($participantCN)) $options['CN'] = $participantCN;
'ROLE' => $role, if (!empty($role)) $options['ROLE'] = $role;
'PARTSTAT' => $status, if (!empty($status)) $options['PARTSTAT'] = $status;
'CUTYPE' => $cutype, if (!empty($cutype)) $options['CUTYPE'] = $cutype;
'RSVP' => $rsvp, if (!empty($rsvp)) $options['RSVP'] = $rsvp;
)+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array())+ if (!empty($info['email'])) $options['EMAIL'] = $info['email'];
($quantity > 1 ? array('X-EGROUPWARE-QUANTITY' => $quantity) : array()); if ($info['type'] != 'e') $options['X-EGROUPWARE-UID'] = $uid;
if ($quantity > 1) $options['X-EGROUPWARE-QUANTITY'] = $quantity;
$attributes['ATTENDEE'][] = $participantURL;
$parameters['ATTENDEE'][] = $options;
} }
break; break;
@ -544,37 +550,38 @@ class calendar_ical extends calendar_boupdate
{ {
$organizerCN = '"' . trim($GLOBALS['egw']->accounts->id2name($event['owner'],'account_firstname') $organizerCN = '"' . trim($GLOBALS['egw']->accounts->id2name($event['owner'],'account_firstname')
. ' ' . $GLOBALS['egw']->accounts->id2name($event['owner'],'account_lastname')) . '"'; . ' ' . $GLOBALS['egw']->accounts->id2name($event['owner'],'account_lastname')) . '"';
$organizerURL = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_email'); $organizerEMail = $GLOBALS['egw']->accounts->id2name($event['owner'],'account_email');
if ($version == '1.0') if ($version == '1.0')
{ {
$organizerURL = trim($organizerCN . (empty($organizerURL) ? '' : ' <' . $organizerURL .'>')); $organizerURL = trim($organizerCN . (empty($organizerURL) ? '' : ' <' . $organizerURL .'>'));
} }
else else
{ {
$organizerURL = empty($organizerURL) ? '' : 'MAILTO:' . $organizerURL; $organizerURL = empty($organizerEMail) ? '' : 'MAILTO:' . $organizerEMail;
} }
$organizerUID = $event['owner']; $organizerUID = $event['owner'];
if (!isset($event['participants'][$event['owner']])) if (!isset($event['participants'][$event['owner']]))
{ {
$attributes['ATTENDEE'][] = $organizerURL; $options = array(
$parameters['ATTENDEE'][] = array(
'CN' => $organizerCN,
'ROLE' => 'CHAIR', 'ROLE' => 'CHAIR',
'PARTSTAT' => 'DELEGATED', 'PARTSTAT' => 'DELEGATED',
'CUTYPE' => 'INDIVIDUAL', 'CUTYPE' => 'INDIVIDUAL',
'RSVP' => 'FALSE', //'RSVP' => 'FALSE',
'X-EGROUPWARE-UID' => $event['owner'], );
); if (!empty($organizerCN)) $options['CN'] = $organizerCN;
if (!empty($organizerEMail)) $options['EMAIL'] = $organizerEMail;
if (!empty($event['owner'])) $options['X-EGROUPWARE-UID'] = $event['owner'];
$attributes['ATTENDEE'][] = $organizerURL;
$parameters['ATTENDEE'][] = $options;
} }
} }
if ($this->productManufacturer != 'groupdav' || if ($this->productManufacturer != 'groupdav' || !$this->check_perms(EGW_ACL_EDIT,$event))
!$this->check_perms(EGW_ACL_EDIT,$event)) {
{
$attributes['ORGANIZER'] = $organizerURL; $attributes['ORGANIZER'] = $organizerURL;
$parameters['ORGANIZER']['CN'] = $organizerCN; $parameters['ORGANIZER']['CN'] = $organizerCN;
if (!empty($organizerUID)) if (!empty($organizerUID))
{ {
$parameters['ORGANIZER']['X-EGROUPWARE-UID'] = $organizerUID; $parameters['ORGANIZER']['X-EGROUPWARE-UID'] = $organizerUID;
} }
} }
break; break;
@ -612,6 +619,8 @@ class calendar_ical extends calendar_boupdate
$rrule = $rriter->generate_rrule($version); $rrule = $rriter->generate_rrule($version);
if ($event['recur_enddate']) if ($event['recur_enddate'])
{ {
$length = ($event['end'] - $event['start']) / 2;
$rrule['UNTIL']->modify($length . ' second');
if (!$tzid || $version != '1.0') if (!$tzid || $version != '1.0')
{ {
if (!isset(self::$tz_cache['UTC'])) if (!isset(self::$tz_cache['UTC']))
@ -1049,6 +1058,7 @@ class calendar_ical extends calendar_boupdate
function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0, $principalURL='', $user=null, $charset=null) function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0, $principalURL='', $user=null, $charset=null)
{ {
$this->events_imported = 0; $this->events_imported = 0;
$replace = $delete_exceptions= false;
if (!is_array($this->supportedFields)) $this->setSupportedFields(); if (!is_array($this->supportedFields)) $this->setSupportedFields();
@ -1062,6 +1072,7 @@ class calendar_ical extends calendar_boupdate
{ {
if (count($events) == 1) if (count($events) == 1)
{ {
$replace = $recur_date == 0;
$events[0]['id'] = $cal_id; $events[0]['id'] = $cal_id;
if (!is_null($etag)) $events[0]['etag'] = (int) $etag; if (!is_null($etag)) $events[0]['etag'] = (int) $etag;
if ($recur_date) $events[0]['recurrence'] = $recur_date; if ($recur_date) $events[0]['recurrence'] = $recur_date;
@ -1117,43 +1128,42 @@ class calendar_ical extends calendar_boupdate
. array2string($event)."\n",3,$this->logfile); . array2string($event)."\n",3,$this->logfile);
} }
/* $updated_id = false;
if ($event['recur_type'] != MCAL_RECUR_NONE)
if ($replace)
{ {
// Adjust the event start -- no exceptions before and at the start $event_info['type'] = $event['recur_type'] == MCAL_RECUR_NONE ?
$length = $event['end'] - $event['start']; 'SINGLE' : 'SERIES-MASTER';
$rriter = calendar_rrule::event2rrule($event, false); $event_info['acl_edit'] = $this->check_perms(EGW_ACL_EDIT, $cal_id);
$rriter->rewind(); if (($event_info['stored_event'] = $this->read($cal_id, 0, false, 'server')) &&
if (!$rriter->valid()) continue; // completely disolved into exceptions $event_info['stored_event']['recur_type'] != MCAL_RECUR_NONE &&
($event_info['stored_event']['recur_type'] != $event['recur_type']
$newstart = egw_time::to($rriter->current, 'server'); || $event_info['stored_event']['recur_interval'] != $event['recur_interval']
if ($newstart != $event['start']) || $event_info['stored_event']['recur_data'] != $event['recur_data']
|| $event_info['stored_event']['start'] != $event['start']))
{ {
// leading exceptions skiped // handle the old exceptions
$event['start'] = $newstart; $recur_exceptions = $this->so->get_related($event_info['stored_event']['uid']);
$event['end'] = $newstart + $length; foreach ($recur_exceptions as $id)
}
$exceptions = $event['recur_exception'];
foreach($exceptions as $key => $day)
{
// remove leading exceptions
if ($day <= $event['start'])
{ {
if ($this->log) if ($delete_exceptions)
{ {
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__. $this->delete($id);
'(): event SERIES-MASTER skip leading exception ' . }
$day . "\n",3,$this->logfile); else
{
if (!($exception = $this->read($id))) continue;
$exception['uid'] = common::generate_uid('calendar', $id);
$exception['reference'] = $exception['recurrence'] = 0;
$this->update($exception, true);
} }
unset($exceptions[$key]);
} }
} }
$event['recur_exception'] = $exceptions;
} }
*/ else
$updated_id = false; {
$event_info = $this->get_event_info($event); $event_info = $this->get_event_info($event);
}
// common adjustments for existing events // common adjustments for existing events
if (is_array($event_info['stored_event'])) if (is_array($event_info['stored_event']))
@ -1468,55 +1478,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']]) &&
$event_info['stored_event']['start'] < $event['start'])
{
// We started with a pseudo exception and moved the
// event start therefore to the future; let's try to go back
$exceptions = $this->so->get_recurrence_exceptions($event_info['stored_event'], $this->tzid, 0, 0, 'rrule');
if ($this->log)
{
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."(START ADJUSTMENT):\n" .
array2string($exceptions)."\n",3,$this->logfile);
}
$startdate = $event_info['stored_event']['start'];
$length = $event['end'] - $event['start'];
$rriter = calendar_rrule::event2rrule($event_info['stored_event'], false);
$rriter->rewind();
do
{
// start is a pseudo excpetion for sure
$rriter->next_no_exception();
$day = $this->date2ts($rriter->current());
if ($this->log)
{
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
'(): event SERIES-MASTER try leading pseudo exception ' .
$day . "\n",3,$this->logfile);
}
if ($day >= $event['start']) break;
if (!isset($exceptions[$day]))
{
// all leading occurrences have to be exceptions;
// if not -> no restore
if ($this->log)
{
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__.
'(): event SERIES-MASTER pseudo exception series broken at ' .
$rriter->current() . "!\n",3,$this->logfile);
}
$startdate = $event['start'];
$recur_exceptions = array();
break;
}
$recur_exceptions[] = $day;
} while ($rriter->valid());
$event['start'] = $startdate;
$event['end'] = $startdate + $length;
} */
foreach ($event['recur_exception'] as $recur_exception) foreach ($event['recur_exception'] as $recur_exception)
{ {
if (isset($days[$recur_exception])) if (isset($days[$recur_exception]))
@ -1589,43 +1551,7 @@ class calendar_ical extends calendar_boupdate
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
$length = $event_info['master_event']['end'] - $event_info['master_event']['start'];
$rriter = calendar_rrule::event2rrule($event_info['master_event'], false);
$rriter->rewind();
if ($rriter->valid())
{
$newstart = egw_time::to($rriter->current, 'server');
foreach($event_info['master_event']['recur_exception'] as $key => $day)
{
// remove leading exceptions
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]);
}
}
}
if ($event_info['master_event']['start'] < $newstart)
{
$event_info['master_event']['start'] = $newstart;
$event_info['master_event']['end'] = $newstart + $length;
}*/
$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'];