aboutsummaryrefslogtreecommitdiffstats
path: root/lib/public/EventDispatcher
diff options
context:
space:
mode:
Diffstat (limited to 'lib/public/EventDispatcher')
-rw-r--r--lib/public/EventDispatcher/ABroadcastedEvent.php53
-rw-r--r--lib/public/EventDispatcher/Event.php68
-rw-r--r--lib/public/EventDispatcher/GenericEvent.php173
-rw-r--r--lib/public/EventDispatcher/IEventDispatcher.php86
-rw-r--r--lib/public/EventDispatcher/IEventListener.php24
-rw-r--r--lib/public/EventDispatcher/IWebhookCompatibleEvent.php24
-rw-r--r--lib/public/EventDispatcher/JsonSerializer.php50
7 files changed, 478 insertions, 0 deletions
diff --git a/lib/public/EventDispatcher/ABroadcastedEvent.php b/lib/public/EventDispatcher/ABroadcastedEvent.php
new file mode 100644
index 00000000000..cb3adbe46b3
--- /dev/null
+++ b/lib/public/EventDispatcher/ABroadcastedEvent.php
@@ -0,0 +1,53 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\EventDispatcher;
+
+use JsonSerializable;
+
+/**
+ * @since 18.0.0
+ */
+abstract class ABroadcastedEvent extends Event implements JsonSerializable {
+ /**
+ * @since 18.0.0
+ */
+ private $broadcasted = false;
+
+ /**
+ * Get the name of the event, as received on the client-side
+ *
+ * Uses the fully qualified event class name by default
+ *
+ * @return string
+ * @since 18.0.0
+ */
+ public function broadcastAs(): string {
+ return get_class($this);
+ }
+
+ /**
+ * @return string[]
+ * @since 18.0.0
+ */
+ abstract public function getUids(): array;
+
+ /**
+ * @since 18.0.0
+ */
+ public function setBroadcasted(): void {
+ $this->broadcasted = true;
+ }
+
+ /**
+ * @since 18.0.0
+ */
+ public function isBroadcasted(): bool {
+ return $this->broadcasted;
+ }
+}
diff --git a/lib/public/EventDispatcher/Event.php b/lib/public/EventDispatcher/Event.php
new file mode 100644
index 00000000000..f8d2e659f27
--- /dev/null
+++ b/lib/public/EventDispatcher/Event.php
@@ -0,0 +1,68 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\EventDispatcher;
+
+use Psr\EventDispatcher\StoppableEventInterface;
+
+/**
+ * Base event class for the event dispatcher service
+ *
+ * Typically this class isn't instantiated directly but sub classed for specific
+ * event types
+ *
+ * This class extended \Symfony\Contracts\EventDispatcher\Event until 21.0, since
+ * 22.0.0 this class directly implements the PSR StoppableEventInterface and no
+ * longer relies on Symfony. This transition does not come with any changes in API,
+ * the class has the same methods and behavior before and after this change.
+ *
+ * @since 17.0.0
+ */
+class Event implements StoppableEventInterface {
+ /**
+ * @var bool
+ *
+ * @since 22.0.0
+ */
+ private $propagationStopped = false;
+
+ /**
+ * Compatibility constructor
+ *
+ * In Nextcloud 17.0.0 this event class used a now deprecated/removed Symfony base
+ * class that had a constructor (with default arguments). To lower the risk of
+ * a breaking change (PHP won't allow parent constructor calls if there is none),
+ * this empty constructor's only purpose is to hopefully not break existing sub-
+ * classes of this class.
+ *
+ * @since 18.0.0
+ */
+ public function __construct() {
+ }
+
+ /**
+ * Stops the propagation of the event to further event listeners
+ *
+ * @return void
+ *
+ * @since 22.0.0
+ */
+ public function stopPropagation(): void {
+ $this->propagationStopped = true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @since 22.0.0
+ * @see \Psr\EventDispatcher\StoppableEventInterface
+ */
+ public function isPropagationStopped(): bool {
+ return $this->propagationStopped;
+ }
+}
diff --git a/lib/public/EventDispatcher/GenericEvent.php b/lib/public/EventDispatcher/GenericEvent.php
new file mode 100644
index 00000000000..7e646c4d6a7
--- /dev/null
+++ b/lib/public/EventDispatcher/GenericEvent.php
@@ -0,0 +1,173 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\EventDispatcher;
+
+use ArrayAccess;
+use ArrayIterator;
+use InvalidArgumentException;
+use IteratorAggregate;
+use Traversable;
+use function array_key_exists;
+
+/**
+ * Class GenericEvent
+ *
+ * convenience re-implementation of \Symfony\Component\GenericEvent against
+ * \OCP\EventDispatcher\Event
+ *
+ * @since 18.0.0
+ * @template-implements ArrayAccess<array-key, mixed>
+ * @template-implements IteratorAggregate<array-key, mixed>
+ * @deprecated 22.0.0 use \OCP\EventDispatcher\Event
+ */
+class GenericEvent extends Event implements ArrayAccess, IteratorAggregate {
+ /** @deprecated 22.0.0 */
+ protected $subject;
+
+ /** @deprecated 22.0.0 */
+ protected $arguments;
+
+ /**
+ * Encapsulate an event with $subject and $args.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function __construct($subject = null, array $arguments = []) {
+ parent::__construct();
+ $this->subject = $subject;
+ $this->arguments = $arguments;
+ }
+
+ /**
+ * Getter for subject property.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function getSubject() {
+ return $this->subject;
+ }
+
+ /**
+ * Get argument by key.
+ *
+ * @throws InvalidArgumentException if key is not found
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function getArgument(string $key) {
+ if ($this->hasArgument($key)) {
+ return $this->arguments[$key];
+ }
+
+ throw new InvalidArgumentException(sprintf('Argument "%s" not found.', $key));
+ }
+
+ /**
+ * Add argument to event.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function setArgument($key, $value): GenericEvent {
+ $this->arguments[$key] = $value;
+ return $this;
+ }
+
+ /**
+ * Getter for all arguments.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function getArguments(): array {
+ return $this->arguments;
+ }
+
+ /**
+ * Set args property.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function setArguments(array $args = []): GenericEvent {
+ $this->arguments = $args;
+ return $this;
+ }
+
+ /**
+ * Has argument.
+ *
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function hasArgument($key): bool {
+ return array_key_exists($key, $this->arguments);
+ }
+
+ /**
+ * Retrieve an external iterator
+ *
+ * @link https://php.net/manual/en/iteratoraggregate.getiterator.php
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function getIterator(): Traversable {
+ return new ArrayIterator($this->arguments);
+ }
+
+ /**
+ * Whether a offset exists
+ *
+ * @link https://php.net/manual/en/arrayaccess.offsetexists.php
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function offsetExists($offset): bool {
+ return $this->hasArgument($offset);
+ }
+
+ /**
+ * Offset to retrieve
+ *
+ * @link https://php.net/manual/en/arrayaccess.offsetget.php
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ * @return mixed
+ */
+ #[\ReturnTypeWillChange]
+ public function offsetGet($offset) {
+ return $this->arguments[$offset];
+ }
+
+ /**
+ * Offset to set
+ *
+ * @link https://php.net/manual/en/arrayaccess.offsetset.php
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function offsetSet($offset, $value): void {
+ $this->setArgument($offset, $value);
+ }
+
+ /**
+ * Offset to unset
+ *
+ * @link https://php.net/manual/en/arrayaccess.offsetunset.php
+ * @since 18.0.0
+ * @deprecated 22.0.0
+ */
+ public function offsetUnset($offset): void {
+ if ($this->hasArgument($offset)) {
+ unset($this->arguments[$offset]);
+ }
+ }
+}
diff --git a/lib/public/EventDispatcher/IEventDispatcher.php b/lib/public/EventDispatcher/IEventDispatcher.php
new file mode 100644
index 00000000000..a1eb75580fe
--- /dev/null
+++ b/lib/public/EventDispatcher/IEventDispatcher.php
@@ -0,0 +1,86 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\EventDispatcher;
+
+/**
+ * Event dispatcher service of Nextcloud
+ *
+ * @since 17.0.0
+ */
+interface IEventDispatcher {
+ /**
+ * @template T of \OCP\EventDispatcher\Event
+ * @param string $eventName preferably the fully-qualified class name of the Event sub class
+ * @psalm-param string|class-string<T> $eventName preferably the fully-qualified class name of the Event sub class
+ * @param callable $listener the object that is invoked when a matching event is dispatched
+ * @psalm-param callable(T):void $listener
+ * @param int $priority The higher this value, the earlier an event
+ * listener will be triggered in the chain (defaults to 0)
+ *
+ * @since 17.0.0
+ */
+ public function addListener(string $eventName, callable $listener, int $priority = 0): void;
+
+ /**
+ * @template T of \OCP\EventDispatcher\Event
+ * @param string $eventName preferably the fully-qualified class name of the Event sub class
+ * @psalm-param string|class-string<T> $eventName preferably the fully-qualified class name of the Event sub class
+ * @param callable $listener the object that is invoked when a matching event is dispatched
+ * @psalm-param callable(T):void $listener
+ *
+ * @since 19.0.0
+ */
+ public function removeListener(string $eventName, callable $listener): void;
+
+ /**
+ * @template T of \OCP\EventDispatcher\Event
+ * @param string $eventName preferably the fully-qualified class name of the Event sub class to listen for
+ * @psalm-param string|class-string<T> $eventName preferably the fully-qualified class name of the Event sub class to listen for
+ * @param string $className fully qualified class name (or ::class notation) of a \OCP\EventDispatcher\IEventListener that can be built by the DI container
+ * @psalm-param class-string<\OCP\EventDispatcher\IEventListener<T>> $className fully qualified class name that can be built by the DI container
+ * @param int $priority The higher this value, the earlier an event
+ * listener will be triggered in the chain (defaults to 0)
+ *
+ * @since 17.0.0
+ */
+ public function addServiceListener(string $eventName, string $className, int $priority = 0): void;
+
+ /**
+ * @template T of \OCP\EventDispatcher\Event
+ * @param string $eventName preferably the fully-qualified class name of the Event sub class
+ *
+ * @return bool TRUE if event has registered listeners
+ * @since 29.0.0
+ */
+ public function hasListeners(string $eventName): bool;
+
+ /**
+ * @template T of \OCP\EventDispatcher\Event
+ * @param string $eventName
+ * @psalm-param string|class-string<T> $eventName
+ * @param Event $event
+ * @psalm-param T $event
+ *
+ * @since 17.0.0
+ * @deprecated 21.0.0 use \OCP\EventDispatcher\IEventDispatcher::dispatchTyped
+ */
+ public function dispatch(string $eventName, Event $event): void;
+
+ /**
+ * Dispatch a typed event
+ *
+ * Only use this with subclasses of ``\OCP\EventDispatcher\Event``.
+ * The object's class will determine the event name.
+ *
+ * @param Event $event
+ *
+ * @since 18.0.0
+ */
+ public function dispatchTyped(Event $event): void;
+}
diff --git a/lib/public/EventDispatcher/IEventListener.php b/lib/public/EventDispatcher/IEventListener.php
new file mode 100644
index 00000000000..46ed53fa7a2
--- /dev/null
+++ b/lib/public/EventDispatcher/IEventListener.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+namespace OCP\EventDispatcher;
+
+/**
+ * @since 17.0.0
+ *
+ * @template T of Event
+ */
+interface IEventListener {
+ /**
+ * @param Event $event
+ * @psalm-param T $event
+ *
+ * @since 17.0.0
+ */
+ public function handle(Event $event): void;
+}
diff --git a/lib/public/EventDispatcher/IWebhookCompatibleEvent.php b/lib/public/EventDispatcher/IWebhookCompatibleEvent.php
new file mode 100644
index 00000000000..b13c35c187b
--- /dev/null
+++ b/lib/public/EventDispatcher/IWebhookCompatibleEvent.php
@@ -0,0 +1,24 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\EventDispatcher;
+
+/**
+ * Interface for events which can be listened to by webhooks
+ *
+ * @since 30.0.0
+ */
+interface IWebhookCompatibleEvent {
+ /**
+ * Return data to be serialized and sent to the webhook. Will be serialized using json_encode.
+ *
+ * @since 30.0.0
+ */
+ public function getWebhookSerializable(): array;
+}
diff --git a/lib/public/EventDispatcher/JsonSerializer.php b/lib/public/EventDispatcher/JsonSerializer.php
new file mode 100644
index 00000000000..d05367b746d
--- /dev/null
+++ b/lib/public/EventDispatcher/JsonSerializer.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+/**
+ * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
+ * SPDX-License-Identifier: AGPL-3.0-or-later
+ */
+
+namespace OCP\EventDispatcher;
+
+use OC\Files\Node\NonExistingFile;
+use OC\Files\Node\NonExistingFolder;
+use OCP\Files\FileInfo;
+use OCP\IUser;
+
+/**
+ * Contains helper static methods to serialize OCP classes into arrays to pass json_encode.
+ * Useful for events implementing \JsonSerializable.
+ *
+ * @since 30.0.0
+ */
+
+final class JsonSerializer {
+ /**
+ * @since 30.0.0
+ */
+ public static function serializeFileInfo(FileInfo $node): array {
+ if ($node instanceof NonExistingFile || $node instanceof NonExistingFolder) {
+ return [
+ 'path' => $node->getPath(),
+ ];
+ } else {
+ return [
+ 'id' => $node->getId(),
+ 'path' => $node->getPath(),
+ ];
+ }
+ }
+
+ /**
+ * @since 30.0.0
+ */
+ public static function serializeUser(IUser $user): array {
+ return [
+ 'uid' => $user->getUID(),
+ 'displayName' => $user->getDisplayName(),
+ ];
+ }
+}