From 2c699e090179a2ca235d28540b5999e27c36b9de Mon Sep 17 00:00:00 2001
From: Christoph Wurst <christoph@winzerhof-wurst.at>
Date: Mon, 22 Jun 2020 12:19:34 +0200
Subject: [PATCH] Migrate comments to unified search API

Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
---
 .../composer/composer/autoload_classmap.php   |   2 +
 .../composer/composer/autoload_static.php     |   2 +
 apps/comments/lib/AppInfo/Application.php     |   4 +-
 .../lib/Search/CommentsSearchResultEntry.php  |  31 +++++
 apps/comments/lib/Search/LegacyProvider.php   | 113 ++++++++++++++++
 apps/comments/lib/Search/Provider.php         | 125 +++++++-----------
 apps/comments/lib/Search/Result.php           |  22 +++
 7 files changed, 222 insertions(+), 77 deletions(-)
 create mode 100644 apps/comments/lib/Search/CommentsSearchResultEntry.php
 create mode 100644 apps/comments/lib/Search/LegacyProvider.php

diff --git a/apps/comments/composer/composer/autoload_classmap.php b/apps/comments/composer/composer/autoload_classmap.php
index d5d51c7a12c..5682d66468d 100644
--- a/apps/comments/composer/composer/autoload_classmap.php
+++ b/apps/comments/composer/composer/autoload_classmap.php
@@ -21,6 +21,8 @@ return array(
     'OCA\\Comments\\Listener\\LoadSidebarScripts' => $baseDir . '/../lib/Listener/LoadSidebarScripts.php',
     'OCA\\Comments\\Notification\\Listener' => $baseDir . '/../lib/Notification/Listener.php',
     'OCA\\Comments\\Notification\\Notifier' => $baseDir . '/../lib/Notification/Notifier.php',
+    'OCA\\Comments\\Search\\CommentsSearchResultEntry' => $baseDir . '/../lib/Search/CommentsSearchResultEntry.php',
+    'OCA\\Comments\\Search\\LegacyProvider' => $baseDir . '/../lib/Search/LegacyProvider.php',
     'OCA\\Comments\\Search\\Provider' => $baseDir . '/../lib/Search/Provider.php',
     'OCA\\Comments\\Search\\Result' => $baseDir . '/../lib/Search/Result.php',
 );
diff --git a/apps/comments/composer/composer/autoload_static.php b/apps/comments/composer/composer/autoload_static.php
index 1292415290b..87a2127c144 100644
--- a/apps/comments/composer/composer/autoload_static.php
+++ b/apps/comments/composer/composer/autoload_static.php
@@ -36,6 +36,8 @@ class ComposerStaticInitComments
         'OCA\\Comments\\Listener\\LoadSidebarScripts' => __DIR__ . '/..' . '/../lib/Listener/LoadSidebarScripts.php',
         'OCA\\Comments\\Notification\\Listener' => __DIR__ . '/..' . '/../lib/Notification/Listener.php',
         'OCA\\Comments\\Notification\\Notifier' => __DIR__ . '/..' . '/../lib/Notification/Notifier.php',
+        'OCA\\Comments\\Search\\CommentsSearchResultEntry' => __DIR__ . '/..' . '/../lib/Search/CommentsSearchResultEntry.php',
+        'OCA\\Comments\\Search\\LegacyProvider' => __DIR__ . '/..' . '/../lib/Search/LegacyProvider.php',
         'OCA\\Comments\\Search\\Provider' => __DIR__ . '/..' . '/../lib/Search/Provider.php',
         'OCA\\Comments\\Search\\Result' => __DIR__ . '/..' . '/../lib/Search/Result.php',
     );
diff --git a/apps/comments/lib/AppInfo/Application.php b/apps/comments/lib/AppInfo/Application.php
index 8bcf17b2afe..fafac0c6040 100644
--- a/apps/comments/lib/AppInfo/Application.php
+++ b/apps/comments/lib/AppInfo/Application.php
@@ -35,6 +35,7 @@ use OCA\Comments\Listener\CommentsEntityEventListener;
 use OCA\Comments\Listener\LoadAdditionalScripts;
 use OCA\Comments\Listener\LoadSidebarScripts;
 use OCA\Comments\Notification\Notifier;
+use OCA\Comments\Search\LegacyProvider;
 use OCA\Comments\Search\Provider;
 use OCA\Files\Event\LoadAdditionalScriptsEvent;
 use OCA\Files\Event\LoadSidebar;
@@ -70,6 +71,7 @@ class Application extends App implements IBootstrap {
 			CommentsEntityEvent::EVENT_ENTITY,
 			CommentsEntityEventListener::class
 		);
