From 9297b242bfc164cb15bb893f3a3a4b5520b36c13 Mon Sep 17 00:00:00 2001 From: ralf Date: Thu, 19 Oct 2023 21:34:38 +0300 Subject: [PATCH] * Addressbook/REST API: allow to pass filters or a search pattern to addressbook REST API --- .../inc/class.addressbook_groupdav.inc.php | 17 ++++++++++++----- api/src/CalDAV.php | 4 ++-- doc/REST-CalDAV-CardDAV/Addressbook.md | 8 +++++++- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/addressbook/inc/class.addressbook_groupdav.inc.php b/addressbook/inc/class.addressbook_groupdav.inc.php index f2e7a6b27b..04a5550686 100644 --- a/addressbook/inc/class.addressbook_groupdav.inc.php +++ b/addressbook/inc/class.addressbook_groupdav.inc.php @@ -55,7 +55,7 @@ class addressbook_groupdav extends Api\CalDAV\Handler * G = primary group * D = distribution lists as groups * O = sync all in one (//addressbook/) - * or nummerical account_id, but not user itself + * or numerical account_id, but not user itself * * @var array */ @@ -269,7 +269,9 @@ class addressbook_groupdav extends Api\CalDAV\Handler if (!in_array(self::$path_attr,$cols)) $cols[] = self::$path_attr; // we need tid for sync-collection report if (array_key_exists('tid', $filter) && !isset($filter['tid']) && !in_array('tid', $cols)) $cols[] = 'tid'; - for($chunk=0; ($contacts =& $this->bo->search([], $cols, $order, '', '', False, 'AND', + $search = $filter['search'] ?? []; + unset($filter['search']); + for($chunk=0; ($contacts =& $this->bo->search($search, $cols, $order, '', '', False, 'AND', [$chunk*self::CHUNK_SIZE, self::CHUNK_SIZE], $filter)); ++$chunk) { // filter[tid] === null also returns no longer shared contacts, to remove them from devices, we need to mark them here as deleted @@ -449,14 +451,19 @@ class addressbook_groupdav extends Api\CalDAV\Handler * Process the filters from the CalDAV REPORT request * * @param array $options - * @param array &$cal_filters + * @param array &$filters * @param string $id * @param int &$nresult on return limit for number or results or unchanged/null * @return boolean true if filter could be processed */ - function _report_filters($options,&$filters,$id, &$nresults) + function _report_filters($options, &$filters, $id, &$nresults) { - if ($options['filters']) + // in case of JSON/REST API pass filters to report + if (Api\CalDAV::isJSON() && !empty($options['filters']) && is_array($options['filters'])) + { + $filters += $options['filters']; // using += to no allow overwriting existing filters + } + elseif (!empty($options['filters'])) { /* Example of a complex filter used by Mac Addressbook diff --git a/api/src/CalDAV.php b/api/src/CalDAV.php index 7752fdfa73..8296b52901 100644 --- a/api/src/CalDAV.php +++ b/api/src/CalDAV.php @@ -1174,10 +1174,10 @@ class CalDAV extends HTTP_WebDAV_Server } } - // ToDo: client want data filtered + // client want data filtered if (isset($_GET['filters'])) { - + $propfind_options['filters'] = $_GET['filters']; } // properties to NOT get the default address-data for addressbook-collections and "all" for the rest diff --git a/doc/REST-CalDAV-CardDAV/Addressbook.md b/doc/REST-CalDAV-CardDAV/Addressbook.md index 6fd8935f7e..2f3114e17a 100644 --- a/doc/REST-CalDAV-CardDAV/Addressbook.md +++ b/doc/REST-CalDAV-CardDAV/Addressbook.md @@ -72,13 +72,19 @@ curl https://example.org/egroupware/groupdav.php//addressbook/ -H "Acc ``` - following GET parameters are supported to customize the returned properties: + Following GET parameters are supported to customize the returned properties: - props[]= eg. props[]=getetag to return only the ETAG (multiple DAV properties can be specified) Default for addressbook collections is to only return address-data (JsContact), other collections return all props. - sync-token= to only request change since last sync-token, like rfc6578 sync-collection REPORT - nresults=N limit number of responses (only for sync-collection / given sync-token parameter!) this will return a "more-results"=true attribute and a new "sync-token" attribute to query for the next chunk + The GET parameter `filters` allows to filter or search for a pattern in an addressbook: + - `filters[search]=` searches for `` in the whole contact like the search in the GUI + - `filters[search][%23]=` filters by a custom-field value + - `filters[]=` filters by a DB-column name and value + > Please note: filters use the database column-names, not JSContact property-names! +
Example: Getting just ETAGs and displayname of all contacts in a given AB