aboutsummaryrefslogtreecommitdiffstats
path: root/apps/dav/lib/Search/ContactsSearchProvider.php
diff options
context:
space:
mode:
Diffstat (limited to 'apps/dav/lib/Search/ContactsSearchProvider.php')
-rw-r--r--apps/dav/lib/Search/ContactsSearchProvider.php166
1 files changed, 75 insertions, 91 deletions
diff --git a/apps/dav/lib/Search/ContactsSearchProvider.php b/apps/dav/lib/Search/ContactsSearchProvider.php
index a7c2969016b..158c0d0813e 100644
--- a/apps/dav/lib/Search/ContactsSearchProvider.php
+++ b/apps/dav/lib/Search/ContactsSearchProvider.php
@@ -3,27 +3,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2020, Georg Ehrke
- *
- * @author Georg Ehrke <oc.list@georgehrke.com>
- * @author Joas Schilling <coding@schilljs.com>
- * @author John Molakvoæ <skjnldsv@protonmail.com>
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
+ * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OCA\DAV\Search;
@@ -32,31 +13,24 @@ use OCP\App\IAppManager;
use OCP\IL10N;
use OCP\IURLGenerator;
use OCP\IUser;
-use OCP\Search\IProvider;
+use OCP\Search\FilterDefinition;
+use OCP\Search\IFilter;
+use OCP\Search\IFilteringProvider;
use OCP\Search\ISearchQuery;
use OCP\Search\SearchResult;
use OCP\Search\SearchResultEntry;
use Sabre\VObject\Component\VCard;
use Sabre\VObject\Reader;
-class ContactsSearchProvider implements IProvider {
-
- /** @var IAppManager */
- private $appManager;
-
- /** @var IL10N */
- private $l10n;
-
- /** @var IURLGenerator */
- private $urlGenerator;
-
- /** @var CardDavBackend */
- private $backend;
+class ContactsSearchProvider implements IFilteringProvider {
+ private static array $searchPropertiesRestricted = [
+ 'N',
+ 'FN',
+ 'NICKNAME',
+ 'EMAIL',
+ ];
- /**
- * @var string[]
- */
- private static $searchProperties = [
+ private static array $searchProperties = [
'N',
'FN',
'NICKNAME',
@@ -68,22 +42,12 @@ class ContactsSearchProvider implements IProvider {
'NOTE',
];
- /**
- * ContactsSearchProvider constructor.
- *
- * @param IAppManager $appManager
- * @param IL10N $l10n
- * @param IURLGenerator $urlGenerator
- * @param CardDavBackend $backend
- */
- public function __construct(IAppManager $appManager,
- IL10N $l10n,
- IURLGenerator $urlGenerator,
- CardDavBackend $backend) {
- $this->appManager = $appManager;
- $this->l10n = $l10n;
- $this->urlGenerator = $urlGenerator;
- $this->backend = $backend;
+ public function __construct(
+ private IAppManager $appManager,
+ private IL10N $l10n,
+ private IURLGenerator $urlGenerator,
+ private CardDavBackend $backend,
+ ) {
}
/**
@@ -100,19 +64,14 @@ class ContactsSearchProvider implements IProvider {
return $this->l10n->t('Contacts');
}
- /**
- * @inheritDoc
- */
- public function getOrder(string $route, array $routeParameters): int {
- if ($route === 'contacts.Page.index') {
- return -1;
+ public function getOrder(string $route, array $routeParameters): ?int {
+ if ($this->appManager->isEnabledForUser('contacts')) {
+ return $route === 'contacts.Page.index' ? -1 : 25;
}
- return 25;
+
+ return null;
}
- /**
- * @inheritDoc
- */
public function search(IUser $user, ISearchQuery $query): SearchResult {
if (!$this->appManager->isEnabledForUser('contacts', $user)) {
return SearchResult::complete($this->getName(), []);
@@ -122,17 +81,21 @@ class ContactsSearchProvider implements IProvider {
$addressBooks = $this->backend->getAddressBooksForUser($principalUri);
$addressBooksById = [];
foreach ($addressBooks as $addressBook) {
- $addressBooksById[(int) $addressBook['id']] = $addressBook;
+ $addressBooksById[(int)$addressBook['id']] = $addressBook;
}
$searchResults = $this->backend->searchPrincipalUri(
$principalUri,
- $query->getTerm(),
- self::$searchProperties,
+ $query->getFilter('term')?->get() ?? '',
+ $query->getFilter('title-only')?->get() ? self::$searchPropertiesRestricted : self::$searchProperties,
[
'limit' => $query->getLimit(),
'offset' => $query->getCursor(),
- ]
+ 'since' => $query->getFilter('since'),
+ 'until' => $query->getFilter('until'),
+ 'person' => $this->getPersonDisplayName($query->getFilter('person')),
+ 'company' => $query->getFilter('company'),
+ ],
);
$formattedResults = \array_map(function (array $contactRow) use ($addressBooksById):SearchResultEntry {
$addressBook = $addressBooksById[$contactRow['addressbookid']];
@@ -146,9 +109,14 @@ class ContactsSearchProvider implements IProvider {
$title = (string)$vCard->FN;
$subline = $this->generateSubline($vCard);
- $resourceUrl = $this->getDeepLinkToContactsApp($addressBook['uri'], (string) $vCard->UID);
+ $resourceUrl = $this->getDeepLinkToContactsApp($addressBook['uri'], (string)$vCard->UID);
+
+ $result = new SearchResultEntry($thumbnailUrl, $title, $subline, $resourceUrl, 'icon-contacts-dark', true);
+ $result->addAttribute('displayName', $title);
+ $result->addAttribute('email', $subline);
+ $result->addAttribute('phoneNumber', (string)$vCard->TEL);
- return new SearchResultEntry($thumbnailUrl, $title, $subline, $resourceUrl, 'icon-contacts-dark', true);
+ return $result;
}, $searchResults);
return SearchResult::paginated(
@@ -157,16 +125,19 @@ class ContactsSearchProvider implements IProvider {
$query->getCursor() + count($formattedResults)
);
}
+ private function getPersonDisplayName(?IFilter $person): ?string {
+ $user = $person?->get();
+ if ($user instanceof IUser) {
+ return $user->getDisplayName();
+ }
+ return null;
+ }
- /**
- * @param string $principalUri
- * @param string $addressBookUri
- * @param string $contactsUri
- * @return string
- */
- protected function getDavUrlForContact(string $principalUri,
- string $addressBookUri,
- string $contactsUri): string {
+ protected function getDavUrlForContact(
+ string $principalUri,
+ string $addressBookUri,
+ string $contactsUri,
+ ): string {
[, $principalType, $principalId] = explode('/', $principalUri, 3);
return $this->urlGenerator->getAbsoluteURL(
@@ -178,13 +149,10 @@ class ContactsSearchProvider implements IProvider {
);
}
- /**
- * @param string $addressBookUri
- * @param string $contactUid
- * @return string
- */
- protected function getDeepLinkToContactsApp(string $addressBookUri,
- string $contactUid): string {
+ protected function getDeepLinkToContactsApp(
+ string $addressBookUri,
+ string $contactUid,
+ ): string {
return $this->urlGenerator->getAbsoluteURL(
$this->urlGenerator->linkToRoute('contacts.contacts.direct', [
'contact' => $contactUid . '~' . $addressBookUri
@@ -192,10 +160,6 @@ class ContactsSearchProvider implements IProvider {
);
}
- /**
- * @param VCard $vCard
- * @return string
- */
protected function generateSubline(VCard $vCard): string {
$emailAddresses = $vCard->select('EMAIL');
if (!is_array($emailAddresses) || empty($emailAddresses)) {
@@ -204,4 +168,24 @@ class ContactsSearchProvider implements IProvider {
return (string)$emailAddresses[0];
}
+
+ public function getSupportedFilters(): array {
+ return [
+ 'term',
+ 'since',
+ 'until',
+ 'person',
+ 'title-only',
+ ];
+ }
+
+ public function getAlternateIds(): array {
+ return [];
+ }
+
+ public function getCustomFilters(): array {
+ return [
+ new FilterDefinition('company'),
+ ];
+ }
}