mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-11-28 10:53:39 +01:00
Updated GroupDAV code to support InfoLog calendars, Addressbook and new principal implementation
This commit is contained in:
parent
9e0f73f0dc
commit
19081734cd
@ -68,7 +68,7 @@ class addressbook_groupdav extends groupdav_handler
|
||||
*/
|
||||
static function get_path($contact)
|
||||
{
|
||||
return '/addressbook/'.$contact[self::PATH_ATTRIBUTE].'.vcf';
|
||||
return $contact[self::PATH_ATTRIBUTE].'.vcf';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -96,8 +96,9 @@ class addressbook_groupdav extends groupdav_handler
|
||||
}
|
||||
if ($this->debug) error_log(__METHOD__."($path,".array2string($options).",,$user,$id) filter=".array2string($filter));
|
||||
|
||||
// check if we have to return the full calendar data or just the etag's
|
||||
if (!($filter['address_data'] = $options['props'] == 'all' && $options['root']['ns'] == groupdav::CARDDAV) && is_array($options['props']))
|
||||
// check if we have to return the full contact data or just the etag's
|
||||
if (!($filter['address_data'] = $options['props'] == 'all' &&
|
||||
$options['root']['ns'] == groupdav::CARDDAV) && is_array($options['props']))
|
||||
{
|
||||
foreach($options['props'] as $prop)
|
||||
{
|
||||
@ -109,7 +110,7 @@ class addressbook_groupdav extends groupdav_handler
|
||||
}
|
||||
}
|
||||
// return iterator, calling ourself to return result in chunks
|
||||
$files['files'] = new groupdav_propfind_iterator($this,$filter,$files['files']);
|
||||
$files['files'] = new groupdav_propfind_iterator($this,$path,$filter,$files['files']);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -117,11 +118,12 @@ class addressbook_groupdav extends groupdav_handler
|
||||
/**
|
||||
* Callback for profind interator
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $filter
|
||||
* @param array|boolean $start=false false=return all or array(start,num)
|
||||
* @return array with "files" array with values for keys path and props
|
||||
*/
|
||||
function &propfind_callback(array $filter,$start=false)
|
||||
function &propfind_callback($path,array $filter,$start=false)
|
||||
{
|
||||
$starttime = microtime(true);
|
||||
|
||||
@ -139,7 +141,7 @@ class addressbook_groupdav extends groupdav_handler
|
||||
{
|
||||
$props = array(
|
||||
HTTP_WebDAV_Server::mkprop('getetag',$this->get_etag($contact)),
|
||||
HTTP_WebDAV_Server::mkprop('getcontenttype', 'text/x-vcard'),
|
||||
HTTP_WebDAV_Server::mkprop('getcontenttype', 'text/vcard'),
|
||||
// getlastmodified and getcontentlength are required by WebDAV and Cadaver eg. reports 404 Not found if not set
|
||||
HTTP_WebDAV_Server::mkprop('getlastmodified', $contact['modified']),
|
||||
);
|
||||
@ -147,19 +149,19 @@ class addressbook_groupdav extends groupdav_handler
|
||||
{
|
||||
$content = $handler->getVCard($contact,$this->charset,false);
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength',bytes($content));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'address-data',$content);
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'address-data',$content,true);
|
||||
}
|
||||
else
|
||||
{
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength', ''); // expensive to calculate and no CalDAV client uses it
|
||||
}
|
||||
$files[] = array(
|
||||
'path' => self::get_path($contact),
|
||||
'path' => $path.self::get_path($contact),
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
}
|
||||
if ($this->debug) error_log(__METHOD__.'('.array2string($filter).','.array2string($start).") took ".(microtime(true) - $starttime).' to return '.count($files).' items');
|
||||
if ($this->debug) error_log(__METHOD__."($path,".array2string($filter).','.array2string($start).") took ".(microtime(true) - $starttime).' to return '.count($files).' items');
|
||||
return $files;
|
||||
}
|
||||
|
||||
@ -266,14 +268,24 @@ class addressbook_groupdav extends groupdav_handler
|
||||
*/
|
||||
function put(&$options,$id,$user=null)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__.'('.array2string($options).",$id,$user)");
|
||||
$ok = $this->_common_get_put_delete('PUT',$options,$id);
|
||||
if (!is_null($ok) && !is_array($ok))
|
||||
{
|
||||
return $ok;
|
||||
}
|
||||
$handler = self::_get_handler();
|
||||
$contact = $handler->vcardtoegw($options['content']);
|
||||
|
||||
$vCard = htmlspecialchars_decode($options['content']);
|
||||
$contactId = (is_array($ok) ? -1 : $ok['id']);
|
||||
$contact = $handler->vcardtoegw($vCard, $contactId);
|
||||
if (is_array($contact['category']))
|
||||
{
|
||||
$contact['category'] = implode(',',$this->bo->find_or_add_categories($contact['category'], $contactId));
|
||||
}
|
||||
elseif ($contactId > 0)
|
||||
{
|
||||
$contact['category'] = $ok['category'];
|
||||
}
|
||||
if (!is_null($ok))
|
||||
{
|
||||
$contact['id'] = $ok['id'];
|
||||
@ -282,6 +294,10 @@ class addressbook_groupdav extends groupdav_handler
|
||||
$contact['owner'] = $ok['owner'];
|
||||
$contact['private'] = $ok['private'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$contact['owner'] = $user;
|
||||
}
|
||||
if ($this->http_if_match) $contact['etag'] = self::etag2value($this->http_if_match);
|
||||
|
||||
if (!($save_ok = $this->bo->save($contact)))
|
||||
@ -295,13 +311,14 @@ class addressbook_groupdav extends groupdav_handler
|
||||
}
|
||||
if (!isset($contact['etag']))
|
||||
{
|
||||
$contact = $this->read($contact['id']);
|
||||
$contact = $this->read($save_ok);
|
||||
}
|
||||
|
||||
header('ETag: '.$this->get_etag($contact));
|
||||
if (is_null($ok))
|
||||
{
|
||||
header($h='Location: '.$this->base_uri.self::get_path($contact));
|
||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||
header($h='Location: '.$path.self::get_path($contact));
|
||||
if ($this->debug) error_log(__METHOD__."($method,,$id) header('$h'): 201 Created");
|
||||
return '201 Created';
|
||||
}
|
||||
@ -323,7 +340,37 @@ class addressbook_groupdav extends groupdav_handler
|
||||
|
||||
$result = $this->bo->search(array(),'MAX(contact_modified) AS contact_modified','','','','','',$filter);
|
||||
|
||||
return '"'.$result[0]['modified'].'"';
|
||||
$ctag = 'EGw-'.$result[0]['modified'].'-wGE';
|
||||
return $ctag;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the privileges of the current user
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @return array
|
||||
*/
|
||||
static function current_user_privilege_set(array $props=array())
|
||||
{
|
||||
$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',''),
|
||||
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,'bind',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'unbind',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-post',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-post-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-respond',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-respond-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-deliver',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-deliver-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write-properties',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write-content',''),
|
||||
))));
|
||||
return $props;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -345,11 +392,17 @@ class addressbook_groupdav extends groupdav_handler
|
||||
* @link http://www.mail-archive.com/calendarserver-users@lists.macosforge.org/msg01156.html
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @param string $displayname
|
||||
* @param string $base_uri=null base url of handler
|
||||
* @return array
|
||||
*/
|
||||
static function extra_properties(array $props=array(), $base_uri=null)
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// addressbook description
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Addressbook of') . ' ' .
|
||||
$displayname,
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-description',$displayname);
|
||||
// supported reports (required property for CardDAV)
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('supported-report-set',array(
|
||||
HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||
@ -359,6 +412,7 @@ class addressbook_groupdav extends groupdav_handler
|
||||
HTTP_WebDAV_Server::mkprop('report',
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-multiget','')))),
|
||||
));
|
||||
//$props = self::current_user_privilege_set($props);
|
||||
return $props;
|
||||
}
|
||||
|
||||
@ -392,7 +446,7 @@ class addressbook_groupdav extends groupdav_handler
|
||||
{
|
||||
return '412 Precondition Failed';
|
||||
}
|
||||
return $ok;
|
||||
//return $ok;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -526,8 +526,8 @@ class addressbook_so
|
||||
/**
|
||||
* reads contact data including custom fields
|
||||
*
|
||||
* @param int/string $contact_id contact_id or 'a'.account_id
|
||||
* @return array/boolean data if row could be retrived else False
|
||||
* @param int|string $contact_id contact_id or 'a'.account_id
|
||||
* @return array|boolean data if row could be retrived else False
|
||||
*/
|
||||
function read($contact_id)
|
||||
{
|
||||
|
@ -123,7 +123,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
*/
|
||||
function addVCard($_vcard, $_abID=null, $merge=false)
|
||||
{
|
||||
if (!$contact = $this->vcardtoegw($_vcard, $_abID))
|
||||
if (!$contact = $this->vcardtoegw($_vcard))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@ -148,6 +148,15 @@ class addressbook_vcal extends addressbook_bo
|
||||
{
|
||||
$contact['account_id'] = $old_contact['account_id'];
|
||||
}
|
||||
if (is_array($contact['category']))
|
||||
{
|
||||
$contact['category'] = implode(',',$this->find_or_add_categories($contact['category'], $_abID));
|
||||
}
|
||||
else
|
||||
{
|
||||
// restore from orignal
|
||||
$contact['category'] = $old_contact['category'];
|
||||
}
|
||||
}
|
||||
}
|
||||
// update entry
|
||||
@ -160,6 +169,10 @@ class addressbook_vcal extends addressbook_bo
|
||||
{
|
||||
$contact['owner'] = $GLOBALS['egw_info']['user']['account_primary_group'];
|
||||
}
|
||||
if (is_array($contact['category']))
|
||||
{
|
||||
$contact['category'] = implode(',',$this->find_or_add_categories($contact['category'], -1));
|
||||
}
|
||||
}
|
||||
return $this->save($contact);
|
||||
}
|
||||
@ -455,8 +468,13 @@ class addressbook_vcal extends addressbook_bo
|
||||
{
|
||||
$result = array();
|
||||
|
||||
if (($contact = $this->vcardtoegw($_vcard, $contentID)))
|
||||
if (($contact = $this->vcardtoegw($_vcard)))
|
||||
{
|
||||
if (is_array($contact['category']))
|
||||
{
|
||||
$contact['category'] = implode(',',$this->find_or_add_categories($contact['category'],
|
||||
$contentID ? $contentID : -1));
|
||||
}
|
||||
if ($contentID)
|
||||
{
|
||||
$contact['id'] = $contentID;
|
||||
@ -475,7 +493,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
if (is_array($_supportedFields)) $this->supportedFields = $_supportedFields;
|
||||
}
|
||||
|
||||
function vcardtoegw($_vcard, $_abID=null)
|
||||
function vcardtoegw($_vcard)
|
||||
{
|
||||
// the horde class does the charset conversion. DO NOT CONVERT HERE.
|
||||
// be as flexible as possible
|
||||
@ -889,7 +907,7 @@ class addressbook_vcal extends addressbook_bo
|
||||
break;
|
||||
|
||||
case 'cat_id':
|
||||
$contact[$fieldName] = implode(',',$this->find_or_add_categories($vcardValues[$vcardKey]['values'], $_abID));
|
||||
$contact[$fieldName] = $vcardValues[$vcardKey]['values'];
|
||||
break;
|
||||
|
||||
case 'jpegphoto':
|
||||
|
@ -23,8 +23,6 @@ class calendar_groupdav extends groupdav_handler
|
||||
*/
|
||||
var $bo;
|
||||
|
||||
const DAV = 'DAV:';
|
||||
|
||||
var $filter_prop2cal = array(
|
||||
'SUMMARY' => 'cal_title',
|
||||
'UID' => 'cal_uid',
|
||||
@ -86,7 +84,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
if (!is_array($event)) $event = $this->bo->read($event);
|
||||
$name = $event[self::PATH_ATTRIBUTE];
|
||||
}
|
||||
return '/calendar/'.$name.'.ics';
|
||||
return $name.'.ics';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,7 +189,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength', ''); // expensive to calculate and no CalDAV client uses it
|
||||
}
|
||||
$files['files'][] = array(
|
||||
'path' => self::get_path($event),
|
||||
'path' => $path.self::get_path($event),
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
@ -447,12 +445,19 @@ class calendar_groupdav extends groupdav_handler
|
||||
if ($this->debug) error_log(__METHOD__.print_r($event,true).function_backtrace());
|
||||
return $event;
|
||||
}
|
||||
$handler = $this->_get_handler();
|
||||
|
||||
if (is_null($event) && !$this->bo->check_perms(EGW_ACL_ADD, 0, $user))
|
||||
{
|
||||
// we have not permission on this user's calendar
|
||||
if ($this->debug) error_log(__METHOD__."(,$user) we have not enough rights on this calendar");
|
||||
return '403 Forbidden';
|
||||
}
|
||||
|
||||
$handler = $this->_get_handler();
|
||||
$vCalendar = htmlspecialchars_decode($options['content']);
|
||||
|
||||
if (!($cal_id = $handler->importVCal($vCalendar, is_numeric($id) ? $id : -1,
|
||||
self::etag2value($this->http_if_match), false, 0, $this->principalURL)))
|
||||
self::etag2value($this->http_if_match), false, 0, $this->principalURL, $user)))
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."(,$id) importVCal($options[content]) returned false");
|
||||
return '403 Forbidden';
|
||||
@ -461,15 +466,11 @@ class calendar_groupdav extends groupdav_handler
|
||||
header('ETag: '.$this->get_etag($cal_id));
|
||||
if (is_null($event) || !$return_no_access) // let lightning think the event is added
|
||||
{
|
||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||
if ($this->debug) error_log(__METHOD__."(,$id,$user) cal_id=$cal_id, is_null(\$event)=".(int)is_null($event));
|
||||
header('Location: '.$this->base_uri.self::get_path($cal_id));
|
||||
header('Location: '.$path.self::get_path($cal_id));
|
||||
return '201 Created';
|
||||
}
|
||||
if (strpos($_SERVER[HTTP_USER_AGENT], 'Mac OS X') !== false)
|
||||
{
|
||||
//return '205 Reset Content'; // would be nicer
|
||||
return '400 Event updated, please reload'; // Enforce a reload by iCal
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -580,8 +581,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
*/
|
||||
function read($id)
|
||||
{
|
||||
//$cal_read = $this->bo->read($id,null,false,'server');//njv: do we actually get anything
|
||||
if ($this->debug > 1) error_log("bo-ical read :$id:");//njv:
|
||||
if ($this->debug > 1) error_log("bo-ical read :$id:");
|
||||
return $this->bo->read($id,null,false,'server');
|
||||
}
|
||||
|
||||
@ -622,12 +622,12 @@ class calendar_groupdav extends groupdav_handler
|
||||
{
|
||||
if ($recurrence['reference']) // ignore series master
|
||||
{
|
||||
$etag .= ':'.substr($this->get_etag($recurrence),1,-1);
|
||||
$etag .= ':'.substr($this->get_etag($recurrence),4,-4);
|
||||
}
|
||||
}
|
||||
}
|
||||
//error_log(__METHOD__ . "($entry[id] ($entry[etag]): $entry[title] --> etag=$etag");
|
||||
return '"'.$etag.'"';
|
||||
return 'EGw-'.$etag.'-wGE';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -650,23 +650,23 @@ class calendar_groupdav extends groupdav_handler
|
||||
*/
|
||||
static function current_user_privilege_set(array $props=array())
|
||||
{
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(self::DAV,'current-user-privilege-set',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::DAV,'privilege',
|
||||
array(//HTTP_WebDAV_Server::mkprop(self::DAV,'all',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'read',''),
|
||||
$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',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'read',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'read-free-busy',''),
|
||||
//HTTP_WebDAV_Server::mkprop(self::DAV,'read-current-user-privilege-set',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'bind',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'unbind',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-post',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-post-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-respond',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-respond-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-deliver',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'schedule-deliver-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'write',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'write-properties',''),
|
||||
HTTP_WebDAV_Server::mkprop(self::DAV,'write-content',''),
|
||||
//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',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-post-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-respond',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-respond-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-deliver',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'schedule-deliver-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write-properties',''),
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::DAV,'write-content',''),
|
||||
))));
|
||||
return $props;
|
||||
}
|
||||
@ -675,42 +675,41 @@ class calendar_groupdav extends groupdav_handler
|
||||
* Add extra properties for calendar collections
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @param string $displayname
|
||||
* @param string $base_uri=null base url of handler
|
||||
* @return array
|
||||
*/
|
||||
static function extra_properties(array $props=array(), $base_uri=null)
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// calendar description
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Calendar of'). ' ' .
|
||||
$GLOBALS['egw_info']['user']['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-description',$displayname);
|
||||
// BOX URLs of the current user
|
||||
/*
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-inbox-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-outbox-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::DAV,'href',$base_uri.'/calendar/')));
|
||||
array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-default-calendar-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::DAV,'href',$base_uri.'/calendar/')));
|
||||
array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'dropbox-home-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::DAV,'href',$base_uri.'/calendar/')));
|
||||
array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'notifications-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(self::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
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set','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'])));
|
||||
// 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' => '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 = self::current_user_privilege_set($props);
|
||||
return $props;
|
||||
}
|
||||
|
@ -1029,9 +1029,10 @@ class calendar_ical extends calendar_boupdate
|
||||
* @param int $recur_date=0 if set, import the recurrence at this timestamp,
|
||||
* default 0 => import whole series (or events, if not recurring)
|
||||
* @param string $principalURL='' Used for CalDAV imports
|
||||
* @param int $user=null account_id of owner, default null
|
||||
* @return int|boolean cal_id > 0 on success, false on failure or 0 for a failed etag
|
||||
*/
|
||||
function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0, $principalURL='')
|
||||
function importVCal($_vcalData, $cal_id=-1, $etag=null, $merge=false, $recur_date=0, $principalURL='', $user=null)
|
||||
{
|
||||
if (!is_array($this->supportedFields)) $this->setSupportedFields();
|
||||
|
||||
@ -1081,7 +1082,7 @@ class calendar_ical extends calendar_boupdate
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__
|
||||
."($cal_id, $etag, $recur_date, $principalURL)\n"
|
||||
."($cal_id, $etag, $recur_date, $principalURL, $user)\n"
|
||||
. array2string($event)."\n",3,$this->logfile);
|
||||
}
|
||||
$updated_id = false;
|
||||
@ -1204,9 +1205,20 @@ class calendar_ical extends calendar_boupdate
|
||||
$event['non_blocking'] = 1;
|
||||
}
|
||||
|
||||
if (!is_null($user))
|
||||
{
|
||||
if ($this->check_perms(EGW_ACL_ADD, 0, $user))
|
||||
{
|
||||
$event['owner'] = $user;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false; // no permission
|
||||
}
|
||||
}
|
||||
// check if an owner is set and the current user has add rights
|
||||
// for that owners calendar; if not set the current user
|
||||
if (!isset($event['owner'])
|
||||
elseif (!isset($event['owner'])
|
||||
|| !$this->check_perms(EGW_ACL_ADD, 0, $event['owner']))
|
||||
{
|
||||
$event['owner'] = $this->user;
|
||||
|
@ -59,6 +59,18 @@ class HTTP_WebDAV_Server
|
||||
*/
|
||||
var $client_require_href_as_url;
|
||||
|
||||
/**
|
||||
* Set if client requires does not allow namespace redundacy.
|
||||
* The XML Namespace specification does allow both
|
||||
* But some clients can NOT deal with one or the other!
|
||||
*
|
||||
* @var boolean (client_refuses_redundand_namespace_declarations)
|
||||
*/
|
||||
var $crrnd = false;
|
||||
|
||||
/**
|
||||
|
||||
|
||||
/**
|
||||
* URI path for this request
|
||||
*
|
||||
@ -229,11 +241,18 @@ class HTTP_WebDAV_Server
|
||||
$this->$wrapper(); // call method by name
|
||||
} else { // method not found/implemented
|
||||
if ($this->_SERVER["REQUEST_METHOD"] == "LOCK") {
|
||||
$this->http_status("412 Precondition failed");
|
||||
$error = '412 Precondition failed';
|
||||
;
|
||||
} else {
|
||||
$this->http_status("405 Method not allowed");
|
||||
$error = '405 Method not allowed';
|
||||
header("Allow: ".join(", ", $this->_allow())); // tell client what's allowed
|
||||
}
|
||||
$this->http_status($error);
|
||||
echo "<html><head><title>Error $error</title></head>\n";
|
||||
echo "<body><h1>$error</h1>\n";
|
||||
echo "The requested could not by handled by this server.\n";
|
||||
echo '(URI ' . $this->_SERVER['REQUEST_URI'] . ")<br>\n<br>\n";
|
||||
echo "</body></html>\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -432,7 +451,7 @@ class HTTP_WebDAV_Server
|
||||
*/
|
||||
// }}}
|
||||
|
||||
// {{{ LOCK()
|
||||
// {{{ ACL()
|
||||
|
||||
/**
|
||||
* ACL implementation
|
||||
@ -585,7 +604,7 @@ class HTTP_WebDAV_Server
|
||||
$options['other'] = $propinfo->other;
|
||||
|
||||
// call user handler
|
||||
if (!$this->$handler($options, $files)) {
|
||||
if (!($retval =$this->$handler($options, $files))) {
|
||||
$files = array("files" => array());
|
||||
if (method_exists($this, "checkLock")) {
|
||||
// is locked?
|
||||
@ -612,26 +631,42 @@ class HTTP_WebDAV_Server
|
||||
}
|
||||
|
||||
// now we generate the reply header ...
|
||||
if ($propinfo->root['name'] == 'principal-search-property-set')
|
||||
{
|
||||
$this->http_status('200 OK');
|
||||
}
|
||||
else
|
||||
if ($retval === true)
|
||||
{
|
||||
$this->http_status('207 Multi-Status');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->http_status($retval);
|
||||
header('Content-Type: text/html');
|
||||
echo "<html><head><title>Error $retval</title></head>\n";
|
||||
echo "<body><h1>$retval</h1>\n";
|
||||
switch (substr($retval, 0 ,3))
|
||||
{
|
||||
case '501': // Not Implemented
|
||||
echo "The requested feature is not (yet) supported by this server.\n";
|
||||
break;
|
||||
default:
|
||||
echo "The request could not be handled by this server.\n";
|
||||
}
|
||||
echo '(URI ' . $this->_SERVER['REQUEST_URI'] . ")<br>\n<br>\n";
|
||||
echo "</body></html>\n";
|
||||
return;
|
||||
}
|
||||
// dav header
|
||||
$dav = array(1); // assume we are always dav class 1 compliant
|
||||
$allow = false;
|
||||
|
||||
// allow extending class to modify DAV
|
||||
if (method_exists($this,'OPTIONS')) {
|
||||
$this->OPTIONS($this->path,$dav,$allow);
|
||||
}
|
||||
header("DAV: " .join(", ", $dav));
|
||||
header('Content-Type: text/xml; charset="utf-8"');
|
||||
|
||||
// ... and payload
|
||||
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
if ($propinfo->root['name'] == 'principal-search-property-set')
|
||||
{
|
||||
echo "<D:principal-search-property-set xmlns:D=\"DAV:\">\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "<D:multistatus xmlns:D=\"DAV:\">\n";
|
||||
}
|
||||
echo ($this->crrnd?'<':'<D:')."multistatus xmlns:D=\"DAV:\">\n";
|
||||
|
||||
// using an ArrayIterator to prevent foreach from copying the array,
|
||||
// as we cant loop by reference, when an iterator is given in $files['files']
|
||||
@ -748,7 +783,14 @@ class HTTP_WebDAV_Server
|
||||
$path = $file['path'];
|
||||
if (!is_string($path) || $path==="") continue;
|
||||
|
||||
if ($propinfo->root['name'] != 'principal-search-property-set') echo " <D:response $ns_defs>\n";
|
||||
if ($this->crrnd)
|
||||
{
|
||||
echo " <response $ns_defs>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " <D:response $ns_defs>\n";
|
||||
}
|
||||
|
||||
/* TODO right now the user implementation has to make sure
|
||||
collections end in a slash, this should be done in here
|
||||
@ -756,15 +798,20 @@ class HTTP_WebDAV_Server
|
||||
// path needs to be urlencoded (only basic version of this class!)
|
||||
$href = $this->_urlencode($this->_mergePathes($this->base_uri, $path));
|
||||
|
||||
if ($propinfo->root['name'] != 'principal-search-property-set') echo " <D:href>$href</D:href>\n";
|
||||
if ($this->crrnd)
|
||||
{
|
||||
echo " <href>$href</href>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " <D:href>$href</D:href>\n";
|
||||
}
|
||||
|
||||
// report all found properties and their values (if any)
|
||||
if (isset($file["props"]) && is_array($file["props"])) {
|
||||
if ($propinfo->root['name'] != 'principal-search-property-set')
|
||||
{
|
||||
echo " <D:propstat>\n";
|
||||
echo " <D:prop>\n";
|
||||
}
|
||||
echo ' <'.($this->crrnd?'':'D:')."propstat>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."prop>\n";
|
||||
|
||||
foreach ($file["props"] as &$prop) {
|
||||
|
||||
if (!is_array($prop)) continue;
|
||||
@ -773,7 +820,7 @@ class HTTP_WebDAV_Server
|
||||
if (!isset($prop["val"]) || $prop["val"] === "" || $prop["val"] === false) {
|
||||
// empty properties (cannot use empty() for check as "0" is a legal value here)
|
||||
if ($prop["ns"]=="DAV:") {
|
||||
echo " <D:$prop[name]/>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."$prop[name]/>\n";
|
||||
} else if (!empty($prop["ns"])) {
|
||||
echo " <".$ns_hash[$prop["ns"]].":$prop[name]/>\n";
|
||||
} else {
|
||||
@ -783,61 +830,34 @@ class HTTP_WebDAV_Server
|
||||
// some WebDAV properties need special treatment
|
||||
switch ($prop["name"]) {
|
||||
case "creationdate":
|
||||
echo " <D:creationdate ns0:dt=\"dateTime.tz\">"
|
||||
echo ' <'.($this->crrnd?'':'D:')."creationdate ns0:dt=\"dateTime.tz\">"
|
||||
. gmdate("Y-m-d\\TH:i:s\\Z", $prop['val'])
|
||||
. "</D:creationdate>\n";
|
||||
. '</'.($this->crrnd?'':'D:')."creationdate>\n";
|
||||
break;
|
||||
case "getlastmodified":
|
||||
echo " <D:getlastmodified ns0:dt=\"dateTime.rfc1123\">"
|
||||
echo ' <'.($this->crrnd?'':'D:')."getlastmodified ns0:dt=\"dateTime.rfc1123\">"
|
||||
. gmdate("D, d M Y H:i:s ", $prop['val'])
|
||||
. "GMT</D:getlastmodified>\n";
|
||||
. "GMT</".($this->crrnd?'':'D:')."getlastmodified>\n";
|
||||
break;
|
||||
/* @Todo: breaks CalDAV - 2010/03/01 jlehrke
|
||||
case "resourcetype":
|
||||
if (!is_array($prop['val'])) {
|
||||
echo ' <D:resourcetype><D:'.$prop['val']."/></D:resourcetype>\n";
|
||||
} else { // multiple resourcetypes from different namespaces as required by GroupDAV
|
||||
$vals = $extra_ns = '';
|
||||
foreach($prop['val'] as $subprop)
|
||||
{
|
||||
if ($subprop['ns'] && $subprop['ns'] != 'DAV:') {
|
||||
// register property namespace if not known yet
|
||||
if (!isset($ns_hash[$subprop['ns']])) {
|
||||
$ns_name = "ns".(count($ns_hash) + 1);
|
||||
$ns_hash[$subprop['ns']] = $ns_name;
|
||||
} else {
|
||||
$ns_name = $ns_hash[$subprop['ns']];
|
||||
}
|
||||
if (strchr($extra_ns,$extra=' xmlns:'.$ns_name.'="'.$subprop['ns'].'"') === false) {
|
||||
$extra_ns .= $extra;
|
||||
}
|
||||
$ns_name .= ':';
|
||||
} elseif ($subprop['ns'] == 'DAV:') {
|
||||
$ns_name = 'D:';
|
||||
} else {
|
||||
$ns_name = '';
|
||||
}
|
||||
$vals .= "<$ns_name$subprop[val]/>";
|
||||
}
|
||||
echo " <D:resourcetype$extra_ns>$vals</D:resourcetype>\n";
|
||||
//error_log("resourcetype: <D:resourcetype$extra_ns>$vals</D:resourcetype>");
|
||||
}
|
||||
break;
|
||||
*/
|
||||
case "supportedlock":
|
||||
echo " <D:supportedlock>$prop[val]</D:supportedlock>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."supportedlock>$prop[val]</".($this->crrnd?'':'D:')."supportedlock>\n";
|
||||
break;
|
||||
case "lockdiscovery":
|
||||
echo " <D:lockdiscovery>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."lockdiscovery>\n";
|
||||
echo $prop["val"];
|
||||
echo " </D:lockdiscovery>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."lockdiscovery>\n";
|
||||
break;
|
||||
default:
|
||||
echo " <D:$prop[name]>".
|
||||
(is_array($prop['val']) ?
|
||||
$this->_hierarchical_prop_encode($prop['val']) :
|
||||
$this->_prop_encode(htmlspecialchars($prop['val']))).
|
||||
"</D:$prop[name]>\n";
|
||||
if (is_array($prop['val']))
|
||||
{
|
||||
$val = $this->_hierarchical_prop_encode($prop['val']);
|
||||
} elseif (isset($prop['raw'])) {
|
||||
$val = $this->_prop_encode('<![CDATA['.$prop['val'].']]>');
|
||||
} else {
|
||||
$val = $this->_prop_encode(htmlspecialchars($prop['val']));
|
||||
}
|
||||
echo ' <'.($this->crrnd?'':'D:')."$prop[name]>$val".
|
||||
'</'.($this->crrnd?'':'D:')."$prop[name]>\n";
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@ -878,25 +898,47 @@ class HTTP_WebDAV_Server
|
||||
}
|
||||
else
|
||||
{
|
||||
$vals .= '>'.htmlspecialchars($subprop['val'])."</$ns_name$subprop[name]>";
|
||||
$vals .= '>';
|
||||
if (isset($subprop['raw'])) {
|
||||
$vals .= '<![CDATA['.$subprop['val'].']]>';
|
||||
} else {
|
||||
$vals .= htmlspecialchars($subprop['val']);
|
||||
}
|
||||
$vals .= "</$ns_name$subprop[name]>";
|
||||
}
|
||||
}
|
||||
echo " <".$ns_hash[$prop['ns']].":$prop[name]$extra_ns>$vals</".$ns_hash[$prop['ns']].":$prop[name]>\n";
|
||||
echo ' <'.$ns_hash[$prop['ns']].":$prop[name]$extra_ns>$vals</".$ns_hash[$prop['ns']].":$prop[name]>\n";
|
||||
} else {
|
||||
if ($prop['raw'])
|
||||
{
|
||||
$val = '<![CDATA['.$prop['val'].']]>';
|
||||
} else {
|
||||
$val = htmlspecialchars($prop['val']);
|
||||
}
|
||||
$val = $this->_prop_encode($val);
|
||||
// properties from namespaces != "DAV:" or without any namespace
|
||||
if ($prop['ns']) {
|
||||
if ($this->crrnd) {
|
||||
echo " <$prop[name]> xmlns:".$ns_hash[$prop['ns']]."=".'"'.$prop["ns"].'">'
|
||||
. $val . "</$prop[name]>\n";
|
||||
} else {
|
||||
echo " <" . $ns_hash[$prop["ns"]] . ":$prop[name]>"
|
||||
. $val . '</'.$ns_hash[$prop['ns']].":$prop[name]>\n";
|
||||
}
|
||||
} else {
|
||||
echo " <$prop[name] xmlns=\"\">$val</$prop[name]>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->crrnd)
|
||||
{
|
||||
echo " </prop>\n";
|
||||
echo " <status>HTTP/1.1 200 OK</status>\n";
|
||||
echo " </propstat>\n";
|
||||
}
|
||||
else
|
||||
// properties from namespaces != "DAV:" or without any namespace
|
||||
if ($prop["ns"]) {
|
||||
echo " <" . $ns_hash[$prop["ns"]] . ":$prop[name]>"
|
||||
. $this->_prop_encode(htmlspecialchars($prop['val']))
|
||||
. "</" . $ns_hash[$prop["ns"]] . ":$prop[name]>\n";
|
||||
} else {
|
||||
echo " <$prop[name] xmlns=\"\">"
|
||||
. $this->_prop_encode(htmlspecialchars($prop['val']))
|
||||
. "</$prop[name]>\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($propinfo->root['name'] != 'principal-search-property-set')
|
||||
{
|
||||
echo " </D:prop>\n";
|
||||
echo " <D:status>HTTP/1.1 200 OK</D:status>\n";
|
||||
@ -906,12 +948,12 @@ class HTTP_WebDAV_Server
|
||||
|
||||
// now report all properties requested but not found
|
||||
if (isset($file["noprops"])) {
|
||||
echo " <D:propstat>\n";
|
||||
echo " <D:prop>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."propstat>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."prop>\n";
|
||||
|
||||
foreach ($file["noprops"] as &$prop) {
|
||||
if ($prop["ns"] == "DAV:") {
|
||||
echo " <D:$prop[name]/>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."$prop[name]/>\n";
|
||||
} else if ($prop["ns"] == "") {
|
||||
echo " <$prop[name] xmlns=\"\"/>\n";
|
||||
} else {
|
||||
@ -919,23 +961,24 @@ class HTTP_WebDAV_Server
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->crrnd)
|
||||
{
|
||||
echo " </prop>\n";
|
||||
echo " <status>HTTP/1.1 404 Not Found</status>\n";
|
||||
echo " </propstat>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo " </D:prop>\n";
|
||||
echo " <D:status>HTTP/1.1 404 Not Found</D:status>\n";
|
||||
echo " </D:propstat>\n";
|
||||
}
|
||||
|
||||
if ($propinfo->root['name'] != 'principal-search-property-set') echo " </D:response>\n";
|
||||
}
|
||||
|
||||
if ($propinfo->root['name'] == 'principal-search-property-set')
|
||||
{
|
||||
echo "</D:principal-search-property-set>\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
echo "</D:multistatus>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."response>\n";
|
||||
}
|
||||
|
||||
echo '</'.($this->crrnd?'':'D:')."multistatus>\n";
|
||||
}
|
||||
|
||||
|
||||
@ -973,24 +1016,24 @@ class HTTP_WebDAV_Server
|
||||
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
|
||||
echo "<D:multistatus xmlns:D=\"DAV:\">\n";
|
||||
echo " <D:response>\n";
|
||||
echo " <D:href>".$this->_urlencode($this->_mergePathes($this->_SERVER["SCRIPT_NAME"], $this->path))."</D:href>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."response>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."href>".$this->_urlencode($this->_mergePathes($this->_SERVER["SCRIPT_NAME"], $this->path)).'</'.($this->crrnd?'':'D:')."href>\n";
|
||||
|
||||
foreach ($options["props"] as $prop) {
|
||||
echo " <D:propstat>\n";
|
||||
echo " <D:prop><$prop[name] xmlns=\"$prop[ns]\"/></D:prop>\n";
|
||||
echo " <D:status>HTTP/1.1 $prop[status]</D:status>\n";
|
||||
echo " </D:propstat>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."propstat>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."prop><$prop[name] xmlns=\"$prop[ns]\"/></".($this->crrnd?'':'D:')."prop>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."status>HTTP/1.1 $prop[status]</".($this->crrnd?'':'D:')."status>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."propstat>\n";
|
||||
}
|
||||
|
||||
if ($responsedescr) {
|
||||
echo " <D:responsedescription>".
|
||||
echo ' <'.($this->crrnd?'':'D:')."responsedescription>".
|
||||
$this->_prop_encode(htmlspecialchars($responsedescr)).
|
||||
"</D:responsedescription>\n";
|
||||
'</'.($this->crrnd?'':'D:')."responsedescription>\n";
|
||||
}
|
||||
|
||||
echo " </D:response>\n";
|
||||
echo "</D:multistatus>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."response>\n";
|
||||
echo '</'.($this->crrnd?'':'D:')."multistatus>\n";
|
||||
} else {
|
||||
$this->http_status("423 Locked");
|
||||
}
|
||||
@ -1580,17 +1623,17 @@ class HTTP_WebDAV_Server
|
||||
header("Lock-Token: <$options[locktoken]>");
|
||||
echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
echo "<D:prop xmlns:D=\"DAV:\">\n";
|
||||
echo " <D:lockdiscovery>\n";
|
||||
echo " <D:activelock>\n";
|
||||
echo " <D:lockscope><D:$options[scope]/></D:lockscope>\n";
|
||||
echo " <D:locktype><D:$options[type]/></D:locktype>\n";
|
||||
echo " <D:depth>$options[depth]</D:depth>\n";
|
||||
echo " <D:owner>$options[owner]</D:owner>\n";
|
||||
echo " <D:timeout>$timeout</D:timeout>\n";
|
||||
echo " <D:locktoken><D:href>$options[locktoken]</D:href></D:locktoken>\n";
|
||||
echo " </D:activelock>\n";
|
||||
echo " </D:lockdiscovery>\n";
|
||||
echo "</D:prop>\n\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."lockdiscovery>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."activelock>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."lockscope><D:$options[scope]/></".($this->crrnd?'':'D:')."lockscope>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."locktype><D:$options[type]/></".($this->crrnd?'':'D:')."locktype>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."depth>$options[depth]</".($this->crrnd?'':'D:')."depth>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."owner>$options[owner]</".($this->crrnd?'':'D:')."owner>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."timeout>$timeout</".($this->crrnd?'':'D:')."timeout>\n";
|
||||
echo ' <'.($this->crrnd?'':'D:')."locktoken><D:href>$options[locktoken]</D:href></".($this->crrnd?'':'D:')."locktoken>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."activelock>\n";
|
||||
echo ' </'.($this->crrnd?'':'D:')."lockdiscovery>\n";
|
||||
echo '</'.($this->crrnd?'':'D:')."prop>\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@ -1627,7 +1670,7 @@ class HTTP_WebDAV_Server
|
||||
|
||||
// }}}
|
||||
|
||||
// {{{ http_UNLOCK()
|
||||
// {{{ http_ACL()
|
||||
|
||||
/**
|
||||
* ACL method handler
|
||||
@ -1660,9 +1703,9 @@ class HTTP_WebDAV_Server
|
||||
$content .= "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
|
||||
$content .= "<D:error xmlns:D=\"DAV:\"> \n";
|
||||
foreach ($options['errors'] as $violation) {
|
||||
$content .= "<D:$violation/>\n";
|
||||
$content .= '<'.($this->crrnd?'':'D:')."$violation/>\n";
|
||||
}
|
||||
$content .= "</D:error>\n";
|
||||
$content .= '</'.($this->crrnd?'':'D:')."error>\n";
|
||||
}
|
||||
header("Content-length: ".$this->bytes($content));
|
||||
if ($content) echo $options['content'];
|
||||
@ -1765,16 +1808,23 @@ class HTTP_WebDAV_Server
|
||||
* @param string XML namespace (optional)
|
||||
* @param string property name
|
||||
* @param string property value
|
||||
* @praram boolen property raw-flag
|
||||
* @return array property array
|
||||
*/
|
||||
function mkprop()
|
||||
{
|
||||
$args = func_get_args();
|
||||
if (count($args) == 3) {
|
||||
return array("ns" => $args[0],
|
||||
"name" => $args[1],
|
||||
"val" => $args[2]);
|
||||
} else {
|
||||
switch (count($args)) {
|
||||
case 4:
|
||||
return array('ns' => $args[0],
|
||||
'name' => $args[1],
|
||||
'val' => $args[2],
|
||||
'raw' => true);
|
||||
case 3:
|
||||
return array('ns' => $args[0],
|
||||
'name' => $args[1],
|
||||
'val' => $args[2]);
|
||||
default:
|
||||
return array("ns" => "DAV:",
|
||||
"name" => $args[0],
|
||||
"val" => $args[1]);
|
||||
@ -2125,6 +2175,21 @@ class HTTP_WebDAV_Server
|
||||
}
|
||||
|
||||
// genreate response block
|
||||
if ($this->crrnd)
|
||||
{
|
||||
$activelocks.= "
|
||||
<activelock>
|
||||
<lockscope><$lock[scope]/></lockscope>
|
||||
<locktype><$lock[type]/></locktype>
|
||||
<depth>$lock[depth]</depth>
|
||||
<owner>$lock[owner]</owner>
|
||||
<timeout>$timeout</timeout>
|
||||
<locktoken><href>$lock[token]</href></locktoken>
|
||||
</activelock>
|
||||
";
|
||||
}
|
||||
else
|
||||
{
|
||||
$activelocks.= "
|
||||
<D:activelock>
|
||||
<D:lockscope><D:$lock[scope]/></D:lockscope>
|
||||
@ -2136,6 +2201,7 @@ class HTTP_WebDAV_Server
|
||||
</D:activelock>
|
||||
";
|
||||
}
|
||||
}
|
||||
|
||||
// return generated response
|
||||
//error_log(__METHOD__."\n".print_r($activelocks,true));
|
||||
|
@ -186,7 +186,7 @@ class HTTP_WebDAV_Server_Filesystem extends HTTP_WebDAV_Server
|
||||
// type and size (caller already made sure that path exists)
|
||||
if (is_dir($fspath)) {
|
||||
// directory (WebDAV collection)
|
||||
$info["props"][] = $this->mkprop("resourcetype", "collection");
|
||||
$info["props"][] = $this->mkprop("resourcetype", array($this->mkprop('collection', '')));
|
||||
$info["props"][] = $this->mkprop("getcontenttype", "httpd/unix-directory");
|
||||
} else {
|
||||
// plain file (WebDAV resource)
|
||||
|
@ -420,13 +420,13 @@ class infolog_bo
|
||||
/**
|
||||
* Read an infolog entry specified by $info_id
|
||||
*
|
||||
* @param int/array $info_id integer id or array with key 'info_id' of the entry to read
|
||||
* @param int|array $info_id integer id or array with key 'info_id' of the entry to read
|
||||
* @param boolean $run_link_id2from=true should link_id2from run, default yes,
|
||||
* need to be set to false if called from link-title to prevent an infinit recursion
|
||||
* @param string $date_format='ts' date-formats: 'ts'=timestamp, 'server'=timestamp in server-time,
|
||||
* 'array'=array or string with date-format
|
||||
*
|
||||
* @return array/boolean infolog entry, null if not found or false if no permission to read it
|
||||
* @return array|boolean infolog entry, null if not found or false if no permission to read it
|
||||
*/
|
||||
function &read($info_id,$run_link_id2from=true,$date_format='ts')
|
||||
{
|
||||
|
@ -57,7 +57,7 @@ class infolog_groupdav extends groupdav_handler
|
||||
if (!is_array($info)) $info = $this->bo->read($info);
|
||||
$name = $info[self::PATH_ATTRIBUTE];
|
||||
}
|
||||
return '/infolog/'.$name.'.ics';
|
||||
return $name.'.ics';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,6 +73,8 @@ class infolog_groupdav extends groupdav_handler
|
||||
{
|
||||
$starttime = microtime(true);
|
||||
|
||||
$myself = ($user == $GLOBALS['egw_info']['user']['account_id']);
|
||||
|
||||
if ($options['filters'])
|
||||
{
|
||||
|
||||
@ -113,13 +115,16 @@ class infolog_groupdav extends groupdav_handler
|
||||
$filter = array(
|
||||
'info_type' => 'task',
|
||||
);
|
||||
|
||||
//if (!$myself) $filter['info_owner'] = $user;
|
||||
|
||||
if ($id) $filter['info_id'] = $id; // propfind on a single id
|
||||
|
||||
// ToDo: add parameter to only return id & etag
|
||||
if (($tasks =& $this->bo->search($params=array(
|
||||
'order' => 'info_datemodified',
|
||||
'sort' => 'DESC',
|
||||
'filter' => 'own', // filter my: entries user is responsible for,
|
||||
'filter' => ($myself ? 'own' : 'own'), // filter my: entries user is responsible for,
|
||||
// filter own: entries the user own or is responsible for
|
||||
'date_format' => 'server',
|
||||
'col_filter' => $filter,
|
||||
@ -148,7 +153,7 @@ class infolog_groupdav extends groupdav_handler
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('getcontentlength', ''); // expensive to calculate and no CalDAV client uses it
|
||||
}
|
||||
$files['files'][] = array(
|
||||
'path' => self::get_path($task),
|
||||
'path' => $path.self::get_path($task),
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
@ -193,8 +198,11 @@ class infolog_groupdav extends groupdav_handler
|
||||
{
|
||||
return $ok;
|
||||
}
|
||||
|
||||
$handler = $this->_get_handler();
|
||||
if (!($info_id = $handler->importVTODO($options['content'],is_numeric($id) ? $id : -1)))
|
||||
$vTodo = htmlspecialchars_decode($options['content']);
|
||||
|
||||
if (!($info_id = $handler->importVTODO($vTodo,is_numeric($id) ? $id : -1, false, $user)))
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."(,$id) import_vtodo($options[content]) returned false");
|
||||
return '403 Forbidden';
|
||||
@ -202,7 +210,8 @@ class infolog_groupdav extends groupdav_handler
|
||||
header('ETag: '.$this->get_etag($info_id));
|
||||
if (is_null($ok) || $id != $info_id)
|
||||
{
|
||||
header('Location: '.$this->base_uri.self::get_path($info_id));
|
||||
$path = preg_replace('|(.*)/[^/]*|', '\1/', $options['path']);
|
||||
header('Location: '.$path.self::get_path($info_id));
|
||||
return '201 Created';
|
||||
}
|
||||
return true;
|
||||
@ -263,36 +272,38 @@ class infolog_groupdav extends groupdav_handler
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return '"'.$info['info_id'].':'.$info['info_datemodified'].'"';
|
||||
return 'EGw-'.$info['info_id'].':'.$info['info_datemodified'].'-wGE';
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra properties for calendar collections
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @param string $displayname
|
||||
* @param string $base_uri=null base url of handler
|
||||
* @return array
|
||||
*/
|
||||
static function extra_properties(array $props=array(), $base_uri=null)
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// calendar description
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Tasks of') . ' ' .
|
||||
$GLOBALS['egw_info']['user']['account_fullname'],
|
||||
$displayname,
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-description',$displayname);
|
||||
// email of the current user, see caldav-sheduling draft
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set','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'])));
|
||||
// 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' => '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'))))));
|
||||
*/
|
||||
|
||||
return $props;
|
||||
}
|
||||
|
||||
|
@ -380,9 +380,10 @@ class infolog_ical extends infolog_bo
|
||||
* @param string $_vcalData
|
||||
* @param int $_taskID=-1 info_id, default -1 = new entry
|
||||
* @param boolean $merge=false merge data with existing entry
|
||||
* @param int $user=null delegate new task to this account_id, default null
|
||||
* @return int|boolean integer info_id or false on error
|
||||
*/
|
||||
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false)
|
||||
function importVTODO(&$_vcalData, $_taskID=-1, $merge=false, $user=null)
|
||||
{
|
||||
if (!($taskData = $this->vtodotoegw($_vcalData,$_taskID))) return false;
|
||||
|
||||
@ -397,6 +398,11 @@ class infolog_ical extends infolog_bo
|
||||
$taskData['info_datecompleted'] = 0;
|
||||
}
|
||||
|
||||
if (!is_null($user))
|
||||
{
|
||||
$taskData['info_responsible'] = array($user);
|
||||
}
|
||||
|
||||
if ($this->log)
|
||||
{
|
||||
error_log(__FILE__.'['.__LINE__.'] '.__METHOD__."()\n" .
|
||||
|
@ -36,6 +36,10 @@ require_once('HTTP/WebDAV/Server.php');
|
||||
*/
|
||||
class groupdav extends HTTP_WebDAV_Server
|
||||
{
|
||||
/**
|
||||
* DAV namespace
|
||||
*/
|
||||
const DAV = 'DAV:';
|
||||
/**
|
||||
* GroupDAV namespace
|
||||
*/
|
||||
@ -107,6 +111,12 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
* @var string
|
||||
*/
|
||||
var $principalURL;
|
||||
/**
|
||||
* Reference to the accounts class
|
||||
*
|
||||
* @var accounts
|
||||
*/
|
||||
var $accounts;
|
||||
|
||||
|
||||
function __construct()
|
||||
@ -122,6 +132,8 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
case 'davkit': // iCal app in OS X 10.6 created wrong request, if full url given
|
||||
$this->client_require_href_as_url = false;
|
||||
break;
|
||||
case 'cfnetwork':
|
||||
$this->crrnd = true; // Apple Addressbook.app does not cope with namespace redundancy
|
||||
}
|
||||
parent::HTTP_WebDAV_Server();
|
||||
|
||||
@ -136,6 +148,8 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
$this->principalURL = (@$_SERVER["HTTPS"] === "on" ? "https:" : "http:") .
|
||||
'//' . $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] . '/';
|
||||
}
|
||||
$this->principalURL .= 'principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/';
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -162,12 +176,24 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
switch($app)
|
||||
{
|
||||
case 'calendar':
|
||||
case 'infolog':
|
||||
$dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
//$dav[] = 'calendar-schedule';
|
||||
//$dav[] = 'calendar-proxy';
|
||||
//$dav[] = 'calendar-avialibility';
|
||||
//$dav[] = 'calendarserver-private-events';
|
||||
break;
|
||||
case 'addressbook':
|
||||
$dav[] = 'addressbook';
|
||||
$dav[] = 2;
|
||||
$dav[] = 3;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'addressbook-access';
|
||||
break;
|
||||
default:
|
||||
$dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
}
|
||||
// not yet implemented: $dav[] = 'access-control';
|
||||
}
|
||||
@ -179,68 +205,92 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
* @param array return array for file properties
|
||||
* @return bool true on success
|
||||
*/
|
||||
function PROPFIND(&$options, &$files,$method='PROPFIND')
|
||||
function PROPFIND(&$options, &$files, $method='PROPFIND')
|
||||
{
|
||||
if ($this->debug) error_log(__CLASS__."::$method(".array2string($options,true).')');
|
||||
|
||||
|
||||
if (groupdav_handler::get_agent() == 'cfnetwork' && // Apple Addressbook
|
||||
$options['root']['name'] == 'propfind')
|
||||
{
|
||||
foreach ($options['props'] as $props)
|
||||
{
|
||||
if ($props['name'] == 'current-user-privilege-set')
|
||||
{
|
||||
if ($this->debug > 2) error_log(__CLASS__."::$method: current-user-privilege-set not implemented!");
|
||||
return '501 Not Implemented';
|
||||
}
|
||||
}
|
||||
}
|
||||
// parse path in form [/account_lid]/app[/more]
|
||||
if (!self::_parse_path($options['path'],$id,$app,$user,$user_prefix) && $app && !$user)
|
||||
{
|
||||
if ($this->debug > 1) error_log(__CLASS__."::$method: user=$user, app=$app, id=$id: 404 not found!");
|
||||
if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id': 404 not found!");
|
||||
return '404 Not Found';
|
||||
}
|
||||
if ($this->debug > 1) error_log(__CLASS__."::$method: user=$user, app='$app', id=$id");
|
||||
if ($this->debug > 1) error_log(__CLASS__."::$method: user='$user', app='$app', id='$id'");
|
||||
|
||||
$files = array('files' => array());
|
||||
|
||||
if (!$app) // root folder containing apps
|
||||
if ($user)
|
||||
{
|
||||
if (empty($user_prefix))
|
||||
{
|
||||
$displayname = 'EGroupware (Cal|Card|Group)DAV server';
|
||||
$account_lid = $this->accounts->id2name($user);
|
||||
}
|
||||
else
|
||||
{
|
||||
$displayname = $this->translation->convert($GLOBALS['egw_info']['user']['account_fullname'],$this->egw_charset,'utf-8');
|
||||
$account_lid = $GLOBALS['egw_info']['user']['account_lid'];
|
||||
}
|
||||
$account = $this->accounts->read($account_lid);
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
|
||||
$files = array('files' => array());
|
||||
$path = $user_prefix = $this->_slashify($user_prefix);
|
||||
|
||||
if (!$app) // user root folder containing apps
|
||||
{
|
||||
if (empty($user_prefix))
|
||||
{
|
||||
$user_prefix = '/'.$GLOBALS['egw_info']['user']['account_lid'].'/';
|
||||
}
|
||||
if ($options['depth'])
|
||||
{
|
||||
$displayname = 'EGroupware (Cal|Card|Group)DAV server';
|
||||
}
|
||||
// self url
|
||||
$files['files'][] = array(
|
||||
'path' => $user_prefix.'/',
|
||||
'props' => array(
|
||||
$props = array(
|
||||
self::mkprop('displayname',$displayname),
|
||||
self::mkprop('resourcetype','collection'),
|
||||
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.'/calendar/'))),
|
||||
self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.$user_prefix.'calendar/'))),
|
||||
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','MAILTO:'.$GLOBALS['egw_info']['user']['email']),
|
||||
self::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
|
||||
self::mkprop('href','MAILTO:'.$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/'))),
|
||||
),
|
||||
);
|
||||
//$props = self::current_user_privilege_set($props);
|
||||
$files['files'][] = array(
|
||||
'path' => $path,
|
||||
'props' => $props,
|
||||
);
|
||||
if ($options['depth'])
|
||||
{
|
||||
if (empty($user_prefix))
|
||||
if (strlen($path) == 1) // GroupDAV Root
|
||||
{
|
||||
// principals collection
|
||||
$files['files'][] = array(
|
||||
'path' => '/principals/',
|
||||
'props' => array(
|
||||
self::mkprop('displayname',lang('Accounts')),
|
||||
self::mkprop('resourcetype','collection'),
|
||||
self::mkprop('resourcetype',array(self::mkprop('collection',''))),
|
||||
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.'/calendar/'))),
|
||||
//self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||
),
|
||||
);
|
||||
// groups collection
|
||||
$files['files'][] = array(
|
||||
'path' => '/groups/',
|
||||
'props' => array(
|
||||
self::mkprop('displayname',lang('Groups')),
|
||||
self::mkprop('resourcetype','collection'),
|
||||
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.'/calendar/'))),
|
||||
//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.'calendar/'))),
|
||||
self::mkprop(groupdav::CARDDAV,'addressbook-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.'/'))),
|
||||
self::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||
),
|
||||
);
|
||||
}
|
||||
@ -249,7 +299,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
if (!$GLOBALS['egw_info']['user']['apps'][$app]) continue; // no rights for the given app
|
||||
|
||||
$files['files'][] = array(
|
||||
'path' => $user_prefix.'/'.$app.'/',
|
||||
'path' => $path.$app.'/',
|
||||
'props' => $this->_properties($app,false,$user),
|
||||
);
|
||||
}
|
||||
@ -266,9 +316,9 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
if ($method != 'REPORT' && !$id) // no self URL for REPORT requests (only PROPFIND) or propfinds on an id
|
||||
{
|
||||
$files['files'][0] = array(
|
||||
'path' => '/'.$app.'/',
|
||||
'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),
|
||||
'props' => $this->_properties($app,$app=='addressbook'&&strpos($_SERVER['HTTP_USER_AGENT'],'KHTML') !== false,$user),
|
||||
);
|
||||
}
|
||||
if (isset($options['depth']) && !$options['depth'] && !$id)
|
||||
@ -281,7 +331,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
return true; // depth 0 --> show only the self url
|
||||
}
|
||||
return $handler->propfind($options['path'],$options,$files,$user,$id);
|
||||
return $handler->propfind($this->_slashify($options['path']),$options,$files,$user,$id);
|
||||
}
|
||||
return '501 Not Implemented';
|
||||
}
|
||||
@ -296,25 +346,52 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
*/
|
||||
function _properties($app,$no_extra_types=false,$user=null)
|
||||
{
|
||||
if (!$user) $user = $GLOBALS['egw_info']['user']['account_fullname'];
|
||||
$displayname = $this->translation->convert($GLOBALS['egw_info']['user']['account_fullname'],$this->egw_charset,'utf-8');
|
||||
if ($this->debug) error_log(__CLASS__."::$method: user='$user', app='$app'");
|
||||
if ($user)
|
||||
{
|
||||
$account_lid = $this->accounts->id2name($user);
|
||||
}
|
||||
else
|
||||
{
|
||||
$account_lid = $GLOBALS['egw_info']['user']['account_lid'];
|
||||
}
|
||||
$account = $this->accounts->read($account_lid);
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$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('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||
//self::mkprop('principal-collection-set',array(self::mkprop('href',$this->base_uri.'/principals/'))),
|
||||
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']))),
|
||||
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/'),
|
||||
)),
|
||||
);
|
||||
|
||||
switch ($app)
|
||||
{
|
||||
case 'calendar':
|
||||
$props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array(self::mkprop('href',$this->base_uri.'/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.'/infolog/')));
|
||||
$props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.'/'.$account_lid.'/infolog/')));
|
||||
$displayname = $this->translation->convert(lang($app).' '.
|
||||
common::grab_owner_name($user),$this->egw_charset,'utf-8');
|
||||
break;
|
||||
default:
|
||||
$displayname = $this->translation->convert(lang($app).' '.common::grab_owner_name($user),$this->egw_charset,'utf-8');
|
||||
$props[] = self::mkprop(groupdav::CALDAV,'calendar-home-set',array(
|
||||
self::mkprop('href',$this->base_uri.'/'.$account_lid.'/calendar/')));
|
||||
$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.'/')));
|
||||
$props[] = self::mkprop('displayname',$displayname);
|
||||
|
||||
foreach((array)$this->root[$app] as $prop => $values)
|
||||
@ -343,7 +420,9 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
if (method_exists($app.'_groupdav','extra_properties'))
|
||||
{
|
||||
$props = ExecMethod2($app.'_groupdav::extra_properties',$props,$this->base_uri);
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$props = ExecMethod2($app.'_groupdav::extra_properties',$props,$displayname,$this->base_uri);
|
||||
}
|
||||
return $props;
|
||||
}
|
||||
@ -448,8 +527,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
$props = $this->props2array($file['props']);
|
||||
//echo $file['path']; _debug_array($props);
|
||||
$class = $class == 'row_on' ? 'row_off' : 'row_on';
|
||||
$name = $this->_slashify(basename($this->_unslashify($file['path'])));
|
||||
/*
|
||||
|
||||
if (substr($file['path'],-1) == '/')
|
||||
{
|
||||
$name = basename(substr($file['path'],0,-1)).'/';
|
||||
@ -458,7 +536,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
{
|
||||
$name = basename($file['path']);
|
||||
}
|
||||
*/
|
||||
|
||||
echo "\t<tr class='$class'>\n\t\t<td>$n</td>\n\t\t<td>".html::a_href(htmlspecialchars($name),'/groupdav.php'.$file['path'])."</td>\n";
|
||||
echo "\t\t<td>".$props['DAV:getcontentlength']."</td>\n";
|
||||
echo "\t\t<td>".(!empty($props['DAV:getlastmodified']) ? date('Y-m-d H:i:s',$props['DAV:getlastmodified']) : '')."</td>\n";
|
||||
@ -761,7 +839,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
$parts = explode('/', $this->_unslashify($path));
|
||||
|
||||
if ($GLOBALS['egw']->accounts->name2id($parts[0]))
|
||||
if ($this->accounts->name2id($parts[0]))
|
||||
{
|
||||
// /$user/$app/...
|
||||
$user = array_shift($parts);
|
||||
@ -772,7 +850,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
if ($user)
|
||||
{
|
||||
$user_prefix = '/'.$user;
|
||||
$user = $GLOBALS['egw']->accounts->name2id($user,'account_lid',$app != 'addressbook' ? 'u' : null);
|
||||
$user = $this->accounts->name2id($user,'account_lid',$app != 'addressbook' ? 'u' : null);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -785,13 +863,39 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
list($id) = explode('.',$id); // remove evtl. .ics extension
|
||||
}
|
||||
|
||||
if (!($ok = $id && in_array($app,array('addressbook','calendar','infolog','principals','groups')) && $user))
|
||||
{
|
||||
$ok = $id && $user && in_array($app,array('addressbook','calendar','infolog','principals','groups'));
|
||||
if ($this->debug)
|
||||
{
|
||||
error_log(__METHOD__."('$path') returning false: id=$id, app='$app', user=$user");
|
||||
}
|
||||
error_log(__METHOD__."('$path') returning " . ($ok ? 'true' : 'false') . ": id='$id', app='$app', user='$user', user_prefix='$user_prefix'");
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/**
|
||||
* Add the privileges of the current user
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @return array
|
||||
*/
|
||||
static function current_user_privilege_set(array $props=array())
|
||||
{
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('current-user-privilege-set',
|
||||
array(HTTP_WebDAV_Server::mkprop('privilege',
|
||||
array(//HTTP_WebDAV_Server::mkprop('all',''),
|
||||
HTTP_WebDAV_Server::mkprop('read',''),
|
||||
HTTP_WebDAV_Server::mkprop('read-free-busy',''),
|
||||
//HTTP_WebDAV_Server::mkprop('read-current-user-privilege-set',''),
|
||||
HTTP_WebDAV_Server::mkprop('bind',''),
|
||||
HTTP_WebDAV_Server::mkprop('unbind',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-post',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-post-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-respond',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-respond-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-deliver',''),
|
||||
HTTP_WebDAV_Server::mkprop('schedule-deliver-vevent',''),
|
||||
HTTP_WebDAV_Server::mkprop('write',''),
|
||||
HTTP_WebDAV_Server::mkprop('write-properties',''),
|
||||
HTTP_WebDAV_Server::mkprop('write-content',''),
|
||||
))));
|
||||
return $props;
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,12 @@ abstract class groupdav_handler
|
||||
* @var translation
|
||||
*/
|
||||
var $translation;
|
||||
/**
|
||||
* Reference to the accounts class
|
||||
*
|
||||
* @var accounts
|
||||
*/
|
||||
var $accounts;
|
||||
/**
|
||||
* Translates method names into ACL bits
|
||||
*
|
||||
@ -88,7 +94,6 @@ abstract class groupdav_handler
|
||||
*/
|
||||
function __construct($app,$debug=null,$base_uri=null,$principalURL=null)
|
||||
{
|
||||
//error_log(__METHOD__." called");
|
||||
$this->app = $app;
|
||||
if (!is_null($debug)) $this->debug = $debug;
|
||||
$this->base_uri = is_null($base_uri) ? $base_uri : $_SERVER['SCRIPT_NAME'];
|
||||
@ -99,13 +104,15 @@ abstract class groupdav_handler
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->principalURL = $principalURL;
|
||||
$this->principalURL = $principalURL.'principals/users/'.
|
||||
$GLOBALS['egw_info']['user']['account_lid'].'/';
|
||||
}
|
||||
|
||||
$this->agent = self::get_agent();
|
||||
|
||||
$this->translation =& $GLOBALS['egw']->translation;
|
||||
$this->egw_charset = $this->translation->charset();
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,12 +129,13 @@ abstract class groupdav_handler
|
||||
/**
|
||||
* Propfind callback, if interator is used
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $filter
|
||||
* @param array|boolean $start false=return all or array(start,num)
|
||||
* @param int &$total
|
||||
* @return array with "files" array with values for keys path and props
|
||||
*/
|
||||
function &propfind_callback(array $filter,$start,&$total) { }
|
||||
function &propfind_callback($path, array $filter,$start,&$total) { }
|
||||
|
||||
/**
|
||||
* Handle get request for an applications entry
|
||||
@ -178,10 +186,11 @@ abstract class groupdav_handler
|
||||
* Add extra properties for collections
|
||||
*
|
||||
* @param array $props=array() regular props by the groupdav handler
|
||||
* @param string $displayname
|
||||
* @param string $base_uri=null base url of handler
|
||||
* @return array
|
||||
*/
|
||||
static function extra_properties(array $props=array(), $base_uri=null)
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
return $props;
|
||||
}
|
||||
@ -203,7 +212,7 @@ abstract class groupdav_handler
|
||||
// error_log(__METHOD__."(".array2string($entry).") Cant create etag!");
|
||||
return false;
|
||||
}
|
||||
return '"'.$entry['id'].':'.(isset($entry['etag']) ? $entry['etag'] : $entry['modified']).'"';
|
||||
return 'EGw-'.$entry['id'].':'.(isset($entry['etag']) ? $entry['etag'] : $entry['modified']).'-wGE';
|
||||
}
|
||||
|
||||
/**
|
||||
@ -214,7 +223,7 @@ abstract class groupdav_handler
|
||||
*/
|
||||
static function etag2value($etag)
|
||||
{
|
||||
list(,$val) = explode(':',substr($etag,1,-1),2);
|
||||
list(,$val) = explode(':',substr($etag,4,-4),2);
|
||||
|
||||
return $val;
|
||||
}
|
||||
@ -278,6 +287,7 @@ abstract class groupdav_handler
|
||||
*
|
||||
* @static
|
||||
* @param string $app 'calendar', 'addressbook' or 'infolog'
|
||||
* @param int $user=null owner of the collection, default current user
|
||||
* @param int $debug=null debug-level to set
|
||||
* @param string $base_uri=null base url of handler
|
||||
* @param string $principalURL=null pricipal url of handler
|
||||
@ -297,7 +307,9 @@ abstract class groupdav_handler
|
||||
$handler_cache[$app]->$debug = $debug;
|
||||
$handler_cache[$app]->$base_uri = $base_uri;
|
||||
$handler_cache[$app]->$principalURL = $principalURL;
|
||||
if ($debug) error_log(__METHOD__."($app, $base_uri, $principalURL)");
|
||||
|
||||
if ($debug) error_log(__METHOD__."('$app', '$base_uri', '$principalURL')");
|
||||
|
||||
return $handler_cache[$app];
|
||||
}
|
||||
|
||||
@ -317,6 +329,7 @@ abstract class groupdav_handler
|
||||
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
||||
foreach(array(
|
||||
'davkit' => 'davkit', // Apple iCal
|
||||
'cfnetwork' => 'cfnetwork', // Apple Addressbook
|
||||
'bionicmessage.net' => 'funambol', // funambol GroupDAV connector from bionicmessage.net
|
||||
'zideone' => 'zideone', // zideone outlook plugin
|
||||
'lightning' => 'lightning', // Lighting (SOGo connector for addressbook)
|
||||
@ -356,6 +369,13 @@ abstract class groupdav_handler
|
||||
*/
|
||||
class groupdav_propfind_iterator implements Iterator
|
||||
{
|
||||
/**
|
||||
* current path
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* Handler to call for entries
|
||||
*
|
||||
@ -375,8 +395,16 @@ class groupdav_propfind_iterator implements Iterator
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $common_files;
|
||||
|
||||
/**
|
||||
* current chunk
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $files;
|
||||
|
||||
|
||||
/**
|
||||
* Start value for callback
|
||||
*
|
||||
@ -397,6 +425,8 @@ class groupdav_propfind_iterator implements Iterator
|
||||
*/
|
||||
public $debug = false;
|
||||
|
||||
/**
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
@ -404,13 +434,14 @@ class groupdav_propfind_iterator implements Iterator
|
||||
* @param array $filter filter for propfind call
|
||||
* @param array $files=null extra files/responses to return too
|
||||
*/
|
||||
public function __construct(groupdav_handler $handler,array $filter,array &$files=null)
|
||||
public function __construct(groupdav_handler $handler, $path, array $filter,array &$files=null)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."(,".array2string($filter).",)");
|
||||
|
||||
if ($this->debug) error_log(__METHOD__."('$path', ".array2string($filter).",)");
|
||||
$this->path = $path;
|
||||
$this->handler = $handler;
|
||||
$this->filter = $filter;
|
||||
$this->files = $files;
|
||||
$this->common_files = $files;
|
||||
reset($this->files);
|
||||
}
|
||||
|
||||
@ -422,7 +453,6 @@ class groupdav_propfind_iterator implements Iterator
|
||||
public function current()
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."() returning ".array2string(current($this->files)));
|
||||
|
||||
return current($this->files);
|
||||
}
|
||||
|
||||
@ -447,21 +477,20 @@ class groupdav_propfind_iterator implements Iterator
|
||||
if (next($this->files) !== false)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."() returning TRUE");
|
||||
|
||||
return true;
|
||||
}
|
||||
if (is_array($this->files) && count($this->files) < self::CHUNK_SIZE) // less entries then asked --> no further available
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."() returning FALSE (no more entries)");
|
||||
|
||||
return false; // no further entries
|
||||
}
|
||||
// try query further files via propfind callback of handler and store result in $this->files
|
||||
$this->files = $this->handler->propfind_callback($this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
$this->files = $this->handler->propfind_callback($this->path,$this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
$this->start += self::CHUNK_SIZE;
|
||||
reset($this->files);
|
||||
|
||||
if ($this->debug) error_log(__METHOD__."() returning ".array2string(current($this->files) !== false));
|
||||
|
||||
return current($this->files) !== false;
|
||||
}
|
||||
|
||||
@ -474,7 +503,8 @@ class groupdav_propfind_iterator implements Iterator
|
||||
|
||||
// query first set of files via propfind callback of handler and store result in $this->files
|
||||
$this->start = 0;
|
||||
$this->files = $this->handler->propfind_callback($this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
$files = $this->handler->propfind_callback($this->path,$this->filter,array($this->start,self::CHUNK_SIZE));
|
||||
$this->files = $this->common_files + $files;
|
||||
$this->start += self::CHUNK_SIZE;
|
||||
reset($this->files);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* @package api
|
||||
* @subpackage groupdav
|
||||
* @author Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2008 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @copyright (c) 2008-10 by Ralf Becker <RalfBecker-AT-outdoor-training.de>
|
||||
* @version $Id$
|
||||
*/
|
||||
|
||||
@ -16,12 +16,6 @@
|
||||
*/
|
||||
class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
/**
|
||||
* Reference to the accounts class
|
||||
*
|
||||
* @var accounts
|
||||
*/
|
||||
var $accounts;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@ -34,8 +28,6 @@ class groupdav_principals extends groupdav_handler
|
||||
function __construct($app,$debug=null,$base_uri=null,$principalURL=null)
|
||||
{
|
||||
parent::__construct($app,$debug,$base_uri,$principalURL);
|
||||
|
||||
$this->accounts = $GLOBALS['egw']->accounts;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -49,10 +41,41 @@ class groupdav_principals extends groupdav_handler
|
||||
*/
|
||||
function propfind($path,$options,&$files,$user)
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."($path,".array2string($options).",,$user,$id)");
|
||||
list(,$principals,$type,$name,$rest) = explode('/',$path,5);
|
||||
// /principals/users/$name/
|
||||
// /users/$name/calendar-proxy-read/
|
||||
// /users/$name/calendar-proxy-write/
|
||||
// /groups/$name/
|
||||
// /resources/$resource/
|
||||
// /__uids__/$uid/.../
|
||||
|
||||
switch($type)
|
||||
{
|
||||
case 'users':
|
||||
$files['files'] = $this->propfind_users($name,$rest,$options);
|
||||
break;
|
||||
case 'groups':
|
||||
$files['files'] = $this->propfind_groups($name,$rest,$options);
|
||||
break;
|
||||
case 'resources':
|
||||
$files['files'] = $this->propfind_resources($name,$rest,$options);
|
||||
break;
|
||||
case '__uids__':
|
||||
$files['files'] = $this->propfind_uids($name,$rest,$options);
|
||||
break;
|
||||
case '':
|
||||
$files['files'] = $this->propfind_principals($options);
|
||||
break;
|
||||
default:
|
||||
return '404 Not Found';
|
||||
}
|
||||
if (!is_array($files['files']))
|
||||
{
|
||||
return $files['files'];
|
||||
}
|
||||
return true;
|
||||
|
||||
list(,,$id) = explode('/',$path);
|
||||
|
||||
if ($id && !($id = $this->accounts->id2name($id)))
|
||||
{
|
||||
return false;
|
||||
@ -61,39 +84,269 @@ class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
if ($options['root']['name'] == 'principal-search-property-set')
|
||||
{
|
||||
$props = array(HTTP_WebDAV_Server::mkprop('principal-search-property',
|
||||
array(HTTP_WebDAV_Server::mkprop('prop',
|
||||
array(HTTP_WebDAV_Server::mkprop('displayname',$displayname))
|
||||
),
|
||||
HTTP_WebDAV_Server::mkprop('description', 'Full name')))
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
$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('alternate-URI-set',''),
|
||||
HTTP_WebDAV_Server::mkprop('current-user-principal',array(HTTP_WebDAV_Server::mkprop('href',$this->principalURL))),
|
||||
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('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-user-address-set','MAILTO:'.$account['account_email']),
|
||||
//HTTP_WebDAV_Server::mkprop('principal-URL',array(HTTP_WebDAV_Server::mkprop('href',$this->principalURL))),
|
||||
);
|
||||
foreach($this->accounts->memberships($account['account_id']) as $gid => $group)
|
||||
{
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('group-membership',$this->base_uri.'/groups/'.$group);
|
||||
}
|
||||
}
|
||||
$files['files'][] = array(
|
||||
'path' => '/principals/'.$account['account_lid'],
|
||||
'props' => $props,
|
||||
);
|
||||
if ($this->debug > 1) error_log(__METHOD__."($path) path=/principals/".$account['account_lid'].', props='.array2string($props));
|
||||
}
|
||||
return true;
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do propfind in /pricipals/users
|
||||
*
|
||||
* @param string $name name of account or empty
|
||||
* @param string $rest rest of path behind account-name
|
||||
* @param array $options
|
||||
* @return array|string array with files or HTTP error code
|
||||
*/
|
||||
protected function propfind_users($name,$rest,array $options)
|
||||
{
|
||||
//echo "<p>".__METHOD__."($name,$rest,".array2string($options).")</p>\n";
|
||||
if (empty($name))
|
||||
{
|
||||
$files = array();
|
||||
// add /pricipals/users/ entry
|
||||
$files[] = $this->add_collection('/principals/users/',array(
|
||||
HTTP_WebDAV_Server::mkprop('current-user-principal',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/'.$GLOBALS['egw_info']['user']['account_lid'].'/'))),
|
||||
));
|
||||
if ($options['depth'])
|
||||
{
|
||||
// add all users
|
||||
foreach($this->accounts->search(array('type' => 'accounts')) as $account)
|
||||
{
|
||||
$files[] = $this->add_account($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($id = $GLOBALS['egw']->accounts->name2id($name,'account_lid','u')) ||
|
||||
!($account = $GLOBALS['egw']->accounts->read($id)))
|
||||
{
|
||||
return '404 Not Found';
|
||||
}
|
||||
switch((string)$rest)
|
||||
{
|
||||
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');
|
||||
break;
|
||||
case 'calendar-proxy-read':
|
||||
case 'calendar-proxy-write':
|
||||
$files = array();
|
||||
$files[] = $this->add_collection('/principals/users/'.$account['account_lid'].'/'.$rest);
|
||||
// add proxys
|
||||
break;
|
||||
default:
|
||||
return '404 Not Found';
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Do propfind in /pricipals/groups
|
||||
*
|
||||
* @param string $name name of group or empty
|
||||
* @param string $rest rest of path behind account-name
|
||||
* @param array $options
|
||||
* @return array|string array with files or HTTP error code
|
||||
*/
|
||||
protected function propfind_groups($name,$rest,array $options)
|
||||
{
|
||||
//echo "<p>".__METHOD__."($name,$rest,".array2string($options).")</p>\n";
|
||||
if (empty($name))
|
||||
{
|
||||
$files = array();
|
||||
// add /pricipals/users/ entry
|
||||
$files[] = $this->add_collection('/principals/groups/',array(
|
||||
HTTP_WebDAV_Server::mkprop('current-user-principal',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/'.$GLOBALS['egw_info']['user']['account_lid'].'/'))),
|
||||
));
|
||||
if ($options['depth'])
|
||||
{
|
||||
// add all users
|
||||
foreach($this->accounts->search(array('type' => 'groups')) as $account)
|
||||
{
|
||||
$files[] = $this->add_group($account);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!($id = $GLOBALS['egw']->accounts->name2id($name,'account_lid','g')) ||
|
||||
!($account = $GLOBALS['egw']->accounts->read($id)))
|
||||
{
|
||||
return '404 Not Found';
|
||||
}
|
||||
switch((string)$rest)
|
||||
{
|
||||
case '':
|
||||
$files[] = $this->add_group($account);
|
||||
$files[] = $this->add_collection('/principals/groups/'.$account['account_lid'].'/calendar-proxy-read');
|
||||
$files[] = $this->add_collection('/principals/groups/'.$account['account_lid'].'/calendar-proxy-write');
|
||||
break;
|
||||
case 'calendar-proxy-read':
|
||||
case 'calendar-proxy-write':
|
||||
$files = array();
|
||||
$files[] = $this->add_collection('/principals/groups/'.$account['account_lid'].'/'.$rest);
|
||||
// add proxys
|
||||
break;
|
||||
default:
|
||||
return '404 Not Found';
|
||||
}
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add collection of a single account to a collection
|
||||
*
|
||||
* @param array $account
|
||||
* @return array with values for keys 'path' and 'props'
|
||||
*/
|
||||
protected function add_account(array $account)
|
||||
{
|
||||
//echo "<p>".__METHOD__."(".array2string($account).")</p>\n";
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$memberships = array();
|
||||
foreach($this->accounts->memberships($account['account_id']) as $gid => $group)
|
||||
{
|
||||
if ($group)
|
||||
{
|
||||
$memberships[] = HTTP_WebDAV_Server::mkprop('href',
|
||||
$this->base_uri.'/principals/groups/'.$group);
|
||||
}
|
||||
}
|
||||
$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('alternate-URI-set',array(
|
||||
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']))),
|
||||
HTTP_WebDAV_Server::mkprop('principal-URL',$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(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(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/'))),
|
||||
HTTP_WebDAV_Server::mkprop('group-member-ship', $memberships),
|
||||
HTTP_WebDAV_Server::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||
);
|
||||
if ($this->debug > 1) error_log(__METHOD__."($path) path=/principals/users/".$account['account_lid'].', props='.array2string($props));
|
||||
return array(
|
||||
'path' => '/principals/users/'.$account['account_lid'].'/',
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add collection of a single group to a collection
|
||||
*
|
||||
* @param array $account
|
||||
* @return array with values for keys 'path' and 'props'
|
||||
*/
|
||||
protected function add_group(array $account)
|
||||
{
|
||||
$displayname = $GLOBALS['egw']->translation->convert(lang('Group').' '.$account['account_lid'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$members = array();
|
||||
foreach($this->accounts->members($account['account_id']) as $gid => $user)
|
||||
{
|
||||
if ($user)
|
||||
{
|
||||
$members[] = HTTP_WebDAV_Server::mkprop('href',
|
||||
$this->base_uri.'/principals/users/'.$user);
|
||||
}
|
||||
}
|
||||
$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('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(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),
|
||||
//HTTP_WebDAV_Server::mkprop('principal-URL',array(self::mkprop('href',$this->principalURL))),
|
||||
);
|
||||
$files['files'][] = array(
|
||||
'path' => '/principals/groups/'.$account['account_lid'].'/',
|
||||
'props' => $props,
|
||||
);
|
||||
if ($this->debug > 1) error_log(__METHOD__."($path) path=/principals/groups/".$account['account_lid'].', props='.array2string($props));
|
||||
return array(
|
||||
'path' => '/principals/groups/'.$account['account_lid'].'/',
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collection
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $props=array() extra properties 'resourcetype' is added anyway
|
||||
* @return array
|
||||
*/
|
||||
protected function add_collection($path,$props=array())
|
||||
{
|
||||
//echo "<p>".__METHOD__."($path,".array($props).")</p>\n";
|
||||
$props[] = HTTP_WebDAV_Server::mkprop('resourcetype',array(
|
||||
HTTP_WebDAV_Server::mkprop('collection',''),
|
||||
HTTP_WebDAV_Server::mkprop('resourcetype','principal'),
|
||||
));
|
||||
return array(
|
||||
'path' => $path,
|
||||
'props' => $props,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do propfind of /pricipals
|
||||
*
|
||||
* @param string $name name of group or empty
|
||||
* @param string $rest name of rest of path behind group-name
|
||||
* @param array $options
|
||||
* @return array|string array with files or HTTP error code
|
||||
*/
|
||||
protected function propfind_principals(array $options)
|
||||
{
|
||||
//echo "<p>".__METHOD__."(".array($options).")</p>\n";
|
||||
$files = array();
|
||||
$files[] = $this->add_collection('/principals/',array(
|
||||
HTTP_WebDAV_Server::mkprop('current-user-principal',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/'))),
|
||||
));
|
||||
|
||||
if ($options['depth'])
|
||||
{
|
||||
$options['depth'] = 0;
|
||||
$files = array_merge($files,$this->propfind_users('','',$options));
|
||||
$files = array_merge($files,$this->propfind_groups('','',$options));
|
||||
//$files = array_merge($this->propfind_resources('','',$options));
|
||||
//$files = array_merge($this->propfind_uids('','',$options));
|
||||
}
|
||||
return $files;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,12 +362,12 @@ class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
return $account;
|
||||
}
|
||||
$displayname = $GLOBALS['egw']->translation->convert(
|
||||
$name = $GLOBALS['egw']->translation->convert(
|
||||
trim($account['account_firstname'].' '.$account['account_lastname']),
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$options['data'] = 'Principal: '.$account['account_lid'].
|
||||
"\nURL: ".$this->base_uri.$options['path'].
|
||||
"\nName: ".$displayname.
|
||||
"\nName: ".$name.
|
||||
"\nEmail: ".$account['account_email'].
|
||||
"\nMemberships: ".implode(', ',$this->accounts->memberships($id))."\n";
|
||||
$options['mimetype'] = 'text/plain; charset=utf-8';
|
||||
@ -156,7 +409,8 @@ class groupdav_principals extends groupdav_handler
|
||||
*/
|
||||
function read($id)
|
||||
{
|
||||
return $this->accounts->read($id);
|
||||
return false;
|
||||
//return $this->accounts->read($id);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -191,6 +445,6 @@ class groupdav_principals extends groupdav_handler
|
||||
{
|
||||
$account = $this->read($account);
|
||||
}
|
||||
return '"'.$account['account_id'].':'.md5(serialize($account)).'"';
|
||||
return 'EGw-'.$account['account_id'].':'.md5(serialize($account)).'-wGE';
|
||||
}
|
||||
}
|
@ -263,7 +263,8 @@ class vfs_webdav_server extends HTTP_WebDAV_Server_Filesystem
|
||||
// type and size (caller already made sure that path exists)
|
||||
if (is_dir($fspath)) {
|
||||
// directory (WebDAV collection)
|
||||
$info['props'][] = HTTP_WebDAV_Server::mkprop ('resourcetype', 'collection');
|
||||
$info['props'][] = HTTP_WebDAV_Server::mkprop ('resourcetype', array(
|
||||
HTTP_WebDAV_Server::mkprop('collection', '')));
|
||||
$info['props'][] = HTTP_WebDAV_Server::mkprop ('getcontenttype', 'httpd/unix-directory');
|
||||
} else {
|
||||
// plain file (WebDAV resource)
|
||||
|
Loading…
Reference in New Issue
Block a user