aboutsummaryrefslogtreecommitdiffstats
path: root/lib/private/Collaboration/Reference/ReferenceManager.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Collaboration/Reference/ReferenceManager.php')
-rw-r--r--lib/private/Collaboration/Reference/ReferenceManager.php120
1 files changed, 49 insertions, 71 deletions
diff --git a/lib/private/Collaboration/Reference/ReferenceManager.php b/lib/private/Collaboration/Reference/ReferenceManager.php
index 2897410f5d6..9287b66b2a2 100644
--- a/lib/private/Collaboration/Reference/ReferenceManager.php
+++ b/lib/private/Collaboration/Reference/ReferenceManager.php
@@ -2,24 +2,8 @@
declare(strict_types=1);
/**
- * @copyright Copyright (c) 2022 Julius Härtl <jus@bitgrid.net>
- *
- * @author Julius Härtl <jus@bitgrid.net>
- *
- * @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/>.
+ * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
*/
namespace OC\Collaboration\Reference;
@@ -27,6 +11,7 @@ namespace OC\Collaboration\Reference;
use OC\AppFramework\Bootstrap\Coordinator;
use OC\Collaboration\Reference\File\FileReferenceProvider;
use OCP\Collaboration\Reference\IDiscoverableReferenceProvider;
+use OCP\Collaboration\Reference\IPublicReferenceProvider;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Collaboration\Reference\IReferenceProvider;
@@ -46,33 +31,22 @@ class ReferenceManager implements IReferenceManager {
/** @var IReferenceProvider[]|null */
private ?array $providers = null;
private ICache $cache;
- private Coordinator $coordinator;
- private ContainerInterface $container;
- private LinkReferenceProvider $linkReferenceProvider;
- private LoggerInterface $logger;
- private IConfig $config;
- private IUserSession $userSession;
-
- public function __construct(LinkReferenceProvider $linkReferenceProvider,
- ICacheFactory $cacheFactory,
- Coordinator $coordinator,
- ContainerInterface $container,
- LoggerInterface $logger,
- IConfig $config,
- IUserSession $userSession) {
- $this->linkReferenceProvider = $linkReferenceProvider;
+
+ public function __construct(
+ private LinkReferenceProvider $linkReferenceProvider,
+ ICacheFactory $cacheFactory,
+ private Coordinator $coordinator,
+ private ContainerInterface $container,
+ private LoggerInterface $logger,
+ private IConfig $config,
+ private IUserSession $userSession,
+ ) {
$this->cache = $cacheFactory->createDistributed('reference');
- $this->coordinator = $coordinator;
- $this->container = $container;
- $this->logger = $logger;
- $this->config = $config;
- $this->userSession = $userSession;
}
/**
* Extract a list of URLs from a text
*
- * @param string $text
* @return string[]
*/
public function extractReferences(string $text): array {
@@ -85,26 +59,20 @@ class ReferenceManager implements IReferenceManager {
/**
* Try to get a cached reference object from a reference string
- *
- * @param string $referenceId
- * @return IReference|null
*/
- public function getReferenceFromCache(string $referenceId): ?IReference {
- $matchedProvider = $this->getMatchedProvider($referenceId);
+ public function getReferenceFromCache(string $referenceId, bool $public = false, string $sharingToken = ''): ?IReference {
+ $matchedProvider = $this->getMatchedProvider($referenceId, $public);
if ($matchedProvider === null) {
return null;
}
- $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId);
+ $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId, $public, $sharingToken);
return $this->getReferenceByCacheKey($cacheKey);
}
/**
* Try to get a cached reference object from a full cache key
- *
- * @param string $cacheKey
- * @return IReference|null
*/
public function getReferenceByCacheKey(string $cacheKey): ?IReference {
$cached = $this->cache->get($cacheKey);
@@ -118,25 +86,32 @@ class ReferenceManager implements IReferenceManager {
/**
* Get a reference object from a reference string with a matching provider
* Use a cached reference if possible
- *
- * @param string $referenceId
- * @return IReference|null
*/
- public function resolveReference(string $referenceId): ?IReference {
- $matchedProvider = $this->getMatchedProvider($referenceId);
+ public function resolveReference(string $referenceId, bool $public = false, $sharingToken = ''): ?IReference {
+ $matchedProvider = $this->getMatchedProvider($referenceId, $public);
if ($matchedProvider === null) {
return null;
}
- $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId);
+ $cacheKey = $this->getFullCacheKey($matchedProvider, $referenceId, $public, $sharingToken);
$cached = $this->cache->get($cacheKey);
if ($cached) {
return Reference::fromCache($cached);
}
- $reference = $matchedProvider->resolveReference($referenceId);
+ $reference = null;
+ if ($public && $matchedProvider instanceof IPublicReferenceProvider) {
+ $reference = $matchedProvider->resolveReferencePublic($referenceId, $sharingToken);
+ } elseif ($matchedProvider instanceof IReferenceProvider) {
+ $reference = $matchedProvider->resolveReference($referenceId);
+ }
if ($reference) {
+ $cachePrefix = $matchedProvider->getCachePrefix($referenceId);
+ if ($cachePrefix !== '') {
+ // If a prefix is used we set an additional key to know when we need to delete by prefix during invalidateCache()
+ $this->cache->set('hasPrefix-' . md5($cachePrefix), true, self::CACHE_TTL);
+ }
$this->cache->set($cacheKey, Reference::toCache($reference), self::CACHE_TTL);
return $reference;
}
@@ -148,12 +123,14 @@ class ReferenceManager implements IReferenceManager {
* Try to match a reference string with all the registered providers
* Fallback to the link reference provider (using OpenGraph)
*
- * @param string $referenceId
- * @return IReferenceProvider|null the first matching provider
+ * @return IReferenceProvider|IPublicReferenceProvider|null the first matching provider
*/
- private function getMatchedProvider(string $referenceId): ?IReferenceProvider {
+ private function getMatchedProvider(string $referenceId, bool $public): null|IReferenceProvider|IPublicReferenceProvider {
$matchedProvider = null;
foreach ($this->getProviders() as $provider) {
+ if ($public && !($provider instanceof IPublicReferenceProvider)) {
+ continue;
+ }
$matchedProvider = $provider->matchReference($referenceId) ? $provider : null;
if ($matchedProvider !== null) {
break;
@@ -169,13 +146,14 @@ class ReferenceManager implements IReferenceManager {
/**
* Get a hashed full cache key from a key and prefix given by a provider
- *
- * @param IReferenceProvider $provider
- * @param string $referenceId
- * @return string
*/
- private function getFullCacheKey(IReferenceProvider $provider, string $referenceId): string {
- $cacheKey = $provider->getCacheKey($referenceId);
+ private function getFullCacheKey(IReferenceProvider $provider, string $referenceId, bool $public, string $sharingToken): string {
+ if ($public && !($provider instanceof IPublicReferenceProvider)) {
+ throw new \RuntimeException('Provider doesn\'t support public lookups');
+ }
+ $cacheKey = $public
+ ? $provider->getCacheKeyPublic($referenceId, $sharingToken)
+ : $provider->getCacheKey($referenceId);
return md5($provider->getCachePrefix($referenceId)) . (
$cacheKey !== null ? ('-' . md5($cacheKey)) : ''
);
@@ -183,14 +161,14 @@ class ReferenceManager implements IReferenceManager {
/**
* Remove a specific cache entry from its key+prefix
- *
- * @param string $cachePrefix
- * @param string|null $cacheKey
- * @return void
*/
public function invalidateCache(string $cachePrefix, ?string $cacheKey = null): void {
if ($cacheKey === null) {
- $this->cache->clear(md5($cachePrefix));
+ // clear might be a heavy operation, so we only do it if there have actually been keys set
+ if ($this->cache->remove('hasPrefix-' . md5($cachePrefix))) {
+ $this->cache->clear(md5($cachePrefix));
+ }
+
return;
}
@@ -253,7 +231,7 @@ class ReferenceManager implements IReferenceManager {
}
$configKey = 'provider-last-use_' . $providerId;
- $this->config->setUserValue($userId, 'references', $configKey, (string) $timestamp);
+ $this->config->setUserValue($userId, 'references', $configKey, (string)$timestamp);
return true;
}
return false;
@@ -276,7 +254,7 @@ class ReferenceManager implements IReferenceManager {
$timestamps = [];
foreach ($keys as $key) {
$providerId = substr($key, strlen($prefix));
- $timestamp = (int) $this->config->getUserValue($userId, 'references', $key);
+ $timestamp = (int)$this->config->getUserValue($userId, 'references', $key);
$timestamps[$providerId] = $timestamp;
}
return $timestamps;