Merge pull request #22059 from owncloud/comments-readmark-dav
Comments DAV methods for read mark manipulation (mark comments of a file as read) + return isUnread status
This commit is contained in:
commit
77942ad38a
|
@ -26,12 +26,17 @@ use OCP\Comments\IComment;
|
|||
use OCP\Comments\ICommentsManager;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use Sabre\DAV\Exception\MethodNotAllowed;
|
||||
use Sabre\DAV\PropPatch;
|
||||
|
||||
class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
||||
const NS_OWNCLOUD = 'http://owncloud.org/ns';
|
||||
|
||||
const PROPERTY_NAME_UNREAD = '{http://owncloud.org/ns}isUnread';
|
||||
const PROPERTY_NAME_MESSAGE = '{http://owncloud.org/ns}message';
|
||||
const PROPERTY_NAME_ACTOR_DISPLAYNAME = '{http://owncloud.org/ns}actorDisplayName';
|
||||
|
||||
/** @var IComment */
|
||||
public $comment;
|
||||
|
||||
|
@ -47,18 +52,23 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
/** @var IUserManager */
|
||||
protected $userManager;
|
||||
|
||||
/** @var IUserSession */
|
||||
protected $userSession;
|
||||
|
||||
/**
|
||||
* CommentNode constructor.
|
||||
*
|
||||
* @param ICommentsManager $commentsManager
|
||||
* @param IComment $comment
|
||||
* @param IUserManager $userManager
|
||||
* @param IUserSession $userSession
|
||||
* @param ILogger $logger
|
||||
*/
|
||||
public function __construct(
|
||||
ICommentsManager $commentsManager,
|
||||
IComment $comment,
|
||||
IUserManager $userManager,
|
||||
IUserSession $userSession,
|
||||
ILogger $logger
|
||||
) {
|
||||
$this->commentsManager = $commentsManager;
|
||||
|
@ -74,6 +84,7 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
$this->properties[$name] = $getter;
|
||||
}
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -87,15 +98,17 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
'{http://owncloud.org/ns}parentId',
|
||||
'{http://owncloud.org/ns}topmostParentId',
|
||||
'{http://owncloud.org/ns}childrenCount',
|
||||
'{http://owncloud.org/ns}message',
|
||||
'{http://owncloud.org/ns}verb',
|
||||
'{http://owncloud.org/ns}actorType',
|
||||
'{http://owncloud.org/ns}actorId',
|
||||
'{http://owncloud.org/ns}actorDisplayName',
|
||||
'{http://owncloud.org/ns}creationDateTime',
|
||||
'{http://owncloud.org/ns}latestChildDateTime',
|
||||
'{http://owncloud.org/ns}objectType',
|
||||
'{http://owncloud.org/ns}objectId',
|
||||
// re-used property names are defined as constants
|
||||
self::PROPERTY_NAME_MESSAGE,
|
||||
self::PROPERTY_NAME_ACTOR_DISPLAYNAME,
|
||||
self::PROPERTY_NAME_UNREAD
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -169,7 +182,7 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
*/
|
||||
function propPatch(PropPatch $propPatch) {
|
||||
// other properties than 'message' are read only
|
||||
$propPatch->handle('{'.self::NS_OWNCLOUD.'}message', [$this, 'updateComment']);
|
||||
$propPatch->handle(self::PROPERTY_NAME_MESSAGE, [$this, 'updateComment']);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -201,9 +214,27 @@ class CommentNode implements \Sabre\DAV\INode, \Sabre\DAV\IProperties {
|
|||
if($this->comment->getActorType() === 'users') {
|
||||
$user = $this->userManager->get($this->comment->getActorId());
|
||||
$displayName = is_null($user) ? null : $user->getDisplayName();
|
||||
$result['{' . self::NS_OWNCLOUD . '}actorDisplayName'] = $displayName;
|
||||
$result[self::PROPERTY_NAME_ACTOR_DISPLAYNAME] = $displayName;
|
||||
}
|
||||
|
||||
$unread = null;
|
||||
$user = $this->userSession->getUser();
|
||||
if(!is_null($user)) {
|
||||
$readUntil = $this->commentsManager->getReadMark(
|
||||
$this->comment->getObjectType(),
|
||||
$this->comment->getObjectId(),
|
||||
$user
|
||||
);
|
||||
if(is_null($readUntil)) {
|
||||
$unread = 'true';
|
||||
} else {
|
||||
$unread = $this->comment->getCreationDateTime() > $readUntil;
|
||||
// re-format for output
|
||||
$unread = $unread ? 'true' : 'false';
|
||||
}
|
||||
}
|
||||
$result[self::PROPERTY_NAME_UNREAD] = $unread;
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,9 @@ use OCP\Comments\ICommentsManager;
|
|||
use OCP\Files\Folder;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
use Sabre\DAV\PropPatch;
|
||||
|
||||
/**
|
||||
* Class EntityCollection
|
||||
|
@ -35,7 +37,9 @@ use Sabre\DAV\Exception\NotFound;
|
|||
*
|
||||
* @package OCA\DAV\Comments
|
||||
*/
|
||||
class EntityCollection extends RootCollection {
|
||||
class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties {
|
||||
const PROPERTY_NAME_READ_MARKER = '{http://owncloud.org/ns}readMarker';
|
||||
|
||||
/** @var Folder */
|
||||
protected $fileRoot;
|
||||
|
||||
|
@ -51,6 +55,7 @@ class EntityCollection extends RootCollection {
|
|||
* @param ICommentsManager $commentsManager
|
||||
* @param Folder $fileRoot
|
||||
* @param IUserManager $userManager
|
||||
* @param IUserSession $userSession
|
||||
* @param ILogger $logger
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -59,6 +64,7 @@ class EntityCollection extends RootCollection {
|
|||
ICommentsManager $commentsManager,
|
||||
Folder $fileRoot,
|
||||
IUserManager $userManager,
|
||||
IUserSession $userSession,
|
||||
ILogger $logger
|
||||
) {
|
||||
foreach(['id', 'name'] as $property) {
|
||||
|
@ -73,6 +79,7 @@ class EntityCollection extends RootCollection {
|
|||
$this->fileRoot = $fileRoot;
|
||||
$this->logger = $logger;
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -97,7 +104,13 @@ class EntityCollection extends RootCollection {
|
|||
function getChild($name) {
|
||||
try {
|
||||
$comment = $this->commentsManager->get($name);
|
||||
return new CommentNode($this->commentsManager, $comment, $this->userManager, $this->logger);
|
||||
return new CommentNode(
|
||||
$this->commentsManager,
|
||||
$comment,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
} catch (\OCP\Comments\NotFoundException $e) {
|
||||
throw new NotFound();
|
||||
}
|
||||
|
@ -125,7 +138,13 @@ class EntityCollection extends RootCollection {
|
|||
$comments = $this->commentsManager->getForObject($this->name, $this->id, $limit, $offset, $datetime);
|
||||
$result = [];
|
||||
foreach($comments as $comment) {
|
||||
$result[] = new CommentNode($this->commentsManager, $comment, $this->userManager, $this->logger);
|
||||
$result[] = new CommentNode(
|
||||
$this->commentsManager,
|
||||
$comment,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
@ -144,5 +163,37 @@ class EntityCollection extends RootCollection {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the read marker to the specified date for the logged in user
|
||||
*
|
||||
* @param \DateTime $value
|
||||
* @return bool
|
||||
*/
|
||||
public function setReadMarker($value) {
|
||||
$dateTime = new \DateTime($value);
|
||||
$user = $this->userSession->getUser();
|
||||
$this->commentsManager->setReadMark($this->name, $this->id, $dateTime, $user);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function propPatch(PropPatch $propPatch) {
|
||||
$propPatch->handle(self::PROPERTY_NAME_READ_MARKER, [$this, 'setReadMarker']);
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
function getProperties($properties) {
|
||||
$marker = null;
|
||||
$user = $this->userSession->getUser();
|
||||
if(!is_null($user)) {
|
||||
$marker = $this->commentsManager->getReadMark($this->name, $this->id, $user);
|
||||
}
|
||||
return [self::PROPERTY_NAME_READ_MARKER => $marker];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@ use OCP\Comments\ICommentsManager;
|
|||
use OCP\Files\Folder;
|
||||
use OCP\ILogger;
|
||||
use OCP\IUserManager;
|
||||
use OCP\IUserSession;
|
||||
use Sabre\DAV\Exception\MethodNotAllowed;
|
||||
use Sabre\DAV\Exception\NotFound;
|
||||
|
||||
|
@ -51,6 +52,7 @@ class EntityTypeCollection extends RootCollection {
|
|||
* @param ICommentsManager $commentsManager
|
||||
* @param Folder $fileRoot
|
||||
* @param IUserManager $userManager
|
||||
* @param IUserSession $userSession
|
||||
* @param ILogger $logger
|
||||
*/
|
||||
public function __construct(
|
||||
|
@ -58,6 +60,7 @@ class EntityTypeCollection extends RootCollection {
|
|||
ICommentsManager $commentsManager,
|
||||
Folder $fileRoot,
|
||||
IUserManager $userManager,
|
||||
IUserSession $userSession,
|
||||
ILogger $logger
|
||||
) {
|
||||
$name = trim($name);
|
||||
|
@ -69,6 +72,7 @@ class EntityTypeCollection extends RootCollection {
|
|||
$this->fileRoot = $fileRoot;
|
||||
$this->logger = $logger;
|
||||
$this->userManager = $userManager;
|
||||
$this->userSession = $userSession;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -91,6 +95,7 @@ class EntityTypeCollection extends RootCollection {
|
|||
$this->commentsManager,
|
||||
$this->fileRoot,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ class RootCollection implements ICollection {
|
|||
$this->commentsManager,
|
||||
$userFolder,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ class CommentsNode extends \Test\TestCase {
|
|||
protected $node;
|
||||
protected $userManager;
|
||||
protected $logger;
|
||||
protected $userSession;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -37,9 +38,16 @@ class CommentsNode extends \Test\TestCase {
|
|||
$this->commentsManager = $this->getMock('\OCP\Comments\ICommentsManager');
|
||||
$this->comment = $this->getMock('\OCP\Comments\IComment');
|
||||
$this->userManager = $this->getMock('\OCP\IUserManager');
|
||||
$this->userSession = $this->getMock('\OCP\IUserSession');
|
||||
$this->logger = $this->getMock('\OCP\ILogger');
|
||||
|
||||
$this->node = new CommentNode($this->commentsManager, $this->comment, $this->userManager, $this->logger);
|
||||
$this->node = new CommentNode(
|
||||
$this->commentsManager,
|
||||
$this->comment,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
public function testDelete() {
|
||||
|
@ -133,6 +141,7 @@ class CommentsNode extends \Test\TestCase {
|
|||
$ns . 'latestChildDateTime' => new \DateTime('2016-01-12 18:48:00'),
|
||||
$ns . 'objectType' => 'files',
|
||||
$ns . 'objectId' => '1848',
|
||||
$ns . 'isUnread' => null,
|
||||
];
|
||||
|
||||
$this->comment->expects($this->once())
|
||||
|
@ -198,10 +207,45 @@ class CommentsNode extends \Test\TestCase {
|
|||
$properties = $this->node->getProperties(null);
|
||||
|
||||
foreach($properties as $name => $value) {
|
||||
$this->assertTrue(isset($expected[$name]));
|
||||
$this->assertTrue(array_key_exists($name, $expected));
|
||||
$this->assertSame($expected[$name], $value);
|
||||
unset($expected[$name]);
|
||||
}
|
||||
$this->assertTrue(empty($expected));
|
||||
}
|
||||
|
||||
public function readCommentProvider() {
|
||||
$creationDT = new \DateTime('2016-01-19 18:48:00');
|
||||
$diff = new \DateInterval('PT2H');
|
||||
$readDT1 = clone $creationDT; $readDT1->sub($diff);
|
||||
$readDT2 = clone $creationDT; $readDT2->add($diff);
|
||||
return [
|
||||
[$creationDT, $readDT1, 'true'],
|
||||
[$creationDT, $readDT2, 'false'],
|
||||
[$creationDT, null, 'true'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider readCommentProvider
|
||||
* @param $expected
|
||||
*/
|
||||
public function testGetPropertiesUnreadProperty($creationDT, $readDT, $expected) {
|
||||
$this->comment->expects($this->any())
|
||||
->method('getCreationDateTime')
|
||||
->will($this->returnValue($creationDT));
|
||||
|
||||
$this->commentsManager->expects($this->once())
|
||||
->method('getReadMark')
|
||||
->will($this->returnValue($readDT));
|
||||
|
||||
$this->userSession->expects($this->once())
|
||||
->method('getUser')
|
||||
->will($this->returnValue($this->getMock('\OCP\IUser')));
|
||||
|
||||
$properties = $this->node->getProperties(null);
|
||||
|
||||
$this->assertTrue(array_key_exists(CommentNode::PROPERTY_NAME_UNREAD, $properties));
|
||||
$this->assertSame($properties[CommentNode::PROPERTY_NAME_UNREAD], $expected);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ class EntityCollection extends \Test\TestCase {
|
|||
protected $userManager;
|
||||
protected $logger;
|
||||
protected $collection;
|
||||
protected $userSession;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -35,6 +36,7 @@ class EntityCollection extends \Test\TestCase {
|
|||
$this->commentsManager = $this->getMock('\OCP\Comments\ICommentsManager');
|
||||
$this->folder = $this->getMock('\OCP\Files\Folder');
|
||||
$this->userManager = $this->getMock('\OCP\IUserManager');
|
||||
$this->userSession = $this->getMock('\OCP\IUserSession');
|
||||
$this->logger = $this->getMock('\OCP\ILogger');
|
||||
|
||||
$this->collection = new \OCA\DAV\Comments\EntityCollection(
|
||||
|
@ -43,6 +45,7 @@ class EntityCollection extends \Test\TestCase {
|
|||
$this->commentsManager,
|
||||
$this->folder,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ class EntityTypeCollection extends \Test\TestCase {
|
|||
protected $userManager;
|
||||
protected $logger;
|
||||
protected $collection;
|
||||
protected $userSession;
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
|
@ -37,6 +38,7 @@ class EntityTypeCollection extends \Test\TestCase {
|
|||
$this->commentsManager = $this->getMock('\OCP\Comments\ICommentsManager');
|
||||
$this->folder = $this->getMock('\OCP\Files\Folder');
|
||||
$this->userManager = $this->getMock('\OCP\IUserManager');
|
||||
$this->userSession = $this->getMock('\OCP\IUserSession');
|
||||
$this->logger = $this->getMock('\OCP\ILogger');
|
||||
|
||||
$this->collection = new \OCA\DAV\Comments\EntityTypeCollection(
|
||||
|
@ -44,6 +46,7 @@ class EntityTypeCollection extends \Test\TestCase {
|
|||
$this->commentsManager,
|
||||
$this->folder,
|
||||
$this->userManager,
|
||||
$this->userSession,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
|
|
@ -629,9 +629,15 @@ class Manager implements ICommentsManager {
|
|||
$affectedRows = $qb
|
||||
->update('comments_read_markers')
|
||||
->set('user_id', $values['user_id'])
|
||||
->set('marker_datetime', $values['marker_datetime'], 'datetime')
|
||||
->set('marker_datetime', $values['marker_datetime'])
|
||||
->set('object_type', $values['object_type'])
|
||||
->set('object_id', $values['object_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_id', $qb->createParameter('object_id')))
|
||||
->setParameter('user_id', $user->getUID(), \PDO::PARAM_STR)
|
||||
->setParameter('object_type', $objectType, \PDO::PARAM_STR)
|
||||
->setParameter('object_id', $objectId, \PDO::PARAM_STR)
|
||||
->execute();
|
||||
|
||||
if ($affectedRows > 0) {
|
||||
|
|
Loading…
Reference in New Issue