Merge pull request #4146 from nextcloud/unread-comments-folder
Allow getting the unread comment count for an entire folder at once
This commit is contained in:
commit
a045f3c4d7
|
@ -42,6 +42,10 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
||||||
/** @var IUserSession */
|
/** @var IUserSession */
|
||||||
private $userSession;
|
private $userSession;
|
||||||
|
|
||||||
|
private $cachedUnreadCount = [];
|
||||||
|
|
||||||
|
private $cachedFolders = [];
|
||||||
|
|
||||||
public function __construct(ICommentsManager $commentsManager, IUserSession $userSession) {
|
public function __construct(ICommentsManager $commentsManager, IUserSession $userSession) {
|
||||||
$this->commentsManager = $commentsManager;
|
$this->commentsManager = $commentsManager;
|
||||||
$this->userSession = $userSession;
|
$this->userSession = $userSession;
|
||||||
|
@ -79,6 +83,18 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// need prefetch ?
|
||||||
|
if ($node instanceof \OCA\DAV\Connector\Sabre\Directory
|
||||||
|
&& $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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$propFind->handle(self::PROPERTY_NAME_COUNT, function() use ($node) {
|
$propFind->handle(self::PROPERTY_NAME_COUNT, function() use ($node) {
|
||||||
return $this->commentsManager->getNumberOfCommentsForObject('files', strval($node->getId()));
|
return $this->commentsManager->getNumberOfCommentsForObject('files', strval($node->getId()));
|
||||||
});
|
});
|
||||||
|
@ -88,7 +104,20 @@ class CommentPropertiesPlugin extends ServerPlugin {
|
||||||
});
|
});
|
||||||
|
|
||||||
$propFind->handle(self::PROPERTY_NAME_UNREAD, function() use ($node) {
|
$propFind->handle(self::PROPERTY_NAME_UNREAD, function() use ($node) {
|
||||||
return $this->getUnreadCount($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 shares for this file
|
||||||
|
if (array_search($parentPath, $this->cachedFolders) === false) {
|
||||||
|
return $this->getUnreadCount($node);
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,11 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace OC\Comments;
|
namespace OC\Comments;
|
||||||
|
|
||||||
use Doctrine\DBAL\Exception\DriverException;
|
use Doctrine\DBAL\Exception\DriverException;
|
||||||
|
use Doctrine\DBAL\Platforms\MySqlPlatform;
|
||||||
use OCP\Comments\CommentsEvent;
|
use OCP\Comments\CommentsEvent;
|
||||||
use OCP\Comments\IComment;
|
use OCP\Comments\IComment;
|
||||||
use OCP\Comments\ICommentsEventHandler;
|
use OCP\Comments\ICommentsEventHandler;
|
||||||
|
@ -46,7 +48,7 @@ class Manager implements ICommentsManager {
|
||||||
/** @var IConfig */
|
/** @var IConfig */
|
||||||
protected $config;
|
protected $config;
|
||||||
|
|
||||||
/** @var IComment[] */
|
/** @var IComment[] */
|
||||||
protected $commentsCache = [];
|
protected $commentsCache = [];
|
||||||
|
|
||||||
/** @var \Closure[] */
|
/** @var \Closure[] */
|
||||||
|
@ -104,7 +106,7 @@ class Manager implements ICommentsManager {
|
||||||
* @throws \UnexpectedValueException
|
* @throws \UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
protected function prepareCommentForDatabaseWrite(IComment $comment) {
|
protected function prepareCommentForDatabaseWrite(IComment $comment) {
|
||||||
if( !$comment->getActorType()
|
if (!$comment->getActorType()
|
||||||
|| !$comment->getActorId()
|
|| !$comment->getActorId()
|
||||||
|| !$comment->getObjectType()
|
|| !$comment->getObjectType()
|
||||||
|| !$comment->getObjectId()
|
|| !$comment->getObjectId()
|
||||||
|
@ -113,17 +115,17 @@ class Manager implements ICommentsManager {
|
||||||
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
|
throw new \UnexpectedValueException('Actor, Object and Verb information must be provided for saving');
|
||||||
}
|
}
|
||||||
|
|
||||||
if($comment->getId() === '') {
|
if ($comment->getId() === '') {
|
||||||
$comment->setChildrenCount(0);
|
$comment->setChildrenCount(0);
|
||||||
$comment->setLatestChildDateTime(new \DateTime('0000-00-00 00:00:00', new \DateTimeZone('UTC')));
|
$comment->setLatestChildDateTime(new \DateTime('0000-00-00 00:00:00', new \DateTimeZone('UTC')));
|
||||||
$comment->setLatestChildDateTime(null);
|
$comment->setLatestChildDateTime(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_null($comment->getCreationDateTime())) {
|
if (is_null($comment->getCreationDateTime())) {
|
||||||
$comment->setCreationDateTime(new \DateTime());
|
$comment->setCreationDateTime(new \DateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
if($comment->getParentId() !== '0') {
|
if ($comment->getParentId() !== '0') {
|
||||||
$comment->setTopmostParentId($this->determineTopmostParentId($comment->getParentId()));
|
$comment->setTopmostParentId($this->determineTopmostParentId($comment->getParentId()));
|
||||||
} else {
|
} else {
|
||||||
$comment->setTopmostParentId('0');
|
$comment->setTopmostParentId('0');
|
||||||
|
@ -143,7 +145,7 @@ class Manager implements ICommentsManager {
|
||||||
*/
|
*/
|
||||||
protected function determineTopmostParentId($id) {
|
protected function determineTopmostParentId($id) {
|
||||||
$comment = $this->get($id);
|
$comment = $this->get($id);
|
||||||
if($comment->getParentId() === '0') {
|
if ($comment->getParentId() === '0') {
|
||||||
return $comment->getId();
|
return $comment->getId();
|
||||||
} else {
|
} else {
|
||||||
return $this->determineTopmostParentId($comment->getId());
|
return $this->determineTopmostParentId($comment->getId());
|
||||||
|
@ -153,16 +155,16 @@ class Manager implements ICommentsManager {
|
||||||
/**
|
/**
|
||||||
* updates child information of a comment
|
* updates child information of a comment
|
||||||
*
|
*
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @param \DateTime $cDateTime the date time of the most recent child
|
* @param \DateTime $cDateTime the date time of the most recent child
|
||||||
* @throws NotFoundException
|
* @throws NotFoundException
|
||||||
*/
|
*/
|
||||||
protected function updateChildrenInformation($id, \DateTime $cDateTime) {
|
protected function updateChildrenInformation($id, \DateTime $cDateTime) {
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
|
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
|
||||||
->from('comments')
|
->from('comments')
|
||||||
->where($qb->expr()->eq('parent_id', $qb->createParameter('id')))
|
->where($qb->expr()->eq('parent_id', $qb->createParameter('id')))
|
||||||
->setParameter('id', $id);
|
->setParameter('id', $id);
|
||||||
|
|
||||||
$resultStatement = $query->execute();
|
$resultStatement = $query->execute();
|
||||||
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
|
$data = $resultStatement->fetch(\PDO::FETCH_NUM);
|
||||||
|
@ -185,8 +187,8 @@ class Manager implements ICommentsManager {
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
protected function checkRoleParameters($role, $type, $id) {
|
protected function checkRoleParameters($role, $type, $id) {
|
||||||
if(
|
if (
|
||||||
!is_string($type) || empty($type)
|
!is_string($type) || empty($type)
|
||||||
|| !is_string($id) || empty($id)
|
|| !is_string($id) || empty($id)
|
||||||
) {
|
) {
|
||||||
throw new \InvalidArgumentException($role . ' parameters must be string and not empty');
|
throw new \InvalidArgumentException($role . ' parameters must be string and not empty');
|
||||||
|
@ -200,7 +202,7 @@ class Manager implements ICommentsManager {
|
||||||
*/
|
*/
|
||||||
protected function cache(IComment $comment) {
|
protected function cache(IComment $comment) {
|
||||||
$id = $comment->getId();
|
$id = $comment->getId();
|
||||||
if(empty($id)) {
|
if (empty($id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$this->commentsCache[strval($id)] = $comment;
|
$this->commentsCache[strval($id)] = $comment;
|
||||||
|
@ -228,11 +230,11 @@ class Manager implements ICommentsManager {
|
||||||
* @since 9.0.0
|
* @since 9.0.0
|
||||||
*/
|
*/
|
||||||
public function get($id) {
|
public function get($id) {
|
||||||
if(intval($id) === 0) {
|
if (intval($id) === 0) {
|
||||||
throw new \InvalidArgumentException('IDs must be translatable to a number in this implementation.');
|
throw new \InvalidArgumentException('IDs must be translatable to a number in this implementation.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isset($this->commentsCache[$id])) {
|
if (isset($this->commentsCache[$id])) {
|
||||||
return $this->commentsCache[$id];
|
return $this->commentsCache[$id];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,7 +247,7 @@ class Manager implements ICommentsManager {
|
||||||
|
|
||||||
$data = $resultStatement->fetch();
|
$data = $resultStatement->fetch();
|
||||||
$resultStatement->closeCursor();
|
$resultStatement->closeCursor();
|
||||||
if(!$data) {
|
if (!$data) {
|
||||||
throw new NotFoundException();
|
throw new NotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,20 +292,20 @@ class Manager implements ICommentsManager {
|
||||||
|
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$query = $qb->select('*')
|
$query = $qb->select('*')
|
||||||
->from('comments')
|
->from('comments')
|
||||||
->where($qb->expr()->eq('topmost_parent_id', $qb->createParameter('id')))
|
->where($qb->expr()->eq('topmost_parent_id', $qb->createParameter('id')))
|
||||||
->orderBy('creation_timestamp', 'DESC')
|
->orderBy('creation_timestamp', 'DESC')
|
||||||
->setParameter('id', $id);
|
->setParameter('id', $id);
|
||||||
|
|
||||||
if($limit > 0) {
|
if ($limit > 0) {
|
||||||
$query->setMaxResults($limit);
|
$query->setMaxResults($limit);
|
||||||
}
|
}
|
||||||
if($offset > 0) {
|
if ($offset > 0) {
|
||||||
$query->setFirstResult($offset);
|
$query->setFirstResult($offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
$resultStatement = $query->execute();
|
$resultStatement = $query->execute();
|
||||||
while($data = $resultStatement->fetch()) {
|
while ($data = $resultStatement->fetch()) {
|
||||||
$comment = new Comment($this->normalizeDatabaseData($data));
|
$comment = new Comment($this->normalizeDatabaseData($data));
|
||||||
$this->cache($comment);
|
$this->cache($comment);
|
||||||
$tree['replies'][] = [
|
$tree['replies'][] = [
|
||||||
|
@ -332,37 +334,37 @@ class Manager implements ICommentsManager {
|
||||||
* @since 9.0.0
|
* @since 9.0.0
|
||||||
*/
|
*/
|
||||||
public function getForObject(
|
public function getForObject(
|
||||||
$objectType,
|
$objectType,
|
||||||
$objectId,
|
$objectId,
|
||||||
$limit = 0,
|
$limit = 0,
|
||||||
$offset = 0,
|
$offset = 0,
|
||||||
\DateTime $notOlderThan = null
|
\DateTime $notOlderThan = null
|
||||||
) {
|
) {
|
||||||
$comments = [];
|
$comments = [];
|
||||||
|
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$query = $qb->select('*')
|
$query = $qb->select('*')
|
||||||
->from('comments')
|
->from('comments')
|
||||||
->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
|
->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
|
||||||
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
|
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
|
||||||
->orderBy('creation_timestamp', 'DESC')
|
->orderBy('creation_timestamp', 'DESC')
|
||||||
->setParameter('type', $objectType)
|
->setParameter('type', $objectType)
|
||||||
->setParameter('id', $objectId);
|
->setParameter('id', $objectId);
|
||||||
|
|
||||||
if($limit > 0) {
|
if ($limit > 0) {
|
||||||
$query->setMaxResults($limit);
|
$query->setMaxResults($limit);
|
||||||
}
|
}
|
||||||
if($offset > 0) {
|
if ($offset > 0) {
|
||||||
$query->setFirstResult($offset);
|
$query->setFirstResult($offset);
|
||||||
}
|
}
|
||||||
if(!is_null($notOlderThan)) {
|
if (!is_null($notOlderThan)) {
|
||||||
$query
|
$query
|
||||||
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
|
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
|
||||||
->setParameter('notOlderThan', $notOlderThan, 'datetime');
|
->setParameter('notOlderThan', $notOlderThan, 'datetime');
|
||||||
}
|
}
|
||||||
|
|
||||||
$resultStatement = $query->execute();
|
$resultStatement = $query->execute();
|
||||||
while($data = $resultStatement->fetch()) {
|
while ($data = $resultStatement->fetch()) {
|
||||||
$comment = new Comment($this->normalizeDatabaseData($data));
|
$comment = new Comment($this->normalizeDatabaseData($data));
|
||||||
$this->cache($comment);
|
$this->cache($comment);
|
||||||
$comments[] = $comment;
|
$comments[] = $comment;
|
||||||
|
@ -383,13 +385,13 @@ class Manager implements ICommentsManager {
|
||||||
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null) {
|
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null) {
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
|
$query = $qb->select($qb->createFunction('COUNT(`id`)'))
|
||||||
->from('comments')
|
->from('comments')
|
||||||
->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
|
->where($qb->expr()->eq('object_type', $qb->createParameter('type')))
|
||||||
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
|
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('id')))
|
||||||
->setParameter('type', $objectType)
|
->setParameter('type', $objectType)
|
||||||
->setParameter('id', $objectId);
|
->setParameter('id', $objectId);
|
||||||
|
|
||||||
if(!is_null($notOlderThan)) {
|
if (!is_null($notOlderThan)) {
|
||||||
$query
|
$query
|
||||||
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
|
->andWhere($qb->expr()->gt('creation_timestamp', $qb->createParameter('notOlderThan')))
|
||||||
->setParameter('notOlderThan', $notOlderThan, 'datetime');
|
->setParameter('notOlderThan', $notOlderThan, 'datetime');
|
||||||
|
@ -401,6 +403,40 @@ class Manager implements ICommentsManager {
|
||||||
return intval($data[0]);
|
return intval($data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of unread comments for all files in a folder
|
||||||
|
*
|
||||||
|
* @param int $folderId
|
||||||
|
* @param IUser $user
|
||||||
|
* @return array [$fileId => $unreadCount]
|
||||||
|
*/
|
||||||
|
public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user) {
|
||||||
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
|
$query = $qb->select('fileid', $qb->createFunction(
|
||||||
|
'COUNT(' . $qb->getColumnName('c.id') . ')')
|
||||||
|
)->from('comments', 'c')
|
||||||
|
->innerJoin('c', 'filecache', 'f', $qb->expr()->andX(
|
||||||
|
$qb->expr()->eq('c.object_type', $qb->createNamedParameter('files')),
|
||||||
|
$qb->expr()->eq('f.fileid', $qb->expr()->castColumn('c.object_id', IQueryBuilder::PARAM_INT))
|
||||||
|
))
|
||||||
|
->leftJoin('c', 'comments_read_markers', 'm', $qb->expr()->andX(
|
||||||
|
$qb->expr()->eq('m.object_type', $qb->createNamedParameter('files')),
|
||||||
|
$qb->expr()->eq('m.object_id', 'c.object_id'),
|
||||||
|
$qb->expr()->eq('m.user_id', $qb->createNamedParameter($user->getUID()))
|
||||||
|
))
|
||||||
|
->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($folderId)))
|
||||||
|
->andWhere($qb->expr()->orX(
|
||||||
|
$qb->expr()->gt('c.creation_timestamp', 'marker_datetime'),
|
||||||
|
$qb->expr()->isNull('marker_datetime')
|
||||||
|
))
|
||||||
|
->groupBy('f.fileid');
|
||||||
|
|
||||||
|
$resultStatement = $query->execute();
|
||||||
|
return array_map(function ($count) {
|
||||||
|
return (int)$count;
|
||||||
|
}, $resultStatement->fetchAll(\PDO::FETCH_KEY_PAIR));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a new comment and returns it. At this point of time, it is not
|
* creates a new comment and returns it. At this point of time, it is not
|
||||||
* saved in the used data storage. Use save() after setting other fields
|
* saved in the used data storage. Use save() after setting other fields
|
||||||
|
@ -433,7 +469,7 @@ class Manager implements ICommentsManager {
|
||||||
* @since 9.0.0
|
* @since 9.0.0
|
||||||
*/
|
*/
|
||||||
public function delete($id) {
|
public function delete($id) {
|
||||||
if(!is_string($id)) {
|
if (!is_string($id)) {
|
||||||
throw new \InvalidArgumentException('Parameter must be string');
|
throw new \InvalidArgumentException('Parameter must be string');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,16 +517,16 @@ class Manager implements ICommentsManager {
|
||||||
* @since 9.0.0
|
* @since 9.0.0
|
||||||
*/
|
*/
|
||||||
public function save(IComment $comment) {
|
public function save(IComment $comment) {
|
||||||
if($this->prepareCommentForDatabaseWrite($comment)->getId() === '') {
|
if ($this->prepareCommentForDatabaseWrite($comment)->getId() === '') {
|
||||||
$result = $this->insert($comment);
|
$result = $this->insert($comment);
|
||||||
} else {
|
} else {
|
||||||
$result = $this->update($comment);
|
$result = $this->update($comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($result && !!$comment->getParentId()) {
|
if ($result && !!$comment->getParentId()) {
|
||||||
$this->updateChildrenInformation(
|
$this->updateChildrenInformation(
|
||||||
$comment->getParentId(),
|
$comment->getParentId(),
|
||||||
$comment->getCreationDateTime()
|
$comment->getCreationDateTime()
|
||||||
);
|
);
|
||||||
$this->cache($comment);
|
$this->cache($comment);
|
||||||
}
|
}
|
||||||
|
@ -509,17 +545,17 @@ class Manager implements ICommentsManager {
|
||||||
$affectedRows = $qb
|
$affectedRows = $qb
|
||||||
->insert('comments')
|
->insert('comments')
|
||||||
->values([
|
->values([
|
||||||
'parent_id' => $qb->createNamedParameter($comment->getParentId()),
|
'parent_id' => $qb->createNamedParameter($comment->getParentId()),
|
||||||
'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
|
'topmost_parent_id' => $qb->createNamedParameter($comment->getTopmostParentId()),
|
||||||
'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
|
'children_count' => $qb->createNamedParameter($comment->getChildrenCount()),
|
||||||
'actor_type' => $qb->createNamedParameter($comment->getActorType()),
|
'actor_type' => $qb->createNamedParameter($comment->getActorType()),
|
||||||
'actor_id' => $qb->createNamedParameter($comment->getActorId()),
|
'actor_id' => $qb->createNamedParameter($comment->getActorId()),
|
||||||
'message' => $qb->createNamedParameter($comment->getMessage()),
|
'message' => $qb->createNamedParameter($comment->getMessage()),
|
||||||
'verb' => $qb->createNamedParameter($comment->getVerb()),
|
'verb' => $qb->createNamedParameter($comment->getVerb()),
|
||||||
'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
|
'creation_timestamp' => $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'),
|
||||||
'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
|
'latest_child_timestamp' => $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'),
|
||||||
'object_type' => $qb->createNamedParameter($comment->getObjectType()),
|
'object_type' => $qb->createNamedParameter($comment->getObjectType()),
|
||||||
'object_id' => $qb->createNamedParameter($comment->getObjectId()),
|
'object_id' => $qb->createNamedParameter($comment->getObjectId()),
|
||||||
])
|
])
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
@ -548,22 +584,22 @@ class Manager implements ICommentsManager {
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$affectedRows = $qb
|
$affectedRows = $qb
|
||||||
->update('comments')
|
->update('comments')
|
||||||
->set('parent_id', $qb->createNamedParameter($comment->getParentId()))
|
->set('parent_id', $qb->createNamedParameter($comment->getParentId()))
|
||||||
->set('topmost_parent_id', $qb->createNamedParameter($comment->getTopmostParentId()))
|
->set('topmost_parent_id', $qb->createNamedParameter($comment->getTopmostParentId()))
|
||||||
->set('children_count', $qb->createNamedParameter($comment->getChildrenCount()))
|
->set('children_count', $qb->createNamedParameter($comment->getChildrenCount()))
|
||||||
->set('actor_type', $qb->createNamedParameter($comment->getActorType()))
|
->set('actor_type', $qb->createNamedParameter($comment->getActorType()))
|
||||||
->set('actor_id', $qb->createNamedParameter($comment->getActorId()))
|
->set('actor_id', $qb->createNamedParameter($comment->getActorId()))
|
||||||
->set('message', $qb->createNamedParameter($comment->getMessage()))
|
->set('message', $qb->createNamedParameter($comment->getMessage()))
|
||||||
->set('verb', $qb->createNamedParameter($comment->getVerb()))
|
->set('verb', $qb->createNamedParameter($comment->getVerb()))
|
||||||
->set('creation_timestamp', $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'))
|
->set('creation_timestamp', $qb->createNamedParameter($comment->getCreationDateTime(), 'datetime'))
|
||||||
->set('latest_child_timestamp', $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'))
|
->set('latest_child_timestamp', $qb->createNamedParameter($comment->getLatestChildDateTime(), 'datetime'))
|
||||||
->set('object_type', $qb->createNamedParameter($comment->getObjectType()))
|
->set('object_type', $qb->createNamedParameter($comment->getObjectType()))
|
||||||
->set('object_id', $qb->createNamedParameter($comment->getObjectId()))
|
->set('object_id', $qb->createNamedParameter($comment->getObjectId()))
|
||||||
->where($qb->expr()->eq('id', $qb->createParameter('id')))
|
->where($qb->expr()->eq('id', $qb->createParameter('id')))
|
||||||
->setParameter('id', $comment->getId())
|
->setParameter('id', $comment->getId())
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
if($affectedRows === 0) {
|
if ($affectedRows === 0) {
|
||||||
throw new NotFoundException('Comment to update does ceased to exist');
|
throw new NotFoundException('Comment to update does ceased to exist');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,8 +623,8 @@ class Manager implements ICommentsManager {
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$affectedRows = $qb
|
$affectedRows = $qb
|
||||||
->update('comments')
|
->update('comments')
|
||||||
->set('actor_type', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
|
->set('actor_type', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
|
||||||
->set('actor_id', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
|
->set('actor_id', $qb->createNamedParameter(ICommentsManager::DELETED_USER))
|
||||||
->where($qb->expr()->eq('actor_type', $qb->createParameter('type')))
|
->where($qb->expr()->eq('actor_type', $qb->createParameter('type')))
|
||||||
->andWhere($qb->expr()->eq('actor_id', $qb->createParameter('id')))
|
->andWhere($qb->expr()->eq('actor_id', $qb->createParameter('id')))
|
||||||
->setParameter('type', $actorType)
|
->setParameter('type', $actorType)
|
||||||
|
@ -662,19 +698,19 @@ class Manager implements ICommentsManager {
|
||||||
|
|
||||||
$qb = $this->dbConn->getQueryBuilder();
|
$qb = $this->dbConn->getQueryBuilder();
|
||||||
$values = [
|
$values = [
|
||||||
'user_id' => $qb->createNamedParameter($user->getUID()),
|
'user_id' => $qb->createNamedParameter($user->getUID()),
|
||||||
'marker_datetime' => $qb->createNamedParameter($dateTime, 'datetime'),
|
'marker_datetime' => $qb->createNamedParameter($dateTime, 'datetime'),
|
||||||
'object_type' => $qb->createNamedParameter($objectType),
|
'object_type' => $qb->createNamedParameter($objectType),
|
||||||
'object_id' => $qb->createNamedParameter($objectId),
|
'object_id' => $qb->createNamedParameter($objectId),
|
||||||
];
|
];
|
||||||
|
|
||||||
// Strategy: try to update, if this does not return affected rows, do an insert.
|
// Strategy: try to update, if this does not return affected rows, do an insert.
|
||||||
$affectedRows = $qb
|
$affectedRows = $qb
|
||||||
->update('comments_read_markers')
|
->update('comments_read_markers')
|
||||||
->set('user_id', $values['user_id'])
|
->set('user_id', $values['user_id'])
|
||||||
->set('marker_datetime', $values['marker_datetime'])
|
->set('marker_datetime', $values['marker_datetime'])
|
||||||
->set('object_type', $values['object_type'])
|
->set('object_type', $values['object_type'])
|
||||||
->set('object_id', $values['object_id'])
|
->set('object_id', $values['object_id'])
|
||||||
->where($qb->expr()->eq('user_id', $qb->createParameter('user_id')))
|
->where($qb->expr()->eq('user_id', $qb->createParameter('user_id')))
|
||||||
->andWhere($qb->expr()->eq('object_type', $qb->createParameter('object_type')))
|
->andWhere($qb->expr()->eq('object_type', $qb->createParameter('object_type')))
|
||||||
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('object_id')))
|
->andWhere($qb->expr()->eq('object_id', $qb->createParameter('object_id')))
|
||||||
|
@ -717,7 +753,7 @@ class Manager implements ICommentsManager {
|
||||||
|
|
||||||
$data = $resultStatement->fetch();
|
$data = $resultStatement->fetch();
|
||||||
$resultStatement->closeCursor();
|
$resultStatement->closeCursor();
|
||||||
if(!$data || is_null($data['marker_datetime'])) {
|
if (!$data || is_null($data['marker_datetime'])) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -774,10 +810,10 @@ class Manager implements ICommentsManager {
|
||||||
* \OutOfBoundsException has to thrown.
|
* \OutOfBoundsException has to thrown.
|
||||||
*/
|
*/
|
||||||
public function registerDisplayNameResolver($type, \Closure $closure) {
|
public function registerDisplayNameResolver($type, \Closure $closure) {
|
||||||
if(!is_string($type)) {
|
if (!is_string($type)) {
|
||||||
throw new \InvalidArgumentException('String expected.');
|
throw new \InvalidArgumentException('String expected.');
|
||||||
}
|
}
|
||||||
if(isset($this->displayNameResolvers[$type])) {
|
if (isset($this->displayNameResolvers[$type])) {
|
||||||
throw new \OutOfBoundsException('Displayname resolver for this type already registered');
|
throw new \OutOfBoundsException('Displayname resolver for this type already registered');
|
||||||
}
|
}
|
||||||
$this->displayNameResolvers[$type] = $closure;
|
$this->displayNameResolvers[$type] = $closure;
|
||||||
|
@ -797,10 +833,10 @@ class Manager implements ICommentsManager {
|
||||||
* provided ID is unknown. It must be ensured that a string is returned.
|
* provided ID is unknown. It must be ensured that a string is returned.
|
||||||
*/
|
*/
|
||||||
public function resolveDisplayName($type, $id) {
|
public function resolveDisplayName($type, $id) {
|
||||||
if(!is_string($type)) {
|
if (!is_string($type)) {
|
||||||
throw new \InvalidArgumentException('String expected.');
|
throw new \InvalidArgumentException('String expected.');
|
||||||
}
|
}
|
||||||
if(!isset($this->displayNameResolvers[$type])) {
|
if (!isset($this->displayNameResolvers[$type])) {
|
||||||
throw new \OutOfBoundsException('No Displayname resolver for this type registered');
|
throw new \OutOfBoundsException('No Displayname resolver for this type registered');
|
||||||
}
|
}
|
||||||
return (string)$this->displayNameResolvers[$type]($id);
|
return (string)$this->displayNameResolvers[$type]($id);
|
||||||
|
@ -812,7 +848,7 @@ class Manager implements ICommentsManager {
|
||||||
* @return \OCP\Comments\ICommentsEventHandler[]
|
* @return \OCP\Comments\ICommentsEventHandler[]
|
||||||
*/
|
*/
|
||||||
private function getEventHandlers() {
|
private function getEventHandlers() {
|
||||||
if(!empty($this->eventHandlers)) {
|
if (!empty($this->eventHandlers)) {
|
||||||
return $this->eventHandlers;
|
return $this->eventHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -73,7 +73,7 @@ class QuoteHelper {
|
||||||
return $string;
|
return $string;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $alias . '.`' . $columnName . '`';
|
return '`' . $alias . '`.`' . $columnName . '`';
|
||||||
}
|
}
|
||||||
|
|
||||||
return '`' . $string . '`';
|
return '`' . $string . '`';
|
||||||
|
|
|
@ -173,7 +173,7 @@ class CleanTags implements IRepairStep {
|
||||||
|
|
||||||
$qb->select('d.' . $deleteId)
|
$qb->select('d.' . $deleteId)
|
||||||
->from($deleteTable, 'd')
|
->from($deleteTable, 'd')
|
||||||
->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, ' s.' . $sourceId))
|
->leftJoin('d', $sourceTable, 's', $qb->expr()->eq('d.' . $deleteId, 's.' . $sourceId))
|
||||||
->where(
|
->where(
|
||||||
$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
|
$qb->expr()->eq('d.type', $qb->expr()->literal('files'))
|
||||||
)
|
)
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
*/
|
*/
|
||||||
namespace OCP\Comments;
|
namespace OCP\Comments;
|
||||||
|
|
||||||
|
use OCP\IUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface ICommentsManager
|
* Interface ICommentsManager
|
||||||
*
|
*
|
||||||
|
@ -125,6 +127,16 @@ interface ICommentsManager {
|
||||||
*/
|
*/
|
||||||
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null);
|
public function getNumberOfCommentsForObject($objectType, $objectId, \DateTime $notOlderThan = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of unread comments for all files in a folder
|
||||||
|
*
|
||||||
|
* @param int $folderId
|
||||||
|
* @param IUser $user
|
||||||
|
* @return array [$fileId => $unreadCount]
|
||||||
|
* @since 12.0.0
|
||||||
|
*/
|
||||||
|
public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* creates a new comment and returns it. At this point of time, it is not
|
* creates a new comment and returns it. At this point of time, it is not
|
||||||
* saved in the used data storage. Use save() after setting other fields
|
* saved in the used data storage. Use save() after setting other fields
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Test\Comments;
|
namespace Test\Comments;
|
||||||
|
use OCP\IUser;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FakeManager
|
* Class FakeManager
|
||||||
|
@ -44,4 +45,6 @@ class FakeManager implements \OCP\Comments\ICommentsManager {
|
||||||
public function registerDisplayNameResolver($type, \Closure $closure) {}
|
public function registerDisplayNameResolver($type, \Closure $closure) {}
|
||||||
|
|
||||||
public function resolveDisplayName($type, $id) {}
|
public function resolveDisplayName($type, $id) {}
|
||||||
|
|
||||||
|
public function getNumberOfUnreadCommentsForFolder($folderId, IUser $user) {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,9 @@ use OC\Comments\Comment;
|
||||||
use OCP\Comments\CommentsEvent;
|
use OCP\Comments\CommentsEvent;
|
||||||
use OCP\Comments\ICommentsEventHandler;
|
use OCP\Comments\ICommentsEventHandler;
|
||||||
use OCP\Comments\ICommentsManager;
|
use OCP\Comments\ICommentsManager;
|
||||||
|
use OCP\IDBConnection;
|
||||||
use OCP\IUser;
|
use OCP\IUser;
|
||||||
|
use Test\Files\Storage\DummyUser;
|
||||||
use Test\TestCase;
|
use Test\TestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,37 +17,44 @@ use Test\TestCase;
|
||||||
* @group DB
|
* @group DB
|
||||||
*/
|
*/
|
||||||
class ManagerTest extends TestCase {
|
class ManagerTest extends TestCase {
|
||||||
|
/** @var IDBConnection */
|
||||||
|
private $connection;
|
||||||
|
|
||||||
public function setUp() {
|
public function setUp() {
|
||||||
parent::setUp();
|
parent::setUp();
|
||||||
|
|
||||||
$sql = \OC::$server->getDatabaseConnection()->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
|
$this->connection = \OC::$server->getDatabaseConnection();
|
||||||
\OC::$server->getDatabaseConnection()->prepare($sql)->execute();
|
|
||||||
|
$sql = $this->connection->getDatabasePlatform()->getTruncateTableSQL('`*PREFIX*comments`');
|
||||||
|
$this->connection->prepare($sql)->execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null) {
|
protected function addDatabaseEntry($parentId, $topmostParentId, $creationDT = null, $latestChildDT = null, $objectId = null) {
|
||||||
if(is_null($creationDT)) {
|
if (is_null($creationDT)) {
|
||||||
$creationDT = new \DateTime();
|
$creationDT = new \DateTime();
|
||||||
}
|
}
|
||||||
if(is_null($latestChildDT)) {
|
if (is_null($latestChildDT)) {
|
||||||
$latestChildDT = new \DateTime('yesterday');
|
$latestChildDT = new \DateTime('yesterday');
|
||||||
}
|
}
|
||||||
|
if (is_null($objectId)) {
|
||||||
|
$objectId = 'file64';
|
||||||
|
}
|
||||||
|
|
||||||
$qb = \OC::$server->getDatabaseConnection()->getQueryBuilder();
|
$qb = $this->connection->getQueryBuilder();
|
||||||
$qb
|
$qb
|
||||||
->insert('comments')
|
->insert('comments')
|
||||||
->values([
|
->values([
|
||||||
'parent_id' => $qb->createNamedParameter($parentId),
|
'parent_id' => $qb->createNamedParameter($parentId),
|
||||||
'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
|
'topmost_parent_id' => $qb->createNamedParameter($topmostParentId),
|
||||||
'children_count' => $qb->createNamedParameter(2),
|
'children_count' => $qb->createNamedParameter(2),
|
||||||
'actor_type' => $qb->createNamedParameter('users'),
|
'actor_type' => $qb->createNamedParameter('users'),
|
||||||
'actor_id' => $qb->createNamedParameter('alice'),
|
'actor_id' => $qb->createNamedParameter('alice'),
|
||||||
'message' => $qb->createNamedParameter('nice one'),
|
'message' => $qb->createNamedParameter('nice one'),
|
||||||
'verb' => $qb->createNamedParameter('comment'),
|
'verb' => $qb->createNamedParameter('comment'),
|
||||||
'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
|
'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
|
||||||
'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
|
'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
|
||||||
'object_type' => $qb->createNamedParameter('files'),
|
'object_type' => $qb->createNamedParameter('files'),
|
||||||
'object_id' => $qb->createNamedParameter('file64'),
|
'object_id' => $qb->createNamedParameter($objectId),
|
||||||
])
|
])
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
@ -83,17 +92,17 @@ class ManagerTest extends TestCase {
|
||||||
$qb
|
$qb
|
||||||
->insert('comments')
|
->insert('comments')
|
||||||
->values([
|
->values([
|
||||||
'parent_id' => $qb->createNamedParameter('2'),
|
'parent_id' => $qb->createNamedParameter('2'),
|
||||||
'topmost_parent_id' => $qb->createNamedParameter('1'),
|
'topmost_parent_id' => $qb->createNamedParameter('1'),
|
||||||
'children_count' => $qb->createNamedParameter(2),
|
'children_count' => $qb->createNamedParameter(2),
|
||||||
'actor_type' => $qb->createNamedParameter('users'),
|
'actor_type' => $qb->createNamedParameter('users'),
|
||||||
'actor_id' => $qb->createNamedParameter('alice'),
|
'actor_id' => $qb->createNamedParameter('alice'),
|
||||||
'message' => $qb->createNamedParameter('nice one'),
|
'message' => $qb->createNamedParameter('nice one'),
|
||||||
'verb' => $qb->createNamedParameter('comment'),
|
'verb' => $qb->createNamedParameter('comment'),
|
||||||
'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
|
'creation_timestamp' => $qb->createNamedParameter($creationDT, 'datetime'),
|
||||||
'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
|
'latest_child_timestamp' => $qb->createNamedParameter($latestChildDT, 'datetime'),
|
||||||
'object_type' => $qb->createNamedParameter('files'),
|
'object_type' => $qb->createNamedParameter('files'),
|
||||||
'object_id' => $qb->createNamedParameter('file64'),
|
'object_id' => $qb->createNamedParameter('file64'),
|
||||||
])
|
])
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
|
@ -149,7 +158,7 @@ class ManagerTest extends TestCase {
|
||||||
$this->assertSame(count($tree['replies']), 3);
|
$this->assertSame(count($tree['replies']), 3);
|
||||||
|
|
||||||
// one level deep
|
// one level deep
|
||||||
foreach($tree['replies'] as $reply) {
|
foreach ($tree['replies'] as $reply) {
|
||||||
$this->assertTrue($reply['comment'] instanceof \OCP\Comments\IComment);
|
$this->assertTrue($reply['comment'] instanceof \OCP\Comments\IComment);
|
||||||
$this->assertSame($reply['comment']->getId(), strval($id));
|
$this->assertSame($reply['comment']->getId(), strval($id));
|
||||||
$this->assertSame(count($reply['replies']), 0);
|
$this->assertSame(count($reply['replies']), 0);
|
||||||
|
@ -171,7 +180,7 @@ class ManagerTest extends TestCase {
|
||||||
$this->assertSame(count($tree['replies']), 0);
|
$this->assertSame(count($tree['replies']), 0);
|
||||||
|
|
||||||
// one level deep
|
// one level deep
|
||||||
foreach($tree['replies'] as $reply) {
|
foreach ($tree['replies'] as $reply) {
|
||||||
throw new \Exception('This ain`t happen');
|
throw new \Exception('This ain`t happen');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -233,14 +242,14 @@ class ManagerTest extends TestCase {
|
||||||
$comments = $manager->getForObject('files', 'file64', 3, $offset);
|
$comments = $manager->getForObject('files', 'file64', 3, $offset);
|
||||||
|
|
||||||
$this->assertTrue(is_array($comments));
|
$this->assertTrue(is_array($comments));
|
||||||
foreach($comments as $comment) {
|
foreach ($comments as $comment) {
|
||||||
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
|
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
|
||||||
$this->assertSame($comment->getMessage(), 'nice one');
|
$this->assertSame($comment->getMessage(), 'nice one');
|
||||||
$this->assertSame($comment->getId(), strval($idToVerify));
|
$this->assertSame($comment->getId(), strval($idToVerify));
|
||||||
$idToVerify--;
|
$idToVerify--;
|
||||||
}
|
}
|
||||||
$offset += 3;
|
$offset += 3;
|
||||||
} while(count($comments) > 0);
|
} while (count($comments) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetForObjectWithDateTimeConstraint() {
|
public function testGetForObjectWithDateTimeConstraint() {
|
||||||
|
@ -272,7 +281,7 @@ class ManagerTest extends TestCase {
|
||||||
$comments = $manager->getForObject('files', 'file64', 3, $offset, new \DateTime('-4 hours'));
|
$comments = $manager->getForObject('files', 'file64', 3, $offset, new \DateTime('-4 hours'));
|
||||||
|
|
||||||
$this->assertTrue(is_array($comments));
|
$this->assertTrue(is_array($comments));
|
||||||
foreach($comments as $comment) {
|
foreach ($comments as $comment) {
|
||||||
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
|
$this->assertTrue($comment instanceof \OCP\Comments\IComment);
|
||||||
$this->assertSame($comment->getMessage(), 'nice one');
|
$this->assertSame($comment->getMessage(), 'nice one');
|
||||||
$this->assertSame($comment->getId(), strval($idToVerify));
|
$this->assertSame($comment->getId(), strval($idToVerify));
|
||||||
|
@ -280,11 +289,11 @@ class ManagerTest extends TestCase {
|
||||||
$idToVerify--;
|
$idToVerify--;
|
||||||
}
|
}
|
||||||
$offset += 3;
|
$offset += 3;
|
||||||
} while(count($comments) > 0);
|
} while (count($comments) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testGetNumberOfCommentsForObject() {
|
public function testGetNumberOfCommentsForObject() {
|
||||||
for($i = 1; $i < 5; $i++) {
|
for ($i = 1; $i < 5; $i++) {
|
||||||
$this->addDatabaseEntry(0, 0);
|
$this->addDatabaseEntry(0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,6 +306,52 @@ class ManagerTest extends TestCase {
|
||||||
$this->assertSame($amount, 4);
|
$this->assertSame($amount, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testGetNumberOfUnreadCommentsForFolder() {
|
||||||
|
// 2 comment for 1111 with 1 before read marker
|
||||||
|
// 2 comments for 1112 with no read marker
|
||||||
|
// 1 comment for 1113 before read marker
|
||||||
|
// 1 comment for 1114 with no read marker
|
||||||
|
$this->addDatabaseEntry(0, 0, null, null, '1112');
|
||||||
|
for ($i = 1; $i < 5; $i++) {
|
||||||
|
$this->addDatabaseEntry(0, 0, null, null, '111' . $i);
|
||||||
|
}
|
||||||
|
$this->addDatabaseEntry(0, 0, (new \DateTime())->modify('-2 days'), null, '1111');
|
||||||
|
$user = $this->createMock(IUser::class);
|
||||||
|
$user->expects($this->any())
|
||||||
|
->method('getUID')
|
||||||
|
->will($this->returnValue('comment_test'));
|
||||||
|
|
||||||
|
$manager = $this->getManager();
|
||||||
|
|
||||||
|
$manager->setReadMark('files', '1111', (new \DateTime())->modify('-1 days'), $user);
|
||||||
|
$manager->setReadMark('files', '1113', (new \DateTime()), $user);
|
||||||
|
|
||||||
|
$query = $this->connection->getQueryBuilder();
|
||||||
|
$query->insert('filecache')
|
||||||
|
->values([
|
||||||
|
'fileid' => $query->createParameter('fileid'),
|
||||||
|
'parent' => $query->createNamedParameter(1000),
|
||||||
|
'size' => $query->createNamedParameter(10),
|
||||||
|
'mtime' => $query->createNamedParameter(10),
|
||||||
|
'storage_mtime' => $query->createNamedParameter(10),
|
||||||
|
'path' => $query->createParameter('path'),
|
||||||
|
'path_hash' => $query->createParameter('path'),
|
||||||
|
]);
|
||||||
|
|
||||||
|
for ($i = 1111; $i < 1115; $i++) {
|
||||||
|
$query->setParameter('path', 'path_' . $i);
|
||||||
|
$query->setParameter('fileid', $i);
|
||||||
|
$query->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
$amount = $manager->getNumberOfUnreadCommentsForFolder(1000, $user);
|
||||||
|
$this->assertEquals([
|
||||||
|
'1111' => 1,
|
||||||
|
'1112' => 2,
|
||||||
|
'1114' => 1,
|
||||||
|
], $amount);
|
||||||
|
}
|
||||||
|
|
||||||
public function invalidCreateArgsProvider() {
|
public function invalidCreateArgsProvider() {
|
||||||
return [
|
return [
|
||||||
['', 'aId-1', 'oType-1', 'oId-1'],
|
['', 'aId-1', 'oType-1', 'oId-1'],
|
||||||
|
@ -380,10 +435,10 @@ class ManagerTest extends TestCase {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$comment = new Comment();
|
$comment = new Comment();
|
||||||
$comment
|
$comment
|
||||||
->setActor('users', 'alice')
|
->setActor('users', 'alice')
|
||||||
->setObject('files', 'file64')
|
->setObject('files', 'file64')
|
||||||
->setMessage('very beautiful, I am impressed!')
|
->setMessage('very beautiful, I am impressed!')
|
||||||
->setVerb('comment');
|
->setVerb('comment');
|
||||||
|
|
||||||
$manager->save($comment);
|
$manager->save($comment);
|
||||||
|
|
||||||
|
@ -401,10 +456,10 @@ class ManagerTest extends TestCase {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$comment = new Comment();
|
$comment = new Comment();
|
||||||
$comment
|
$comment
|
||||||
->setActor('users', 'alice')
|
->setActor('users', 'alice')
|
||||||
->setObject('files', 'file64')
|
->setObject('files', 'file64')
|
||||||
->setMessage('very beautiful, I am impressed!')
|
->setMessage('very beautiful, I am impressed!')
|
||||||
->setVerb('comment');
|
->setVerb('comment');
|
||||||
|
|
||||||
$manager->save($comment);
|
$manager->save($comment);
|
||||||
|
|
||||||
|
@ -428,16 +483,16 @@ class ManagerTest extends TestCase {
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
for($i = 0; $i < 3; $i++) {
|
for ($i = 0; $i < 3; $i++) {
|
||||||
$comment = new Comment();
|
$comment = new Comment();
|
||||||
$comment
|
$comment
|
||||||
->setActor('users', 'alice')
|
->setActor('users', 'alice')
|
||||||
->setObject('files', 'file64')
|
->setObject('files', 'file64')
|
||||||
->setParentId(strval($id))
|
->setParentId(strval($id))
|
||||||
->setMessage('full ack')
|
->setMessage('full ack')
|
||||||
->setVerb('comment')
|
->setVerb('comment')
|
||||||
// setting the creation time avoids using sleep() while making sure to test with different timestamps
|
// setting the creation time avoids using sleep() while making sure to test with different timestamps
|
||||||
->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
|
->setCreationDateTime(new \DateTime('+' . $i . ' minutes'));
|
||||||
|
|
||||||
$manager->save($comment);
|
$manager->save($comment);
|
||||||
|
|
||||||
|
@ -450,11 +505,11 @@ class ManagerTest extends TestCase {
|
||||||
|
|
||||||
public function invalidActorArgsProvider() {
|
public function invalidActorArgsProvider() {
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
['', ''],
|
['', ''],
|
||||||
[1, 'alice'],
|
[1, 'alice'],
|
||||||
['users', 1],
|
['users', 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -482,7 +537,7 @@ class ManagerTest extends TestCase {
|
||||||
$wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
|
$wasSuccessful = $manager->deleteReferencesOfActor('users', 'alice');
|
||||||
$this->assertTrue($wasSuccessful);
|
$this->assertTrue($wasSuccessful);
|
||||||
|
|
||||||
foreach($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
$comment = $manager->get(strval($id));
|
$comment = $manager->get(strval($id));
|
||||||
$this->assertSame($comment->getActorType(), ICommentsManager::DELETED_USER);
|
$this->assertSame($comment->getActorType(), ICommentsManager::DELETED_USER);
|
||||||
$this->assertSame($comment->getActorId(), ICommentsManager::DELETED_USER);
|
$this->assertSame($comment->getActorId(), ICommentsManager::DELETED_USER);
|
||||||
|
@ -516,11 +571,11 @@ class ManagerTest extends TestCase {
|
||||||
|
|
||||||
public function invalidObjectArgsProvider() {
|
public function invalidObjectArgsProvider() {
|
||||||
return
|
return
|
||||||
[
|
[
|
||||||
['', ''],
|
['', ''],
|
||||||
[1, 'file64'],
|
[1, 'file64'],
|
||||||
['files', 1],
|
['files', 1],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -549,7 +604,7 @@ class ManagerTest extends TestCase {
|
||||||
$this->assertTrue($wasSuccessful);
|
$this->assertTrue($wasSuccessful);
|
||||||
|
|
||||||
$verified = 0;
|
$verified = 0;
|
||||||
foreach($ids as $id) {
|
foreach ($ids as $id) {
|
||||||
try {
|
try {
|
||||||
$manager->get(strval($id));
|
$manager->get(strval($id));
|
||||||
} catch (\OCP\Comments\NotFoundException $e) {
|
} catch (\OCP\Comments\NotFoundException $e) {
|
||||||
|
@ -575,7 +630,7 @@ class ManagerTest extends TestCase {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
||||||
|
|
||||||
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
||||||
|
|
||||||
$this->assertEquals($dateTimeGet->getTimestamp(), $dateTimeSet->getTimestamp());
|
$this->assertEquals($dateTimeGet->getTimestamp(), $dateTimeSet->getTimestamp());
|
||||||
}
|
}
|
||||||
|
@ -594,7 +649,7 @@ class ManagerTest extends TestCase {
|
||||||
$dateTimeSet = new \DateTime('today');
|
$dateTimeSet = new \DateTime('today');
|
||||||
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
||||||
|
|
||||||
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
||||||
|
|
||||||
$this->assertEquals($dateTimeGet, $dateTimeSet);
|
$this->assertEquals($dateTimeGet, $dateTimeSet);
|
||||||
}
|
}
|
||||||
|
@ -611,7 +666,7 @@ class ManagerTest extends TestCase {
|
||||||
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
||||||
|
|
||||||
$manager->deleteReadMarksFromUser($user);
|
$manager->deleteReadMarksFromUser($user);
|
||||||
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
||||||
|
|
||||||
$this->assertNull($dateTimeGet);
|
$this->assertNull($dateTimeGet);
|
||||||
}
|
}
|
||||||
|
@ -628,7 +683,7 @@ class ManagerTest extends TestCase {
|
||||||
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
$manager->setReadMark('robot', '36', $dateTimeSet, $user);
|
||||||
|
|
||||||
$manager->deleteReadMarksOnObject('robot', '36');
|
$manager->deleteReadMarksOnObject('robot', '36');
|
||||||
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
$dateTimeGet = $manager->getReadMark('robot', '36', $user);
|
||||||
|
|
||||||
$this->assertNull($dateTimeGet);
|
$this->assertNull($dateTimeGet);
|
||||||
}
|
}
|
||||||
|
@ -643,8 +698,12 @@ class ManagerTest extends TestCase {
|
||||||
->method('handle');
|
->method('handle');
|
||||||
|
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
$manager->registerEventHandler(function () use ($handler1) {return $handler1; });
|
$manager->registerEventHandler(function () use ($handler1) {
|
||||||
$manager->registerEventHandler(function () use ($handler2) {return $handler2; });
|
return $handler1;
|
||||||
|
});
|
||||||
|
$manager->registerEventHandler(function () use ($handler2) {
|
||||||
|
return $handler2;
|
||||||
|
});
|
||||||
|
|
||||||
$comment = new Comment();
|
$comment = new Comment();
|
||||||
$comment
|
$comment
|
||||||
|
@ -667,11 +726,11 @@ class ManagerTest extends TestCase {
|
||||||
public function testResolveDisplayName() {
|
public function testResolveDisplayName() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function($name) {
|
$planetClosure = function ($name) {
|
||||||
return ucfirst($name);
|
return ucfirst($name);
|
||||||
};
|
};
|
||||||
|
|
||||||
$galaxyClosure = function($name) {
|
$galaxyClosure = function ($name) {
|
||||||
return strtoupper($name);
|
return strtoupper($name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -688,7 +747,7 @@ class ManagerTest extends TestCase {
|
||||||
public function testRegisterResolverDuplicate() {
|
public function testRegisterResolverDuplicate() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function($name) {
|
$planetClosure = function ($name) {
|
||||||
return ucfirst($name);
|
return ucfirst($name);
|
||||||
};
|
};
|
||||||
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
|
@ -701,7 +760,7 @@ class ManagerTest extends TestCase {
|
||||||
public function testRegisterResolverInvalidType() {
|
public function testRegisterResolverInvalidType() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function($name) {
|
$planetClosure = function ($name) {
|
||||||
return ucfirst($name);
|
return ucfirst($name);
|
||||||
};
|
};
|
||||||
$manager->registerDisplayNameResolver(1337, $planetClosure);
|
$manager->registerDisplayNameResolver(1337, $planetClosure);
|
||||||
|
@ -713,7 +772,7 @@ class ManagerTest extends TestCase {
|
||||||
public function testResolveDisplayNameUnregisteredType() {
|
public function testResolveDisplayNameUnregisteredType() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function($name) {
|
$planetClosure = function ($name) {
|
||||||
return ucfirst($name);
|
return ucfirst($name);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -724,7 +783,9 @@ class ManagerTest extends TestCase {
|
||||||
public function testResolveDisplayNameDirtyResolver() {
|
public function testResolveDisplayNameDirtyResolver() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function() { return null; };
|
$planetClosure = function () {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
$this->assertTrue(is_string($manager->resolveDisplayName('planet', 'neptune')));
|
$this->assertTrue(is_string($manager->resolveDisplayName('planet', 'neptune')));
|
||||||
|
@ -736,7 +797,9 @@ class ManagerTest extends TestCase {
|
||||||
public function testResolveDisplayNameInvalidType() {
|
public function testResolveDisplayNameInvalidType() {
|
||||||
$manager = $this->getManager();
|
$manager = $this->getManager();
|
||||||
|
|
||||||
$planetClosure = function() { return null; };
|
$planetClosure = function () {
|
||||||
|
return null;
|
||||||
|
};
|
||||||
|
|
||||||
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
$manager->registerDisplayNameResolver('planet', $planetClosure);
|
||||||
$this->assertTrue(is_string($manager->resolveDisplayName(1337, 'neptune')));
|
$this->assertTrue(is_string($manager->resolveDisplayName(1337, 'neptune')));
|
||||||
|
|
|
@ -1200,7 +1200,7 @@ class QueryBuilderTest extends \Test\TestCase {
|
||||||
public function dataGetColumnName() {
|
public function dataGetColumnName() {
|
||||||
return [
|
return [
|
||||||
['column', '', '`column`'],
|
['column', '', '`column`'],
|
||||||
['column', 'a', 'a.`column`'],
|
['column', 'a', '`a`.`column`'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,7 +65,7 @@ class QuoteHelperTest extends \Test\TestCase {
|
||||||
public function dataQuoteColumnNames() {
|
public function dataQuoteColumnNames() {
|
||||||
return [
|
return [
|
||||||
// Single case
|
// Single case
|
||||||
['d.column', 'd.`column`'],
|
['d.column', '`d`.`column`'],
|
||||||
['column', '`column`'],
|
['column', '`column`'],
|
||||||
[new Literal('literal'), 'literal'],
|
[new Literal('literal'), 'literal'],
|
||||||
[new Literal(1), '1'],
|
[new Literal(1), '1'],
|
||||||
|
|
Loading…
Reference in New Issue