Fix CalDAV group attendee issue; various GroupDAV improvements

This commit is contained in:
Jörg Lehrke 2010-06-27 22:16:22 +00:00
parent c6b0f825d9
commit bce68a9e82
5 changed files with 90 additions and 67 deletions

View File

@ -391,9 +391,9 @@ class addressbook_groupdav extends groupdav_handler
// should we hide the accounts addressbook // should we hide the accounts addressbook
if ($GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts']) $filter['account_id'] = null; if ($GLOBALS['egw_info']['user']['preferences']['addressbook']['hide_accounts']) $filter['account_id'] = null;
$result = $this->bo->search(array(),'MAX(contact_modified) AS contact_modified','','','','','',$filter); $result = $this->bo->search(array(),'MAX(contact_modified) AS contact_modified','','','',false,'AND',false,$filter);
$ctag = 'EGw-'.$result[0]['modified'].'-wGE'; $ctag = 'EGw-'.$result[0]['contact_modified'].'-wGE';
return $ctag; return $ctag;
} }

View File

@ -591,6 +591,8 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
*/ */
function post(&$options,$id,$user=null) function post(&$options,$id,$user=null)
{ {
$status = $this->put($options,$id,$user);
// error_log("CalDAV POST: $status" . print_r($options, true));
return true; return true;
} }
@ -869,8 +871,12 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/'))); array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/')));
*/ */
// email of the current user, see caldav-sheduling draft // email of the current user, see caldav-sheduling draft
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array( $props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))); HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']),
HTTP_WebDAV_Server::mkprop('href',$base_uri.'/principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/'),
HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.$GLOBALS['egw_info']['user']['account_lid'])));
//$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
// HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email'])));
// supported components, currently only VEVENT // supported components, currently only VEVENT
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-component-set',array( $props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-component-set',array(
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VCALENDAR')), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VCALENDAR')),
@ -886,6 +892,8 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f
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'))));
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::ICAL,'calendar-color','#0040A0FF'); // TODO: make it configurable $props[] = HTTP_WebDAV_Server::mkprop(groupdav::ICAL,'calendar-color','#0040A0FF'); // TODO: make it configurable
//$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'publish-url',array(
// HTTP_WebDAV_Server::mkprop('href',$base_uri.'/calendar/')));
//$props = self::current_user_privilege_set($props); //$props = self::current_user_privilege_set($props);
return $props; return $props;

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)
@ -496,15 +475,15 @@ class calendar_ical extends calendar_boupdate
{ {
$participantURL = empty($info['email']) ? '' : 'MAILTO:' . $info['email']; $participantURL = empty($info['email']) ? '' : 'MAILTO:' . $info['email'];
} }
// 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}
@ -512,6 +491,11 @@ class calendar_ical extends calendar_boupdate
{ {
case 'g': case 'g':
$cutype = 'GROUP'; $cutype = 'GROUP';
if ($this->productManufacturer == 'groupdav')
{
$participantURL = 'invalid:nomail';
$cutype = 'INDIVIDUAL';
}
break; break;
case 'r': case 'r':
$cutype = 'RESOURCE'; $cutype = 'RESOURCE';
@ -526,14 +510,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;
@ -547,37 +534,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;
@ -615,7 +603,7 @@ 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']; $length = ($event['end'] - $event['start']) / 2;
$rrule['UNTIL']->modify($length . ' second'); $rrule['UNTIL']->modify($length . ' second');
if (!$tzid || $version != '1.0') if (!$tzid || $version != '1.0')
{ {

View File

@ -273,12 +273,16 @@ class groupdav extends HTTP_WebDAV_Server
self::mkprop('href',$this->base_uri.$user_prefix))), self::mkprop('href',$this->base_uri.$user_prefix))),
self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))), self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))),
self::mkprop(groupdav::CALDAV,'calendar-user-address-set',array( self::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
self::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))), self::mkprop('href','MAILTO:'.$account['account_email']),
self::mkprop('principal-collection-set',array( self::mkprop('href',$this->base_uri.'/principals/users/'.$account['account_lid'].'/'),
self::mkprop('href',$this->base_uri.'/principals/users/'), self::mkprop('href','urn:uuid:'.$account['account_lid']))),
self::mkprop('href',$this->base_uri.'/principals/groups/'))), self::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
self::mkprop(groupdav::CALENDARSERVER,'email-address',$GLOBALS['egw_info']['user']['email']))),
//self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))), //self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
//self::mkprop('principal-collection-set',array(self::mkprop('href',$this->base_uri.'/principals/'))), self::mkprop('principal-collection-set',array(self::mkprop('href',$this->base_uri.'/principals/'))),
// OUTBOX URLs of the current user
self::mkprop(groupdav::CALDAV,'schedule-outbox-URL',array(
self::mkprop(groupdav::DAV,'href',$this->base_uri.'/calendar/'))),
); );
//$props = self::current_user_privilege_set($props); //$props = self::current_user_privilege_set($props);
$files['files'][] = array( $files['files'][] = array(
@ -296,11 +300,11 @@ class groupdav extends HTTP_WebDAV_Server
self::mkprop('displayname',lang('Accounts')), self::mkprop('displayname',lang('Accounts')),
self::mkprop('resourcetype',array(self::mkprop('principals',''))), self::mkprop('resourcetype',array(self::mkprop('principals',''))),
self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))), self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))),
self::mkprop(groupdav::CALDAV,'calendar-home-set',array( //self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
self::mkprop('href',$this->base_uri.$user_prefix))), // self::mkprop('href',$this->base_uri.$user_prefix))),
self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( //self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
self::mkprop('href',$this->base_uri.$user_prefix))), // self::mkprop('href',$this->base_uri.$user_prefix))),
self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))), //self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
), ),
); );
} }
@ -382,9 +386,15 @@ class groupdav extends HTTP_WebDAV_Server
self::mkprop('alternate-URI-set',array( self::mkprop('alternate-URI-set',array(
self::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))), self::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))),
self::mkprop('principal-collection-set',array( self::mkprop('principal-collection-set',array(
self::mkprop('href',$this->base_uri.'/principals/users/'), self::mkprop('href',$this->base_uri.'/principals/'),
self::mkprop('href',$this->base_uri.'/principals/groups/'),
)), )),
self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
self::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
self::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']),
self::mkprop('href',$this->base_uri.'/principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/'),
self::mkprop('href','urn:uuid:'.$GLOBALS['egw_info']['user']['account_lid']))),
self::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
self::mkprop(groupdav::CALENDARSERVER,'email-address',$GLOBALS['egw_info']['user']['email']))),
); );
switch ($app) switch ($app)

