forked from extern/egroupware
- improved principal-property-search report to support test=(allof|anyof) and match-type=(contains|starts-with) attributes used by iOS iCal to autocomplete participants
--> participants are - thanks to CalDAV scheduling - now setable for new event, thought searching for them does NOT yet work, no idea why ;-) - added somehow missing calendar-query report to supported-report-set
This commit is contained in:
parent
f6f47e586b
commit
0a7b7e40c8
@ -1016,6 +1016,8 @@ class calendar_groupdav extends groupdav_handler
|
|||||||
));
|
));
|
||||||
$props['supported-report-set'] = 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('supported-report',array(
|
||||||
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-query',''))),
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget',''))),
|
HTTP_WebDAV_Server::mkprop(groupdav::CALDAV,'calendar-multiget',''))),
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
|
@ -378,7 +378,7 @@ class groupdav extends HTTP_WebDAV_Server
|
|||||||
* @param array $supported_privileges=null default $this->supported_privileges
|
* @param array $supported_privileges=null default $this->supported_privileges
|
||||||
* @return array with values for keys 'path' and 'props'
|
* @return array with values for keys 'path' and 'props'
|
||||||
*/
|
*/
|
||||||
public function add_collection($path, array $props = array(), array $privileges=array('read','read-current-user-privilege-set'), array $supported_privileges=null)
|
public function add_collection($path, array $props = array(), array $privileges=array('read','read-acl','read-current-user-privilege-set'), array $supported_privileges=null)
|
||||||
{
|
{
|
||||||
// resourcetype: collection
|
// resourcetype: collection
|
||||||
$props['resourcetype'][] = self::mkprop('collection','');
|
$props['resourcetype'][] = self::mkprop('collection','');
|
||||||
|
@ -43,9 +43,15 @@ class groupdav_principals extends groupdav_handler
|
|||||||
'acl-principal-prop-set' => array(
|
'acl-principal-prop-set' => array(
|
||||||
// not sure why we return that report, if we not implement it ...
|
// not sure why we return that report, if we not implement it ...
|
||||||
),
|
),
|
||||||
|
/*'principal-match' => array(
|
||||||
|
// an other report calendarserver announces
|
||||||
|
),*/
|
||||||
'principal-property-search' => array(
|
'principal-property-search' => array(
|
||||||
'method' => 'principal_property_search_report',
|
'method' => 'principal_property_search_report',
|
||||||
),
|
),
|
||||||
|
/*'expand-property' => array(
|
||||||
|
// an other report calendarserver announces
|
||||||
|
),*/
|
||||||
'addressbook-findshared' => array(
|
'addressbook-findshared' => array(
|
||||||
'ns' => groupdav::ADDRESSBOOKSERVER,
|
'ns' => groupdav::ADDRESSBOOKSERVER,
|
||||||
'method' => 'addressbook_findshared_report',
|
'method' => 'addressbook_findshared_report',
|
||||||
@ -68,9 +74,9 @@ class groupdav_principals extends groupdav_handler
|
|||||||
$supported = array();
|
$supported = array();
|
||||||
foreach($reports as $name => $data)
|
foreach($reports as $name => $data)
|
||||||
{
|
{
|
||||||
$supported[] = HTTP_WebDAV_Server::mkprop('supported-report',array(
|
$supported[$name] = HTTP_WebDAV_Server::mkprop('supported-report',array(
|
||||||
HTTP_WebDAV_Server::mkprop('report',array(
|
HTTP_WebDAV_Server::mkprop('report',array(
|
||||||
!$data['ns'] ? HTTP_WebDAV_Server::mkprop($name) :
|
!$data['ns'] ? HTTP_WebDAV_Server::mkprop($name, '') :
|
||||||
HTTP_WebDAV_Server::mkprop($data['ns'], $name, '')))));
|
HTTP_WebDAV_Server::mkprop($data['ns'], $name, '')))));
|
||||||
}
|
}
|
||||||
return $supported;
|
return $supported;
|
||||||
@ -193,6 +199,9 @@ class groupdav_principals extends groupdav_handler
|
|||||||
{
|
{
|
||||||
//error_log(__METHOD__."('$path', ".array2string($options).",, $user)");
|
//error_log(__METHOD__."('$path', ".array2string($options).",, $user)");
|
||||||
|
|
||||||
|
// cant find the test attribute to root principal-property-search element in WebDAV rfc, but iPhones use it ...
|
||||||
|
$anyof = !empty($options['root']['attrs']['test']) && $options['root']['attrs']['test'] == 'anyof'; // "allof" (default) or "anyof"
|
||||||
|
|
||||||
// parse property-search prop(s) contained in $options['other']
|
// parse property-search prop(s) contained in $options['other']
|
||||||
foreach($options['other'] as $n => $prop)
|
foreach($options['other'] as $n => $prop)
|
||||||
{
|
{
|
||||||
@ -214,6 +223,8 @@ class groupdav_principals extends groupdav_handler
|
|||||||
if (isset($property_search) && is_array($search_props[$property_search]))
|
if (isset($property_search) && is_array($search_props[$property_search]))
|
||||||
{
|
{
|
||||||
$search_props[$property_search]['match'] = $prop['data'];
|
$search_props[$property_search]['match'] = $prop['data'];
|
||||||
|
// optional match-type: "contains" (default), "starts-with"
|
||||||
|
$search_props[$property_search]['match-type'] = $prop['attrs']['match-type'];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -250,6 +261,9 @@ class groupdav_principals extends groupdav_handler
|
|||||||
// run "regular" propfind
|
// run "regular" propfind
|
||||||
$options['other'] = array();
|
$options['other'] = array();
|
||||||
$options['root']['name'] = 'propfind';
|
$options['root']['name'] = 'propfind';
|
||||||
|
// search all principals, but not the proxys, rfc requires depth=0, but to search all principals
|
||||||
|
$options['depth'] = 5 - count(explode('/', $path)); // /principals/ --> 3
|
||||||
|
|
||||||
if (($ret = $this->propfind($path, $options, $files, $user)) !== true)
|
if (($ret = $this->propfind($path, $options, $files, $user)) !== true)
|
||||||
{
|
{
|
||||||
return $ret;
|
return $ret;
|
||||||
@ -257,12 +271,13 @@ class groupdav_principals extends groupdav_handler
|
|||||||
// now filter out not matching "files"
|
// now filter out not matching "files"
|
||||||
foreach($files['files'] as $n => $resource)
|
foreach($files['files'] as $n => $resource)
|
||||||
{
|
{
|
||||||
if (count(explode('/', $resource['path'])) < 4) // hack to only return principals, not the collections itself
|
if (count(explode('/', $resource['path'])) < 5) // hack to only return principals, not the collections itself
|
||||||
{
|
{
|
||||||
unset($files['files'][$n]);
|
unset($files['files'][$n]);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// search with all $search_props
|
// match with $search_props
|
||||||
|
$matches = 0;
|
||||||
foreach($search_props as $search_prop)
|
foreach($search_props as $search_prop)
|
||||||
{
|
{
|
||||||
// search resource for $search_prop
|
// search resource for $search_prop
|
||||||
@ -272,21 +287,46 @@ class groupdav_principals extends groupdav_handler
|
|||||||
foreach((array)$prop['val'] as $value)
|
foreach((array)$prop['val'] as $value)
|
||||||
{
|
{
|
||||||
if (is_array($value)) $value = $value['val']; // eg. href prop
|
if (is_array($value)) $value = $value['val']; // eg. href prop
|
||||||
if (stripos($value, $search_prop['match']) !== false) // prop does match
|
if (self::match($value, $search_prop['match'], $search_prop['match-type']) !== false) // prop does match
|
||||||
{
|
{
|
||||||
//error_log("$resource[path]: $search_prop[name]=".array2string($prop['name'] !== $search_prop['name'] ? null : $prop['val'])." does match '$search_prop[match]'");
|
++$matches;
|
||||||
continue 2; // search next search_prop
|
//error_log("$matches: $resource[path]: $search_prop[name]=".array2string($prop['name'] !== $search_prop['name'] ? null : $prop['val'])." does match '$search_prop[match]'");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//error_log("$resource[path]: $search_prop[name]=".array2string($prop['name'] !== $search_prop['name'] ? null : $prop['val'])." does NOT match '$search_prop[match]' --> remove from result");
|
if ($anyof && $matches || $matches == count($search_props))
|
||||||
unset($files['files'][$n]);
|
{
|
||||||
continue 2;
|
//error_log("$resource[path]: anyof=$anyof, $matches matches --> keep");
|
||||||
|
continue 2; // enough matches --> keep
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
//error_log("$resource[path]: anyof=$anyof, $matches matches --> skip");
|
||||||
|
unset($files['files'][$n]);
|
||||||
}
|
}
|
||||||
return $ret;
|
return $ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Match using $match_type
|
||||||
|
*
|
||||||
|
* @param string $value value to test
|
||||||
|
* @param string $match criteria/sub-string
|
||||||
|
* @param string $match_type='contains' or 'starts-with'
|
||||||
|
*/
|
||||||
|
private static function match($value, $match, $match_type='contains')
|
||||||
|
{
|
||||||
|
switch($match_type)
|
||||||
|
{
|
||||||
|
case 'starts-with':
|
||||||
|
return stripos($value, $match) === 0;
|
||||||
|
|
||||||
|
case 'contains':
|
||||||
|
default:
|
||||||
|
return stripos($value, $match) !== false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Do propfind in /pricipals/users
|
* Do propfind in /pricipals/users
|
||||||
*
|
*
|
||||||
@ -573,6 +613,10 @@ class groupdav_principals extends groupdav_handler
|
|||||||
*/
|
*/
|
||||||
protected function add_collection($path, array $props = array())
|
protected function add_collection($path, array $props = array())
|
||||||
{
|
{
|
||||||
|
if ($this->groupdav->prop_requested('supported-report-set'))
|
||||||
|
{
|
||||||
|
$props['supported-report-set'] = $this->supported_report_set($path);
|
||||||
|
}
|
||||||
return $this->groupdav->add_collection($path, $props);
|
return $this->groupdav->add_collection($path, $props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user