summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/private/Comments/Manager.php115
-rw-r--r--lib/public/Comments/ICommentsManager.php17
-rw-r--r--tests/lib/Comments/ManagerTest.php42
3 files changed, 174 insertions, 0 deletions
diff --git a/lib/private/Comments/Manager.php b/lib/private/Comments/Manager.php
index 2b43a27b7ac..37b5f033097 100644
--- a/lib/private/Comments/Manager.php
+++ b/lib/private/Comments/Manager.php
@@ -377,6 +377,121 @@ class Manager implements ICommentsManager {
}
/**
+ * @param string $objectType
+ * @param string $objectId
+ * @param int $lastKnownCommentId
+ * @param string $sortDirection
+ * @param int $limit
+ * @return array
+ */
+ public function getForObjectSince(
+ string $objectType,
+ string $objectId,
+ int $lastKnownCommentId,
+ string $sortDirection = 'asc',
+ int $limit = 30
+ ): array {
+ $comments = [];
+
+ $query = $this->dbConn->getQueryBuilder();
+ $query->select('*')
+ ->from('comments')
+ ->where($query->expr()->eq('object_type', $query->createNamedParameter($objectType)))
+ ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId)))
+ ->orderBy('creation_timestamp', $sortDirection === 'desc' ? 'DESC' : 'ASC')
+ ->addOrderBy('id', $sortDirection === 'desc' ? 'DESC' : 'ASC');
+
+ if ($limit > 0) {
+ $query->setMaxResults($limit);
+ }
+
+ $lastKnownComment = $this->getLastKnownComment(
+ $objectType,
+ $objectId,
+ $lastKnownCommentId
+ );
+ if ($lastKnownComment instanceof IComment) {
+ $lastKnownCommentDateTime = $lastKnownComment->getCreationDateTime();
+ if ($sortDirection === 'desc') {
+ $query->andWhere(
+ $query->expr()->orX(
+ $query->expr()->lt(
+ 'creation_timestamp',
+ $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE),
+ IQueryBuilder::PARAM_DATE
+ ),
+ $query->expr()->andX(
+ $query->expr()->eq(
+ 'creation_timestamp',
+ $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE),
+ IQueryBuilder::PARAM_DATE
+ ),
+ $query->expr()->lt('id', $query->createNamedParameter($lastKnownCommentId))
+ )
+ )
+ );
+ } else {
+ $query->andWhere(
+ $query->expr()->orX(
+ $query->expr()->gt(
+ 'creation_timestamp',
+ $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE),
+ IQueryBuilder::PARAM_DATE
+ ),
+ $query->expr()->andX(
+ $query->expr()->eq(
+ 'creation_timestamp',
+ $query->createNamedParameter($lastKnownCommentDateTime, IQueryBuilder::PARAM_DATE),
+ IQueryBuilder::PARAM_DATE
+ ),
+ $query->expr()->gt('id', $query->createNamedParameter($lastKnownCommentId))
+ )
+ )
+ );
+ }
+ }
+
+ $resultStatement = $query->execute();
+ while ($data = $resultStatement->fetch()) {
+ $comment = new Comment($this->normalizeDatabaseData($data));
+ $this->cache($comment);
+ $comments[] = $comment;
+ }
+ $resultStatement->closeCursor();
+
+ return $comments;
+ }
+
+ /**
+ * @param string $objectType
+ * @param string $objectId
+ * @param int $id
+ * @return Comment|null
+ */
+ protected function getLastKnownComment(string $objectType,
+ string $objectId,
+ int $id) {
+ $query = $this->dbConn->getQueryBuilder();
+ $query->select('*')
+ ->from('comments')
+ ->where($query->expr()->eq('object_type', $query->createNamedParameter($objectType)))
+ ->andWhere($query->expr()->eq('object_id', $query->createNamedParameter($objectId)))
+ ->andWhere($query->expr()->eq('id', $query->createNamedParameter($id, IQueryBuilder::PARAM_INT)));
+
+ $result = $query->execute();
+ $row = $result->fetch();
+ $result->closeCursor();
+
+ if ($row) {
+ $comment = new Comment($this->normalizeDatabaseData($row));
+ $this->cache($comment);
+ return $comment;
+ }
+
+ return null;
+ }
+
+ /**
* @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
diff --git a/lib/public/Comments/ICommentsManager.php b/lib/public/Comments/ICommentsManager.php
index bd9c4ff5ba6..888e7df3e7f 100644
--- a/lib/public/Comments/ICommentsManager.php
+++ b/lib/public/Comments/ICommentsManager.php
@@ -121,6 +121,23 @@ interface ICommentsManager {
);
/**
+ * @param string $objectType
+ * @param string $objectId
+ * @param int $lastKnownCommentId
+ * @param string $sortDirection
+ * @param int $limit
+ * @return array
+ * @since 14.0.0
+ */
+ public function getForObjectSince(
+ string $objectType,
+ string $objectId,
+ int $lastKnownCommentId,
+ string $sortDirection = 'asc',
+ int $limit = 30
+ ): array;
+
+ /**
* @param $objectType string the object type, e.g. 'files'
* @param $objectId string the id of the object
* @param \DateTime|null $notOlderThan optional, timestamp of the oldest comments
diff --git a/tests/lib/Comments/ManagerTest.php b/tests/lib/Comments/ManagerTest.php
index 671389232e2..28002ff42cc 100644
--- a/tests/lib/Comments/ManagerTest.php
+++ b/tests/lib/Comments/ManagerTest.php
@@ -354,6 +354,48 @@ class ManagerTest extends TestCase {
], $amount);
}
+ /**
+ * @dataProvider dataGetForObjectSince
+ * @param $lastKnown
+ * @param $order
+ * @param $limit
+ * @param $resultFrom
+ * @param $resultTo
+ */
+ public function testGetForObjectSince($lastKnown, $order, $limit, $resultFrom, $resultTo) {
+ $ids = [];
+ $ids[] = $this->addDatabaseEntry(0, 0);
+ $ids[] = $this->addDatabaseEntry(0, 0);
+ $ids[] = $this->addDatabaseEntry(0, 0);
+ $ids[] = $this->addDatabaseEntry(0, 0);
+ $ids[] = $this->addDatabaseEntry(0, 0);
+
+ $manager = $this->getManager();
+ $comments = $manager->getForObjectSince('files', 'file64', ($lastKnown === null ? 0 : $ids[$lastKnown]), $order, $limit);
+
+ $expected = array_slice($ids, $resultFrom, $resultTo - $resultFrom + 1);
+ if ($order === 'desc') {
+ $expected = array_reverse($expected);
+ }
+
+ $this->assertSame($expected, array_map(function(IComment $c) {
+ return (int) $c->getId();
+ }, $comments));
+ }
+
+ public function dataGetForObjectSince() {
+ return [
+ [null, 'asc', 20, 0, 4],
+ [null, 'asc', 2, 0, 1],
+ [null, 'desc', 20, 0, 4],
+ [null, 'desc', 2, 3, 4],
+ [1, 'asc', 20, 2, 4],
+ [1, 'asc', 2, 2, 3],
+ [3, 'desc', 20, 0, 2],
+ [3, 'desc', 2, 1, 2],
+ ];
+ }
+
public function invalidCreateArgsProvider() {
return [
['', 'aId-1', 'oType-1', 'oId-1'],