diff options
Diffstat (limited to 'lib/private/Search')
-rw-r--r-- | lib/private/Search/Filter/BooleanFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/Filter/DateTimeFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/Filter/FloatFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/Filter/GroupFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/Filter/IntegerFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/Filter/UserFilter.php | 2 | ||||
-rw-r--r-- | lib/private/Search/FilterFactory.php | 4 | ||||
-rw-r--r-- | lib/private/Search/Provider/File.php | 87 | ||||
-rw-r--r-- | lib/private/Search/Result/Audio.php | 25 | ||||
-rw-r--r-- | lib/private/Search/Result/File.php | 132 | ||||
-rw-r--r-- | lib/private/Search/Result/Folder.php | 21 | ||||
-rw-r--r-- | lib/private/Search/Result/Image.php | 25 | ||||
-rw-r--r-- | lib/private/Search/SearchComposer.php | 45 | ||||
-rw-r--r-- | lib/private/Search/SearchQuery.php | 2 | ||||
-rw-r--r-- | lib/private/Search/UnsupportedFilter.php | 2 |
15 files changed, 48 insertions, 307 deletions
diff --git a/lib/private/Search/Filter/BooleanFilter.php b/lib/private/Search/Filter/BooleanFilter.php index 92572a60073..894dc13b657 100644 --- a/lib/private/Search/Filter/BooleanFilter.php +++ b/lib/private/Search/Filter/BooleanFilter.php @@ -19,7 +19,7 @@ class BooleanFilter implements IFilter { $this->value = match ($value) { 'true', 'yes', 'y', '1' => true, 'false', 'no', 'n', '0', '' => false, - default => throw new InvalidArgumentException('Invalid boolean value '. $value), + default => throw new InvalidArgumentException('Invalid boolean value ' . $value), }; } diff --git a/lib/private/Search/Filter/DateTimeFilter.php b/lib/private/Search/Filter/DateTimeFilter.php index 367af80b505..48c1725a5e1 100644 --- a/lib/private/Search/Filter/DateTimeFilter.php +++ b/lib/private/Search/Filter/DateTimeFilter.php @@ -17,7 +17,7 @@ class DateTimeFilter implements IFilter { public function __construct(string $value) { if (filter_var($value, FILTER_VALIDATE_INT)) { - $value = '@'.$value; + $value = '@' . $value; } $this->value = new DateTimeImmutable($value); diff --git a/lib/private/Search/Filter/FloatFilter.php b/lib/private/Search/Filter/FloatFilter.php index 97d767e62cb..f2384552943 100644 --- a/lib/private/Search/Filter/FloatFilter.php +++ b/lib/private/Search/Filter/FloatFilter.php @@ -18,7 +18,7 @@ class FloatFilter implements IFilter { public function __construct(string $value) { $this->value = filter_var($value, FILTER_VALIDATE_FLOAT); if ($this->value === false) { - throw new InvalidArgumentException('Invalid float value '. $value); + throw new InvalidArgumentException('Invalid float value ' . $value); } } diff --git a/lib/private/Search/Filter/GroupFilter.php b/lib/private/Search/Filter/GroupFilter.php index e7694a6daa2..fe0b2ce42d8 100644 --- a/lib/private/Search/Filter/GroupFilter.php +++ b/lib/private/Search/Filter/GroupFilter.php @@ -23,7 +23,7 @@ class GroupFilter implements IFilter { ) { $group = $groupManager->get($value); if ($group === null) { - throw new InvalidArgumentException('Group '.$value.' not found'); + throw new InvalidArgumentException('Group ' . $value . ' not found'); } $this->group = $group; } diff --git a/lib/private/Search/Filter/IntegerFilter.php b/lib/private/Search/Filter/IntegerFilter.php index 825c7ddd3eb..028b7d0678f 100644 --- a/lib/private/Search/Filter/IntegerFilter.php +++ b/lib/private/Search/Filter/IntegerFilter.php @@ -18,7 +18,7 @@ class IntegerFilter implements IFilter { public function __construct(string $value) { $this->value = filter_var($value, FILTER_VALIDATE_INT); if ($this->value === false) { - throw new InvalidArgumentException('Invalid integer value '. $value); + throw new InvalidArgumentException('Invalid integer value ' . $value); } } diff --git a/lib/private/Search/Filter/UserFilter.php b/lib/private/Search/Filter/UserFilter.php index fbbc793e633..4f2061a4ba6 100644 --- a/lib/private/Search/Filter/UserFilter.php +++ b/lib/private/Search/Filter/UserFilter.php @@ -23,7 +23,7 @@ class UserFilter implements IFilter { ) { $user = $userManager->get($value); if ($user === null) { - throw new InvalidArgumentException('User '.$value.' not found'); + throw new InvalidArgumentException('User ' . $value . ' not found'); } $this->user = $user; } diff --git a/lib/private/Search/FilterFactory.php b/lib/private/Search/FilterFactory.php index 1317dd759af..07063c604f4 100644 --- a/lib/private/Search/FilterFactory.php +++ b/lib/private/Search/FilterFactory.php @@ -27,8 +27,8 @@ final class FilterFactory { FilterDefinition::TYPE_NC_USER => new Filter\UserFilter($filter, \OC::$server->get(IUserManager::class)), FilterDefinition::TYPE_PERSON => self::getPerson($filter), FilterDefinition::TYPE_STRING => new Filter\StringFilter($filter), - FilterDefinition::TYPE_STRINGS => new Filter\StringsFilter(... (array) $filter), - default => throw new RuntimeException('Invalid filter type '. $type), + FilterDefinition::TYPE_STRINGS => new Filter\StringsFilter(... (array)$filter), + default => throw new RuntimeException('Invalid filter type ' . $type), }; } diff --git a/lib/private/Search/Provider/File.php b/lib/private/Search/Provider/File.php deleted file mode 100644 index ca4b1b8677f..00000000000 --- a/lib/private/Search/Provider/File.php +++ /dev/null @@ -1,87 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -namespace OC\Search\Provider; - -use OC\Files\Search\SearchComparison; -use OC\Files\Search\SearchOrder; -use OC\Files\Search\SearchQuery; -use OCP\Files\FileInfo; -use OCP\Files\IRootFolder; -use OCP\Files\Search\ISearchComparison; -use OCP\Files\Search\ISearchOrder; -use OCP\IUserSession; -use OCP\Search\PagedProvider; - -/** - * Provide search results from the 'files' app - * @deprecated 20.0.0 - */ -class File extends PagedProvider { - /** - * Search for files and folders matching the given query - * - * @param string $query - * @param int|null $limit - * @param int|null $offset - * @return \OCP\Search\Result[] - * @deprecated 20.0.0 - */ - public function search($query, ?int $limit = null, ?int $offset = null) { - /** @var IRootFolder $rootFolder */ - $rootFolder = \OCP\Server::get(IRootFolder::class); - /** @var IUserSession $userSession */ - $userSession = \OCP\Server::get(IUserSession::class); - $user = $userSession->getUser(); - if (!$user) { - return []; - } - $userFolder = $rootFolder->getUserFolder($user->getUID()); - $fileQuery = new SearchQuery( - new SearchComparison(ISearchComparison::COMPARE_LIKE, 'name', '%' . $query . '%'), - (int)$limit, - (int)$offset, - [ - new SearchOrder(ISearchOrder::DIRECTION_DESCENDING, 'mtime'), - ], - $user - ); - $files = $userFolder->search($fileQuery); - $results = []; - // edit results - foreach ($files as $fileData) { - // create audio result - if ($fileData->getMimePart() === 'audio') { - $result = new \OC\Search\Result\Audio($fileData); - } - // create image result - elseif ($fileData->getMimePart() === 'image') { - $result = new \OC\Search\Result\Image($fileData); - } - // create folder result - elseif ($fileData->getMimetype() === FileInfo::MIMETYPE_FOLDER) { - $result = new \OC\Search\Result\Folder($fileData); - } - // or create file result - else { - $result = new \OC\Search\Result\File($fileData); - } - // add to results - $results[] = $result; - } - // return - return $results; - } - - public function searchPaged($query, $page, $size) { - if ($size === 0) { - return $this->search($query); - } else { - return $this->search($query, $size, ($page - 1) * $size); - } - } -} diff --git a/lib/private/Search/Result/Audio.php b/lib/private/Search/Result/Audio.php deleted file mode 100644 index 42b8ac75da0..00000000000 --- a/lib/private/Search/Result/Audio.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -namespace OC\Search\Result; - -/** - * A found audio file - * @deprecated 20.0.0 - */ -class Audio extends File { - /** - * Type name; translated in templates - * @var string - * @deprecated 20.0.0 - */ - public $type = 'audio'; - - /** - * @TODO add ID3 information - */ -} diff --git a/lib/private/Search/Result/File.php b/lib/private/Search/Result/File.php deleted file mode 100644 index f1346481b86..00000000000 --- a/lib/private/Search/Result/File.php +++ /dev/null @@ -1,132 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -namespace OC\Search\Result; - -use OCP\Files\FileInfo; -use OCP\Files\Folder; -use OCP\IPreview; -use OCP\IUserSession; - -/** - * A found file - * @deprecated 20.0.0 - */ -class File extends \OCP\Search\Result { - /** - * Type name; translated in templates - * @var string - * @deprecated 20.0.0 - */ - public $type = 'file'; - - /** - * Path to file - * @var string - * @deprecated 20.0.0 - */ - public $path; - - /** - * Size, in bytes - * @var int - * @deprecated 20.0.0 - */ - public $size; - - /** - * Date modified, in human readable form - * @var string - * @deprecated 20.0.0 - */ - public $modified; - - /** - * File mime type - * @var string - * @deprecated 20.0.0 - */ - public $mime_type; - - /** - * File permissions: - * - * @var string - * @deprecated 20.0.0 - */ - public $permissions; - - /** - * Has a preview - * - * @var string - * @deprecated 20.0.0 - */ - public $has_preview; - - /** - * Create a new file search result - * @param FileInfo $data file data given by provider - * @deprecated 20.0.0 - */ - public function __construct(FileInfo $data) { - $path = $this->getRelativePath($data->getPath()); - - $this->id = $data->getId(); - $this->name = $data->getName(); - $this->link = \OC::$server->getURLGenerator()->linkToRoute( - 'files.view.index', - [ - 'dir' => dirname($path), - 'scrollto' => $data->getName(), - ] - ); - $this->permissions = $data->getPermissions(); - $this->path = $path; - $this->size = $data->getSize(); - $this->modified = $data->getMtime(); - $this->mime_type = $data->getMimetype(); - $this->has_preview = $this->hasPreview($data); - } - - /** - * @var Folder $userFolderCache - * @deprecated 20.0.0 - */ - protected static $userFolderCache = null; - - /** - * converts a path relative to the users files folder - * eg /user/files/foo.txt -> /foo.txt - * @param string $path - * @return string relative path - * @deprecated 20.0.0 - */ - protected function getRelativePath($path) { - if (!isset(self::$userFolderCache)) { - $userSession = \OC::$server->get(IUserSession::class); - $userID = $userSession->getUser()->getUID(); - self::$userFolderCache = \OC::$server->getUserFolder($userID); - } - $relativePath = self::$userFolderCache->getRelativePath($path); - if ($relativePath === null) { - throw new \Exception("Search result not in user folder"); - } - return $relativePath; - } - - /** - * Is the preview available - * @param FileInfo $data - * @return bool - * @deprecated 20.0.0 - */ - protected function hasPreview($data) { - $previewManager = \OC::$server->get(IPreview::class); - return $previewManager->isAvailable($data); - } -} diff --git a/lib/private/Search/Result/Folder.php b/lib/private/Search/Result/Folder.php deleted file mode 100644 index 37de0a031a7..00000000000 --- a/lib/private/Search/Result/Folder.php +++ /dev/null @@ -1,21 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -namespace OC\Search\Result; - -/** - * A found folder - * @deprecated 20.0.0 - */ -class Folder extends File { - /** - * Type name; translated in templates - * @var string - * @deprecated 20.0.0 - */ - public $type = 'folder'; -} diff --git a/lib/private/Search/Result/Image.php b/lib/private/Search/Result/Image.php deleted file mode 100644 index e1333424017..00000000000 --- a/lib/private/Search/Result/Image.php +++ /dev/null @@ -1,25 +0,0 @@ -<?php - -/** - * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors - * SPDX-FileCopyrightText: 2016 ownCloud, Inc. - * SPDX-License-Identifier: AGPL-3.0-only - */ -namespace OC\Search\Result; - -/** - * A found image file - * @deprecated 20.0.0 - */ -class Image extends File { - /** - * Type name; translated in templates - * @var string - * @deprecated 20.0.0 - */ - public $type = 'image'; - - /** - * @TODO add EXIF information - */ -} diff --git a/lib/private/Search/SearchComposer.php b/lib/private/Search/SearchComposer.php index 8108c6bcde4..be366e8ba6c 100644 --- a/lib/private/Search/SearchComposer.php +++ b/lib/private/Search/SearchComposer.php @@ -10,9 +10,12 @@ namespace OC\Search; use InvalidArgumentException; use OC\AppFramework\Bootstrap\Coordinator; +use OC\Core\ResponseDefinitions; +use OCP\IAppConfig; use OCP\IURLGenerator; use OCP\IUser; use OCP\Search\FilterDefinition; +use OCP\Search\IExternalProvider; use OCP\Search\IFilter; use OCP\Search\IFilteringProvider; use OCP\Search\IInAppSearch; @@ -23,7 +26,10 @@ use Psr\Container\ContainerExceptionInterface; use Psr\Container\ContainerInterface; use Psr\Log\LoggerInterface; use RuntimeException; +use function array_filter; use function array_map; +use function array_values; +use function in_array; /** * Queries individual \OCP\Search\IProvider implementations and composes a @@ -43,6 +49,7 @@ use function array_map; * results are awaited or shown as they come in. * * @see IProvider::search() for the arguments of the individual search requests + * @psalm-import-type CoreUnifiedSearchProvider from ResponseDefinitions */ class SearchComposer { /** @@ -59,7 +66,8 @@ class SearchComposer { private Coordinator $bootstrapCoordinator, private ContainerInterface $container, private IURLGenerator $urlGenerator, - private LoggerInterface $logger + private LoggerInterface $logger, + private IAppConfig $appConfig, ) { $this->commonFilters = [ IFilter::BUILTIN_TERM => new FilterDefinition(IFilter::BUILTIN_TERM, FilterDefinition::TYPE_STRING), @@ -111,6 +119,8 @@ class SearchComposer { } } + $this->filterProviders(); + $this->loadFilters(); } @@ -130,7 +140,7 @@ class SearchComposer { } foreach ($provider->getSupportedFilters() as $filterName) { if ($this->getFilterDefinition($filterName, $providerId) === null) { - throw new InvalidArgumentException('Invalid filter '. $filterName); + throw new InvalidArgumentException('Invalid filter ' . $filterName); } } } @@ -156,7 +166,7 @@ class SearchComposer { * @param string $route the route the user is currently at * @param array $routeParameters the parameters of the route the user is currently at * - * @return array + * @return list<CoreUnifiedSearchProvider> */ public function getProviders(string $route, array $routeParameters): array { $this->loadLazyProviders(); @@ -169,6 +179,7 @@ class SearchComposer { if ($order === null) { return; } + $isExternalProvider = $provider instanceof IExternalProvider ? $provider->isExternalProvider() : false; $triggers = [$provider->getId()]; if ($provider instanceof IFilteringProvider) { $triggers += $provider->getAlternateIds(); @@ -183,7 +194,8 @@ class SearchComposer { 'name' => $provider->getName(), 'icon' => $this->fetchIcon($appId, $provider->getId()), 'order' => $order, - 'triggers' => $triggers, + 'isExternalProvider' => $isExternalProvider, + 'triggers' => array_values($triggers), 'filters' => $this->getFiltersType($filters, $provider->getId()), 'inAppSearch' => $provider instanceof IInAppSearch, ]; @@ -200,12 +212,31 @@ class SearchComposer { return $providers; } + /** + * Filter providers based on 'unified_search.providers_allowed' core app config array + * Will remove providers that are not in the allowed list + */ + private function filterProviders(): void { + $allowedProviders = $this->appConfig->getValueArray('core', 'unified_search.providers_allowed'); + + if (empty($allowedProviders)) { + return; + } + + foreach (array_keys($this->providers) as $providerId) { + if (!in_array($providerId, $allowedProviders, true)) { + unset($this->providers[$providerId]); + unset($this->handlers[$providerId]); + } + } + } + private function fetchIcon(string $appId, string $providerId): string { $icons = [ - [$providerId, $providerId.'.svg'], + [$providerId, $providerId . '.svg'], [$providerId, 'app.svg'], - [$appId, $providerId.'.svg'], - [$appId, $appId.'.svg'], + [$appId, $providerId . '.svg'], + [$appId, $appId . '.svg'], [$appId, 'app.svg'], ['core', 'places/default-app-icon.svg'], ]; diff --git a/lib/private/Search/SearchQuery.php b/lib/private/Search/SearchQuery.php index a78443922ae..791edb7a0f7 100644 --- a/lib/private/Search/SearchQuery.php +++ b/lib/private/Search/SearchQuery.php @@ -25,7 +25,7 @@ class SearchQuery implements ISearchQuery { private int $limit = self::LIMIT_DEFAULT, private int|string|null $cursor = null, private string $route = '', - private array $routeParameters = [], + private array $routeParameters = [], ) { } diff --git a/lib/private/Search/UnsupportedFilter.php b/lib/private/Search/UnsupportedFilter.php index bf251a91d31..ea520e6b872 100644 --- a/lib/private/Search/UnsupportedFilter.php +++ b/lib/private/Search/UnsupportedFilter.php @@ -12,6 +12,6 @@ use Exception; final class UnsupportedFilter extends Exception { public function __construct(string $filerName, $providerId) { - parent::__construct('Provider '.$providerId.' doesn’t support filter '.$filerName.'.'); + parent::__construct('Provider ' . $providerId . ' doesn’t support filter ' . $filerName . '.'); } } |