View File

@ -84,6 +84,7 @@ class groupdav_principals extends groupdav_handler
{ {
$displayname = $this->translation->convert($account['account_fullname'], $displayname = $this->translation->convert($account['account_fullname'],
$this->translation->charset(),'utf-8'); $this->translation->charset(),'utf-8');
$props = array( $props = array(
HTTP_WebDAV_Server::mkprop('displayname',$displayname), HTTP_WebDAV_Server::mkprop('displayname',$displayname),
HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($account)), HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($account)),
@ -91,9 +92,12 @@ class groupdav_principals extends groupdav_handler
HTTP_WebDAV_Server::mkprop('principal', ''))), HTTP_WebDAV_Server::mkprop('principal', ''))),
HTTP_WebDAV_Server::mkprop('alternate-URI-set',''), HTTP_WebDAV_Server::mkprop('alternate-URI-set',''),
HTTP_WebDAV_Server::mkprop('principal-URL',$this->base_uri.'/principals/'.$account['account_lid']), HTTP_WebDAV_Server::mkprop('principal-URL',$this->base_uri.'/principals/'.$account['account_lid']),
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',$this->base_uri.$account['account_lid'].'/'), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array(
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set','MAILTO:'.$account['account_email']), HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
); );
foreach($this->accounts->memberships($account['account_id']) as $gid => $group) foreach($this->accounts->memberships($account['account_id']) as $gid => $group)
{ {
$props[] = HTTP_WebDAV_Server::mkprop('group-membership',$this->base_uri.'/groups/'.$group); $props[] = HTTP_WebDAV_Server::mkprop('group-membership',$this->base_uri.'/groups/'.$group);
@ -146,8 +150,11 @@ class groupdav_principals extends groupdav_handler
{ {
case '': case '':
$files[] = $this->add_account($account); $files[] = $this->add_account($account);
$files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-read'); if ($options['depth'])
$files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-write'); {
$files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-read');
$files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-write');
}
break; break;
case 'calendar-proxy-read': case 'calendar-proxy-read':
case 'calendar-proxy-write': case 'calendar-proxy-write':
@ -250,10 +257,20 @@ class groupdav_principals extends groupdav_handler
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array( HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))), HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array( HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']))), HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']),
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/users/'.$account['account_lid'].'/'),
HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.$account['account_lid']))),
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-outbox-URL',array(
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$this->base_uri.'/calendar/'))),
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address',$account['account_email']))),
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))), HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
HTTP_WebDAV_Server::mkprop('group-member-ship', $memberships), HTTP_WebDAV_Server::mkprop('group-member-ship', $memberships),
HTTP_WebDAV_Server::mkprop('supported-report-set',array(
HTTP_WebDAV_Server::mkprop('supported-report',array(
HTTP_WebDAV_Server::mkprop('report',
HTTP_WebDAV_Server::mkprop('acl-principal-prop-set')))))),
); );
if ($this->debug > 1) error_log(__METHOD__."($path) path=/principals/users/".$account['account_lid'].', props='.array2string($props)); if ($this->debug > 1) error_log(__METHOD__."($path) path=/principals/users/".$account['account_lid'].', props='.array2string($props));
return array( return array(
@ -288,7 +305,7 @@ class groupdav_principals extends groupdav_handler
HTTP_WebDAV_Server::mkprop('principal', ''))), HTTP_WebDAV_Server::mkprop('principal', ''))),
HTTP_WebDAV_Server::mkprop('alternate-URI-set',''), HTTP_WebDAV_Server::mkprop('alternate-URI-set',''),
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array( HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/calendar/'))), HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))), HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
HTTP_WebDAV_Server::mkprop('group-member-set', $members), HTTP_WebDAV_Server::mkprop('group-member-set', $members),