diff options
Diffstat (limited to 'lib/private/Comments')
-rw-r--r-- | lib/private/Comments/Comment.php | 56 | ||||
-rw-r--r-- | lib/private/Comments/Manager.php | 74 |
2 files changed, 74 insertions, 56 deletions
diff --git a/lib/private/Comments/Comment.php b/lib/private/Comments/Comment.php index 422e29c084d..7190f252c82 100644 --- a/lib/private/Comments/Comment.php +++ b/lib/private/Comments/Comment.php @@ -16,7 +16,7 @@ class Comment implements IComment { 'id' => '', 'parentId' => '0', 'topmostParentId' => '0', - 'childrenCount' => '0', + 'childrenCount' => 0, 'message' => '', 'verb' => '', 'actorType' => '', @@ -34,8 +34,8 @@ class Comment implements IComment { /** * Comment constructor. * - * @param array $data optional, array with keys according to column names from - * the comments database scheme + * @param array $data optional, array with keys according to column names from + * the comments database scheme */ public function __construct(?array $data = null) { if (is_array($data)) { @@ -175,7 +175,7 @@ class Comment implements IComment { } $message = trim($message); if ($maxLength && mb_strlen($message, 'UTF-8') > $maxLength) { - throw new MessageTooLongException('Comment message must not exceed ' . $maxLength. ' characters'); + throw new MessageTooLongException('Comment message must not exceed ' . $maxLength . ' characters'); } $this->data['message'] = $message; return $this; @@ -185,24 +185,15 @@ class Comment implements IComment { * returns an array containing mentions that are included in the comment * * @return array each mention provides a 'type' and an 'id', see example below + * @psalm-return list<array{type: 'guest'|'email'|'federated_group'|'group'|'federated_team'|'team'|'federated_user'|'user', id: non-empty-lowercase-string}> + * @since 30.0.2 Type 'email' is supported + * @since 29.0.0 Types 'federated_group', 'federated_team', 'team' and 'federated_user' are supported + * @since 23.0.0 Type 'group' is supported + * @since 17.0.0 Type 'guest' is supported * @since 11.0.0 - * - * The return array looks like: - * [ - * [ - * 'type' => 'user', - * 'id' => 'citizen4' - * ], - * [ - * 'type' => 'group', - * 'id' => 'media' - * ], - * … - * ] - * */ public function getMentions(): array { - $ok = preg_match_all("/\B(?<![^a-z0-9_\-@\.\'\s])@(\"guest\/[a-f0-9]+\"|\"(?:federated_)?(?:group|team|user){1}\/[a-z0-9_\-@\.\' \/:]+\"|\"[a-z0-9_\-@\.\' ]+\"|[a-z0-9_\-@\.\']+)/i", $this->getMessage(), $mentions); + $ok = preg_match_all("/\B(?<![^a-z0-9_\-@\.\'\s])@(\"(guest|email)\/[a-f0-9]+\"|\"(?:federated_)?(?:group|team|user){1}\/[a-z0-9_\-@\.\' \/:]+\"|\"[a-z0-9_\-@\.\' ]+\"|[a-z0-9_\-@\.\']+)/i", $this->getMessage(), $mentions); if (!$ok || !isset($mentions[0])) { return []; } @@ -213,20 +204,35 @@ class Comment implements IComment { $result = []; foreach ($mentionIds as $mentionId) { // Cut-off the @ and remove wrapping double-quotes + /** @var non-empty-lowercase-string $cleanId */ $cleanId = trim(substr($mentionId, 1), '"'); if (str_starts_with($cleanId, 'guest/')) { $result[] = ['type' => 'guest', 'id' => $cleanId]; + } elseif (str_starts_with($cleanId, 'email/')) { + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 6); + $result[] = ['type' => 'email', 'id' => $cleanId]; } elseif (str_starts_with($cleanId, 'federated_group/')) { - $result[] = ['type' => 'federated_group', 'id' => substr($cleanId, 16)]; + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 16); + $result[] = ['type' => 'federated_group', 'id' => $cleanId]; } elseif (str_starts_with($cleanId, 'group/')) { - $result[] = ['type' => 'group', 'id' => substr($cleanId, 6)]; + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 6); + $result[] = ['type' => 'group', 'id' => $cleanId]; } elseif (str_starts_with($cleanId, 'federated_team/')) { - $result[] = ['type' => 'federated_team', 'id' => substr($cleanId, 15)]; + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 15); + $result[] = ['type' => 'federated_team', 'id' => $cleanId]; } elseif (str_starts_with($cleanId, 'team/')) { - $result[] = ['type' => 'team', 'id' => substr($cleanId, 5)]; + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 5); + $result[] = ['type' => 'team', 'id' => $cleanId]; } elseif (str_starts_with($cleanId, 'federated_user/')) { - $result[] = ['type' => 'federated_user', 'id' => substr($cleanId, 15)]; + /** @var non-empty-lowercase-string $cleanId */ + $cleanId = substr($cleanId, 15); + $result[] = ['type' => 'federated_user', 'id' => $cleanId]; } else { $result[] = ['type' => 'user', 'id' => $cleanId]; } @@ -297,7 +303,7 @@ class Comment implements IComment { * * If not explicitly set, it shall default to the time of initialization. * @since 9.0.0 - * @throw \LogicException if creation date time is not set yet + * @throws \LogicException if creation date time is not set yet */ public function getCreationDateTime(): \DateTime { if (!isset($this->data['creationDT'])) { diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php index 21ff5322f23..047fa361dad 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -33,10 +33,10 @@ class Manager implements ICommentsManager { /** @var IComment[] */ protected array $commentsCache = []; - /** @var \Closure[] */ + /** @var \Closure[] */ protected array $eventHandlerClosures = []; - /** @var ICommentsEventHandler[] */ + /** @var ICommentsEventHandler[] */ protected array $eventHandlers = []; /** @var \Closure[] */ @@ -132,7 +132,7 @@ class Manager implements ICommentsManager { try { $comment->getCreationDateTime(); - } catch(\LogicException $e) { + } catch (\LogicException $e) { $comment->setCreationDateTime(new \DateTime()); } @@ -308,10 +308,10 @@ class Manager implements ICommentsManager { * @param string $objectType the object type, e.g. 'files' * @param string $objectId the id of the object * @param int $limit optional, number of maximum comments to be returned. if - * not specified, all comments are returned. + * not specified, all comments are returned. * @param int $offset optional, starting point * @param \DateTime $notOlderThan optional, timestamp of the oldest comments - * that may be returned + * that may be returned * @return list<IComment> * @since 9.0.0 */ @@ -320,7 +320,7 @@ class Manager implements ICommentsManager { $objectId, $limit = 0, $offset = 0, - ?\DateTime $notOlderThan = null + ?\DateTime $notOlderThan = null, ) { $comments = []; @@ -362,8 +362,9 @@ class Manager implements ICommentsManager { * @param int $lastKnownCommentId the last known comment (will be used as offset) * @param string $sortDirection direction of the comments (`asc` or `desc`) * @param int $limit optional, number of maximum comments to be returned. if - * set to 0, all comments are returned. + * set to 0, all comments are returned. * @param bool $includeLastKnown + * @param string $topmostParentId Limit the comments to a list of replies and its original root comment * @return list<IComment> */ public function getForObjectSince( @@ -372,7 +373,8 @@ class Manager implements ICommentsManager { int $lastKnownCommentId, string $sortDirection = 'asc', int $limit = 30, - bool $includeLastKnown = false + bool $includeLastKnown = false, + string $topmostParentId = '', ): array { return $this->getCommentsWithVerbForObjectSinceComment( $objectType, @@ -381,7 +383,8 @@ class Manager implements ICommentsManager { $lastKnownCommentId, $sortDirection, $limit, - $includeLastKnown + $includeLastKnown, + $topmostParentId, ); } @@ -392,8 +395,9 @@ class Manager implements ICommentsManager { * @param int $lastKnownCommentId the last known comment (will be used as offset) * @param string $sortDirection direction of the comments (`asc` or `desc`) * @param int $limit optional, number of maximum comments to be returned. if - * set to 0, all comments are returned. + * set to 0, all comments are returned. * @param bool $includeLastKnown + * @param string $topmostParentId Limit the comments to a list of replies and its original root comment * @return list<IComment> */ public function getCommentsWithVerbForObjectSinceComment( @@ -403,7 +407,8 @@ class Manager implements ICommentsManager { int $lastKnownCommentId, string $sortDirection = 'asc', int $limit = 30, - bool $includeLastKnown = false + bool $includeLastKnown = false, + string $topmostParentId = '', ): array { $comments = []; @@ -423,6 +428,13 @@ class Manager implements ICommentsManager { $query->andWhere($query->expr()->in('verb', $query->createNamedParameter($verbs, IQueryBuilder::PARAM_STR_ARRAY))); } + if ($topmostParentId !== '') { + $query->andWhere($query->expr()->orX( + $query->expr()->eq('id', $query->createNamedParameter($topmostParentId)), + $query->expr()->eq('topmost_parent_id', $query->createNamedParameter($topmostParentId)), + )); + } + $lastKnownComment = $lastKnownCommentId > 0 ? $this->getLastKnownComment( $objectType, $objectId, @@ -440,14 +452,14 @@ class Manager implements ICommentsManager { $query->expr()->orX( $query->expr()->lt( 'creation_timestamp', - $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), - IQueryBuilder::PARAM_DATE + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE), + IQueryBuilder::PARAM_DATETIME_MUTABLE ), $query->expr()->andX( $query->expr()->eq( 'creation_timestamp', - $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), - IQueryBuilder::PARAM_DATE + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE), + IQueryBuilder::PARAM_DATETIME_MUTABLE ), $idComparison ) @@ -463,14 +475,14 @@ class Manager implements ICommentsManager { $query->expr()->orX( $query->expr()->gt( 'creation_timestamp', - $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), - IQueryBuilder::PARAM_DATE + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE), + IQueryBuilder::PARAM_DATETIME_MUTABLE ), $query->expr()->andX( $query->expr()->eq( 'creation_timestamp', - $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE), - IQueryBuilder::PARAM_DATE + $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATETIME_MUTABLE), + IQueryBuilder::PARAM_DATETIME_MUTABLE ), $idComparison ) @@ -575,7 +587,7 @@ class Manager implements ICommentsManager { if ($search !== '') { $query->where($query->expr()->iLike('message', $query->createNamedParameter( - '%' . $this->dbConn->escapeLikeParameter($search). '%' + '%' . $this->dbConn->escapeLikeParameter($search) . '%' ))); } @@ -608,7 +620,7 @@ class Manager implements ICommentsManager { * @param $objectType string the object type, e.g. 'files' * @param $objectId string the id of the object * @param \DateTime $notOlderThan optional, timestamp of the oldest comments - * that may be returned + * that may be returned * @param string $verb Limit the verb of the comment - Added in 14.0.0 * @return Int * @since 9.0.0 @@ -675,7 +687,7 @@ class Manager implements ICommentsManager { $result = $query->executeQuery(); while ($row = $result->fetch()) { - $unreadComments[$row['object_id']] = (int) $row['num_comments']; + $unreadComments[$row['object_id']] = (int)$row['num_comments']; } $result->closeCursor(); } @@ -723,7 +735,7 @@ class Manager implements ICommentsManager { $data = $result->fetch(); $result->closeCursor(); - return (int) ($data['num_messages'] ?? 0); + return (int)($data['num_messages'] ?? 0); } /** @@ -740,7 +752,7 @@ class Manager implements ICommentsManager { ->from('comments') ->where($query->expr()->eq('object_type', $query->createNamedParameter($objectType))) ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId))) - ->andWhere($query->expr()->lt('creation_timestamp', $query->createNamedParameter($beforeDate, IQueryBuilder::PARAM_DATE))) + ->andWhere($query->expr()->lt('creation_timestamp', $query->createNamedParameter($beforeDate, IQueryBuilder::PARAM_DATETIME_MUTABLE))) ->orderBy('creation_timestamp', 'desc'); if ($verb !== '') { @@ -751,7 +763,7 @@ class Manager implements ICommentsManager { $data = $result->fetch(); $result->closeCursor(); - return (int) ($data['id'] ?? 0); + return (int)($data['id'] ?? 0); } /** @@ -769,7 +781,7 @@ class Manager implements ICommentsManager { string $objectId, string $verb, string $actorType, - array $actors + array $actors, ): array { $lastComments = []; @@ -808,9 +820,9 @@ class Manager implements ICommentsManager { return []; } $children = $directory->getDirectoryListing(); - $ids = array_map(fn (FileInfo $child) => (string) $child->getId(), $children); + $ids = array_map(fn (FileInfo $child) => (string)$child->getId(), $children); - $ids[] = (string) $directory->getId(); + $ids[] = (string)$directory->getId(); $counts = $this->getNumberOfUnreadCommentsForObjects('files', $ids, $user); return array_filter($counts, function (int $count) { return $count > 0; @@ -1079,7 +1091,7 @@ class Manager implements ICommentsManager { $result = $this->update($comment); } - if ($result && !!$comment->getParentId()) { + if ($result && (bool)$comment->getParentId()) { $this->updateChildrenInformation( $comment->getParentId(), $comment->getCreationDateTime() @@ -1141,7 +1153,7 @@ class Manager implements ICommentsManager { ->andWhere($qb->expr()->eq('actor_id', $qb->createNamedParameter($reaction->getActorId()))) ->andWhere($qb->expr()->eq('reaction', $qb->createNamedParameter($reaction->getMessage()))); $result = $qb->executeQuery(); - $exists = (int) $result->fetchOne(); + $exists = (int)$result->fetchOne(); if (!$exists) { $qb = $this->dbConn->getQueryBuilder(); try { @@ -1551,7 +1563,7 @@ class Manager implements ICommentsManager { $qb = $this->dbConn->getQueryBuilder(); $qb->delete('comments') ->where($qb->expr()->lte('expire_date', - $qb->createNamedParameter($this->timeFactory->getDateTime(), IQueryBuilder::PARAM_DATE))) + $qb->createNamedParameter($this->timeFactory->getDateTime(), IQueryBuilder::PARAM_DATETIME_MUTABLE))) ->andWhere($qb->expr()->eq('object_type', $qb->createNamedParameter($objectType))); if ($objectId !== '') { |