From 46a6bd1bd6c0b1ecfc1a4303544065e033b2bc3a Mon Sep 17 00:00:00 2001 From: korelstar Date: Tue, 15 Sep 2020 21:45:28 +0200 Subject: [PATCH] add provider for Nextcloud's unified search --- css/global.scss | 1 + img/notes-trans.svg | 1 + lib/AppInfo/Application.php | 1 + lib/AppInfo/SearchProvider.php | 84 ++++++++++++++++++++++++++++++++++ lib/Service/NotesService.php | 33 +++++++++++++ 5 files changed, 120 insertions(+) create mode 100644 img/notes-trans.svg create mode 100644 lib/AppInfo/SearchProvider.php diff --git a/css/global.scss b/css/global.scss index 41ae33b2..0dcd63a4 100644 --- a/css/global.scss +++ b/css/global.scss @@ -1 +1,2 @@ @include icon-black-white('notes', 'notes', 1); +@include icon-black-white('notes-trans', 'notes', 1); diff --git a/img/notes-trans.svg b/img/notes-trans.svg new file mode 100644 index 00000000..1850accb --- /dev/null +++ b/img/notes-trans.svg @@ -0,0 +1 @@ + diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index fff09806..261fb666 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -20,6 +20,7 @@ class Application extends App implements IBootstrap { public function register(IRegistrationContext $context): void { $context->registerCapability(Capabilities::class); + $context->registerSearchProvider(SearchProvider::class); $context->registerDashboardWidget(DashboardWidget::class); $context->registerEventListener( BeforeTemplateRenderedEvent::class, diff --git a/lib/AppInfo/SearchProvider.php b/lib/AppInfo/SearchProvider.php new file mode 100644 index 00000000..aa680229 --- /dev/null +++ b/lib/AppInfo/SearchProvider.php @@ -0,0 +1,84 @@ +util = $util; + $this->notesService = $notesService; + $this->url = $url; + } + + + public function getId(): string { + return Application::APP_ID; + } + + public function getName(): string { + return $this->util->l10n->t('Notes'); + } + + public function getOrder(string $route, array $routeParameters): int { + if (strpos($route, 'files' . '.') === 0) { + return 25; + } elseif (strpos($route, Application::APP_ID . '.') === 0) { + return -1; + } + return 4; + } + + public function search(IUser $user, ISearchQuery $query): SearchResult { + $notes = $this->notesService->search($user->getUID(), $query->getTerm()); + // sort by modified time + usort($notes, function (Note $a, Note $b) { + return $b->getModified() - $a->getModified(); + }); + // create SearchResultEntry from Note + $result = array_map( + function (Note $note) : SearchResultEntry { + $excerpt = $note->getCategory(); + try { + $excerpt = $note->getExcerpt(); + } catch (\Throwable $e) { + } + return new SearchResultEntry( + '', + $note->getTitle(), + $excerpt, + $this->url->linkToRouteAbsolute('notes.page.index') . 'note/'.$note->getId(), + 'icon-notes-trans' + ); + }, + $notes + ); + return SearchResult::complete( + $this->getName(), + $result + ); + } +} diff --git a/lib/Service/NotesService.php b/lib/Service/NotesService.php index 3c940b8e..d7621be1 100644 --- a/lib/Service/NotesService.php +++ b/lib/Service/NotesService.php @@ -58,6 +58,39 @@ class NotesService { return $note; } + public function search(string $userId, string $search) : array { + $terms = preg_split('/\s+/', $search); + $notes = $this->getAll($userId)['notes']; + return array_values(array_filter( + $notes, + function (Note $note) use ($terms) : bool { + return $this->searchTermsInNote($note, $terms); + } + )); + } + private function searchTermsInNote(Note $note, array $terms) : bool { + try { + $d = $note->getData(); + $strings = [ $d['title'], $d['category'], $d['content'] ]; + foreach ($terms as $term) { + if (!$this->searchTermInData($strings, $term)) { + return false; + } + } + return true; + } catch (\Throwable $e) { + return false; + } + } + private function searchTermInData(array $strings, string $term) : bool { + foreach ($strings as $str) { + if (stripos($str, $term) !== false) { + return true; + } + } + return false; + } + /** * @throws \OCP\Files\NotPermittedException