use Closure;
use OCP\Calendar\Resource\IBackend as IResourceBackend;
use OCP\Calendar\Room\IBackend as IRoomBackend;
+use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\Talk\ITalkBackend;
use RuntimeException;
use function array_shift;
/** @var ServiceRegistration<ICalendarProvider>[] */
private $calendarProviders = [];
+ /** @var ServiceRegistration<IReferenceProvider>[] */
+ private array $referenceProviders = [];
+
/** @var ParameterRegistration[] */
private $sensitiveMethods = [];
);
}
+ public function registerReferenceProvider(string $class): void {
+ $this->context->registerReferenceProvider(
+ $this->appId,
+ $class
+ );
+ }
+
public function registerProfileLinkAction(string $actionClass): void {
$this->context->registerProfileLinkAction(
$this->appId,
$this->calendarProviders[] = new ServiceRegistration($appId, $class);
}
+ public function registerReferenceProvider(string $appId, string $class): void {
+ $this->referenceProviders[] = new ServiceRegistration($appId, $class);
+ }
+
/**
* @psalm-param class-string<ILinkAction> $actionClass
*/
return $this->calendarProviders;
}
+ /**
+ * @return ServiceRegistration<IReferenceProvider>[]
+ */
+ public function getReferenceProviders(): array {
+ return $this->referenceProviders;
+ }
+
/**
* @return ServiceRegistration<ILinkAction>[]
*/
namespace OC\Collaboration\Reference;
+use OC\AppFramework\Bootstrap\Coordinator;
use OCP\Collaboration\Reference\IReference;
use OCP\Collaboration\Reference\IReferenceManager;
use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\ICache;
use OCP\ICacheFactory;
+use Psr\Container\ContainerInterface;
+use Throwable;
+use function OCP\Log\logger;
class ReferenceManager implements IReferenceManager {
public const URL_PATTERN = '/(\s|\n|^)(https?:\/\/)?((?:[-A-Z0-9+_]+\.)+[-A-Z]+(?:\/[-A-Z0-9+&@#%?=~_|!:,.;()]*)*)(\s|\n|$)/mi';
public const CACHE_TTL = 60;
- /** @var IReferenceProvider[] */
- private array $providers = [];
+ /** @var IReferenceProvider[]|null */
+ private ?array $providers = null;
private ICache $cache;
+ private Coordinator $coordinator;
+ private ContainerInterface $container;
- private LinkReferenceProvider $linkReferenceProvider;
-
- public function __construct(LinkReferenceProvider $linkReferenceProvider, FileReferenceProvider $fileReferenceProvider, ICacheFactory $cacheFactory) {
- $this->registerReferenceProvider($fileReferenceProvider);
+ public function __construct(LinkReferenceProvider $linkReferenceProvider, ICacheFactory $cacheFactory, Coordinator $coordinator, ContainerInterface $container) {
$this->linkReferenceProvider = $linkReferenceProvider;
$this->cache = $cacheFactory->createDistributed('reference');
+ $this->coordinator = $coordinator;
+ $this->container = $container;
}
public function extractReferences(string $text): array {
private function getMatchedProvider(string $referenceId): ?IReferenceProvider {
$matchedProvider = null;
- foreach ($this->providers as $provider) {
+ foreach ($this->getProviders() as $provider) {
$matchedProvider = $provider->matchReference($referenceId) ? $provider : null;
}
$this->cache->remove($this->getCacheKey($matchedProvider, $referenceId));
}
- public function registerReferenceProvider(IReferenceProvider $provider): void {
- $this->providers[] = $provider;
+ /**
+ * @return IReferenceProvider[]
+ */
+ public function getProviders(): array {
+ if ($this->providers === null) {
+ $context = $this->coordinator->getRegistrationContext();
+ if ($context === null) {
+ return [];
+ }
+
+ $this->providers = array_filter(array_map(function ($registration): ?IReferenceProvider {
+ try {
+ /** @var IReferenceProvider $provider */
+ $provider = $this->container->get($registration->getService());
+ } catch (Throwable $e) {
+ logger()->error('Could not load reference provider ' . $registration->getService() . ': ' . $e->getMessage(), [
+ 'exception' => $e,
+ ]);
+ return null;
+ }
+
+ return $provider;
+ }, $context->getReferenceProviders()));
+
+ // TODO: Move to files app
+ $this->providers[] = $this->container->get(FileReferenceProvider::class);
+ }
+
+ return $this->providers;
}
}
use OCP\Authentication\TwoFactorAuth\IProvider;
use OCP\Calendar\ICalendarProvider;
use OCP\Capabilities\ICapability;
+use OCP\Collaboration\Reference\IReferenceProvider;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\Files\Template\ICustomTemplateProvider;
use OCP\IContainer;
*/
public function registerCalendarProvider(string $class): void;
+ /**
+ * Register a reference provider
+ *
+ * @param string $class
+ * @psalm-param class-string<IReferenceProvider> $class
+ * @since 25.0.0
+ */
+ public function registerReferenceProvider(string $class): void;
+
/**
* Register an implementation of \OCP\Profile\ILinkAction that
* will handle the implementation of a profile link action