diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index a3545e99f..0cd87502a 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -62,6 +62,7 @@ use OCA\Circles\Notification\Notifier; use OCA\Circles\Service\ConfigService; use OCA\Circles\Service\DavService; +use OCA\Circles\UnifiedSearch\UnifiedSearchProvider; use OCP\App\ManagerEvent; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; @@ -155,6 +156,7 @@ public function register(IRegistrationContext $context): void { } ); + $context->registerSearchProvider(UnifiedSearchProvider::class); $context->registerWellKnownHandler(WebfingerHandler::class); $this->loadExampleEvents($context); diff --git a/lib/Service/CircleService.php b/lib/Service/CircleService.php index d4ec6a3b9..d1b4905f2 100644 --- a/lib/Service/CircleService.php +++ b/lib/Service/CircleService.php @@ -66,6 +66,7 @@ use OCA\Circles\Model\Probes\CircleProbe; use OCA\Circles\Model\Probes\MemberProbe; use OCA\Circles\StatusCode; +use OCP\IL10N; /** * Class CircleService @@ -78,6 +79,9 @@ class CircleService { use TNC22Logger; + /** @var IL10N */ + private $l10n; + /** @var CircleRequest */ private $circleRequest; @@ -112,6 +116,7 @@ class CircleService { * @param ConfigService $configService */ public function __construct( + IL10N $l10n, CircleRequest $circleRequest, MemberRequest $memberRequest, RemoteStreamService $remoteStreamService, @@ -120,6 +125,7 @@ public function __construct( MemberService $memberService, ConfigService $configService ) { + $this->l10n = $l10n; $this->circleRequest = $circleRequest; $this->memberRequest = $memberRequest; $this->remoteStreamService = $remoteStreamService; @@ -603,4 +609,25 @@ public function cleanCircleName(string $name): string { return trim($name); } + + + /** + * @param Circle $circle + * + * @return string + */ + public function getDefinition(Circle $circle): string { + $source = Circle::$DEF_SOURCE[$circle->getSource()]; + if ($circle->isConfig(Circle::CFG_NO_OWNER)) { + return $this->l10n->t('%s', [$source]); + } + + return $this->l10n->t( + '%s owned by %s', + [ + $source, + $this->configService->displayFederatedUser($circle->getOwner(), true) + ] + ); + } } diff --git a/lib/UnifiedSearch/UnifiedSearchProvider.php b/lib/UnifiedSearch/UnifiedSearchProvider.php new file mode 100644 index 000000000..dc5ec91c3 --- /dev/null +++ b/lib/UnifiedSearch/UnifiedSearchProvider.php @@ -0,0 +1,177 @@ + + * @copyright 2021 + * @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 . + * + */ + + +namespace OCA\Circles\UnifiedSearch; + +use ArtificialOwl\MySmallPhpTools\Traits\Nextcloud\nc22\TNC22Logger; +use Exception; +use OCA\Circles\AppInfo\Application; +use OCA\Circles\Model\Circle; +use OCA\Circles\Model\Probes\CircleProbe; +use OCA\Circles\Service\CircleService; +use OCA\Circles\Service\FederatedUserService; +use OCP\IL10N; +use OCP\IURLGenerator; +use OCP\IUser; +use OCP\Search\IProvider; +use OCP\Search\ISearchQuery; +use OCP\Search\SearchResult; + +/** + * Class UnifiedSearchProvider + * + * @package OCA\Circles\UnifiedSearch + */ +class UnifiedSearchProvider implements IProvider { + use TNC22Logger; + + + public const ORDER = 9; + + + /** @var IL10N */ + private $l10n; + + /** @var IURLGenerator */ + private $urlGenerator; + + /** @var FederatedUserService */ + private $federatedUserService; + + /** @var CircleService */ + private $circleService; + + + /** + * UnifiedSearchProvider constructor. + * + * @param IL10N $l10n + * @param IURLGenerator $urlGenerator + * @param FederatedUserService $federatedUserService + * @param CircleService $circleService + */ + public function __construct( + IL10N $l10n, + IURLGenerator $urlGenerator, + FederatedUserService $federatedUserService, + CircleService $circleService + ) { + $this->l10n = $l10n; + $this->urlGenerator = $urlGenerator; + $this->federatedUserService = $federatedUserService; + $this->circleService = $circleService; + + $this->setup('app', Application::APP_ID); + } + + + /** + * return unique id of the provider + */ + public function getId(): string { + return Application::APP_ID; + } + + + /** + * @return string + */ + public function getName(): string { + return $this->l10n->t('Circles'); + } + + + /** + * @param string $route + * @param array $routeParameters + * + * @return int + */ + public function getOrder(string $route, array $routeParameters): int { + return self::ORDER; + } + + + /** + * @param IUser $user + * @param ISearchQuery $query + * + * @return SearchResult + */ + public function search(IUser $user, ISearchQuery $query): SearchResult { + $result = []; + + $circle = new Circle(); + $circle->setDisplayName($query->getTerm()); + + $probe = new CircleProbe(); + $probe->filterHiddenCircles() + ->filterBackendCircles(); + $probe->setFilterCircle($circle); + + try { + $this->federatedUserService->initCurrentUser(); + $circles = $this->circleService->getCircles($probe); + $result = $this->convertSearchResult($circles); + } catch (Exception $e) { + } + + return SearchResult::paginated( + $this->getName(), + $result, + ($query->getCursor() ?? 0) + $query->getLimit() + ); + } + + + /** + * @param Circle[] $circles + * + * @return UnifiedSearchResult[] + */ + private function convertSearchResult(array $circles): array { + $result = []; + + $iconPath = $this->urlGenerator->imagePath(Application::APP_ID, 'circles.svg'); + $icon = $this->urlGenerator->getAbsoluteURL($iconPath); + foreach ($circles as $circle) { + $result[] = new UnifiedSearchResult( + '', + $circle->getDisplayName(), + $this->circleService->getDefinition($circle), + $circle->getUrl(), + $icon + ); + } + + return $result; + } +} diff --git a/lib/UnifiedSearch/UnifiedSearchResult.php b/lib/UnifiedSearch/UnifiedSearchResult.php new file mode 100644 index 000000000..302dfd709 --- /dev/null +++ b/lib/UnifiedSearch/UnifiedSearchResult.php @@ -0,0 +1,63 @@ + + * @copyright 2021 + * @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 . + * + */ + + +namespace OCA\Circles\UnifiedSearch; + +use OCP\Search\SearchResultEntry; + +/** + * Class UnifiedSearchResult + * + * @package OCA\Circles\UnifiedSearch + */ +class UnifiedSearchResult extends SearchResultEntry { + + /** + * UnifiedSearchResult constructor. + * + * @param string $thumbnailUrl + * @param string $title + * @param string $subtitle + * @param string $resourceUrl + * @param string $icon + * @param bool $rounded + */ + public function __construct( + string $thumbnailUrl = '', + string $title = '', + string $subtitle = '', + string $resourceUrl = '', + string $icon = '', + bool $rounded = false + ) { + parent::__construct($thumbnailUrl, $title, $subtitle, $resourceUrl, $icon, $rounded); + } +}