diff options
Diffstat (limited to 'core/Controller/UnifiedSearchController.php')
-rw-r--r-- | core/Controller/UnifiedSearchController.php | 124 |
1 files changed, 64 insertions, 60 deletions
diff --git a/core/Controller/UnifiedSearchController.php b/core/Controller/UnifiedSearchController.php index 3290307dc23..c770c6240df 100644 --- a/core/Controller/UnifiedSearchController.php +++ b/core/Controller/UnifiedSearchController.php @@ -3,35 +3,22 @@ declare(strict_types=1); /** - * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at> - * - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @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 OC\Core\Controller; +use InvalidArgumentException; +use OC\Core\ResponseDefinitions; use OC\Search\SearchComposer; use OC\Search\SearchQuery; -use OCP\AppFramework\OCSController; +use OC\Search\UnsupportedFilter; use OCP\AppFramework\Http; +use OCP\AppFramework\Http\Attribute\ApiRoute; +use OCP\AppFramework\Http\Attribute\NoAdminRequired; +use OCP\AppFramework\Http\Attribute\NoCSRFRequired; use OCP\AppFramework\Http\DataResponse; +use OCP\AppFramework\OCSController; use OCP\IRequest; use OCP\IURLGenerator; use OCP\IUserSession; @@ -39,31 +26,32 @@ use OCP\Route\IRouter; use OCP\Search\ISearchQuery; use Symfony\Component\Routing\Exception\ResourceNotFoundException; +/** + * @psalm-import-type CoreUnifiedSearchProvider from ResponseDefinitions + * @psalm-import-type CoreUnifiedSearchResult from ResponseDefinitions + */ class UnifiedSearchController extends OCSController { - private SearchComposer $composer; - private IUserSession $userSession; - private IRouter $router; - private IURLGenerator $urlGenerator; - - public function __construct(IRequest $request, - IUserSession $userSession, - SearchComposer $composer, - IRouter $router, - IURLGenerator $urlGenerator) { + public function __construct( + IRequest $request, + private IUserSession $userSession, + private SearchComposer $composer, + private IRouter $router, + private IURLGenerator $urlGenerator, + ) { parent::__construct('core', $request); - - $this->composer = $composer; - $this->userSession = $userSession; - $this->router = $router; - $this->urlGenerator = $urlGenerator; } /** - * @NoAdminRequired - * @NoCSRFRequired + * Get the providers for unified search * * @param string $from the url the user is currently at + * @return DataResponse<Http::STATUS_OK, list<CoreUnifiedSearchProvider>, array{}> + * + * 200: Providers returned */ + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/providers', root: '/search')] public function getProviders(string $from = ''): DataResponse { [$route, $parameters] = $this->getRouteInformation($from); @@ -74,42 +62,58 @@ class UnifiedSearchController extends OCSController { } /** - * @NoAdminRequired - * @NoCSRFRequired + * Launch a search for a specific search provider. * - * @param string $providerId - * @param string $term - * @param int|null $sortOrder - * @param int|null $limit - * @param int|string|null $cursor - * @param string $from + * Additional filters are available for each provider. + * Send a request to /providers endpoint to list providers with their available filters. * - * @return DataResponse + * @param string $providerId ID of the provider + * @param string $term Term to search + * @param int|null $sortOrder Order of entries + * @param int|null $limit Maximum amount of entries, limited to 25 + * @param int|string|null $cursor Offset for searching + * @param string $from The current user URL + * + * @return DataResponse<Http::STATUS_OK, CoreUnifiedSearchResult, array{}>|DataResponse<Http::STATUS_BAD_REQUEST, string, array{}> + * + * 200: Search entries returned + * 400: Searching is not possible */ - public function search(string $providerId, - string $term = '', - ?int $sortOrder = null, - ?int $limit = null, - $cursor = null, - string $from = ''): DataResponse { - if (empty(trim($term))) { - return new DataResponse(null, Http::STATUS_BAD_REQUEST); - } + #[NoAdminRequired] + #[NoCSRFRequired] + #[ApiRoute(verb: 'GET', url: '/providers/{providerId}/search', root: '/search')] + public function search( + string $providerId, + // Unused parameter for OpenAPI spec generator + string $term = '', + ?int $sortOrder = null, + ?int $limit = null, + $cursor = null, + string $from = '', + ): DataResponse { [$route, $routeParameters] = $this->getRouteInformation($from); + $limit ??= SearchQuery::LIMIT_DEFAULT; + $limit = max(1, min($limit, 25)); + + try { + $filters = $this->composer->buildFilterList($providerId, $this->request->getParams()); + } catch (UnsupportedFilter|InvalidArgumentException $e) { + return new DataResponse($e->getMessage(), Http::STATUS_BAD_REQUEST); + } return new DataResponse( $this->composer->search( $this->userSession->getUser(), $providerId, new SearchQuery( - $term, + $filters, $sortOrder ?? ISearchQuery::SORT_DATE_DESC, - $limit ?? SearchQuery::LIMIT_DEFAULT, + $limit, $cursor, $route, $routeParameters ) - ) + )->jsonSerialize() ); } |