diff options
Diffstat (limited to 'apps/dav/lib/Search/ContactsSearchProvider.php')
-rw-r--r-- | apps/dav/lib/Search/ContactsSearchProvider.php | 166 |
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'), + ]; + } } |