diff --git a/apps/comments/appinfo/app.php b/apps/comments/appinfo/app.php index cd1ccb2d7d..b060a5db1c 100644 --- a/apps/comments/appinfo/app.php +++ b/apps/comments/appinfo/app.php @@ -51,3 +51,10 @@ $managerListener = function(\OCP\Comments\CommentsEvent $event) use ($activityMa }; $eventDispatcher->addListener(\OCP\Comments\CommentsEvent::EVENT_ADD, $managerListener); + +$eventDispatcher->addListener(\OCP\Comments\CommentsEntityEvent::EVENT_ENTITY, function(\OCP\Comments\CommentsEntityEvent $event) { + $event->addEntityCollection('files', function($name) { + $nodes = \OC::$server->getUserFolder()->getById(intval($name)); + return !empty($nodes); + }); +}); diff --git a/apps/dav/lib/Comments/EntityCollection.php b/apps/dav/lib/Comments/EntityCollection.php index a55a18c00c..8fa13da616 100644 --- a/apps/dav/lib/Comments/EntityCollection.php +++ b/apps/dav/lib/Comments/EntityCollection.php @@ -22,11 +22,12 @@ namespace OCA\DAV\Comments; use OCP\Comments\ICommentsManager; -use OCP\Files\Folder; +use OCP\Comments\NotFoundException; use OCP\ILogger; use OCP\IUserManager; use OCP\IUserSession; use Sabre\DAV\Exception\NotFound; +use Sabre\DAV\IProperties; use Sabre\DAV\PropPatch; /** @@ -37,12 +38,9 @@ use Sabre\DAV\PropPatch; * * @package OCA\DAV\Comments */ -class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties { +class EntityCollection extends RootCollection implements IProperties { const PROPERTY_NAME_READ_MARKER = '{http://owncloud.org/ns}readMarker'; - /** @var Folder */ - protected $fileRoot; - /** @var string */ protected $id; @@ -53,7 +51,6 @@ class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties * @param string $id * @param string $name * @param ICommentsManager $commentsManager - * @param Folder $fileRoot * @param IUserManager $userManager * @param IUserSession $userSession * @param ILogger $logger @@ -62,7 +59,6 @@ class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties $id, $name, ICommentsManager $commentsManager, - Folder $fileRoot, IUserManager $userManager, IUserSession $userSession, ILogger $logger @@ -76,7 +72,6 @@ class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties $this->id = $id; $this->name = $name; $this->commentsManager = $commentsManager; - $this->fileRoot = $fileRoot; $this->logger = $logger; $this->userManager = $userManager; $this->userSession = $userSession; @@ -111,7 +106,7 @@ class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties $this->userSession, $this->logger ); - } catch (\OCP\Comments\NotFoundException $e) { + } catch (NotFoundException $e) { throw new NotFound(); } } @@ -159,7 +154,7 @@ class EntityCollection extends RootCollection implements \Sabre\DAV\IProperties try { $this->commentsManager->get($name); return true; - } catch (\OCP\Comments\NotFoundException $e) { + } catch (NotFoundException $e) { return false; } } diff --git a/apps/dav/lib/Comments/EntityTypeCollection.php b/apps/dav/lib/Comments/EntityTypeCollection.php index 6bc4248420..66fdb7f8de 100644 --- a/apps/dav/lib/Comments/EntityTypeCollection.php +++ b/apps/dav/lib/Comments/EntityTypeCollection.php @@ -22,7 +22,6 @@ namespace OCA\DAV\Comments; use OCP\Comments\ICommentsManager; -use OCP\Files\Folder; use OCP\ILogger; use OCP\IUserManager; use OCP\IUserSession; @@ -41,27 +40,31 @@ use Sabre\DAV\Exception\NotFound; * @package OCA\DAV\Comments */ class EntityTypeCollection extends RootCollection { - /** @var Folder */ - protected $fileRoot; /** @var ILogger */ protected $logger; + /** @var IUserManager */ + protected $userManager; + + /** @var \Closure */ + protected $childExistsFunction; + /** * @param string $name * @param ICommentsManager $commentsManager - * @param Folder $fileRoot * @param IUserManager $userManager * @param IUserSession $userSession * @param ILogger $logger + * @param \Closure $childExistsFunction */ public function __construct( $name, ICommentsManager $commentsManager, - Folder $fileRoot, IUserManager $userManager, IUserSession $userSession, - ILogger $logger + ILogger $logger, + \Closure $childExistsFunction ) { $name = trim($name); if(empty($name) || !is_string($name)) { @@ -69,10 +72,10 @@ class EntityTypeCollection extends RootCollection { } $this->name = $name; $this->commentsManager = $commentsManager; - $this->fileRoot = $fileRoot; $this->logger = $logger; $this->userManager = $userManager; $this->userSession = $userSession; + $this->childExistsFunction = $childExistsFunction; } /** @@ -93,7 +96,6 @@ class EntityTypeCollection extends RootCollection { $name, $this->name, $this->commentsManager, - $this->fileRoot, $this->userManager, $this->userSession, $this->logger @@ -117,9 +119,7 @@ class EntityTypeCollection extends RootCollection { * @return bool */ function childExists($name) { - $nodes = $this->fileRoot->getById(intval($name)); - return !empty($nodes); + return call_user_func($this->childExistsFunction, $name); } - } diff --git a/apps/dav/lib/Comments/RootCollection.php b/apps/dav/lib/Comments/RootCollection.php index cda666f716..b02532b067 100644 --- a/apps/dav/lib/Comments/RootCollection.php +++ b/apps/dav/lib/Comments/RootCollection.php @@ -21,8 +21,8 @@ namespace OCA\DAV\Comments; +use OCP\Comments\CommentsEntityEvent; use OCP\Comments\ICommentsManager; -use OCP\Files\IRootFolder; use OCP\ILogger; use OCP\IUserManager; use OCP\IUserSession; @@ -30,11 +30,12 @@ use Sabre\DAV\Exception\NotAuthenticated; use Sabre\DAV\Exception\Forbidden; use Sabre\DAV\Exception\NotFound; use Sabre\DAV\ICollection; +use Symfony\Component\EventDispatcher\EventDispatcherInterface; class RootCollection implements ICollection { - /** @var EntityTypeCollection[] */ - private $entityTypeCollections = []; + /** @var EntityTypeCollection[]|null */ + private $entityTypeCollections; /** @var ICommentsManager */ protected $commentsManager; @@ -47,34 +48,32 @@ class RootCollection implements ICollection { /** @var IUserManager */ protected $userManager; - /** - * @var IUserSession - */ + + /** @var IUserSession */ protected $userSession; - /** - * @var IRootFolder - */ - protected $rootFolder; + + /** @var EventDispatcherInterface */ + protected $dispatcher; /** * @param ICommentsManager $commentsManager * @param IUserManager $userManager * @param IUserSession $userSession - * @param IRootFolder $rootFolder + * @param EventDispatcherInterface $dispatcher * @param ILogger $logger */ public function __construct( ICommentsManager $commentsManager, IUserManager $userManager, IUserSession $userSession, - IRootFolder $rootFolder, + EventDispatcherInterface $dispatcher, ILogger $logger) { $this->commentsManager = $commentsManager; $this->logger = $logger; $this->userManager = $userManager; $this->userSession = $userSession; - $this->rootFolder = $rootFolder; + $this->dispatcher = $dispatcher; } /** @@ -85,22 +84,28 @@ class RootCollection implements ICollection { * @throws NotAuthenticated */ protected function initCollections() { - if(!empty($this->entityTypeCollections)) { + if($this->entityTypeCollections !== null) { return; } $user = $this->userSession->getUser(); if(is_null($user)) { throw new NotAuthenticated(); } - $userFolder = $this->rootFolder->getUserFolder($user->getUID()); - $this->entityTypeCollections['files'] = new EntityTypeCollection( - 'files', - $this->commentsManager, - $userFolder, - $this->userManager, - $this->userSession, - $this->logger - ); + + $event = new CommentsEntityEvent(CommentsEntityEvent::EVENT_ENTITY); + $this->dispatcher->dispatch(CommentsEntityEvent::EVENT_ENTITY, $event); + + $this->entityTypeCollections = []; + foreach ($event->getEntityCollections() as $entity => $entityExistsFunction) { + $this->entityTypeCollections[$entity] = new EntityTypeCollection( + $entity, + $this->commentsManager, + $this->userManager, + $this->userSession, + $this->logger, + $entityExistsFunction + ); + } } /** diff --git a/apps/dav/lib/RootCollection.php b/apps/dav/lib/RootCollection.php index b6e1747e99..f18bfaf496 100644 --- a/apps/dav/lib/RootCollection.php +++ b/apps/dav/lib/RootCollection.php @@ -77,7 +77,7 @@ class RootCollection extends SimpleCollection { \OC::$server->getCommentsManager(), \OC::$server->getUserManager(), \OC::$server->getUserSession(), - \OC::$server->getRootFolder(), + \OC::$server->getEventDispatcher(), \OC::$server->getLogger() ); diff --git a/apps/dav/tests/unit/comments/entitycollection.php b/apps/dav/tests/unit/comments/entitycollection.php index 5bf155f12b..bc009e9254 100644 --- a/apps/dav/tests/unit/comments/entitycollection.php +++ b/apps/dav/tests/unit/comments/entitycollection.php @@ -23,18 +23,21 @@ namespace OCA\DAV\Tests\Unit\Comments; class EntityCollection extends \Test\TestCase { + /** @var \OCP\Comments\ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ protected $commentsManager; - protected $folder; + /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ protected $userManager; + /** @var \OCP\ILogger|\PHPUnit_Framework_MockObject_MockObject */ protected $logger; + /** @var \OCA\DAV\Comments\EntityCollection */ protected $collection; + /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ protected $userSession; public function setUp() { parent::setUp(); $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'); @@ -43,7 +46,6 @@ class EntityCollection extends \Test\TestCase { '19', 'files', $this->commentsManager, - $this->folder, $this->userManager, $this->userSession, $this->logger diff --git a/apps/dav/tests/unit/comments/entitytypecollection.php b/apps/dav/tests/unit/comments/entitytypecollection.php index f3aa2dbd71..96b1cad837 100644 --- a/apps/dav/tests/unit/comments/entitytypecollection.php +++ b/apps/dav/tests/unit/comments/entitytypecollection.php @@ -25,52 +25,52 @@ use OCA\DAV\Comments\EntityCollection as EntityCollectionImplemantation; class EntityTypeCollection extends \Test\TestCase { + /** @var \OCP\Comments\ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ protected $commentsManager; - protected $folder; + /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ protected $userManager; + /** @var \OCP\ILogger|\PHPUnit_Framework_MockObject_MockObject */ protected $logger; + /** @var \OCA\DAV\Comments\EntityTypeCollection */ protected $collection; + /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ protected $userSession; + protected $childMap = []; + public function setUp() { parent::setUp(); $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'); + $instance = $this; + $this->collection = new \OCA\DAV\Comments\EntityTypeCollection( 'files', $this->commentsManager, - $this->folder, $this->userManager, $this->userSession, - $this->logger + $this->logger, + function ($child) use ($instance) { + return !empty($instance->childMap[$child]); + } ); } public function testChildExistsYes() { - $this->folder->expects($this->once()) - ->method('getById') - ->with('17') - ->will($this->returnValue([$this->getMock('\OCP\Files\Node')])); + $this->childMap[17] = true; $this->assertTrue($this->collection->childExists('17')); } public function testChildExistsNo() { - $this->folder->expects($this->once()) - ->method('getById') - ->will($this->returnValue([])); $this->assertFalse($this->collection->childExists('17')); } public function testGetChild() { - $this->folder->expects($this->once()) - ->method('getById') - ->with('17') - ->will($this->returnValue([$this->getMock('\OCP\Files\Node')])); + $this->childMap[17] = true; $ec = $this->collection->getChild('17'); $this->assertTrue($ec instanceof EntityCollectionImplemantation); @@ -80,11 +80,6 @@ class EntityTypeCollection extends \Test\TestCase { * @expectedException \Sabre\DAV\Exception\NotFound */ public function testGetChildException() { - $this->folder->expects($this->once()) - ->method('getById') - ->with('17') - ->will($this->returnValue([])); - $this->collection->getChild('17'); } diff --git a/apps/dav/tests/unit/comments/rootcollection.php b/apps/dav/tests/unit/comments/rootcollection.php index 369006e715..a59482fba7 100644 --- a/apps/dav/tests/unit/comments/rootcollection.php +++ b/apps/dav/tests/unit/comments/rootcollection.php @@ -22,15 +22,24 @@ namespace OCA\DAV\Tests\Unit\Comments; use OCA\DAV\Comments\EntityTypeCollection as EntityTypeCollectionImplementation; +use OCP\Comments\CommentsEntityEvent; +use Symfony\Component\EventDispatcher\EventDispatcher; class RootCollection extends \Test\TestCase { + /** @var \OCP\Comments\ICommentsManager|\PHPUnit_Framework_MockObject_MockObject */ protected $commentsManager; + /** @var \OCP\IUserManager|\PHPUnit_Framework_MockObject_MockObject */ protected $userManager; + /** @var \OCP\ILogger|\PHPUnit_Framework_MockObject_MockObject */ protected $logger; + /** @var \OCA\DAV\Comments\RootCollection */ protected $collection; + /** @var \OCP\IUserSession|\PHPUnit_Framework_MockObject_MockObject */ protected $userSession; - protected $rootFolder; + /** @var \Symfony\Component\EventDispatcher\EventDispatcherInterface */ + protected $dispatcher; + /** @var \OCP\IUser|\PHPUnit_Framework_MockObject_MockObject */ protected $user; public function setUp() { @@ -41,14 +50,14 @@ class RootCollection extends \Test\TestCase { $this->commentsManager = $this->getMock('\OCP\Comments\ICommentsManager'); $this->userManager = $this->getMock('\OCP\IUserManager'); $this->userSession = $this->getMock('\OCP\IUserSession'); - $this->rootFolder = $this->getMock('\OCP\Files\IRootFolder'); + $this->dispatcher = new EventDispatcher(); $this->logger = $this->getMock('\OCP\ILogger'); $this->collection = new \OCA\DAV\Comments\RootCollection( $this->commentsManager, $this->userManager, $this->userSession, - $this->rootFolder, + $this->dispatcher, $this->logger ); } @@ -62,10 +71,11 @@ class RootCollection extends \Test\TestCase { ->method('getUser') ->will($this->returnValue($this->user)); - $this->rootFolder->expects($this->once()) - ->method('getUserFolder') - ->with('alice') - ->will($this->returnValue($this->getMock('\OCP\Files\Folder'))); + $this->dispatcher->addListener(CommentsEntityEvent::EVENT_ENTITY, function(CommentsEntityEvent $event) { + $event->addEntityCollection('files', function() { + return true; + }); + }); } /** diff --git a/lib/public/Comments/CommentsEntityEvent.php b/lib/public/Comments/CommentsEntityEvent.php new file mode 100644 index 0000000000..5f012a7988 --- /dev/null +++ b/lib/public/Comments/CommentsEntityEvent.php @@ -0,0 +1,76 @@ + + * + * @copyright Copyright (c) 2016, ownCloud, Inc. + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ + +namespace OCP\Comments; + +use Symfony\Component\EventDispatcher\Event; + +/** + * Class CommentsEntityEvent + * + * @package OCP\Comments + * @since 9.1.0 + */ +class CommentsEntityEvent extends Event { + + const EVENT_ENTITY = 'OCP\Comments\ICommentsManager::registerEntity'; + + /** @var string */ + protected $event; + /** @var \Closure[] */ + protected $collections; + + /** + * DispatcherEvent constructor. + * + * @param string $event + * @since 9.1.0 + */ + public function __construct($event) { + $this->event = $event; + $this->collections = []; + } + + /** + * @param string $name + * @param \Closure $entityExistsFunction The closure should take one + * argument, which is the id of the entity, that comments + * should be handled for. The return should then be bool, + * depending on whether comments are allowed (true) or not. + * @throws \OutOfBoundsException when the entity name is already taken + * @since 9.1.0 + */ + public function addEntityCollection($name, \Closure $entityExistsFunction) { + if (isset($this->collections[$name])) { + throw new \OutOfBoundsException('Duplicate entity name "' . $name . '"'); + } + + $this->collections[$name] = $entityExistsFunction; + } + + /** + * @return \Closure[] + * @since 9.1.0 + */ + public function getEntityCollections() { + return $this->collections; + } +}