123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362 |
- <?php
- /**
- * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
- * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
- * SPDX-License-Identifier: AGPL-3.0-only
- */
- namespace OC\Activity;
- use OCP\Activity\ActivitySettings;
- use OCP\Activity\Exceptions\FilterNotFoundException;
- use OCP\Activity\Exceptions\IncompleteActivityException;
- use OCP\Activity\Exceptions\SettingNotFoundException;
- use OCP\Activity\IConsumer;
- use OCP\Activity\IEvent;
- use OCP\Activity\IFilter;
- use OCP\Activity\IManager;
- use OCP\Activity\IProvider;
- use OCP\Activity\ISetting;
- use OCP\IConfig;
- use OCP\IL10N;
- use OCP\IRequest;
- use OCP\IUser;
- use OCP\IUserSession;
- use OCP\RichObjectStrings\IValidator;
- class Manager implements IManager {
- /** @var IRequest */
- protected $request;
- /** @var IUserSession */
- protected $session;
- /** @var IConfig */
- protected $config;
- /** @var IValidator */
- protected $validator;
- /** @var string */
- protected $formattingObjectType;
- /** @var int */
- protected $formattingObjectId;
- /** @var bool */
- protected $requirePNG = false;
- /** @var string */
- protected $currentUserId;
- protected $l10n;
- public function __construct(
- IRequest $request,
- IUserSession $session,
- IConfig $config,
- IValidator $validator,
- IL10N $l10n
- ) {
- $this->request = $request;
- $this->session = $session;
- $this->config = $config;
- $this->validator = $validator;
- $this->l10n = $l10n;
- }
- /** @var \Closure[] */
- private $consumersClosures = [];
- /** @var IConsumer[] */
- private $consumers = [];
- /**
- * @return \OCP\Activity\IConsumer[]
- */
- protected function getConsumers(): array {
- if (!empty($this->consumers)) {
- return $this->consumers;
- }
- $this->consumers = [];
- foreach ($this->consumersClosures as $consumer) {
- $c = $consumer();
- if ($c instanceof IConsumer) {
- $this->consumers[] = $c;
- } else {
- throw new \InvalidArgumentException('The given consumer does not implement the \OCP\Activity\IConsumer interface');
- }
- }
- return $this->consumers;
- }
- /**
- * Generates a new IEvent object
- *
- * Make sure to call at least the following methods before sending it to the
- * app with via the publish() method:
- * - setApp()
- * - setType()
- * - setAffectedUser()
- * - setSubject()
- *
- * @return IEvent
- */
- public function generateEvent(): IEvent {
- return new Event($this->validator);
- }
- /**
- * {@inheritDoc}
- */
- public function publish(IEvent $event): void {
- if ($event->getAuthor() === '') {
- if ($this->session->getUser() instanceof IUser) {
- $event->setAuthor($this->session->getUser()->getUID());
- }
- }
- if (!$event->getTimestamp()) {
- $event->setTimestamp(time());
- }
- if (!$event->isValid()) {
- throw new IncompleteActivityException('The given event is invalid');
- }
- foreach ($this->getConsumers() as $c) {
- $c->receive($event);
- }
- }
- /**
- * In order to improve lazy loading a closure can be registered which will be called in case
- * activity consumers are actually requested
- *
- * $callable has to return an instance of OCA\Activity\IConsumer
- *
- * @param \Closure $callable
- */
- public function registerConsumer(\Closure $callable): void {
- $this->consumersClosures[] = $callable;
- $this->consumers = [];
- }
- /** @var string[] */
- protected $filterClasses = [];
- /** @var IFilter[] */
- protected $filters = [];
- /**
- * @param string $filter Class must implement OCA\Activity\IFilter
- * @return void
- */
- public function registerFilter(string $filter): void {
- $this->filterClasses[$filter] = false;
- }
- /**
- * @return IFilter[]
- * @throws \InvalidArgumentException
- */
- public function getFilters(): array {
- foreach ($this->filterClasses as $class => $false) {
- /** @var IFilter $filter */
- $filter = \OCP\Server::get($class);
- if (!$filter instanceof IFilter) {
- throw new \InvalidArgumentException('Invalid activity filter registered');
- }
- $this->filters[$filter->getIdentifier()] = $filter;
- unset($this->filterClasses[$class]);
- }
- return $this->filters;
- }
- /**
- * {@inheritDoc}
- */
- public function getFilterById(string $id): IFilter {
- $filters = $this->getFilters();
- if (isset($filters[$id])) {
- return $filters[$id];
- }
- throw new FilterNotFoundException($id);
- }
- /** @var string[] */
- protected $providerClasses = [];
- /** @var IProvider[] */
- protected $providers = [];
- /**
- * @param string $provider Class must implement OCA\Activity\IProvider
- * @return void
- */
- public function registerProvider(string $provider): void {
- $this->providerClasses[$provider] = false;
- }
- /**
- * @return IProvider[]
- * @throws \InvalidArgumentException
- */
- public function getProviders(): array {
- foreach ($this->providerClasses as $class => $false) {
- /** @var IProvider $provider */
- $provider = \OCP\Server::get($class);
- if (!$provider instanceof IProvider) {
- throw new \InvalidArgumentException('Invalid activity provider registered');
- }
- $this->providers[] = $provider;
- unset($this->providerClasses[$class]);
- }
- return $this->providers;
- }
- /** @var string[] */
- protected $settingsClasses = [];
- /** @var ISetting[] */
- protected $settings = [];
- /**
- * @param string $setting Class must implement OCA\Activity\ISetting
- * @return void
- */
- public function registerSetting(string $setting): void {
- $this->settingsClasses[$setting] = false;
- }
- /**
- * @return ActivitySettings[]
- * @throws \InvalidArgumentException
- */
- public function getSettings(): array {
- foreach ($this->settingsClasses as $class => $false) {
- /** @var ISetting $setting */
- $setting = \OCP\Server::get($class);
- if ($setting instanceof ISetting) {
- if (!$setting instanceof ActivitySettings) {
- $setting = new ActivitySettingsAdapter($setting, $this->l10n);
- }
- } else {
- throw new \InvalidArgumentException('Invalid activity filter registered');
- }
- $this->settings[$setting->getIdentifier()] = $setting;
- unset($this->settingsClasses[$class]);
- }
- return $this->settings;
- }
- /**
- * {@inheritDoc}
- */
- public function getSettingById(string $id): ActivitySettings {
- $settings = $this->getSettings();
- if (isset($settings[$id])) {
- return $settings[$id];
- }
- throw new SettingNotFoundException($id);
- }
- /**
- * @param string $type
- * @param int $id
- */
- public function setFormattingObject(string $type, int $id): void {
- $this->formattingObjectType = $type;
- $this->formattingObjectId = $id;
- }
- /**
- * @return bool
- */
- public function isFormattingFilteredObject(): bool {
- return $this->formattingObjectType !== null && $this->formattingObjectId !== null
- && $this->formattingObjectType === $this->request->getParam('object_type')
- && $this->formattingObjectId === (int)$this->request->getParam('object_id');
- }
- /**
- * @param bool $status Set to true, when parsing events should not use SVG icons
- */
- public function setRequirePNG(bool $status): void {
- $this->requirePNG = $status;
- }
- /**
- * @return bool
- */
- public function getRequirePNG(): bool {
- return $this->requirePNG;
- }
- /**
- * Set the user we need to use
- *
- * @param string|null $currentUserId
- */
- public function setCurrentUserId(?string $currentUserId = null): void {
- $this->currentUserId = $currentUserId;
- }
- /**
- * Get the user we need to use
- *
- * Either the user is logged in, or we try to get it from the token
- *
- * @return string
- * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
- */
- public function getCurrentUserId(): string {
- if ($this->currentUserId !== null) {
- return $this->currentUserId;
- }
- if (!$this->session->isLoggedIn()) {
- return $this->getUserFromToken();
- }
- return $this->session->getUser()->getUID();
- }
- /**
- * Get the user for the token
- *
- * @return string
- * @throws \UnexpectedValueException If the token is invalid, does not exist or is not unique
- */
- protected function getUserFromToken(): string {
- $token = (string)$this->request->getParam('token', '');
- if (strlen($token) !== 30) {
- throw new \UnexpectedValueException('The token is invalid');
- }
- $users = $this->config->getUsersForUserValue('activity', 'rsstoken', $token);
- if (count($users) !== 1) {
- // No unique user found
- throw new \UnexpectedValueException('The token is invalid');
- }
- // Token found login as that user
- return array_shift($users);
- }
- }
|