From bce68a9e821d86eae1d6d2f05045537f072beab4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lehrke?= Date: Sun, 27 Jun 2010 22:16:22 +0000 Subject: [PATCH] Fix CalDAV group attendee issue; various GroupDAV improvements --- .../inc/class.addressbook_groupdav.inc.php | 4 +- calendar/inc/class.calendar_groupdav.inc.php | 12 ++- calendar/inc/class.calendar_ical.inc.php | 78 ++++++++----------- phpgwapi/inc/class.groupdav.inc.php | 34 +++++--- .../inc/class.groupdav_principals.inc.php | 29 +++++-- 5 files changed, 90 insertions(+), 67 deletions(-) diff --git a/addressbook/inc/class.addressbook_groupdav.inc.php b/addressbook/inc/class.addressbook_groupdav.inc.php index 97c14c6798..70ae27d8b8 100644 --- a/addressbook/inc/class.addressbook_groupdav.inc.php +++ b/addressbook/inc/class.addressbook_groupdav.inc.php @@ -391,9 +391,9 @@ class addressbook_groupdav extends groupdav_handler // should we hide the accounts addressbook 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; } diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index 73c0e95616..18dfcc61d4 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -591,6 +591,8 @@ error_log(__METHOD__."($path,,".array2string($start).") filter=".array2string($f */ function post(&$options,$id,$user=null) { + $status = $this->put($options,$id,$user); + // error_log("CalDAV POST: $status" . print_r($options, 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/'))); */ // email of the current user, see caldav-sheduling draft - $props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array( - HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))); + $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',$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 $props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-component-set',array( 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/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::CALENDARSERVER,'publish-url',array( + // HTTP_WebDAV_Server::mkprop('href',$base_uri.'/calendar/'))); //$props = self::current_user_privilege_set($props); return $props; diff --git a/calendar/inc/class.calendar_ical.inc.php b/calendar/inc/class.calendar_ical.inc.php index 3bd314fa25..4f5fbad689 100644 --- a/calendar/inc/class.calendar_ical.inc.php +++ b/calendar/inc/class.calendar_ical.inc.php @@ -433,27 +433,6 @@ class calendar_ical extends calendar_boupdate sort($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) @@ -496,15 +475,15 @@ class calendar_ical extends calendar_boupdate { $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') { $organizerURL = $participantURL; + $rsvp = ''; $organizerCN = $participantCN; $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. $status = $this->status_egw2ical[$status]; // CUTYPE={INDIVIDUAL|GROUP|RESOURCE|ROOM|UNKNOWN} @@ -512,6 +491,11 @@ class calendar_ical extends calendar_boupdate { case 'g': $cutype = 'GROUP'; + if ($this->productManufacturer == 'groupdav') + { + $participantURL = 'invalid:nomail'; + $cutype = 'INDIVIDUAL'; + } break; case 'r': $cutype = 'RESOURCE'; @@ -526,14 +510,17 @@ class calendar_ical extends calendar_boupdate break; }; // ROLE={CHAIR|REQ-PARTICIPANT|OPT-PARTICIPANT|NON-PARTICIPANT|X-*} - $parameters['ATTENDEE'][] = array( - 'CN' => $participantCN, - 'ROLE' => $role, - 'PARTSTAT' => $status, - 'CUTYPE' => $cutype, - 'RSVP' => $rsvp, - )+($info['type'] != 'e' ? array('X-EGROUPWARE-UID' => $uid) : array())+ - ($quantity > 1 ? array('X-EGROUPWARE-QUANTITY' => $quantity) : array()); + $options = array(); + if (!empty($participantCN)) $options['CN'] = $participantCN; + if (!empty($role)) $options['ROLE'] = $role; + if (!empty($status)) $options['PARTSTAT'] = $status; + if (!empty($cutype)) $options['CUTYPE'] = $cutype; + if (!empty($rsvp)) $options['RSVP'] = $rsvp; + if (!empty($info['email'])) $options['EMAIL'] = $info['email']; + if ($info['type'] != 'e') $options['X-EGROUPWARE-UID'] = $uid; + if ($quantity > 1) $options['X-EGROUPWARE-QUANTITY'] = $quantity; + $attributes['ATTENDEE'][] = $participantURL; + $parameters['ATTENDEE'][] = $options; } break; @@ -547,37 +534,38 @@ class calendar_ical extends calendar_boupdate { $organizerCN = '"' . trim($GLOBALS['egw']->accounts->id2name($event['owner'],'account_firstname') . ' ' . $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') { $organizerURL = trim($organizerCN . (empty($organizerURL) ? '' : ' <' . $organizerURL .'>')); } else { - $organizerURL = empty($organizerURL) ? '' : 'MAILTO:' . $organizerURL; + $organizerURL = empty($organizerEMail) ? '' : 'MAILTO:' . $organizerEMail; } $organizerUID = $event['owner']; if (!isset($event['participants'][$event['owner']])) { - $attributes['ATTENDEE'][] = $organizerURL; - $parameters['ATTENDEE'][] = array( - 'CN' => $organizerCN, + $options = array( 'ROLE' => 'CHAIR', 'PARTSTAT' => 'DELEGATED', 'CUTYPE' => 'INDIVIDUAL', - 'RSVP' => 'FALSE', - 'X-EGROUPWARE-UID' => $event['owner'], - ); + //'RSVP' => 'FALSE', + ); + 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' || - !$this->check_perms(EGW_ACL_EDIT,$event)) - { + if ($this->productManufacturer != 'groupdav' || !$this->check_perms(EGW_ACL_EDIT,$event)) + { $attributes['ORGANIZER'] = $organizerURL; $parameters['ORGANIZER']['CN'] = $organizerCN; if (!empty($organizerUID)) { - $parameters['ORGANIZER']['X-EGROUPWARE-UID'] = $organizerUID; + $parameters['ORGANIZER']['X-EGROUPWARE-UID'] = $organizerUID; } } break; @@ -615,7 +603,7 @@ class calendar_ical extends calendar_boupdate $rrule = $rriter->generate_rrule($version); if ($event['recur_enddate']) { - $length = $event['end'] - $event['start']; + $length = ($event['end'] - $event['start']) / 2; $rrule['UNTIL']->modify($length . ' second'); if (!$tzid || $version != '1.0') { diff --git a/phpgwapi/inc/class.groupdav.inc.php b/phpgwapi/inc/class.groupdav.inc.php index 773bd96bf5..988fdc2649 100644 --- a/phpgwapi/inc/class.groupdav.inc.php +++ b/phpgwapi/inc/class.groupdav.inc.php @@ -273,12 +273,16 @@ class groupdav extends HTTP_WebDAV_Server self::mkprop('href',$this->base_uri.$user_prefix))), self::mkprop('current-user-principal',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('principal-collection-set',array( - self::mkprop('href',$this->base_uri.'/principals/users/'), - self::mkprop('href',$this->base_uri.'/principals/groups/'))), + self::mkprop('href','MAILTO:'.$account['account_email']), + self::mkprop('href',$this->base_uri.'/principals/users/'.$account['account_lid'].'/'), + self::mkprop('href','urn:uuid:'.$account['account_lid']))), + 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-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); $files['files'][] = array( @@ -296,11 +300,11 @@ class groupdav extends HTTP_WebDAV_Server self::mkprop('displayname',lang('Accounts')), self::mkprop('resourcetype',array(self::mkprop('principals',''))), self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))), - self::mkprop(groupdav::CALDAV,'calendar-home-set',array( - self::mkprop('href',$this->base_uri.$user_prefix))), - self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( - self::mkprop('href',$this->base_uri.$user_prefix))), - self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))), + //self::mkprop(groupdav::CALDAV,'calendar-home-set',array( + // self::mkprop('href',$this->base_uri.$user_prefix))), + //self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( + // self::mkprop('href',$this->base_uri.$user_prefix))), + //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('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))), self::mkprop('principal-collection-set',array( - self::mkprop('href',$this->base_uri.'/principals/users/'), - self::mkprop('href',$this->base_uri.'/principals/groups/'), + self::mkprop('href',$this->base_uri.'/principals/'), )), + 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) diff --git a/phpgwapi/inc/class.groupdav_principals.inc.php b/phpgwapi/inc/class.groupdav_principals.inc.php index 1ae8150950..731e57fc99 100644 --- a/phpgwapi/inc/class.groupdav_principals.inc.php +++ b/phpgwapi/inc/class.groupdav_principals.inc.php @@ -84,6 +84,7 @@ class groupdav_principals extends groupdav_handler { $displayname = $this->translation->convert($account['account_fullname'], $this->translation->charset(),'utf-8'); + $props = array( HTTP_WebDAV_Server::mkprop('displayname',$displayname), 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('alternate-URI-set',''), 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-user-address-set','MAILTO:'.$account['account_email']), + 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(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) { $props[] = HTTP_WebDAV_Server::mkprop('group-membership',$this->base_uri.'/groups/'.$group); @@ -146,8 +150,11 @@ class groupdav_principals extends groupdav_handler { case '': $files[] = $this->add_account($account); - $files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-read'); - $files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/calendar-proxy-write'); + if ($options['depth']) + { + $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; case 'calendar-proxy-read': 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('href',$this->base_uri.'/'.$account['account_lid'].'/'))), 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('href',$this->base_uri.'/'.$account['account_lid'].'/'))), 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)); return array( @@ -288,7 +305,7 @@ class groupdav_principals extends groupdav_handler HTTP_WebDAV_Server::mkprop('principal', ''))), HTTP_WebDAV_Server::mkprop('alternate-URI-set',''), 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('href',$this->base_uri.'/'.$account['account_lid'].'/'))), HTTP_WebDAV_Server::mkprop('group-member-set', $members),