From 470810c290624a5f09930bfeb8572525a96ec8d8 Mon Sep 17 00:00:00 2001 From: Christian Hartmann Date: Fri, 3 Jan 2025 15:44:56 +0100 Subject: [PATCH] make Forms available in unified search Signed-off-by: Christian Hartmann --- lib/AppInfo/Application.php | 2 + lib/Db/FormMapper.php | 16 ++++++- lib/Search/FormsSearchResultEntry.php | 18 +++++++ lib/Search/SearchProvider.php | 68 +++++++++++++++++++++++++++ lib/Service/FormsService.php | 28 +++++++++++ 5 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 lib/Search/FormsSearchResultEntry.php create mode 100644 lib/Search/SearchProvider.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 1dbf407bc..319e48f3e 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -14,6 +14,7 @@ use OCA\Forms\FormsMigrator; use OCA\Forms\Listener\AnalyticsDatasourceListener; use OCA\Forms\Listener\UserDeletedListener; +use OCA\Forms\Search\SearchProvider; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; @@ -42,6 +43,7 @@ public function register(IRegistrationContext $context): void { $context->registerCapability(Capabilities::class); $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); $context->registerEventListener(DatasourceEvent::class, AnalyticsDatasourceListener::class); + $context->registerSearchProvider(SearchProvider::class); $context->registerUserMigrator(FormsMigrator::class); } diff --git a/lib/Db/FormMapper.php b/lib/Db/FormMapper.php index 89a032f3b..a785d5893 100644 --- a/lib/Db/FormMapper.php +++ b/lib/Db/FormMapper.php @@ -97,9 +97,10 @@ public function findByHash(string $hash): Form { * @param string[] $groups IDs of groups the user is memeber of * @param string[] $teams IDs of teams the user is memeber of * @param bool $filterShown Set to false to also include forms shared but not visible on sidebar + * @param string $queryTerm optional: The search query for universal search * @return Form[] */ - public function findSharedForms(string $userId, array $groups = [], array $teams = [], bool $filterShown = true): array { + public function findSharedForms(string $userId, array $groups = [], array $teams = [], bool $filterShown = true, ?string $queryTerm = null): array { $qbShares = $this->db->getQueryBuilder(); $qbForms = $this->db->getQueryBuilder(); @@ -156,6 +157,11 @@ public function findSharedForms(string $userId, array $groups = [], array $teams ->addOrderBy('last_updated', 'DESC') ->addOrderBy('created', 'DESC'); + if ($queryTerm) { + $qbForms->andWhere($qbForms->expr()->like('title', $qbForms->createNamedParameter('%' . $queryTerm . '%')) . + ' OR ' . $qbForms->expr()->like('description', $qbForms->createNamedParameter('%' . $queryTerm . '%'))); + } + // We need to add the parameters from the shared forms IDs select to the final select query $qbForms->setParameters($qbShares->getParameters(), $qbShares->getParameterTypes()); @@ -163,9 +169,10 @@ public function findSharedForms(string $userId, array $groups = [], array $teams } /** + * @param string $queryTerm optional: The search query for universal search * @return Form[] */ - public function findAllByOwnerId(string $ownerId): array { + public function findAllByOwnerId(string $ownerId, ?string $queryTerm = null): array { $qb = $this->db->getQueryBuilder(); $qb->select('*') @@ -177,6 +184,11 @@ public function findAllByOwnerId(string $ownerId): array { ->addOrderBy('last_updated', 'DESC') ->addOrderBy('created', 'DESC'); + if ($queryTerm) { + $qb->andWhere($qb->expr()->like('title', $qb->createNamedParameter('%' . $queryTerm . '%')) . + ' OR ' . $qb->expr()->like('description', $qb->createNamedParameter('%' . $queryTerm . '%'))); + } + return $this->findEntities($qb); } diff --git a/lib/Search/FormsSearchResultEntry.php b/lib/Search/FormsSearchResultEntry.php new file mode 100644 index 000000000..7e0814e5a --- /dev/null +++ b/lib/Search/FormsSearchResultEntry.php @@ -0,0 +1,18 @@ +getTitle(), $form->getDescription(), $formUrl, 'forms-dark'); + } +} diff --git a/lib/Search/SearchProvider.php b/lib/Search/SearchProvider.php new file mode 100644 index 000000000..149e6161c --- /dev/null +++ b/lib/Search/SearchProvider.php @@ -0,0 +1,68 @@ +l10n->t('Forms'); + } + + public function search(IUser $user, ISearchQuery $query): SearchResult { + $forms = $this->formsService->search($query); + + $results = array_map(function (Form $form) { + $formUrl = $this->urlGenerator->linkToRoute('forms.page.views', ['hash' => $form->getHash(), 'view' => 'submit']); + return [ + 'object' => $form, + 'entry' => new FormsSearchResultEntry($form, $formUrl) + ]; + }, $forms); + + $resultEntries = array_map(function (array $result) { + return $result['entry']; + }, $results); + + return SearchResult::complete( + $this->l10n->t('Forms'), + $resultEntries + ); + } + + public function getOrder(string $route, array $routeParameters): int { + if (str_contains($route, Application::APP_ID)) { + // Active app, prefer my results + return -1; + } + return 77; + } +} diff --git a/lib/Service/FormsService.php b/lib/Service/FormsService.php index d9be9a3c8..62a85799c 100644 --- a/lib/Service/FormsService.php +++ b/lib/Service/FormsService.php @@ -29,6 +29,7 @@ use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; +use OCP\Search\ISearchQuery; use OCP\Security\ISecureRandom; use OCP\Share\IShare; @@ -698,6 +699,33 @@ public function areExtraSettingsValid(array $extraSettings, string $questionType return true; } + /** + * Get list of forms + * + * @param ISearchQuery $query the query to search the forms + * @return Form[] list of forms that match the query + */ + public function search(ISearchQuery $query): array { + $formsList = []; + $groups = $this->groupManager->getUserGroupIds($this->currentUser); + $teams = $this->circlesService->getUserTeamIds($this->currentUser->getUID()); + + try { + $ownedForms = $this->formMapper->findAllByOwnerId($this->currentUser->getUID(), $query->getTerm()); + $sharedForms = $this->formMapper->findSharedForms( + $this->currentUser->getUID(), + $groups, + $teams, + true, + $query->getTerm() + ); + $formsList = array_merge($ownedForms, $sharedForms); + } catch (DoesNotExistException $e) { + // silent catch + } + return $formsList; + } + public function getFilePath(Form $form): ?string { $fileId = $form->getFileId();