From 30a3296c8e7903b4f3d7533a88369476ffdf141e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Lehrke?= Date: Tue, 13 Apr 2010 15:31:59 +0000 Subject: [PATCH] Optimze and clean up GroupDAV --- .../inc/class.addressbook_groupdav.inc.php | 4 +- calendar/inc/class.calendar_groupdav.inc.php | 39 +++++++++++++-- infolog/inc/class.infolog_groupdav.inc.php | 46 +++++++++++++++++- phpgwapi/inc/class.groupdav.inc.php | 48 ++++++++++++------- .../inc/class.groupdav_principals.inc.php | 16 ++++--- 5 files changed, 123 insertions(+), 30 deletions(-) diff --git a/addressbook/inc/class.addressbook_groupdav.inc.php b/addressbook/inc/class.addressbook_groupdav.inc.php index 46e8bf54cf..3ae4fc6cd5 100644 --- a/addressbook/inc/class.addressbook_groupdav.inc.php +++ b/addressbook/inc/class.addressbook_groupdav.inc.php @@ -387,10 +387,10 @@ class addressbook_groupdav extends groupdav_handler { $props[] = HTTP_WebDAV_Server::mkprop(groupdav::DAV,'current-user-privilege-set', array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'privilege', - array(//HTTP_WebDAV_Server::mkprop(groupdav::DAV,'all',''), + array( HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read',''), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'read-free-busy',''), - //HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read-current-user-privilege-set',''), + HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read-current-user-privilege-set',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'bind',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'unbind',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-post',''), diff --git a/calendar/inc/class.calendar_groupdav.inc.php b/calendar/inc/class.calendar_groupdav.inc.php index 101d13fda4..c1a2289b39 100644 --- a/calendar/inc/class.calendar_groupdav.inc.php +++ b/calendar/inc/class.calendar_groupdav.inc.php @@ -646,6 +646,34 @@ class calendar_groupdav extends groupdav_handler return $this->bo->read($id,null,false,'server'); } + /** + * Query ctag for calendar + * + * @return string + */ + public function getctag($path,$user) + { + $filter = array( + 'users' => $user, + 'start' => time()-100*24*3600, // default one month back -30 breaks all sync recurrences + 'end' => time()+365*24*3600, // default one year into the future +365 + 'enum_recuring' => false, + 'daywise' => false, + 'date_format' => 'server', + 'order' => 'cal_modified DESC', + 'offset' => 0, + 'num_rows' => 1, + ); + + if ($path == '/calendar/') $filter['filter'] = 'owner'; + + $result =& $this->bo->search($filter); + + $entry = array_shift($result); + + return $this->get_etag($entry); + } + /** * Get the etag for an entry, reimplemented to include the participants and stati in the etag * @@ -713,10 +741,10 @@ class calendar_groupdav extends groupdav_handler { $props[] = HTTP_WebDAV_Server::mkprop(groupdav::DAV,'current-user-privilege-set', array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'privilege', - array(//HTTP_WebDAV_Server::mkprop(groupdav::DAV,'all',''), + array( HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read',''), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'read-free-busy',''), - //HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read-current-user-privilege-set',''), + HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read-current-user-privilege-set',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'bind',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'unbind',''), HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-post',''), @@ -762,14 +790,19 @@ class calendar_groupdav extends groupdav_handler 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')), + HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VTIMEZONE')), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VEVENT')), // HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VTODO')), // not yet supported )); - $props[] = HTTP_WebDAV_Server::mkprop('supported-report-set',array( HTTP_WebDAV_Server::mkprop('supported-report',array( HTTP_WebDAV_Server::mkprop('report', HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget')))))); + $props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-data',array( + 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 = self::current_user_privilege_set($props); return $props; diff --git a/infolog/inc/class.infolog_groupdav.inc.php b/infolog/inc/class.infolog_groupdav.inc.php index fe21dc748a..eb652f7aea 100644 --- a/infolog/inc/class.infolog_groupdav.inc.php +++ b/infolog/inc/class.infolog_groupdav.inc.php @@ -476,6 +476,48 @@ class infolog_groupdav extends groupdav_handler return $this->bo->check_access($task,$acl); } + /** + * Query ctag for infolog + * + * @return string + */ + public function getctag($path,$user) + { + $myself = ($user == $GLOBALS['egw_info']['user']['account_id']); + + if ($path == '/infolog/') + { + $task_filter= 'own'; + } + else + { + if ($myself) + { + $task_filter = 'open'; + } + else + { + $task_filter = 'open-user' . $user; + } + } + + $query = array( + 'order' => 'info_datemodified', + 'sort' => 'DESC', + 'filter' => $task_filter, + 'date_format' => 'server', + 'col_filter' => array('info_type' => 'task'), + 'start' => 0, + 'num_rows' => 1, + ); + + $result =& $this->bo->search($query); + + $entry = array_shift($result); + + return $this->get_etag($entry); + } + /** * Get the etag for an infolog entry * @@ -516,13 +558,15 @@ class infolog_groupdav extends groupdav_handler // 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' => 'VEVENT')), + HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VCALENDAR')), + HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VTIMEZONE')), HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'comp',array('name' => 'VTODO')), )); $props[] = HTTP_WebDAV_Server::mkprop('supported-report-set',array( HTTP_WebDAV_Server::mkprop('supported-report',array( HTTP_WebDAV_Server::mkprop('report', - HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget')))))); + HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget','')))))); return $props; } diff --git a/phpgwapi/inc/class.groupdav.inc.php b/phpgwapi/inc/class.groupdav.inc.php index be7f15f570..abbd6f2153 100644 --- a/phpgwapi/inc/class.groupdav.inc.php +++ b/phpgwapi/inc/class.groupdav.inc.php @@ -56,10 +56,14 @@ class groupdav extends HTTP_WebDAV_Server * Calendarserver namespace (eg. for ctag) */ const CALENDARSERVER = 'http://calendarserver.org/ns/'; + /** + * Apple iCal namespace (eg. for calendar color) + */ + const ICAL = 'http://apple.com/ns/ical/'; /** * Realm and powered by string */ - const REALM = 'eGroupWare CalDAV/CardDAV/GroupDAV server'; + const REALM = 'EGroupware CalDAV/CardDAV/GroupDAV server'; var $dav_powered_by = self::REALM; var $http_auth_realm = self::REALM; @@ -249,7 +253,7 @@ class groupdav extends HTTP_WebDAV_Server { if (empty($user_prefix)) { - $user_prefix = '/'.$GLOBALS['egw_info']['user']['account_lid'].'/'; + $user_prefix = '/'; //.$GLOBALS['egw_info']['user']['account_lid'].'/'; } if ($options['depth']) { @@ -261,12 +265,15 @@ class groupdav extends HTTP_WebDAV_Server self::mkprop('resourcetype',array(self::mkprop('collection',''))), // adding the calendar extra property (calendar-home-set, etc.) here, allows apple iCal to "autodetect" the URL self::mkprop(groupdav::CALDAV,'calendar-home-set',array( - self::mkprop('href',$this->base_uri.$user_prefix.'calendar/'))), + 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('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('principal-URL',array(self::mkprop('href',$this->principalURL))), //self::mkprop('principal-collection-set',array(self::mkprop('href',$this->base_uri.'/principals/'))), ); @@ -284,10 +291,10 @@ class groupdav extends HTTP_WebDAV_Server 'path' => '/principals/', 'props' => array( self::mkprop('displayname',lang('Accounts')), - self::mkprop('resourcetype',array(self::mkprop('collection',''))), + 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.'calendar/'))), + self::mkprop('href',$this->base_uri.$user_prefix))), self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( self::mkprop('href',$this->base_uri.'/'))), self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))), @@ -297,10 +304,16 @@ class groupdav extends HTTP_WebDAV_Server foreach($this->root as $app => $data) { if (!$GLOBALS['egw_info']['user']['apps'][$app]) continue; // no rights for the given app - + $props = $this->_properties($app,false,$user,$path); + // add ctag if handler implements it + if (($handler = self::app_handler($app)) && method_exists($handler,'getctag')) + { + $props[] = self::mkprop( + groupdav::CALENDARSERVER,'getctag',$handler->getctag($options['path'],$user)); + } $files['files'][] = array( 'path' => $path.$app.'/', - 'props' => $this->_properties($app,false,$user), + 'props' => $props, ); } } @@ -318,7 +331,7 @@ class groupdav extends HTTP_WebDAV_Server $files['files'][0] = array( 'path' => $path.$app.'/', // KAddressbook doubles the folder, if the self URL contains the GroupDAV/CalDAV resourcetypes - 'props' => $this->_properties($app,$app=='addressbook'&&strpos($_SERVER['HTTP_USER_AGENT'],'KHTML') !== false,$user), + 'props' => $this->_properties($app,$app=='addressbook'&&strpos($_SERVER['HTTP_USER_AGENT'],'KHTML') !== false,$user,$path), ); } if (isset($options['depth']) && !$options['depth'] && !$id) @@ -342,9 +355,10 @@ class groupdav extends HTTP_WebDAV_Server * @param string $app * @param boolean $no_extra_types=false should the GroupDAV and CalDAV types be added (KAddressbook has problems with it in self URL) * @param int $user=null owner of the collection, default current user + * @param string $path='/' * @return array of DAV properties */ - function _properties($app,$no_extra_types=false,$user=null) + function _properties($app,$no_extra_types=false,$user=null,$path='/') { if ($this->debug) error_log(__CLASS__."::$method: user='$user', app='$app'"); if ($user) @@ -360,7 +374,7 @@ class groupdav extends HTTP_WebDAV_Server $GLOBALS['egw']->translation->charset(),'utf-8'); $props = array( self::mkprop('current-user-principal',array(self::mkprop('href',$this->principalURL))), - self::mkprop('owner',$displayname), + self::mkprop('owner',array(self::mkprop('href',$this->base_uri.'/principals/users/'.$account_lid.'/'))), self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))), self::mkprop('alternate-URI-set',array( self::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']))), @@ -374,24 +388,20 @@ class groupdav extends HTTP_WebDAV_Server switch ($app) { - case 'calendar': - $props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array( - self::mkprop('href',$this->base_uri.'/'.$account_lid.'/calendar/'))); - break; case 'infolog': $props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array( - self::mkprop('href',$this->base_uri.'/'.$account_lid.'/infolog/'))); + self::mkprop('href',$this->base_uri.$path.'infolog/'))); $displayname = $this->translation->convert(lang($app).' '. common::grab_owner_name($user),$this->egw_charset,'utf-8'); break; default: $props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array( - self::mkprop('href',$this->base_uri.'/'.$account_lid.'/calendar/'))); + self::mkprop('href',$this->base_uri.$path))); $displayname = $this->translation->convert(lang($app).' '. common::grab_owner_name($user),$this->egw_charset,'utf-8'); } $props[] = self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( - self::mkprop('href',$this->base_uri.'/'.$account_lid.'/'))); + self::mkprop('href',$this->base_uri.$path))); $props[] = self::mkprop('displayname',$displayname); foreach((array)$this->root[$app] as $prop => $values) @@ -625,8 +635,10 @@ class groupdav extends HTTP_WebDAV_Server default: $ns = $prop['ns']; } + $ns_defs = ''; + $ns_hash = array($prop['ns'] => $ns, 'DAV:' => 'D'); $arr[$ns.':'.$prop['name']] = is_array($prop['val']) ? - $this->_hierarchical_prop_encode($prop['val']) : $prop['val']; + $this->_hierarchical_prop_encode($prop['val'], $prop['ns'], $ns_defs, $ns_hash) : $prop['val']; } return $arr; } diff --git a/phpgwapi/inc/class.groupdav_principals.inc.php b/phpgwapi/inc/class.groupdav_principals.inc.php index 7aa3197e67..9abcef6ed7 100644 --- a/phpgwapi/inc/class.groupdav_principals.inc.php +++ b/phpgwapi/inc/class.groupdav_principals.inc.php @@ -87,10 +87,11 @@ class groupdav_principals extends groupdav_handler $props = array( HTTP_WebDAV_Server::mkprop('displayname',$displayname), HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($account)), - HTTP_WebDAV_Server::mkprop('resourcetype','principal'), + HTTP_WebDAV_Server::mkprop('resourcetype',array( + 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'].'/calendar/'), + 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']), ); foreach($this->accounts->memberships($account['account_id']) as $gid => $group) @@ -240,13 +241,14 @@ class groupdav_principals extends groupdav_handler $props = array( HTTP_WebDAV_Server::mkprop('displayname',$displayname), HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($account)), - HTTP_WebDAV_Server::mkprop('resourcetype','principal'), + HTTP_WebDAV_Server::mkprop('resourcetype',array( + HTTP_WebDAV_Server::mkprop('principal', ''))), HTTP_WebDAV_Server::mkprop('alternate-URI-set',array( HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']))), HTTP_WebDAV_Server::mkprop('principal-URL',array( HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/users/'.$account['account_lid'].'/'))), 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::CALDAV,'calendar-user-address-set',array( HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']))), HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',array( @@ -282,7 +284,8 @@ class groupdav_principals extends groupdav_handler $props = array( HTTP_WebDAV_Server::mkprop('displayname',$displayname), HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($account)), - HTTP_WebDAV_Server::mkprop('resourcetype','principal'), + HTTP_WebDAV_Server::mkprop('resourcetype',array( + 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/'))), @@ -314,7 +317,8 @@ class groupdav_principals extends groupdav_handler //echo "

".__METHOD__."($path,".array($props).")

\n"; $props[] = HTTP_WebDAV_Server::mkprop('resourcetype',array( HTTP_WebDAV_Server::mkprop('collection',''), - HTTP_WebDAV_Server::mkprop('resourcetype','principal'), + HTTP_WebDAV_Server::mkprop('resourcetype',array( + HTTP_WebDAV_Server::mkprop('principal', ''))), )); return array( 'path' => $path,