mirror of
https://github.com/EGroupware/egroupware.git
synced 2024-12-26 16:48:49 +01:00
first step for CalDAV scheduling
- principal reports scheduling-inbox-URL /<username>/inbox/ and scheduling-outbox-URL /<username>/outbox/ - outbox collection contains no events - outbox correctly answers POST for freebusy information - outbox respons to all other POST with "204 No Content", ignore client request to deliver invitations - inbox collection contains events of unknown status (PARTSTAT=NEEDS-ACTION) - inbox responds to DELETE with "200 Ok" --> iCal under OS X now shows freebusy times :-) (had to add "write-content" privilege for calendar collections user has edit rights for, to allow adding events)
This commit is contained in:
parent
7297e02f39
commit
c26fcffda7
@ -142,6 +142,16 @@ class calendar_groupdav extends groupdav_handler
|
||||
{
|
||||
$filter['filter'] = 'owner';
|
||||
}
|
||||
// scheduling inbox, shows only not yet accepted or rejected events
|
||||
elseif (substr($path,-7) == '/inbox/')
|
||||
{
|
||||
$filter['filter'] = 'unknown';
|
||||
}
|
||||
// ToDo: not sure what scheduling outbox is supposed to show, leave it empty for now
|
||||
elseif (substr($path,-8) == '/outbox/')
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$filter['filter'] = 'default'; // not rejected
|
||||
@ -318,6 +328,7 @@ class calendar_groupdav extends groupdav_handler
|
||||
$cal_filters['end'] = $cal_end;
|
||||
}
|
||||
}
|
||||
|
||||
// multiget or propfind on a given id
|
||||
//error_log(__FILE__ . __METHOD__ . "multiget of propfind:");
|
||||
if ($options['root']['name'] == 'calendar-multiget' || $id)
|
||||
@ -600,30 +611,51 @@ class calendar_groupdav extends groupdav_handler
|
||||
{
|
||||
if ($this->debug) error_log(__METHOD__."($id, $user)".print_r($options,true));
|
||||
|
||||
if (preg_match('/^METHOD:(PUBLISH|REQUEST)(\r\n|\r|\n)(.*)^BEGIN:VEVENT/ism', $options['content']))
|
||||
$vCalendar = htmlspecialchars_decode($options['content']);
|
||||
$charset = null;
|
||||
if (!empty($options['content_type']))
|
||||
{
|
||||
$handler = $this->_get_handler();
|
||||
$vCalendar = htmlspecialchars_decode($options['content']);
|
||||
$charset = null;
|
||||
if (!empty($options['content_type']))
|
||||
$content_type = explode(';', $options['content_type']);
|
||||
if (count($content_type) > 1)
|
||||
{
|
||||
$content_type = explode(';', $options['content_type']);
|
||||
if (count($content_type) > 1)
|
||||
array_shift($content_type);
|
||||
foreach ($content_type as $attribute)
|
||||
{
|
||||
array_shift($content_type);
|
||||
foreach ($content_type as $attribute)
|
||||
trim($attribute);
|
||||
list($key, $value) = explode('=', $attribute);
|
||||
switch (strtolower($key))
|
||||
{
|
||||
trim($attribute);
|
||||
list($key, $value) = explode('=', $attribute);
|
||||
switch (strtolower($key))
|
||||
{
|
||||
case 'charset':
|
||||
$charset = strtoupper(substr($value,1,-1));
|
||||
}
|
||||
case 'charset':
|
||||
$charset = strtoupper(substr($value,1,-1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (substr($options['path'],-8) == '/outbox/')
|
||||
{
|
||||
if (preg_match('/^METHOD:REQUEST(\r\n|\r|\n)(.*)^BEGIN:VFREEBUSY/ism', $vCalendar))
|
||||
{
|
||||
if ($user != $GLOBALS['egw_info']['user']['account_id'])
|
||||
{
|
||||
error_log(__METHOD__."() freebusy request only allowed to own outbox!");
|
||||
return '403 Forbidden';
|
||||
}
|
||||
// do freebusy request
|
||||
return $this->outbox_freebusy_request($vCalendar, $charset, $user, $options);
|
||||
}
|
||||
else
|
||||
{
|
||||
// POST to deliver an invitation, containing http headers:
|
||||
// Originator: mailto:<organizer-email>
|
||||
// Recipient: mailto:<attendee-email>
|
||||
// --> currently we simply ignore these posts, as EGroupware does it's own notifications based on user preferences
|
||||
return '204 No Content';
|
||||
}
|
||||
}
|
||||
if (preg_match('/^METHOD:(PUBLISH|REQUEST)(\r\n|\r|\n)(.*)^BEGIN:VEVENT/ism', $options['content']))
|
||||
{
|
||||
$handler = $this->_get_handler();
|
||||
if (($foundEvents = $handler->search($vCalendar, null, false, $charset)))
|
||||
{
|
||||
$eventId = array_shift($foundEvents);
|
||||
@ -640,6 +672,85 @@ class calendar_groupdav extends groupdav_handler
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle outbox freebusy request
|
||||
*
|
||||
* @param string $ical
|
||||
* @param string $charset of ical
|
||||
* @param int $user account_id of owner
|
||||
* @param array &$options
|
||||
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
|
||||
*/
|
||||
protected function outbox_freebusy_request($ical, $charset, $user, array &$options)
|
||||
{
|
||||
include_once EGW_SERVER_ROOT.'/phpgwapi/inc/horde/lib/core.php';
|
||||
$vcal = new Horde_iCalendar();
|
||||
if (!$vcal->parsevCalendar($ical, 'VCALENDAR', $charset))
|
||||
{
|
||||
return '400 Bad request';
|
||||
}
|
||||
$version = $vcal->getAttribute('VERSION');
|
||||
|
||||
//echo $ical."\n";
|
||||
|
||||
$handler = $this->_get_handler();
|
||||
$handler->setSupportedFields('groupdav');
|
||||
$handler->calendarOwner = $handler->user = 0; // to NOT default owner/organizer to something
|
||||
if (!($component = $vcal->getComponent(0)) ||
|
||||
!($event = $handler->vevent2egw($component, $version, $handler->supportedFields, $this->groupdav->current_user_principal, 'Horde_iCalendar_vfreebusy')))
|
||||
{
|
||||
return '400 Bad request';
|
||||
}
|
||||
if ($event['owner'] != $user)
|
||||
{
|
||||
error_log(__METHOD__."('$ical',,$user) ORGANIZER is NOT principal!");
|
||||
return '403 Forbidden';
|
||||
}
|
||||
//print_r($event);
|
||||
$organizer = $component->getAttribute('ORGANIZER');
|
||||
$attendees = $component->getAttribute('ATTENDEE');
|
||||
// X-CALENDARSERVER-MASK-UID specifies to exclude given event from busy-time
|
||||
$mask_uid = $component->getAttribte('X-CALENDARSERVER-MASK-UID');
|
||||
|
||||
header('Content-type: text/xml; charset=UTF-8');
|
||||
|
||||
$xml = new XMLWriter;
|
||||
$xml->openMemory();
|
||||
$xml->startDocument('1.0', 'UTF-8');
|
||||
$xml->startElementNs('C', 'schedule-response', groupdav::CALDAV);
|
||||
|
||||
foreach($event['participants'] as $uid => $status)
|
||||
{
|
||||
$xml->startElementNs('C', 'response', null);
|
||||
|
||||
$xml->startElementNs('C', 'recipient', null);
|
||||
$xml->writeElementNs('D', 'href', 'DAV:', $attendee=array_shift($attendees));
|
||||
$xml->endElement(); // recipient
|
||||
|
||||
if (is_numeric($uid))
|
||||
{
|
||||
$xml->writeElementNs('C', 'request-status', null, '2.0;Success');
|
||||
$xml->writeElementNs('C', 'calendar-data', null, str_replace("\r", '', // CalDAV rfc example has no encoded "\r"
|
||||
$handler->freebusy($uid, $event['end'], true, 'utf-8', $event['start'], 'REPLY', array(
|
||||
'UID' => $event['uid'],
|
||||
'ORGANIZER' => $organizer,
|
||||
'ATTENDEE' => $attendee,
|
||||
'X-CALENDARSERVER-MASK-UID' => $mask_uid,
|
||||
))));
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml->writeElementNs('C', 'request-status', null, '3.7;Invalid calendar user');
|
||||
}
|
||||
$xml->endElement(); // response
|
||||
}
|
||||
$xml->endElement(); // schedule-response
|
||||
$xml->endDocument();
|
||||
echo $xml->outputMemory();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix event series with exceptions, called by calendar_ical::importVCal():
|
||||
* a) only series master = first event got cal_id from URL
|
||||
@ -725,6 +836,10 @@ class calendar_groupdav extends groupdav_handler
|
||||
*/
|
||||
function delete(&$options,$id)
|
||||
{
|
||||
if (strpos($options['path'], '/inbox/') !== false)
|
||||
{
|
||||
return true; // simply ignore DELETE in inbox for now
|
||||
}
|
||||
$return_no_access = true; // to allow to check if current use is a participant and reject the event for him
|
||||
if (!is_array($event = $this->_common_get_put_delete('DELETE',$options,$id,$return_no_access)) || !$return_no_access)
|
||||
{
|
||||
@ -815,35 +930,6 @@ class calendar_groupdav extends groupdav_handler
|
||||
return $this->bo->check_perms($acl,$event,0,'server');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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,'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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add extra properties for calendar collections
|
||||
*
|
||||
@ -855,45 +941,26 @@ class calendar_groupdav extends groupdav_handler
|
||||
static function extra_properties(array $props=array(), $displayname, $base_uri=null)
|
||||
{
|
||||
// calendar description
|
||||
$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(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-default-calendar-URL',
|
||||
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(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'notifications-URL',
|
||||
array(HTTP_WebDAV_Server::mkprop(groupdav::DAV,'href',$base_uri.'/calendar/')));
|
||||
*/
|
||||
$props['calendar-description'] = 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',array(
|
||||
$props['calendar-user-address-set'] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
|
||||
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email']),
|
||||
HTTP_WebDAV_Server::mkprop('href',$base_uri.'/principals/users/'.$GLOBALS['egw_info']['user']['account_lid'].'/'),
|
||||
HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.$GLOBALS['egw_info']['user']['account_lid'])));
|
||||
//$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
|
||||
// HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$GLOBALS['egw_info']['user']['email'])));
|
||||
// supported components, currently only VEVENT
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-component-set',array(
|
||||
$props['supported-calendar-component-set'] = 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(
|
||||
$props['supported-report-set'] = HTTP_WebDAV_Server::mkprop('supported-report-set',array(
|
||||
HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||
HTTP_WebDAV_Server::mkprop('report',array(
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget','')))))));
|
||||
$props[] = HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'supported-calendar-data',array(
|
||||
$props['supported-calendar-data'] = 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::CALENDARSERVER,'publish-url',array(
|
||||
// HTTP_WebDAV_Server::mkprop('href',$base_uri.'/calendar/')));
|
||||
|
||||
//$props = self::current_user_privilege_set($props);
|
||||
return $props;
|
||||
}
|
||||
|
||||
|
@ -966,12 +966,12 @@ class calendar_ical extends calendar_boupdate
|
||||
{
|
||||
foreach (is_array($value) && $parameters[$key]['VALUE']!='DATE' ? $value : array($value) as $valueID => $valueData)
|
||||
{
|
||||
$valueData = $GLOBALS['egw']->translation->convert($valueData,$GLOBALS['egw']->translation->charset(),$charset);
|
||||
$paramData = (array) $GLOBALS['egw']->translation->convert(is_array($value) ?
|
||||
$valueData = translation::convert($valueData,translation::charset(),$charset);
|
||||
$paramData = (array) translation::convert(is_array($value) ?
|
||||
$parameters[$key][$valueID] : $parameters[$key],
|
||||
$GLOBALS['egw']->translation->charset(),$charset);
|
||||
$valuesData = (array) $GLOBALS['egw']->translation->convert($values[$key],
|
||||
$GLOBALS['egw']->translation->charset(),$charset);
|
||||
translation::charset(),$charset);
|
||||
$valuesData = (array) translation::convert($values[$key],
|
||||
translation::charset(),$charset);
|
||||
$content = $valueData . implode(';', $valuesData);
|
||||
|
||||
if (preg_match('/[^\x20-\x7F]/', $content) ||
|
||||
@ -2233,12 +2233,13 @@ class calendar_ical extends calendar_boupdate
|
||||
* @param string $version vCal version (1.0/2.0)
|
||||
* @param array $supportedFields supported fields of the device
|
||||
* @param string $principalURL='' Used for CalDAV imports
|
||||
* @param string $check_component='Horde_iCalendar_vevent'
|
||||
*
|
||||
* @return array|boolean event on success, false on failure
|
||||
*/
|
||||
function vevent2egw(&$component, $version, $supportedFields, $principalURL='')
|
||||
function vevent2egw(&$component, $version, $supportedFields, $principalURL='', $check_component='Horde_iCalendar_vevent')
|
||||
{
|
||||
if (!is_a($component, 'Horde_iCalendar_vevent'))
|
||||
if ($check_component && !is_a($component, $check_component))
|
||||
{
|
||||
if ($this->log)
|
||||
{
|
||||
@ -3034,52 +3035,47 @@ class calendar_ical extends calendar_boupdate
|
||||
* @param mixed $end=null end-date, default now+1 month
|
||||
* @param boolean $utc=true if false, use severtime for dates
|
||||
* @param string $charset='UTF-8' encoding of the vcalendar, default UTF-8
|
||||
* @return string
|
||||
* @param mixed $start=null default now
|
||||
* @param string $method='PUBLISH' or eg. 'REPLY'
|
||||
* @param array $extra=null extra attributes to add
|
||||
* X-CALENDARSERVER-MASK-UID can be used to not include an event specified by this uid as busy
|
||||
*/
|
||||
function freebusy($user,$end=null,$utc=true, $charset='UTF-8')
|
||||
function freebusy($user,$end=null,$utc=true, $charset='UTF-8', $start=null, $method='PUBLISH', array $extra=null)
|
||||
{
|
||||
if (!$end) $end = $this->now_su + 100*DAY_s; // default next 100 days
|
||||
if (!$start) $start = time(); // default now
|
||||
if (!$end) $end = time() + 100*DAY_s; // default next 100 days
|
||||
|
||||
$vcal = new Horde_iCalendar;
|
||||
$vcal->setAttribute('PRODID','-//eGroupWare//NONSGML eGroupWare Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'.
|
||||
$vcal->setAttribute('PRODID','-//EGroupware//NONSGML EGroupware Calendar '.$GLOBALS['egw_info']['apps']['calendar']['version'].'//'.
|
||||
strtoupper($GLOBALS['egw_info']['user']['preferences']['common']['lang']));
|
||||
$vcal->setAttribute('VERSION','2.0');
|
||||
$vcal->setAttribute('METHOD',$method);
|
||||
|
||||
$vfreebusy = Horde_iCalendar::newComponent('VFREEBUSY',$vcal);
|
||||
$parameters = array(
|
||||
'ORGANIZER' => $GLOBALS['egw']->translation->convert(
|
||||
$GLOBALS['egw']->accounts->id2name($user,'account_firstname').' '.
|
||||
$GLOBALS['egw']->accounts->id2name($user,'account_lastname'),
|
||||
$GLOBALS['egw']->translation->charset(),$charset),
|
||||
if ($uid) $vfreebusy->setAttribute('UID', $uid);
|
||||
|
||||
$attributes = array(
|
||||
'DTSTAMP' => time(),
|
||||
'DTSTART' => $this->date2ts($start,true), // true = server-time
|
||||
'DTEND' => $this->date2ts($end,true), // true = server-time
|
||||
);
|
||||
if ($utc)
|
||||
if (!$utc)
|
||||
{
|
||||
foreach (array(
|
||||
'URL' => $this->freebusy_url($user),
|
||||
'DTSTART' => $this->date2ts($this->now_su,true), // true = server-time
|
||||
'DTEND' => $this->date2ts($end,true), // true = server-time
|
||||
'ORGANIZER' => $GLOBALS['egw']->accounts->id2name($user,'account_email'),
|
||||
'DTSTAMP' => time(),
|
||||
) as $attr => $value)
|
||||
foreach ($attributes as $attr => $value)
|
||||
{
|
||||
$vfreebusy->setAttribute($attr, $value);
|
||||
$attributes[$attr] = date('Ymd\THis', $value);
|
||||
}
|
||||
}
|
||||
else
|
||||
if (is_null($extra)) $extra = array(
|
||||
'URL' => $this->freebusy_url($user),
|
||||
'ORGANIZER' => 'mailto:'.$GLOBALS['egw']->accounts->id2name($user,'account_email'),
|
||||
);
|
||||
foreach($attributes+$extra as $attr => $value)
|
||||
{
|
||||
foreach (array(
|
||||
'URL' => $this->freebusy_url($user),
|
||||
'DTSTART' => date('Ymd\THis',$this->date2ts($this->now_su,true)), // true = server-time
|
||||
'DTEND' => date('Ymd\THis',$this->date2ts($end,true)), // true = server-time
|
||||
'ORGANIZER' => $GLOBALS['egw']->accounts->id2name($user,'account_email'),
|
||||
'DTSTAMP' => date('Ymd\THis',time()),
|
||||
) as $attr => $value)
|
||||
{
|
||||
$vfreebusy->setAttribute($attr, $value);
|
||||
}
|
||||
$vfreebusy->setAttribute($attr, $value);
|
||||
}
|
||||
$fbdata = parent::search(array(
|
||||
'start' => $this->now_su,
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'users' => $user,
|
||||
'date_format' => 'server',
|
||||
@ -3090,6 +3086,7 @@ class calendar_ical extends calendar_boupdate
|
||||
foreach ($fbdata as $event)
|
||||
{
|
||||
if ($event['non_blocking']) continue;
|
||||
if ($event['uid'] === $extra['X-CALENDARSERVER-MASK-UID']) continue;
|
||||
|
||||
if ($utc)
|
||||
{
|
||||
|
@ -92,16 +92,16 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
'resourcetype' => array(self::GROUPDAV => 'vevent-collection', self::CALDAV => 'calendar'),
|
||||
'component-set' => array(self::GROUPDAV => 'VEVENT'),
|
||||
),
|
||||
/*'inbox' => array(
|
||||
'inbox' => array(
|
||||
'resourcetype' => array(self::CALDAV => 'schedule-inbox'),
|
||||
'app' => 'calendar',
|
||||
'no-root' => true,
|
||||
'user-only' => true, // display just in user home
|
||||
),
|
||||
'outbox' => array(
|
||||
'resourcetype' => array(self::CALDAV => 'schedule-outbox'),
|
||||
'app' => 'calendar',
|
||||
'no-root' => true,
|
||||
),*/
|
||||
'user-only' => true, // display just in user home
|
||||
),
|
||||
'infolog' => array(
|
||||
'resourcetype' => array(self::GROUPDAV => 'vtodo-collection', self::CALDAV => 'calendar'),
|
||||
'component-set' => array(self::GROUPDAV => 'VTODO'),
|
||||
@ -265,7 +265,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
//$dav[] = 'calendar-auto-schedule';
|
||||
$dav[] = 'calendar-auto-schedule';
|
||||
$dav[] = 'calendar-proxy';
|
||||
//$dav[] = 'calendar-availibility';
|
||||
//$dav[] = 'calendarserver-private-events';
|
||||
@ -546,7 +546,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
foreach($this->root as $app => $data)
|
||||
{
|
||||
if (!$GLOBALS['egw_info']['user']['apps'][$data['app'] ? $data['app'] : $app]) continue; // no rights for the given app
|
||||
if ($path == '/' && !empty($data['no-root'])) continue;
|
||||
if (!empty($data['user-only']) && ($path == '/' || $user < 0)) continue;
|
||||
|
||||
$files['files'][] = $this->add_app($app,false,$user,$path);
|
||||
}
|
||||
@ -593,8 +593,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
|
||||
$account = $this->accounts->read($account_lid);
|
||||
$displayname = $GLOBALS['egw']->translation->convert($account['account_fullname'],
|
||||
$GLOBALS['egw']->translation->charset(),'utf-8');
|
||||
$displayname = translation::convert($account['account_fullname'],translation::charset(),'utf-8');
|
||||
|
||||
if ($user < 0)
|
||||
{
|
||||
@ -655,7 +654,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
break;
|
||||
case 'app':
|
||||
case 'no-root':
|
||||
case 'user-only':
|
||||
break; // no props, already handled
|
||||
default:
|
||||
if (is_array($values))
|
||||
@ -888,31 +887,30 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
$arr = array();
|
||||
foreach($props as $prop)
|
||||
{
|
||||
$ns_hash = array('DAV:' => 'D');
|
||||
switch($prop['ns'])
|
||||
{
|
||||
case 'DAV:';
|
||||
$ns = 'DAV';
|
||||
break;
|
||||
case self::CALDAV:
|
||||
$ns = 'CalDAV';
|
||||
$ns = $ns_hash[$prop['ns']] = 'CalDAV';
|
||||
break;
|
||||
case self::CARDDAV:
|
||||
$ns = 'CardDAV';
|
||||
$ns = $ns_hash[$prop['ns']] = 'CardDAV';
|
||||
break;
|
||||
case self::GROUPDAV:
|
||||
$ns = 'GroupDAV';
|
||||
$ns = $ns_hash[$prop['ns']] = 'GroupDAV';
|
||||
break;
|
||||
default:
|
||||
$ns = $prop['ns'];
|
||||
}
|
||||
$ns_defs = '';
|
||||
$ns_hash = array($prop['ns'] => $ns, 'DAV:' => 'D');
|
||||
if (is_array($prop['val']))
|
||||
{
|
||||
$prop['val'] = $this->_hierarchical_prop_encode($prop['val'], $prop['ns'], $ns_defs, $ns_hash);
|
||||
$prop['val'] = $this->_hierarchical_prop_encode($prop['val'], $prop['ns'], $ns_defs='', $ns_hash);
|
||||
// hack to show real namespaces instead of not (visibly) defined shortcuts
|
||||
unset($ns_hash['DAV:']);
|
||||
$value = strtr($this->prop_value($prop['val']),array_flip($ns_hash));
|
||||
$value = strtr($v=$this->prop_value($prop['val']),array_flip($ns_hash));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -412,6 +412,10 @@ abstract class groupdav_handler
|
||||
$priviledes[] = 'bind'; // PUT for new resources
|
||||
}
|
||||
if (!$user || $grants[$user] & EGW_ACL_EDIT)
|
||||
{
|
||||
$priviledes[] = 'write-content'; // otherwise iOS calendar does not allow to add events
|
||||
}
|
||||
if (!$user || $grants[$user] & EGW_ACL_DELETE)
|
||||
{
|
||||
$priviledes[] = 'unbind'; // DELETE
|
||||
}
|
||||
|
@ -368,24 +368,32 @@ class groupdav_principals extends groupdav_handler
|
||||
return $this->add_principal('users/'.$account['account_lid'], array(
|
||||
'getetag' => $this->get_etag($account),
|
||||
'displayname' => $displayname,
|
||||
'alternate-URI-set' => array(
|
||||
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email'])),
|
||||
// CalDAV
|
||||
'calendar-home-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-home-set',$calendars),
|
||||
// CalDAV scheduling
|
||||
'schedule-outbox-URL' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-outbox-URL',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/outbox/'))),
|
||||
'schedule-inbox-URL' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-inbox-URL',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/'.$account['account_lid'].'/inbox/'))),
|
||||
'calendar-user-address-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-address-set',array(
|
||||
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email']),
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/principals/users/'.$account['account_lid'].'/'),
|
||||
HTTP_WebDAV_Server::mkprop('href','urn:uuid:'.$account['account_lid']))),
|
||||
'schedule-outbox-URL' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'schedule-outbox-URL',array(
|
||||
HTTP_WebDAV_Server::mkprop('href',$this->base_uri.'/calendar/'))),
|
||||
'calendar-user-type' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-type','INDIVIDUAL'),
|
||||
// Calendarserver
|
||||
'email-address-set' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address-set',array(
|
||||
HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'email-address',$account['account_email']))),
|
||||
'last-name' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'last-name',$account['account_lastname']),
|
||||
'first-name' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'first-name',$account['account_firstname']),
|
||||
'record-type' => HTTP_WebDAV_Server::mkprop(groupdav::CALENDARSERVER,'record-type','user'),
|
||||
'calendar-user-type' => HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-user-type','INDIVIDUAL'),
|
||||
'addressbook-home-set' => HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',$addressbooks),
|
||||
// WebDAV ACL and CalDAV proxy
|
||||
'group-membership' => $this->principal_set('group-membership', $this->accounts->memberships($account['account_id']),
|
||||
'calendar', $account['account_id']), // add proxy-rights
|
||||
'alternate-URI-set' => array(
|
||||
HTTP_WebDAV_Server::mkprop('href','MAILTO:'.$account['account_email'])),
|
||||
// CardDAV
|
||||
'addressbook-home-set' => HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV,'addressbook-home-set',$addressbooks),
|
||||
// CardDAV directory
|
||||
'directory-gateway' => HTTP_WebDAV_Server::mkprop(groupdav::CARDDAV, 'directory-gateway',array(
|
||||
HTTP_WebDAV_Server::mkprop('href', $this->base_uri.'/addressbook/'))),
|
||||
));
|
||||
|
Loading…
Reference in New Issue
Block a user