@@ -18,11 +18,11 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | #[Consumable(since: '33.0.0')] |
| 20 | 20 | final class BeforeCommentUpdatedEvent extends CommentsEvent { |
| 21 | - /** |
|
| 22 | - * CommentEvent constructor. |
|
| 23 | - */ |
|
| 24 | - public function __construct(IComment $comment) { |
|
| 25 | - /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | - parent::__construct(CommentsEvent::EVENT_PRE_UPDATE, $comment); |
|
| 27 | - } |
|
| 21 | + /** |
|
| 22 | + * CommentEvent constructor. |
|
| 23 | + */ |
|
| 24 | + public function __construct(IComment $comment) { |
|
| 25 | + /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | + parent::__construct(CommentsEvent::EVENT_PRE_UPDATE, $comment); |
|
| 27 | + } |
|
| 28 | 28 | } |
@@ -18,11 +18,11 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | #[Consumable(since: '33.0.0')] |
| 20 | 20 | final class CommentAddedEvent extends CommentsEvent { |
| 21 | - /** |
|
| 22 | - * CommentAddedEvent constructor. |
|
| 23 | - */ |
|
| 24 | - public function __construct(IComment $comment) { |
|
| 25 | - /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | - parent::__construct(CommentsEvent::EVENT_ADD, $comment); |
|
| 27 | - } |
|
| 21 | + /** |
|
| 22 | + * CommentAddedEvent constructor. |
|
| 23 | + */ |
|
| 24 | + public function __construct(IComment $comment) { |
|
| 25 | + /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | + parent::__construct(CommentsEvent::EVENT_ADD, $comment); |
|
| 27 | + } |
|
| 28 | 28 | } |
@@ -18,11 +18,11 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | #[Consumable(since: '33.0.0')] |
| 20 | 20 | final class CommentDeletedEvent extends CommentsEvent { |
| 21 | - /** |
|
| 22 | - * CommentRemovedEvent constructor. |
|
| 23 | - */ |
|
| 24 | - public function __construct(IComment $comment) { |
|
| 25 | - /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | - parent::__construct(CommentsEvent::EVENT_DELETE, $comment); |
|
| 27 | - } |
|
| 21 | + /** |
|
| 22 | + * CommentRemovedEvent constructor. |
|
| 23 | + */ |
|
| 24 | + public function __construct(IComment $comment) { |
|
| 25 | + /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | + parent::__construct(CommentsEvent::EVENT_DELETE, $comment); |
|
| 27 | + } |
|
| 28 | 28 | } |
@@ -18,11 +18,11 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | #[Consumable(since: '33.0.0')] |
| 20 | 20 | final class CommentUpdatedEvent extends CommentsEvent { |
| 21 | - /** |
|
| 22 | - * CommentUpdatedEvent constructor. |
|
| 23 | - */ |
|
| 24 | - public function __construct(IComment $comment) { |
|
| 25 | - /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | - parent::__construct(CommentsEvent::EVENT_UPDATE, $comment); |
|
| 27 | - } |
|
| 21 | + /** |
|
| 22 | + * CommentUpdatedEvent constructor. |
|
| 23 | + */ |
|
| 24 | + public function __construct(IComment $comment) { |
|
| 25 | + /** @psalm-suppress DeprecatedConstant */ |
|
| 26 | + parent::__construct(CommentsEvent::EVENT_UPDATE, $comment); |
|
| 27 | + } |
|
| 28 | 28 | } |
@@ -19,54 +19,54 @@ |
||
| 19 | 19 | */ |
| 20 | 20 | #[Consumable(since: '9.0.0')] |
| 21 | 21 | class CommentsEvent extends Event { |
| 22 | - /** |
|
| 23 | - * @since 11.0.0 |
|
| 24 | - * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentAddedEvent instead. |
|
| 25 | - */ |
|
| 26 | - public const EVENT_ADD = 'OCP\Comments\ICommentsManager::addComment'; |
|
| 22 | + /** |
|
| 23 | + * @since 11.0.0 |
|
| 24 | + * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentAddedEvent instead. |
|
| 25 | + */ |
|
| 26 | + public const EVENT_ADD = 'OCP\Comments\ICommentsManager::addComment'; |
|
| 27 | 27 | |
| 28 | - /** |
|
| 29 | - * @since 11.0.0 |
|
| 30 | - * @deprecated 33.0.0 Use \OCP\Comments\Events\BeforeCommentUpdatedEvent instead. |
|
| 31 | - */ |
|
| 32 | - public const EVENT_PRE_UPDATE = 'OCP\Comments\ICommentsManager::preUpdateComment'; |
|
| 28 | + /** |
|
| 29 | + * @since 11.0.0 |
|
| 30 | + * @deprecated 33.0.0 Use \OCP\Comments\Events\BeforeCommentUpdatedEvent instead. |
|
| 31 | + */ |
|
| 32 | + public const EVENT_PRE_UPDATE = 'OCP\Comments\ICommentsManager::preUpdateComment'; |
|
| 33 | 33 | |
| 34 | - /** |
|
| 35 | - * @since 11.0.0 |
|
| 36 | - * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentUpdatedEvent instead. |
|
| 37 | - */ |
|
| 38 | - public const EVENT_UPDATE = 'OCP\Comments\ICommentsManager::updateComment'; |
|
| 34 | + /** |
|
| 35 | + * @since 11.0.0 |
|
| 36 | + * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentUpdatedEvent instead. |
|
| 37 | + */ |
|
| 38 | + public const EVENT_UPDATE = 'OCP\Comments\ICommentsManager::updateComment'; |
|
| 39 | 39 | |
| 40 | - /** |
|
| 41 | - * @since 11.0.0 |
|
| 42 | - * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentDeletedEvent instead. |
|
| 43 | - */ |
|
| 44 | - public const EVENT_DELETE = 'OCP\Comments\ICommentsManager::deleteComment'; |
|
| 40 | + /** |
|
| 41 | + * @since 11.0.0 |
|
| 42 | + * @deprecated 33.0.0 Use \OCP\Comments\Events\CommentDeletedEvent instead. |
|
| 43 | + */ |
|
| 44 | + public const EVENT_DELETE = 'OCP\Comments\ICommentsManager::deleteComment'; |
|
| 45 | 45 | |
| 46 | - /** |
|
| 47 | - * CommentsEvent constructor. |
|
| 48 | - * |
|
| 49 | - * @since 9.0.0 |
|
| 50 | - */ |
|
| 51 | - public function __construct( |
|
| 52 | - protected readonly string $event, |
|
| 53 | - protected readonly IComment $comment, |
|
| 54 | - ) { |
|
| 55 | - parent::__construct(); |
|
| 56 | - } |
|
| 46 | + /** |
|
| 47 | + * CommentsEvent constructor. |
|
| 48 | + * |
|
| 49 | + * @since 9.0.0 |
|
| 50 | + */ |
|
| 51 | + public function __construct( |
|
| 52 | + protected readonly string $event, |
|
| 53 | + protected readonly IComment $comment, |
|
| 54 | + ) { |
|
| 55 | + parent::__construct(); |
|
| 56 | + } |
|
| 57 | 57 | |
| 58 | - /** |
|
| 59 | - * @since 9.0.0 |
|
| 60 | - * @depreacted Since 33.0.0 use instanceof CommentAddedEvent, CommentRemovedEvent, CommentUpdatedEvent or BeforeCommentUpdatedEvent instead. |
|
| 61 | - */ |
|
| 62 | - public function getEvent(): string { |
|
| 63 | - return $this->event; |
|
| 64 | - } |
|
| 58 | + /** |
|
| 59 | + * @since 9.0.0 |
|
| 60 | + * @depreacted Since 33.0.0 use instanceof CommentAddedEvent, CommentRemovedEvent, CommentUpdatedEvent or BeforeCommentUpdatedEvent instead. |
|
| 61 | + */ |
|
| 62 | + public function getEvent(): string { |
|
| 63 | + return $this->event; |
|
| 64 | + } |
|
| 65 | 65 | |
| 66 | - /** |
|
| 67 | - * @since 9.0.0 |
|
| 68 | - */ |
|
| 69 | - public function getComment(): IComment { |
|
| 70 | - return $this->comment; |
|
| 71 | - } |
|
| 66 | + /** |
|
| 67 | + * @since 9.0.0 |
|
| 68 | + */ |
|
| 69 | + public function getComment(): IComment { |
|
| 70 | + return $this->comment; |
|
| 71 | + } |
|
| 72 | 72 | } |
@@ -18,46 +18,46 @@ |
||
| 18 | 18 | */ |
| 19 | 19 | #[Consumable(since: '9.1.0')] |
| 20 | 20 | class CommentsEntityEvent extends Event { |
| 21 | - /** |
|
| 22 | - * @since 9.1.0 |
|
| 23 | - * @deprecated 22.0.0 - Listen to the typed event instead. |
|
| 24 | - */ |
|
| 25 | - public const EVENT_ENTITY = 'OCP\Comments\ICommentsManager::registerEntity'; |
|
| 26 | - |
|
| 27 | - /** @var (\Closure(string $id): bool)[] */ |
|
| 28 | - protected array $collections = []; |
|
| 29 | - |
|
| 30 | - /** |
|
| 31 | - * DispatcherEvent constructor. |
|
| 32 | - * |
|
| 33 | - * @since 9.1.0 |
|
| 34 | - */ |
|
| 35 | - public function __construct() { |
|
| 36 | - parent::__construct(); |
|
| 37 | - } |
|
| 38 | - |
|
| 39 | - /** |
|
| 40 | - * @param string $name |
|
| 41 | - * @param \Closure(string $id):bool $entityExistsFunction The closure should take one |
|
| 42 | - * argument, which is the id of the entity, that comments |
|
| 43 | - * should be handled for. The return should then be bool, |
|
| 44 | - * depending on whether comments are allowed (true) or not. |
|
| 45 | - * @throws \OutOfBoundsException when the entity name is already taken |
|
| 46 | - * @since 9.1.0 |
|
| 47 | - */ |
|
| 48 | - public function addEntityCollection(string $name, \Closure $entityExistsFunction): void { |
|
| 49 | - if (isset($this->collections[$name])) { |
|
| 50 | - throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"'); |
|
| 51 | - } |
|
| 52 | - |
|
| 53 | - $this->collections[$name] = $entityExistsFunction; |
|
| 54 | - } |
|
| 55 | - |
|
| 56 | - /** |
|
| 57 | - * @return (\Closure(string $id): bool)[] |
|
| 58 | - * @since 9.1.0 |
|
| 59 | - */ |
|
| 60 | - public function getEntityCollections(): array { |
|
| 61 | - return $this->collections; |
|
| 62 | - } |
|
| 21 | + /** |
|
| 22 | + * @since 9.1.0 |
|
| 23 | + * @deprecated 22.0.0 - Listen to the typed event instead. |
|
| 24 | + */ |
|
| 25 | + public const EVENT_ENTITY = 'OCP\Comments\ICommentsManager::registerEntity'; |
|
| 26 | + |
|
| 27 | + /** @var (\Closure(string $id): bool)[] */ |
|
| 28 | + protected array $collections = []; |
|
| 29 | + |
|
| 30 | + /** |
|
| 31 | + * DispatcherEvent constructor. |
|
| 32 | + * |
|
| 33 | + * @since 9.1.0 |
|
| 34 | + */ |
|
| 35 | + public function __construct() { |
|
| 36 | + parent::__construct(); |
|
| 37 | + } |
|
| 38 | + |
|
| 39 | + /** |
|
| 40 | + * @param string $name |
|
| 41 | + * @param \Closure(string $id):bool $entityExistsFunction The closure should take one |
|
| 42 | + * argument, which is the id of the entity, that comments |
|
| 43 | + * should be handled for. The return should then be bool, |
|
| 44 | + * depending on whether comments are allowed (true) or not. |
|
| 45 | + * @throws \OutOfBoundsException when the entity name is already taken |
|
| 46 | + * @since 9.1.0 |
|
| 47 | + */ |
|
| 48 | + public function addEntityCollection(string $name, \Closure $entityExistsFunction): void { |
|
| 49 | + if (isset($this->collections[$name])) { |
|
| 50 | + throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"'); |
|
| 51 | + } |
|
| 52 | + |
|
| 53 | + $this->collections[$name] = $entityExistsFunction; |
|
| 54 | + } |
|
| 55 | + |
|
| 56 | + /** |
|
| 57 | + * @return (\Closure(string $id): bool)[] |
|
| 58 | + * @since 9.1.0 |
|
| 59 | + */ |
|
| 60 | + public function getEntityCollections(): array { |
|
| 61 | + return $this->collections; |
|
| 62 | + } |
|
| 63 | 63 | } |
@@ -33,1543 +33,1543 @@ |
||
| 33 | 33 | use Psr\Log\LoggerInterface; |
| 34 | 34 | |
| 35 | 35 | class Manager implements ICommentsManager { |
| 36 | - /** @var IComment[] */ |
|
| 37 | - protected array $commentsCache = []; |
|
| 38 | - |
|
| 39 | - /** @var \Closure[] */ |
|
| 40 | - protected array $eventHandlerClosures = []; |
|
| 41 | - |
|
| 42 | - /** @var ICommentsEventHandler[] */ |
|
| 43 | - protected array $eventHandlers = []; |
|
| 44 | - |
|
| 45 | - /** @var \Closure[] */ |
|
| 46 | - protected array $displayNameResolvers = []; |
|
| 47 | - |
|
| 48 | - public function __construct( |
|
| 49 | - protected IDBConnection $dbConn, |
|
| 50 | - protected LoggerInterface $logger, |
|
| 51 | - protected IConfig $config, |
|
| 52 | - protected ITimeFactory $timeFactory, |
|
| 53 | - protected IEmojiHelper $emojiHelper, |
|
| 54 | - protected IInitialStateService $initialStateService, |
|
| 55 | - protected IRootFolder $rootFolder, |
|
| 56 | - protected IEventDispatcher $eventDispatcher, |
|
| 57 | - ) { |
|
| 58 | - } |
|
| 59 | - |
|
| 60 | - /** |
|
| 61 | - * converts data base data into PHP native, proper types as defined by |
|
| 62 | - * IComment interface. |
|
| 63 | - * |
|
| 64 | - * @param array $data |
|
| 65 | - */ |
|
| 66 | - protected function normalizeDatabaseData(array $data): array { |
|
| 67 | - $data['id'] = (string)$data['id']; |
|
| 68 | - $data['parent_id'] = (string)$data['parent_id']; |
|
| 69 | - $data['topmost_parent_id'] = (string)$data['topmost_parent_id']; |
|
| 70 | - $data['creation_timestamp'] = new \DateTime($data['creation_timestamp']); |
|
| 71 | - if (!is_null($data['latest_child_timestamp'])) { |
|
| 72 | - $data['latest_child_timestamp'] = new \DateTime($data['latest_child_timestamp']); |
|
| 73 | - } |
|
| 74 | - if (!is_null($data['expire_date'])) { |
|
| 75 | - $data['expire_date'] = new \DateTime($data['expire_date']); |
|
| 76 | - } |
|
| 77 | - $data['children_count'] = (int)$data['children_count']; |
|
| 78 | - $data['reference_id'] = $data['reference_id']; |
|
| 79 | - $data['meta_data'] = json_decode($data['meta_data'], true); |
|
| 80 | - if ($this->supportReactions()) { |
|
| 81 | - if ($data['reactions'] !== null) { |
|
| 82 | - $list = json_decode($data['reactions'], true); |
|
| 83 | - // Ordering does not work on the database with group concat and Oracle, |
|
| 84 | - // So we simply sort on the output. |
|
| 85 | - if (is_array($list)) { |
|
| 86 | - uasort($list, static function ($a, $b) { |
|
| 87 | - if ($a === $b) { |
|
| 88 | - return 0; |
|
| 89 | - } |
|
| 90 | - return ($a > $b) ? -1 : 1; |
|
| 91 | - }); |
|
| 92 | - $data['reactions'] = $list; |
|
| 93 | - } else { |
|
| 94 | - $data['reactions'] = []; |
|
| 95 | - } |
|
| 96 | - } else { |
|
| 97 | - $data['reactions'] = []; |
|
| 98 | - } |
|
| 99 | - } |
|
| 100 | - return $data; |
|
| 101 | - } |
|
| 102 | - |
|
| 103 | - public function getCommentFromData(array $data): IComment { |
|
| 104 | - return new Comment($this->normalizeDatabaseData($data)); |
|
| 105 | - } |
|
| 106 | - |
|
| 107 | - /** |
|
| 108 | - * prepares a comment for an insert or update operation after making sure |
|
| 109 | - * all necessary fields have a value assigned. |
|
| 110 | - * |
|
| 111 | - * @param IComment $comment |
|
| 112 | - * @return IComment returns the same updated IComment instance as provided |
|
| 113 | - * by parameter for convenience |
|
| 114 | - * @throws \UnexpectedValueException |
|
| 115 | - */ |
|
| 116 | - protected function prepareCommentForDatabaseWrite(IComment $comment): IComment { |
|
| 117 | - if (!$comment->getActorType() |
|
| 118 | - || $comment->getActorId() === '' |
|
| 119 | - || !$comment->getObjectType() |
|
| 120 | - || $comment->getObjectId() === '' |
|
| 121 | - || !$comment->getVerb() |
|
| 122 | - ) { |
|
| 123 | - throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving'); |
|
| 124 | - } |
|
| 125 | - |
|
| 126 | - if ($comment->getVerb() === 'reaction' && !$this->emojiHelper->isValidSingleEmoji($comment->getMessage())) { |
|
| 127 | - // 4 characters: laptop + person + gender + skin color => " |
|
@@ -15,25 +15,25 @@ |
||
| 15 | 15 | |
| 16 | 16 | /** @template-implements IEventListener<CommentsEntityEvent> */ |
| 17 | 17 | class CommentsEntityEventListener implements IEventListener { |
| 18 | - public function __construct( |
|
| 19 | - private IRootFolder $rootFolder, |
|
| 20 | - private ?string $userId = null, |
|
| 21 | - ) { |
|
| 22 | - } |
|
| 18 | + public function __construct( |
|
| 19 | + private IRootFolder $rootFolder, |
|
| 20 | + private ?string $userId = null, |
|
| 21 | + ) { |
|
| 22 | + } |
|
| 23 | 23 | |
| 24 | - public function handle(Event $event): void { |
|
| 25 | - if (!($event instanceof CommentsEntityEvent)) { |
|
| 26 | - // Unrelated |
|
| 27 | - return; |
|
| 28 | - } |
|
| 24 | + public function handle(Event $event): void { |
|
| 25 | + if (!($event instanceof CommentsEntityEvent)) { |
|
| 26 | + // Unrelated |
|
| 27 | + return; |
|
| 28 | + } |
|
| 29 | 29 | |
| 30 | - if ($this->userId === null) { |
|
| 31 | - return; |
|
| 32 | - } |
|
| 30 | + if ($this->userId === null) { |
|
| 31 | + return; |
|
| 32 | + } |
|
| 33 | 33 | |
| 34 | - $event->addEntityCollection('files', function ($name): bool { |
|
| 35 | - $nodes = $this->rootFolder->getUserFolder($this->userId)->getById((int)$name); |
|
| 36 | - return !empty($nodes); |
|
| 37 | - }); |
|
| 38 | - } |
|
| 34 | + $event->addEntityCollection('files', function ($name): bool { |
|
| 35 | + $nodes = $this->rootFolder->getUserFolder($this->userId)->getById((int)$name); |
|
| 36 | + return !empty($nodes); |
|
| 37 | + }); |
|
| 38 | + } |
|
| 39 | 39 | } |
@@ -18,45 +18,45 @@ |
||
| 18 | 18 | |
| 19 | 19 | /** @template-implements IEventListener<CommentsEvent|Event> */ |
| 20 | 20 | class CommentsEventListener implements IEventListener { |
| 21 | - public function __construct( |
|
| 22 | - private ActivityListener $activityListener, |
|
| 23 | - private NotificationListener $notificationListener, |
|
| 24 | - ) { |
|
| 25 | - } |
|
| 26 | - |
|
| 27 | - public function handle(Event $event): void { |
|
| 28 | - if (!$event instanceof CommentsEvent) { |
|
| 29 | - return; |
|
| 30 | - } |
|
| 31 | - |
|
| 32 | - if ($event->getComment()->getObjectType() !== 'files') { |
|
| 33 | - // this is a 'files'-specific Handler |
|
| 34 | - return; |
|
| 35 | - } |
|
| 36 | - |
|
| 37 | - $eventType = $event->getEvent(); |
|
| 38 | - if ($eventType === CommentsEvent::EVENT_ADD) { |
|
| 39 | - $this->notificationHandler($event); |
|
| 40 | - $this->activityHandler($event); |
|
| 41 | - return; |
|
| 42 | - } |
|
| 43 | - |
|
| 44 | - $applicableEvents = [ |
|
| 45 | - CommentsEvent::EVENT_PRE_UPDATE, |
|
| 46 | - CommentsEvent::EVENT_UPDATE, |
|
| 47 | - CommentsEvent::EVENT_DELETE, |
|
| 48 | - ]; |
|
| 49 | - if (in_array($eventType, $applicableEvents)) { |
|
| 50 | - $this->notificationHandler($event); |
|
| 51 | - return; |
|
| 52 | - } |
|
| 53 | - } |
|
| 54 | - |
|
| 55 | - private function activityHandler(CommentsEvent $event): void { |
|
| 56 | - $this->activityListener->commentEvent($event); |
|
| 57 | - } |
|
| 58 | - |
|
| 59 | - private function notificationHandler(CommentsEvent $event): void { |
|
| 60 | - $this->notificationListener->evaluate($event); |
|
| 61 | - } |
|
| 21 | + public function __construct( |
|
| 22 | + private ActivityListener $activityListener, |
|
| 23 | + private NotificationListener $notificationListener, |
|
| 24 | + ) { |
|
| 25 | + } |
|
| 26 | + |
|
| 27 | + public function handle(Event $event): void { |
|
| 28 | + if (!$event instanceof CommentsEvent) { |
|
| 29 | + return; |
|
| 30 | + } |
|
| 31 | + |
|
| 32 | + if ($event->getComment()->getObjectType() !== 'files') { |
|
| 33 | + // this is a 'files'-specific Handler |
|
| 34 | + return; |
|
| 35 | + } |
|
| 36 | + |
|
| 37 | + $eventType = $event->getEvent(); |
|
| 38 | + if ($eventType === CommentsEvent::EVENT_ADD) { |
|
| 39 | + $this->notificationHandler($event); |
|
| 40 | + $this->activityHandler($event); |
|
| 41 | + return; |
|
| 42 | + } |
|
| 43 | + |
|
| 44 | + $applicableEvents = [ |
|
| 45 | + CommentsEvent::EVENT_PRE_UPDATE, |
|
| 46 | + CommentsEvent::EVENT_UPDATE, |
|
| 47 | + CommentsEvent::EVENT_DELETE, |
|
| 48 | + ]; |
|
| 49 | + if (in_array($eventType, $applicableEvents)) { |
|
| 50 | + $this->notificationHandler($event); |
|
| 51 | + return; |
|
| 52 | + } |
|
| 53 | + } |
|
| 54 | + |
|
| 55 | + private function activityHandler(CommentsEvent $event): void { |
|
| 56 | + $this->activityListener->commentEvent($event); |
|
| 57 | + } |
|
| 58 | + |
|
| 59 | + private function notificationHandler(CommentsEvent $event): void { |
|
| 60 | + $this->notificationListener->evaluate($event); |
|
| 61 | + } |
|
| 62 | 62 | } |