Merge pull request #23792 from nextcloud/techdebt/noid/group-unread-comment-count-query
Add a function to get the unread count for multiple objects in one go
This commit is contained in:
commit
c3969d9493
|
@ -47,8 +47,6 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
|||
|
||||
private $cachedUnreadCount = [];
|
||||
|
||||
private $cachedFolders = [];
|
||||
|
||||
public function __construct(ICommentsManager $commentsManager, IUserSession $userSession) {
|
||||
$this->commentsManager = $commentsManager;
|
||||
$this->userSession = $userSession;
|
||||
|
@ -70,6 +68,31 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
|||
$this->server->on('propFind', [$this, 'handleGetProperties']);
|
||||
}
|
||||
|
||||
private function cacheDirectory(Directory $directory) {
|
||||
$children = $directory->getChildren();
|
||||
|
||||
$ids = [];
|
||||
foreach ($children as $child) {
|
||||
if (!($child instanceof File || $child instanceof Directory)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $child->getId();
|
||||
if ($id === null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$ids[] = (string)$id;
|
||||
}
|
||||
|
||||
$ids[] = (string) $directory->getId();
|
||||
$unread = $this->commentsManager->getNumberOfUnreadCommentsForObjects('files', $ids, $this->userSession->getUser());
|
||||
|
||||
foreach ($unread as $id => $count) {
|
||||
$this->cachedUnreadCount[(int)$id] = $count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds tags and favorites properties to the response,
|
||||
* if requested.
|
||||
|
@ -91,11 +114,7 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
|||
&& $propFind->getDepth() !== 0
|
||||
&& !is_null($propFind->getStatus(self::PROPERTY_NAME_UNREAD))
|
||||
) {
|
||||
$unreadCounts = $this->commentsManager->getNumberOfUnreadCommentsForFolder($node->getId(), $this->userSession->getUser());
|
||||
$this->cachedFolders[] = $node->getPath();
|
||||
foreach ($unreadCounts as $id => $count) {
|
||||
$this->cachedUnreadCount[$id] = $count;
|
||||
}
|
||||
$this->cacheDirectory($node);
|
||||
}
|
||||
|
||||
$propFind->handle(self::PROPERTY_NAME_COUNT, function () use ($node) {
|
||||
|
@ -109,18 +128,8 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
|||
$propFind->handle(self::PROPERTY_NAME_UNREAD, function () use ($node) {
|
||||
if (isset($this->cachedUnreadCount[$node->getId()])) {
|
||||
return $this->cachedUnreadCount[$node->getId()];
|
||||
} else {
|
||||
list($parentPath,) = \Sabre\Uri\split($node->getPath());
|
||||
if ($parentPath === '') {
|
||||
$parentPath = '/';
|
||||
}
|
||||
// if we already cached the folder this file is in we know there are no comments for this file
|
||||
if (array_search($parentPath, $this->cachedFolders) === false) {
|
||||
return 0;
|
||||
} else {
|
||||
return $this->getUnreadCount($node);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -624,6 +624,46 @@ class Manager implements ICommentsManager {
|
|||
return (int)$data[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $objectType the object type, e.g. 'files'
|
||||
* @param string[] $objectIds the id of the object
|
||||
* @param IUser $user
|
||||
* @param string $verb Limit the verb of the comment - Added in 14.0.0
|
||||
* @return array Map with object id => # of unread comments
|
||||
* @psalm-return array<string, int>
|
||||
* @since 21.0.0
|
||||
*/
|
||||
public function getNumberOfUnreadCommentsForObjects(string $objectType, array $objectIds, IUser $user, $verb = ''): array {
|
||||
$query = $this->dbConn->getQueryBuilder();
|
||||
$query->select('c.object_id', $query->func()->count('c.id', 'num_comments'))
|
||||
->from('comments', 'c')
|
||||
->leftJoin('c', 'comments_read_markers', 'm', $query->expr()->andX(
|
||||
$query->expr()->eq('m.user_id', $query->createNamedParameter($user->getUID())),
|
||||
$query->expr()->eq('c.object_type', 'm.object_type'),
|
||||
$query->expr()->eq('c.object_id', 'm.object_id')
|
||||
))
|
||||
->where($query->expr()->eq('c.object_type', $query->createNamedParameter($objectType)))
|
||||
->andWhere($query->expr()->in('c.object_id', $query->createNamedParameter($objectIds, IQueryBuilder::PARAM_STR_ARRAY)))
|
||||
->andWhere($query->expr()->orX(
|
||||
$query->expr()->gt('c.creation_timestamp', 'm.marker_datetime'),
|
||||
$query->expr()->isNull('m.marker_datetime')
|
||||
))
|
||||
->groupBy('c.object_id');
|
||||
|
||||
if ($verb !== '') {
|
||||
$query->andWhere($query->expr()->eq('c.verb', $query->createNamedParameter($verb)));
|
||||
}
|
||||
|
||||
$result = $query->execute();
|
||||
$unreadComments = array_fill_keys($objectIds, 0);
|
||||
while ($row = $result->fetch()) {
|
||||
$unreadComments[$row['object_id']] = (int) $row['num_comments'];
|
||||
}
|
||||
$result->closeCursor();
|
||||
|
||||
return $unreadComments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $objectType
|
||||
* @param string $objectId
|
||||
|
|
|
@ -180,6 +180,17 @@ interface ICommentsManager {
|
|||
*/
|
||||
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null, $verb = '');
|
||||
|
||||
/**
|
||||
* @param string $objectType the object type, e.g. 'files'
|
||||
* @param string[] $objectIds the id of the object
|
||||
* @param IUser $user
|
||||
* @param string $verb Limit the verb of the comment - Added in 14.0.0
|
||||
* @return array Map with object id => # of unread comments
|
||||
* @psalm-return array<string, int>
|
||||
* @since 21.0.0
|
||||
*/
|
||||
public function getNumberOfUnreadCommentsForObjects(string $objectType, array $objectIds, IUser $user, $verb = ''): array;
|
||||
|
||||
/**
|
||||
* @param string $objectType
|
||||
* @param string $objectId
|
||||
|
|
|
@ -82,6 +82,11 @@ class FakeManager implements ICommentsManager {
|
|||
public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user) {
|
||||
}
|
||||
|
||||
public function getNumberOfUnreadCommentsForObjects(string $objectType, array $objectIds, IUser $user, $verb = ''): array {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
||||
public function getActorsInTree($id) {
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue