forked from extern/egroupware
iOS iCal sends now pricipal-property-search reports to autocomplete participants, but not (yet) displays the result, for whatever reason ...
This commit is contained in:
parent
b4b04844fe
commit
14dde4c1ff
@ -44,4 +44,4 @@ $headertime = microtime(true);
|
||||
|
||||
$groupdav = new groupdav();
|
||||
$groupdav->ServeRequest();
|
||||
//error_log(sprintf("GroupDAV %s request took %5.3f s (header include took %5.3f s)",$_SERVER['REQUEST_METHOD'],microtime(true)-$starttime,$headertime-$starttime));
|
||||
error_log(sprintf('GroupDAV %s request: status "%s", took %5.3f s'.($headertime?' (header include took %5.3f s)':''),$_SERVER['REQUEST_METHOD'].($_SERVER['REQUEST_METHOD']=='REPORT'?' '.$groupdav->propfind_options['root']['name']:'').' '.$_SERVER['PATH_INFO'],$groupdav->_http_status,microtime(true)-$starttime,$headertime-$starttime));
|
||||
|
@ -277,32 +277,40 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
*/
|
||||
function OPTIONS($path, &$dav, &$allow)
|
||||
{
|
||||
list(,$app) = explode('/',$path);
|
||||
switch($app)
|
||||
if (preg_match('#/(calendar|inbox|outbox)/#', $path))
|
||||
{
|
||||
case 'calendar':
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
$dav[] = 'calendar-auto-schedule';
|
||||
$dav[] = 'calendar-proxy';
|
||||
//$dav[] = 'calendar-availibility';
|
||||
//$dav[] = 'calendarserver-private-events';
|
||||
break;
|
||||
case 'addressbook':
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
//$dav[] = 3; // revision aka versioning support not implemented
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'addressbook'; // CardDAV uses "addressbook" NOT "addressbook-access"
|
||||
break;
|
||||
default: // used eg. for root, and needs all above settings, as some clients only use these!
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
$dav[] = 'calendar-access';
|
||||
$dav[] = 'calendar-auto-schedule';
|
||||
$dav[] = 'calendar-proxy';
|
||||
$dav[] = 'addressbook';
|
||||
$app = 'calendar';
|
||||
}
|
||||
elseif (strpos($path, '/addressbook/') !== false)
|
||||
{
|
||||
$app = 'addressbook';
|
||||
}
|
||||
// CalDAV and CardDAV
|
||||
if (!in_array(2,$dav)) $dav[] = 2;
|
||||
$dav[] = 'access-control';
|
||||
|
||||
if ($app !== 'addressbook') // CalDAV
|
||||
{
|
||||
$dav[] = 'calendar-access';
|
||||
$dav[] = 'calendar-auto-schedule';
|
||||
$dav[] = 'calendar-proxy';
|
||||
// required by iOS iCal to use principal-property-search to autocomplete participants (and locations)
|
||||
$dav[] = 'calendarserver-principal-property-search';
|
||||
// other capabilities calendarserver announces
|
||||
//$dav[] = 'calendar-schedule';
|
||||
//$dav[] = 'calendar-availability';
|
||||
//$dav[] = 'inbox-availability';
|
||||
//$dav[] = 'calendarserver-private-events';
|
||||
//$dav[] = 'calendarserver-private-comments';
|
||||
//$dav[] = 'calendarserver-sharing';
|
||||
//$dav[] = 'calendarserver-sharing-no-scheduling';
|
||||
|
||||
}
|
||||
elseif ($app !== 'calendar') // CardDAV
|
||||
{
|
||||
$dav[] = 'addressbook'; // CardDAV uses "addressbook" NOT "addressbook-access"
|
||||
}
|
||||
//error_log(__METHOD__."('$path') --> app='$app' --> DAV: ".implode(', ', $dav));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -502,7 +510,7 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
$ret = false;
|
||||
foreach($this->propfind_options['props'] as $prop)
|
||||
{
|
||||
if ($prop['name'] == $name && (is_null($ns) || $prop['ns'] == $ns))
|
||||
if ($prop['name'] == $name && (is_null($ns) || $prop['xmlns'] == $ns))
|
||||
{
|
||||
$ret = true;
|
||||
break;
|
||||
@ -858,6 +866,11 @@ class groupdav extends HTTP_WebDAV_Server
|
||||
}
|
||||
echo "</table>\n";
|
||||
|
||||
$dav = array(1);
|
||||
$allow = false;
|
||||
$this->OPTIONS($options['path'], $dav, $allow);
|
||||
echo "<p>DAV: ".implode(', ', $dav)."</p>\n";
|
||||
|
||||
echo "</body>\n</html>\n";
|
||||
|
||||
common::egw_exit();
|
||||
|
@ -49,6 +49,9 @@ class groupdav_principals extends groupdav_handler
|
||||
'principal-property-search' => array(
|
||||
'method' => 'principal_property_search_report',
|
||||
),
|
||||
'principal-search-property-set' => array(
|
||||
'method' => 'principal_search_property_set_report',
|
||||
),
|
||||
/*'expand-property' => array(
|
||||
// an other report calendarserver announces
|
||||
),*/
|
||||
@ -189,6 +192,43 @@ class groupdav_principals extends groupdav_handler
|
||||
* but interprets returning all principals (all have a matching calendar-home-set) as NOT supporting CalDAV scheduling
|
||||
* --> search only current user's principal, when Lightning searches for calendar-home-set
|
||||
*
|
||||
* Example from iOS iCal autocompleting invitees using calendarserver-principal-property-search WebDAV extension
|
||||
* <x0:principal-property-search xmlns:x2="urn:ietf:params:xml:ns:caldav" xmlns:x1="http://calendarserver.org/ns/" xmlns:x0="DAV:" test="anyof">
|
||||
* <x0:property-search>
|
||||
* <x0:prop>
|
||||
* <x0:displayname/>
|
||||
* </x0:prop>
|
||||
* <x0:match match-type="contains">beck</x0:match>
|
||||
* </x0:property-search>
|
||||
* <x0:property-search>
|
||||
* <x0:prop>
|
||||
* <x1:email-address-set/>
|
||||
* </x0:prop>
|
||||
* <x0:match match-type="starts-with">beck</x0:match>
|
||||
* </x0:property-search>
|
||||
* <x0:property-search>
|
||||
* <x0:prop>
|
||||
* <x1:first-name/>
|
||||
* </x0:prop>
|
||||
* <x0:match match-type="starts-with">beck</x0:match>
|
||||
* </x0:property-search>
|
||||
* <x0:property-search>
|
||||
* <x0:prop>
|
||||
* <x1:last-name/>
|
||||
* </x0:prop>
|
||||
* <x0:match match-type="starts-with">beck</x0:match>
|
||||
* </x0:property-search>
|
||||
* <x0:prop>
|
||||
* <x1:first-name/>
|
||||
* <x1:last-name/>
|
||||
* <x0:displayname/>
|
||||
* <x1:email-address-set/>
|
||||
* <x2:calendar-user-address-set/>
|
||||
* <x1:record-type/>
|
||||
* <x0:principal-URL/>
|
||||
* </x0:prop>
|
||||
* </x0:principal-property-search>
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $options
|
||||
* @param array &$files
|
||||
@ -223,7 +263,7 @@ class groupdav_principals extends groupdav_handler
|
||||
if (isset($property_search) && is_array($search_props[$property_search]))
|
||||
{
|
||||
$search_props[$property_search]['match'] = $prop['data'];
|
||||
// optional match-type: "contains" (default), "starts-with"
|
||||
// optional match-type: "contains" (default), "starts-with", "ends-with", "equals"
|
||||
$search_props[$property_search]['match-type'] = $prop['attrs']['match-type'];
|
||||
}
|
||||
break;
|
||||
@ -314,7 +354,7 @@ class groupdav_principals extends groupdav_handler
|
||||
*
|
||||
* @param string $value value to test
|
||||
* @param string $match criteria/sub-string
|
||||
* @param string $match_type='contains' or 'starts-with'
|
||||
* @param string $match_type='contains' 'starts-with', 'ends-with' or 'equals'
|
||||
*/
|
||||
private static function match($value, $match, $match_type='contains')
|
||||
{
|
||||
@ -335,6 +375,109 @@ class groupdav_principals extends groupdav_handler
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle principal-search-property-set report
|
||||
*
|
||||
* REPORT /principals/ HTTP/1.1
|
||||
* <?xml version="1.0" encoding="utf-8" ?>
|
||||
* <x0:principal-search-property-set xmlns:x0="DAV:"/>
|
||||
*
|
||||
* <?xml version='1.0' encoding='UTF-8'?>
|
||||
* <principal-search-property-set xmlns='DAV:'>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <displayname/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>Display Name</description>
|
||||
* </principal-search-property>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <email-address-set xmlns='http://calendarserver.org/ns/'/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>Email Addresses</description>
|
||||
* </principal-search-property>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <last-name xmlns='http://calendarserver.org/ns/'/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>Last Name</description>
|
||||
* </principal-search-property>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <calendar-user-type xmlns='urn:ietf:params:xml:ns:caldav'/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>Calendar User Type</description>
|
||||
* </principal-search-property>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <first-name xmlns='http://calendarserver.org/ns/'/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>First Name</description>
|
||||
* </principal-search-property>
|
||||
* <principal-search-property>
|
||||
* <prop>
|
||||
* <calendar-user-address-set xmlns='urn:ietf:params:xml:ns:caldav'/>
|
||||
* </prop>
|
||||
* <description xml:lang='en'>Calendar User Address Set</description>
|
||||
* </principal-search-property>
|
||||
* </principal-search-property-set>
|
||||
*
|
||||
* @param string $path
|
||||
* @param array $options
|
||||
* @param array &$files
|
||||
* @param int $user account_id
|
||||
* @return mixed boolean true on success, false on failure or string with http status (eg. '404 Not Found')
|
||||
*/
|
||||
function principal_search_property_set_report($path,&$options,&$files,$user)
|
||||
{
|
||||
static $search_props = array(
|
||||
// from iOS iCal
|
||||
'displayname' => 'Display Name',
|
||||
'email-address-set' => array('description' => 'Email Addresses', 'ns' => groupdav::CALENDARSERVER),
|
||||
'last-name' => array('description' => 'Last Name', 'ns' => groupdav::CALENDARSERVER),
|
||||
'calendar-user-type' => array('description' => 'Calendar User Type', 'ns' => groupdav::CALENDARSERVER),
|
||||
'first-name' => array('description' => 'First Name', 'ns' => groupdav::CALENDARSERVER),
|
||||
'calendar-user-address-set' => array('description' => 'Calendar User Address Set', 'ns' => groupdav::CALENDARSERVER),
|
||||
// Lightning
|
||||
'calendar-home-set' => array('description' => 'Calendar Home Set', 'ns' => groupdav::CALENDARSERVER),
|
||||
// others, we generally support all properties of the principal
|
||||
);
|
||||
header('Content-type: text/xml; charset=UTF-8');
|
||||
|
||||
$xml = new XMLWriter;
|
||||
$xml->openMemory();
|
||||
$xml->setIndent(true);
|
||||
$xml->startDocument('1.0', 'UTF-8');
|
||||
$xml->startElementNs(null, 'principal-search-property-set', 'DAV:');
|
||||
|
||||
foreach($search_props as $name => $data)
|
||||
{
|
||||
$xml->startElement('principal-search-property');
|
||||
$xml->startElement('prop');
|
||||
if (is_array($data) && !empty($data['ns']))
|
||||
{
|
||||
$xml->writeElementNs(null, $name, $data['ns']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$xml->writeElement($name);
|
||||
}
|
||||
$xml->endElement(); // prop
|
||||
|
||||
$xml->startElement('description');
|
||||
$xml->writeAttribute('xml:lang', 'en');
|
||||
$xml->text(is_array($data) ? $data['description'] : $data);
|
||||
$xml->endElement(); // description
|
||||
|
||||
$xml->endElement(); // principal-search-property
|
||||
}
|
||||
$xml->endElement(); // principal-search-property-set
|
||||
$xml->endDocument();
|
||||
echo $xml->outputMemory();
|
||||
|
||||
common::egw_exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Do propfind in /pricipals/users
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user