diff options
Diffstat (limited to 'lib/private/Comments/Manager.php')
-rw-r--r-- | lib/private/Comments/Manager.php | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php index d62db2926fb..7af905c43c9 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -102,6 +102,7 @@ class Manager implements ICommentsManager { } $data['children_count'] = (int)$data['children_count']; $data['reference_id'] = $data['reference_id'] ?? null; + $data['reactions'] = json_decode($data['reactions'], true); return $data; } @@ -899,12 +900,136 @@ class Manager implements ICommentsManager { } if ($affectedRows > 0 && $comment instanceof IComment) { + if ($comment->getVerb() === 'reaction_deleted') { + $this->deleteReaction($comment); + } $this->sendEvent(CommentsEvent::EVENT_DELETE, $comment); } return ($affectedRows > 0); } + private function deleteReaction(IComment $comment): void { + $qb = $this->dbConn->getQueryBuilder(); + $qb->delete('reactions') + ->where($qb->expr()->eq('parent_id', $qb->createNamedParameter($comment->getParentId()))) + ->andWhere($qb->expr()->eq('message_id', $qb->createNamedParameter($comment->getId()))) + ->executeStatement(); + $this->sumReactions($comment); + } + + /** + * Get comment related with user reaction + * + * @param integer $parentId + * @param string $actorType + * @param string $actorId + * @param string $reaction + * @return IComment + * @throws NotFoundException + * @since 24.0.0 + */ + public function getReactionComment(int $parentId, string $actorType, string $actorId, string $reaction): IComment { + $qb = $this->dbConn->getQueryBuilder(); + $messageId = $qb + ->select('message_id') + ->from('reactions') + ->where($qb->expr()->eq('parent_id', $qb->createNamedParameter($parentId))) + ->andWhere($qb->expr()->eq('actor_type', $qb->createNamedParameter($actorType))) + ->andWhere($qb->expr()->eq('actor_id', $qb->createNamedParameter($actorId))) + ->andWhere($qb->expr()->eq('reaction', $qb->createNamedParameter($reaction))) + ->executeQuery() + ->fetchOne(); + if (!$messageId) { + throw new NotFoundException('Comment related with reaction not found'); + } + return $this->get($messageId); + } + + /** + * Retrieve all reactions with specific reaction of a message + * + * @param integer $parentId + * @param string $reaction + * @return IComment[] + * @since 24.0.0 + */ + public function retrieveAllReactionsWithSpecificReaction(int $parentId, string $reaction): ?array { + $qb = $this->dbConn->getQueryBuilder(); + $result = $qb + ->select('message_id') + ->from('reactions') + ->where($qb->expr()->eq('parent_id', $qb->createNamedParameter($parentId))) + ->andWhere($qb->expr()->eq('reaction', $qb->createNamedParameter($reaction))) + ->executeQuery(); + + $commentIds = []; + while ($data = $result->fetch()) { + $commentIds[] = $data['message_id']; + } + $comments = []; + if ($commentIds) { + $comments = $this->getCommentsOnList($commentIds); + } + + return $comments; + } + + /** + * Retrieve all reactions of a message + * + * @param integer $parentId + * @param string $reaction + * @return IComment[] + * @since 24.0.0 + */ + public function retrieveAllReactions(int $parentId): array { + $qb = $this->dbConn->getQueryBuilder(); + $result = $qb + ->select('message_id') + ->from('reactions') + ->where($qb->expr()->eq('parent_id', $qb->createNamedParameter($parentId))) + ->executeQuery(); + + $commentIds = []; + while ($data = $result->fetch()) { + $commentIds[] = $data['message_id']; + } + $comments = []; + if ($commentIds) { + $comments = $this->getCommentsOnList($commentIds); + } + + return $comments; + } + + /** + * Get all comments on list + * + * @param integer[] $objectIds + * @return IComment[] + * @since 24.0.0 + */ + private function getCommentsOnList(array $objectIds): array { + $query = $this->dbConn->getQueryBuilder(); + + $query->select('*') + ->from('comments') + ->where($query->expr()->in('id', $query->createNamedParameter($objectIds, IQueryBuilder::PARAM_STR_ARRAY))) + ->orderBy('creation_timestamp', 'DESC') + ->addOrderBy('id', 'DESC'); + + $comments = []; + $result = $query->executeQuery(); + while ($data = $result->fetch()) { + $comment = $this->getCommentFromData($data); + $this->cache($comment); + $comments[] = $comment; + } + $result->closeCursor(); + return $comments; + } + /** * saves the comment permanently * @@ -988,12 +1113,66 @@ class Manager implements ICommentsManager { if ($affectedRows > 0) { $comment->setId((string)$qb->getLastInsertId()); + if ($comment->getVerb() === 'reaction') { + $this->addReaction($comment); + } $this->sendEvent(CommentsEvent::EVENT_ADD, $comment); } return $affectedRows > 0; } + private function addReaction(IComment $comment): void { + $qb = $this->dbConn->getQueryBuilder(); + $qb->insert('reactions') + ->values([ + 'parent_id' => $qb->createNamedParameter($comment->getParentId()), + 'message_id' => $qb->createNamedParameter($comment->getId()), + 'actor_type' => $qb->createNamedParameter($comment->getActorType()), + 'actor_id' => $qb->createNamedParameter($comment->getActorId()), + 'reaction' => $qb->createNamedParameter($comment->getMessage()), + ]) + ->executeStatement(); + $this->sumReactions($comment); + } + + private function sumReactions(IComment $comment): void { + $qb = $this->dbConn->getQueryBuilder(); + + $totalQuery = $this->dbConn->getQueryBuilder(); + $totalQuery + ->selectAlias( + $totalQuery->func()->concat( + $totalQuery->expr()->literal('"'), + 'reaction', + $totalQuery->expr()->literal('":'), + $totalQuery->func()->count('id') + ), + 'total' + ) + ->from('reactions', 'r') + ->where($totalQuery->expr()->eq('r.parent_id', $qb->createNamedParameter($comment->getParentId()))) + ->groupBy('r.reaction'); + + $jsonQuery = $this->dbConn->getQueryBuilder(); + $jsonQuery + ->selectAlias( + $totalQuery->func()->concat( + $jsonQuery->expr()->literal('{'), + $jsonQuery->func()->groupConcat('total'), + $jsonQuery->expr()->literal('}') + ), + 'json' + ) + ->from($jsonQuery->createFunction('(' . $totalQuery->getSQL() . ')'), 'json'); + + $qb + ->update('comments') + ->set('reactions', $jsonQuery->createFunction('(' . $jsonQuery->getSQL() . ')')) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($comment->getParentId()))) + ->executeStatement(); + } + /** * updates a Comment data row * @@ -1015,6 +1194,10 @@ class Manager implements ICommentsManager { $result = $this->updateQuery($comment, false); } + if ($comment->getVerb() === 'reaction_deleted') { + $this->deleteReaction($comment); + } + $this->sendEvent(CommentsEvent::EVENT_UPDATE, $comment); return $result; |