diff options
author | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-05-11 10:35:54 +0200 |
---|---|---|
committer | Christoph Wurst <christoph@winzerhof-wurst.at> | 2020-06-24 14:20:25 +0200 |
commit | 4488e846a526ed8de37e9756621b7c008d7a9466 (patch) | |
tree | 2e2a9bfe4b2c5fcfb82fc1bcd9ab23693b58fe08 /lib/private/Search | |
parent | 50b1568d48efddc315e503c6a2c3ffe485db7658 (diff) | |
download | nextcloud-server-4488e846a526ed8de37e9756621b7c008d7a9466.tar.gz nextcloud-server-4488e846a526ed8de37e9756621b7c008d7a9466.zip |
Add unified search API
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
Diffstat (limited to 'lib/private/Search')
-rw-r--r-- | lib/private/Search/SearchComposer.php | 107 | ||||
-rw-r--r-- | lib/private/Search/SearchQuery.php | 88 |
2 files changed, 195 insertions, 0 deletions
diff --git a/lib/private/Search/SearchComposer.php b/lib/private/Search/SearchComposer.php new file mode 100644 index 00000000000..f8369292103 --- /dev/null +++ b/lib/private/Search/SearchComposer.php @@ -0,0 +1,107 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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/>. + */ + +namespace OC\Search; + +use OCP\AppFramework\QueryException; +use OCP\ILogger; +use OCP\IServerContainer; +use OCP\IUser; +use OCP\Search\IProvider; +use OCP\Search\ISearchQuery; +use OCP\Search\SearchResult; +use function array_map; + +/** + * Queries individual \OCP\Search\IProvider implementations and composes a + * unified search result for the user's search term + */ +class SearchComposer { + + /** @var string[] */ + private $lazyProviders = []; + + /** @var IProvider[] */ + private $providers = []; + + /** @var IServerContainer */ + private $container; + + /** @var ILogger */ + private $logger; + + public function __construct(IServerContainer $container, + ILogger $logger) { + $this->container = $container; + $this->logger = $logger; + } + + public function registerProvider(string $class): void { + $this->lazyProviders[] = $class; + } + + /** + * Load all providers dynamically that were registered through `registerProvider` + * + * If a provider can't be loaded we log it but the operation continues nevertheless + */ + private function loadLazyProviders(): void { + $classes = $this->lazyProviders; + foreach ($classes as $class) { + try { + /** @var IProvider $provider */ + $provider = $this->container->query($class); + $this->providers[$provider->getId()] = $provider; + } catch (QueryException $e) { + // Log an continue. We can be fault tolerant here. + $this->logger->logException($e, [ + 'message' => 'Could not load search provider dynamically: ' . $e->getMessage(), + 'level' => ILogger::ERROR, + ]); + } + } + $this->lazyProviders = []; + } + + public function getProviders(): array { + $this->loadLazyProviders(); + + /** + * Return an array with the IDs, but strip the associative keys + */ + return array_values( + array_map(function (IProvider $provider) { + return $provider->getId(); + }, $this->providers)); + } + + public function search(IUser $user, + string $providerId, + ISearchQuery $query): SearchResult { + $this->loadLazyProviders(); + + return $this->providers[$providerId]->search($user, $query); + } +} diff --git a/lib/private/Search/SearchQuery.php b/lib/private/Search/SearchQuery.php new file mode 100644 index 00000000000..2ed31fed441 --- /dev/null +++ b/lib/private/Search/SearchQuery.php @@ -0,0 +1,88 @@ +<?php + +declare(strict_types=1); + +/** + * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at> + * + * @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/>. + */ + +namespace OC\Search; + +use OCP\Search\ISearchQuery; + +class SearchQuery implements ISearchQuery { + public const LIMIT_DEFAULT = 20; + + /** @var string */ + private $term; + + /** @var int */ + private $sortOrder; + + /** @var int */ + private $limit; + + /** @var int|string|null */ + private $cursor; + + /** + * @param string $term + * @param int $sortOrder + * @param int $limit + * @param int|string|null $cursor + */ + public function __construct(string $term, + int $sortOrder = ISearchQuery::SORT_DATE_DESC, + int $limit = self::LIMIT_DEFAULT, + $cursor = null) { + $this->term = $term; + $this->sortOrder = $sortOrder; + $this->limit = $limit; + $this->cursor = $cursor; + } + + /** + * @inheritDoc + */ + public function getTerm(): string { + return $this->term; + } + + /** + * @inheritDoc + */ + public function getSortOrder(): int { + return $this->sortOrder; + } + + /** + * @inheritDoc + */ + public function getLimit(): int { + return $this->limit; + } + + /** + * @inheritDoc + */ + public function getCursor() { + return $this->cursor; + } +} |