bookmarks/lib/Reference/BookmarkReferenceProvider.php

151 lines
4.2 KiB
PHP

<?php
/*
* @copyright Copyright (c) 2022 Julien Veyssier <eneiluj@posteo.net>
*
* @author Julien Veyssier <eneiluj@posteo.net>
* @author The Nextcloud Bookmarks contributors
*
* This file is licensed under the Affero General Public License version 3 or later. See the COPYING file.
*/
namespace OCA\Bookmarks\Reference;
use OCA\Bookmarks\AppInfo\Application;
use OCA\Bookmarks\Exception\UrlParseError;
use OCA\Bookmarks\Service\Authorizer;
use OCA\Bookmarks\Service\BookmarkService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\Collaboration\Reference\ADiscoverableReferenceProvider;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\Reference;
use OCP\IL10N;
use OCP\IURLGenerator;
class BookmarkReferenceProvider extends ADiscoverableReferenceProvider {
private ?string $userId;
private IL10N $l10n;
private IURLGenerator $urlGenerator;
private BookmarkService $bookmarkService;
private Authorizer $authorizer;
public function __construct(IL10N $l10n, ?string $userId, IURLGenerator $urlGenerator, BookmarkService $bookmarkService, Authorizer $authorizer) {
$this->userId = $userId;
$this->l10n = $l10n;
$this->urlGenerator = $urlGenerator;
$this->bookmarkService = $bookmarkService;
$this->authorizer = $authorizer;
}
/**
* @inheritDoc
*/
public function getId(): string {
return Application::APP_ID . '-ref-bookmarks';
}
/**
* @inheritDoc
*/
public function getTitle(): string {
return $this->l10n->t('Bookmarks');
}
/**
* @inheritDoc
*/
public function getOrder(): int {
return 10;
}
/**
* @inheritDoc
*/
public function getIconUrl(): string {
return $this->urlGenerator->getAbsoluteURL(
$this->urlGenerator->imagePath(Application::APP_ID, 'bookmarks-black.svg')
);
}
/**
* @inheritDoc
*/
public function matchReference(string $referenceText): bool {
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
// link example: https://nextcloud.local/index.php/apps/deck/#/board/2/card/11
$noIndexMatch = preg_match('/^' . preg_quote($start, '/') . '\/bookmarks\/[0-9]+$/', $referenceText) === 1;
$indexMatch = preg_match('/^' . preg_quote($startIndex, '/') . '\/bookmarks\/[0-9]+$/', $referenceText) === 1;
if ($noIndexMatch || $indexMatch) {
return true;
}
try {
$this->bookmarkService->findByUrl($this->userId, $referenceText);
return true;
} catch (UrlParseError|DoesNotExistException $e) {
return false;
}
}
/**
* @inheritDoc
*/
public function resolveReference(string $referenceText): ?IReference {
if (!$this->matchReference($referenceText)) {
return null;
}
$id = $this->getBookmarkId($referenceText);
if ($id === null) {
try {
$bookmark = $this->bookmarkService->findByUrl($this->userId, $referenceText);
} catch (UrlParseError|DoesNotExistException $e) {
return null;
}
} else {
$bookmark = $this->bookmarkService->findById((int)$id);
}
if ($bookmark === null) {
return null;
}
if (!Authorizer::hasPermission(Authorizer::PERM_READ, $this->authorizer->getUserPermissionsForBookmark($this->userId, (int)$id))) {
return null;
}
/** @var IReference $reference */
$reference = new Reference($referenceText);
$reference->setRichObject(Application::APP_ID . '-bookmark', [
'id' => $id,
'bookmark' => $bookmark->toArray(),
]);
return $reference;
}
private function getBookmarkId(string $url): ?string {
$start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID);
$startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID);
preg_match('/^' . preg_quote($start, '/') . '\/bookmarks\/([0-9]+)$/', $url, $matches);
if ($matches && count($matches) > 1) {
return $matches[1];
}
preg_match('/^' . preg_quote($startIndex, '/') . '\/bookmarks\/([0-9]+)$/', $url, $matches2);
if ($matches2 && count($matches2) > 1) {
return $matches2[1];
}
return null;
}
public function getCachePrefix(string $referenceId): string {
$id = $this->getBookmarkId($referenceId);
return $id ?? $referenceId;
}
public function getCacheKey(string $referenceId): ?string {
return $this->userId ?? '';
}
}