+		$context->registerSearchProvider(Provider::class);
 	}
 
 	public function boot(IBootContext $context): void {
@@ -79,7 +81,7 @@ class Application extends App implements IBootstrap {
 		$jsSettingsHelper = new JSSettingsHelper($context->getServerContainer());
 		Util::connectHook('\OCP\Config', 'js', $jsSettingsHelper, 'extend');
 
-		$context->getServerContainer()->getSearch()->registerProvider(Provider::class, ['apps' => ['files']]);
+		$context->getServerContainer()->getSearch()->registerProvider(LegacyProvider::class, ['apps' => ['files']]);
 	}
 
 	protected function registerNotifier(IServerContainer $container) {
diff --git a/apps/comments/lib/Search/CommentsSearchResultEntry.php b/apps/comments/lib/Search/CommentsSearchResultEntry.php
new file mode 100644
index 00000000000..de24cf9cc52
--- /dev/null
+++ b/apps/comments/lib/Search/CommentsSearchResultEntry.php
@@ -0,0 +1,31 @@
+<?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 OCA\Comments\Search;
+
+use OCP\Search\ASearchResultEntry;
+
+class CommentsSearchResultEntry extends ASearchResultEntry {
+}
diff --git a/apps/comments/lib/Search/LegacyProvider.php b/apps/comments/lib/Search/LegacyProvider.php
new file mode 100644
index 00000000000..abcb8535f5c
--- /dev/null
+++ b/apps/comments/lib/Search/LegacyProvider.php
@@ -0,0 +1,113 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
+ *
+ * @author Joas Schilling <coding@schilljs.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/>.
+ *
+ */
+
+namespace OCA\Comments\Search;
+
+use OCP\Comments\IComment;
+use OCP\Files\Folder;
+use OCP\Files\Node;
+use OCP\Files\NotFoundException;
+use OCP\IUser;
+use OCP\Search\Provider;
+use function count;
+
+class LegacyProvider extends Provider {
+
+	/**
+	 * Search for $query
+	 *
+	 * @param string $query
+	 * @return array An array of OCP\Search\Result's
+	 * @since 7.0.0
+	 */
+	public function search($query): array {
+		$cm = \OC::$server->getCommentsManager();
+		$us = \OC::$server->getUserSession();
+
+		$user = $us->getUser();
+		if (!$user instanceof IUser) {
+			return [];
+		}
+		$uf = \OC::$server->getUserFolder($user->getUID());
+
+		if ($uf === null) {
+			return [];
+		}
+
+		$result = [];
+		$numComments = 50;
+		$offset = 0;
+
+		while (count($result) < $numComments) {
+			/** @var IComment[] $comments */
+			$comments = $cm->search($query, 'files', '', 'comment', $offset, $numComments);
+
+			foreach ($comments as $comment) {
+				if ($comment->getActorType() !== 'users') {
+					continue;
+				}
+
+				$displayName = $cm->resolveDisplayName('user', $comment->getActorId());
+
+				try {
+					$file = $this->getFileForComment($uf, $comment);
+					$result[] = new Result($query,
+						$comment,
+						$displayName,
+						$file->getPath()
+					);
+				} catch (NotFoundException $e) {
+					continue;
+				}
+			}
+
+			if (count($comments) < $numComments) {
+				// Didn't find more comments when we tried to get, so there are no more comments.
+				return $result;
+			}
+
+			$offset += $numComments;
+			$numComments = 50 - count($result);
+		}
+
+		return $result;
+	}
+
+	/**
+	 * @param Folder $userFolder
+	 * @param IComment $comment
+	 * @return Node
+	 * @throws NotFoundException
+	 */
+	protected function getFileForComment(Folder $userFolder, IComment $comment): Node {
+		$nodes = $userFolder->getById((int) $comment->getObjectId());
+		if (empty($nodes)) {
+			throw new NotFoundException('File not found');
+		}
+
+		return array_shift($nodes);
+	}
+}
diff --git a/apps/comments/lib/Search/Provider.php b/apps/comments/lib/Search/Provider.php
index ad3b63d46b5..0c0561c988c 100644
--- a/apps/comments/lib/Search/Provider.php
+++ b/apps/comments/lib/Search/Provider.php
@@ -1,8 +1,11 @@
 <?php
+
+declare(strict_types=1);
+
 /**
- * @copyright Copyright (c) 2018 Joas Schilling <coding@schilljs.com>
+ * @copyright 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
  *
- * @author Joas Schilling <coding@schilljs.com>
+ * @author 2020 Christoph Wurst <christoph@winzerhof-wurst.at>
  *
  * @license GNU AGPL version 3 or any later version
  *
@@ -17,92 +20,62 @@
  * 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/>.
- *
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
 namespace OCA\Comments\Search;
 
-use OCP\Comments\IComment;
-use OCP\Files\Folder;
-use OCP\Files\Node;
-use OCP\Files\NotFoundException;
+use OCP\IL10N;
+use OCP\IURLGenerator;
 use OCP\IUser;
+use OCP\Search\IProvider;
+use OCP\Search\ISearchQuery;
+use OCP\Search\SearchResult;
+use function array_map;
+use function pathinfo;
 
-class Provider extends \OCP\Search\Provider {
-
-	/**
-	 * Search for $query
-	 *
-	 * @param string $query
-	 * @return array An array of OCP\Search\Result's
-	 * @since 7.0.0
-	 */
-	public function search($query): array {
-		$cm = \OC::$server->getCommentsManager();
-		$us = \OC::$server->getUserSession();
-
-		$user = $us->getUser();
-		if (!$user instanceof IUser) {
-			return [];
-		}
-		$uf = \OC::$server->getUserFolder($user->getUID());
-
-		if ($uf === null) {
-			return [];
-		}
+class Provider implements IProvider {
 
-		$result = [];
-		$numComments = 50;
-		$offset = 0;
+	/** @var IL10N */
+	private $l10n;
 
-		while (\count($result) < $numComments) {
-			/** @var IComment[] $comments */
-			$comments = $cm->search($query, 'files', '', 'comment', $offset, $numComments);
+	/** @var IURLGenerator */
+	private $urlGenerator;
 
-			foreach ($comments as $comment) {
-				if ($comment->getActorType() !== 'users') {
-					continue;
-				}
+	/** @var LegacyProvider */
+	private $legacyProvider;
 
-				$displayName = $cm->resolveDisplayName('user', $comment->getActorId());
-
-				try {
-					$file = $this->getFileForComment($uf, $comment);
-					$result[] = new Result($query,
-						$comment,
-						$displayName,
-						$file->getPath()
-					);
-				} catch (NotFoundException $e) {
-					continue;
-				}
-			}
-
-			if (\count($comments) < $numComments) {
-				// Didn't find more comments when we tried to get, so there are no more comments.
-				return $result;
-			}
-
-			$offset += $numComments;
-			$numComments = 50 - \count($result);
-		}
-
-		return $result;
+	public function __construct(IL10N $l10n,
+								IURLGenerator $urlGenerator,
+								LegacyProvider $legacyProvider) {
+		$this->l10n = $l10n;
+		$this->urlGenerator = $urlGenerator;
+		$this->legacyProvider = $legacyProvider;
 	}
 
-	/**
-	 * @param Folder $userFolder
-	 * @param IComment $comment
-	 * @return Node
-	 * @throws NotFoundException
-	 */
-	protected function getFileForComment(Folder $userFolder, IComment $comment): Node {
-		$nodes = $userFolder->getById((int) $comment->getObjectId());
-		if (empty($nodes)) {
-			throw new NotFoundException('File not found');
-		}
+	public function getId(): string {
+		return 'comments';
+	}
 
-		return array_shift($nodes);
+	public function search(IUser $user, ISearchQuery $query): SearchResult {
+		return SearchResult::complete(
+			$this->l10n->t('Comments'),
+			array_map(function (Result $result) {
+				$path = $result->path;
+				$pathInfo = pathinfo($path);
+				return new CommentsSearchResultEntry(
+					$this->urlGenerator->linkToRoute('core.Preview.getPreviewByFileId', ['x' => 32, 'y' => 32, 'fileId' => $result->id]),
+					$result->name,
+					$path,
+					$this->urlGenerator->linkToRoute(
+						'files.view.index',
+						[
+							'dir' => $pathInfo['dirname'],
+							'scrollto' => $pathInfo['basename'],
+						]
+					)
+				);
+			}, $this->legacyProvider->search($query->getTerm()))
+		);
 	}
 }
diff --git a/apps/comments/lib/Search/Result.php b/apps/comments/lib/Search/Result.php
index 9f0e6936320..d0e9902c1fb 100644
--- a/apps/comments/lib/Search/Result.php
+++ b/apps/comments/lib/Search/Result.php
@@ -28,12 +28,33 @@ use OCP\Comments\IComment;
 use OCP\Files\NotFoundException;
 use OCP\Search\Result as BaseResult;
 
+/**
+ * @deprecated 20.0.0
+ */
 class Result extends BaseResult {
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $type = 'comment';
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $comment;
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $authorId;
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $authorName;
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $path;
+	/**
+	 * @deprecated 20.0.0
+	 */
 	public $fileName;
 
 	/**
@@ -42,6 +63,7 @@ class Result extends BaseResult {
 	 * @param string $authorName
 	 * @param string $path
 	 * @throws NotFoundException
+	 * @deprecated 20.0.0
 	 */
 	public function __construct(string $search,
 								IComment $comment,
-- 
GitLab