From 322480a3b749d88342444fdd752a16322673b5a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Thu, 1 Apr 2021 11:43:35 +0200 Subject: [PATCH 1/2] Move full text search to proper events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- lib/AppInfo/Application.php | 190 ++++++++++++- lib/AppInfo/Application20.php | 252 ------------------ lib/AppInfo/ApplicationLegacy.php | 249 ----------------- lib/Event/{FTSEvent.php => AAclEvent.php} | 33 +-- lib/Event/ACardEvent.php | 44 +++ lib/Event/AclCreatedEvent.php | 9 + lib/Event/AclDeletedEvent.php | 30 +++ lib/Event/AclUpdatedEvent.php | 30 +++ lib/Event/CardCreatedEvent.php | 30 +++ lib/Event/CardDeletedEvent.php | 30 +++ lib/Event/CardUpdatedEvent.php | 30 +++ lib/Listeners/FullTextSearchEventListener.php | 104 ++++++++ lib/Service/AssignmentService.php | 10 +- lib/Service/BoardService.php | 54 +--- lib/Service/CardService.php | 43 +-- lib/Service/FullTextSearchService.php | 97 +------ lib/Service/StackService.php | 17 -- tests/unit/Service/BoardServiceTest.php | 7 +- tests/unit/Service/StackServiceTest.php | 6 - 19 files changed, 540 insertions(+), 725 deletions(-) delete mode 100644 lib/AppInfo/Application20.php delete mode 100644 lib/AppInfo/ApplicationLegacy.php rename lib/Event/{FTSEvent.php => AAclEvent.php} (61%) create mode 100644 lib/Event/ACardEvent.php create mode 100644 lib/Event/AclCreatedEvent.php create mode 100644 lib/Event/AclDeletedEvent.php create mode 100644 lib/Event/AclUpdatedEvent.php create mode 100644 lib/Event/CardCreatedEvent.php create mode 100644 lib/Event/CardDeletedEvent.php create mode 100644 lib/Event/CardUpdatedEvent.php create mode 100644 lib/Listeners/FullTextSearchEventListener.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 3393e6f98..1cef397ff 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -23,11 +23,191 @@ namespace OCA\Deck\AppInfo; -$version = \OCP\Util::getVersion()[0]; -if ($version >= 20) { - class Application extends Application20 { +use Closure; +use Exception; +use OC\EventDispatcher\SymfonyAdapter; +use OCA\Deck\Activity\CommentEventHandler; +use OCA\Deck\Capabilities; +use OCA\Deck\Collaboration\Resources\ResourceProvider; +use OCA\Deck\Collaboration\Resources\ResourceProviderCard; +use OCA\Deck\Dashboard\DeckWidget; +use OCA\Deck\Db\Acl; +use OCA\Deck\Db\AclMapper; +use OCA\Deck\Db\AssignmentMapper; +use OCA\Deck\Db\BoardMapper; +use OCA\Deck\Db\CardMapper; +use OCA\Deck\Event\AclCreatedEvent; +use OCA\Deck\Event\AclDeletedEvent; +use OCA\Deck\Event\AclUpdatedEvent; +use OCA\Deck\Event\CardCreatedEvent; +use OCA\Deck\Event\CardDeletedEvent; +use OCA\Deck\Event\CardUpdatedEvent; +use OCA\Deck\Listeners\BeforeTemplateRenderedListener; +use OCA\Deck\Listeners\FullTextSearchEventListener; +use OCA\Deck\Middleware\DefaultBoardMiddleware; +use OCA\Deck\Middleware\ExceptionMiddleware; +use OCA\Deck\Notification\Notifier; +use OCA\Deck\Search\DeckProvider; +use OCA\Deck\Service\PermissionService; +use OCA\Deck\Sharing\DeckShareProvider; +use OCA\Deck\Sharing\Listener; +use OCP\AppFramework\App; +use OCP\AppFramework\Bootstrap\IBootContext; +use OCP\AppFramework\Bootstrap\IBootstrap; +use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\Collaboration\Resources\IProviderManager; +use OCP\Comments\CommentsEntityEvent; +use OCP\Comments\ICommentsManager; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventDispatcher; +use OCP\IConfig; +use OCP\IDBConnection; +use OCP\IGroup; +use OCP\IGroupManager; +use OCP\IServerContainer; +use OCP\IUser; +use OCP\IUserManager; +use OCP\Notification\IManager as NotificationManager; +use OCP\Share\IManager; +use OCP\Util; +use Psr\Container\ContainerInterface; + +class Application extends App implements IBootstrap { + public const APP_ID = 'deck'; + + public const COMMENT_ENTITY_TYPE = 'deckCard'; + + /** @var IServerContainer */ + private $server; + + public function __construct(array $urlParams = []) { + parent::__construct(self::APP_ID, $urlParams); + + $this->server = \OC::$server; } -} else { - class Application extends ApplicationLegacy { + + public function boot(IBootContext $context): void { + $context->injectFn(Closure::fromCallable([$this, 'registerUserGroupHooks'])); + $context->injectFn(Closure::fromCallable([$this, 'registerCommentsEntity'])); + $context->injectFn(Closure::fromCallable([$this, 'registerCommentsEventHandler'])); + $context->injectFn(Closure::fromCallable([$this, 'registerNotifications'])); + $context->injectFn(Closure::fromCallable([$this, 'registerCollaborationResources'])); + + $context->injectFn(function (IManager $shareManager) { + if (method_exists($shareManager, 'registerShareProvider')) { + $shareManager->registerShareProvider(DeckShareProvider::class); + } + }); + + $context->injectFn(function (Listener $listener, IEventDispatcher $eventDispatcher) { + $listener->register($eventDispatcher); + }); + } + + public function register(IRegistrationContext $context): void { + if ((@include_once __DIR__ . '/../../vendor/autoload.php') === false) { + throw new Exception('Cannot include autoload. Did you run install dependencies using composer?'); + } + + $context->registerCapability(Capabilities::class); + $context->registerMiddleWare(ExceptionMiddleware::class); + $context->registerMiddleWare(DefaultBoardMiddleware::class); + + $context->registerService('databaseType', static function (ContainerInterface $c) { + return $c->get(IConfig::class)->getSystemValue('dbtype', 'sqlite'); + }); + $context->registerService('database4ByteSupport', static function (ContainerInterface $c) { + return $c->get(IDBConnection::class)->supports4ByteText(); + }); + + $context->registerSearchProvider(DeckProvider::class); + $context->registerDashboardWidget(DeckWidget::class); + + $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); + + // Event listening for full text search indexing + $context->registerEventListener(CardCreatedEvent::class, FullTextSearchEventListener::class); + $context->registerEventListener(CardUpdatedEvent::class, FullTextSearchEventListener::class); + $context->registerEventListener(CardDeletedEvent::class, FullTextSearchEventListener::class); + $context->registerEventListener(AclCreatedEvent::class, FullTextSearchEventListener::class); + $context->registerEventListener(AclUpdatedEvent::class, FullTextSearchEventListener::class); + $context->registerEventListener(AclDeletedEvent::class, FullTextSearchEventListener::class); + } + + public function registerNotifications(NotificationManager $notificationManager): void { + $notificationManager->registerNotifierService(Notifier::class); + } + + private function registerUserGroupHooks(IUserManager $userManager, IGroupManager $groupManager): void { + $container = $this->getContainer(); + // Delete user/group acl entries when they get deleted + $userManager->listen('\OC\User', 'postDelete', static function (IUser $user) use ($container) { + // delete existing acl entries for deleted user + /** @var AclMapper $aclMapper */ + $aclMapper = $container->query(AclMapper::class); + $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_USER, $user->getUID()); + foreach ($acls as $acl) { + $aclMapper->delete($acl); + } + // delete existing user assignments + $assignmentMapper = $container->query(AssignmentMapper::class); + $assignments = $assignmentMapper->findByParticipant($user->getUID()); + foreach ($assignments as $assignment) { + $assignmentMapper->delete($assignment); + } + + /** @var BoardMapper $boardMapper */ + $boardMapper = $container->query(BoardMapper::class); + $boards = $boardMapper->findAllByOwner($user->getUID()); + foreach ($boards as $board) { + $boardMapper->delete($board); + } + }); + + $groupManager->listen('\OC\Group', 'postDelete', static function (IGroup $group) use ($container) { + /** @var AclMapper $aclMapper */ + $aclMapper = $container->query(AclMapper::class); + $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); + $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); + foreach ($acls as $acl) { + $aclMapper->delete($acl); + } + }); + } + + public function registerCommentsEntity(IEventDispatcher $eventDispatcher): void { + $eventDispatcher->addListener(CommentsEntityEvent::EVENT_ENTITY, function (CommentsEntityEvent $event) { + $event->addEntityCollection(self::COMMENT_ENTITY_TYPE, function ($name) { + /** @var CardMapper */ + $cardMapper = $this->getContainer()->get(CardMapper::class); + $permissionService = $this->getContainer()->get(PermissionService::class); + + try { + return $permissionService->checkPermission($cardMapper, (int) $name, Acl::PERMISSION_READ); + } catch (\Exception $e) { + return false; + } + }); + }); + } + + protected function registerCommentsEventHandler(ICommentsManager $commentsManager): void { + $commentsManager->registerEventHandler(function () { + return $this->getContainer()->query(CommentEventHandler::class); + }); + } + + protected function registerCollaborationResources(IProviderManager $resourceManager, SymfonyAdapter $symfonyAdapter): void { + $resourceManager->registerResourceProvider(ResourceProvider::class); + $resourceManager->registerResourceProvider(ResourceProviderCard::class); + + $symfonyAdapter->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', static function () { + if (strpos(\OC::$server->getRequest()->getPathInfo(), '/call/') === 0) { + // Talk integration has its own entrypoint which already includes collections handling + return; + } + Util::addScript('deck', 'collections'); + }); } } diff --git a/lib/AppInfo/Application20.php b/lib/AppInfo/Application20.php deleted file mode 100644 index 9dd4f0eb0..000000000 --- a/lib/AppInfo/Application20.php +++ /dev/null @@ -1,252 +0,0 @@ - - * - * @author Julius Härtl - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see . - * - */ - -namespace OCA\Deck\AppInfo; - -use Closure; -use Exception; -use OC\EventDispatcher\SymfonyAdapter; -use OCA\Deck\Activity\CommentEventHandler; -use OCA\Deck\Capabilities; -use OCA\Deck\Collaboration\Resources\ResourceProvider; -use OCA\Deck\Collaboration\Resources\ResourceProviderCard; -use OCA\Deck\Dashboard\DeckWidget; -use OCA\Deck\Db\Acl; -use OCA\Deck\Db\AclMapper; -use OCA\Deck\Db\AssignmentMapper; -use OCA\Deck\Db\BoardMapper; -use OCA\Deck\Db\CardMapper; -use OCA\Deck\Listeners\BeforeTemplateRenderedListener; -use OCA\Deck\Middleware\DefaultBoardMiddleware; -use OCA\Deck\Middleware\ExceptionMiddleware; -use OCA\Deck\Notification\Notifier; -use OCA\Deck\Search\DeckProvider; -use OCA\Deck\Service\FullTextSearchService; -use OCA\Deck\Service\PermissionService; -use OCA\Deck\Sharing\DeckShareProvider; -use OCA\Deck\Sharing\Listener; -use OCP\AppFramework\App; -use OCP\AppFramework\Bootstrap\IBootContext; -use OCP\AppFramework\Bootstrap\IBootstrap; -use OCP\AppFramework\Bootstrap\IRegistrationContext; -use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; -use OCP\Collaboration\Resources\IProviderManager; -use OCP\Comments\CommentsEntityEvent; -use OCP\Comments\ICommentsManager; -use OCP\EventDispatcher\Event; -use OCP\EventDispatcher\IEventDispatcher; -use OCP\FullTextSearch\IFullTextSearchManager; -use OCP\IConfig; -use OCP\IDBConnection; -use OCP\IGroup; -use OCP\IGroupManager; -use OCP\IServerContainer; -use OCP\IUser; -use OCP\IUserManager; -use OCP\Notification\IManager as NotificationManager; -use OCP\Share\IManager; -use OCP\Util; -use Psr\Container\ContainerInterface; - -class Application20 extends App implements IBootstrap { - public const APP_ID = 'deck'; - - public const COMMENT_ENTITY_TYPE = 'deckCard'; - - /** @var IServerContainer */ - private $server; - - /** @var FullTextSearchService */ - private $fullTextSearchService; - - /** @var IFullTextSearchManager */ - private $fullTextSearchManager; - - public function __construct(array $urlParams = []) { - parent::__construct(self::APP_ID, $urlParams); - - $this->server = \OC::$server; - } - - public function boot(IBootContext $context): void { - $context->injectFn(Closure::fromCallable([$this, 'registerUserGroupHooks'])); - $context->injectFn(Closure::fromCallable([$this, 'registerCommentsEntity'])); - $context->injectFn(Closure::fromCallable([$this, 'registerCommentsEventHandler'])); - $context->injectFn(Closure::fromCallable([$this, 'registerNotifications'])); - $context->injectFn(Closure::fromCallable([$this, 'registerFullTextSearch'])); - $context->injectFn(Closure::fromCallable([$this, 'registerCollaborationResources'])); - - $context->injectFn(function (IManager $shareManager) { - if (method_exists($shareManager, 'registerShareProvider')) { - $shareManager->registerShareProvider(DeckShareProvider::class); - } - }); - - $context->injectFn(function (Listener $listener, IEventDispatcher $eventDispatcher) { - $listener->register($eventDispatcher); - }); - } - - public function register(IRegistrationContext $context): void { - if ((@include_once __DIR__ . '/../../vendor/autoload.php') === false) { - throw new Exception('Cannot include autoload. Did you run install dependencies using composer?'); - } - - $context->registerCapability(Capabilities::class); - $context->registerMiddleWare(ExceptionMiddleware::class); - $context->registerMiddleWare(DefaultBoardMiddleware::class); - - $context->registerService('databaseType', static function (ContainerInterface $c) { - return $c->get(IConfig::class)->getSystemValue('dbtype', 'sqlite'); - }); - $context->registerService('database4ByteSupport', static function (ContainerInterface $c) { - return $c->get(IDBConnection::class)->supports4ByteText(); - }); - - $context->registerSearchProvider(DeckProvider::class); - $context->registerDashboardWidget(DeckWidget::class); - - $context->registerEventListener(BeforeTemplateRenderedEvent::class, BeforeTemplateRenderedListener::class); - } - - public function registerNotifications(NotificationManager $notificationManager): void { - $notificationManager->registerNotifierService(Notifier::class); - } - - private function registerUserGroupHooks(IUserManager $userManager, IGroupManager $groupManager): void { - $container = $this->getContainer(); - // Delete user/group acl entries when they get deleted - $userManager->listen('\OC\User', 'postDelete', static function (IUser $user) use ($container) { - // delete existing acl entries for deleted user - /** @var AclMapper $aclMapper */ - $aclMapper = $container->query(AclMapper::class); - $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_USER, $user->getUID()); - foreach ($acls as $acl) { - $aclMapper->delete($acl); - } - // delete existing user assignments - $assignmentMapper = $container->query(AssignmentMapper::class); - $assignments = $assignmentMapper->findByParticipant($user->getUID()); - foreach ($assignments as $assignment) { - $assignmentMapper->delete($assignment); - } - - /** @var BoardMapper $boardMapper */ - $boardMapper = $container->query(BoardMapper::class); - $boards = $boardMapper->findAllByOwner($user->getUID()); - foreach ($boards as $board) { - $boardMapper->delete($board); - } - }); - - $groupManager->listen('\OC\Group', 'postDelete', static function (IGroup $group) use ($container) { - /** @var AclMapper $aclMapper */ - $aclMapper = $container->query(AclMapper::class); - $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); - $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); - foreach ($acls as $acl) { - $aclMapper->delete($acl); - } - }); - } - - public function registerCommentsEntity(IEventDispatcher $eventDispatcher): void { - $eventDispatcher->addListener(CommentsEntityEvent::EVENT_ENTITY, function (CommentsEntityEvent $event) { - $event->addEntityCollection(self::COMMENT_ENTITY_TYPE, function ($name) { - /** @var CardMapper */ - $cardMapper = $this->getContainer()->get(CardMapper::class); - $permissionService = $this->getContainer()->get(PermissionService::class); - - try { - return $permissionService->checkPermission($cardMapper, (int) $name, Acl::PERMISSION_READ); - } catch (\Exception $e) { - return false; - } - }); - }); - } - - protected function registerCommentsEventHandler(ICommentsManager $commentsManager): void { - $commentsManager->registerEventHandler(function () { - return $this->getContainer()->query(CommentEventHandler::class); - }); - } - - protected function registerCollaborationResources(IProviderManager $resourceManager, SymfonyAdapter $symfonyAdapter): void { - $resourceManager->registerResourceProvider(ResourceProvider::class); - $resourceManager->registerResourceProvider(ResourceProviderCard::class); - - $symfonyAdapter->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', static function () { - if (strpos(\OC::$server->getRequest()->getPathInfo(), '/call/') === 0) { - // Talk integration has its own entrypoint which already includes collections handling - return; - } - Util::addScript('deck', 'collections'); - }); - } - - public function registerFullTextSearch(IFullTextSearchManager $fullTextSearchManager, IEventDispatcher $eventDispatcher): void { - if (!$fullTextSearchManager->isAvailable()) { - return; - } - - // FIXME move to addServiceListener - $server = $this->server; - $eventDispatcher->addListener( - '\OCA\Deck\Card::onCreate', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onCardCreated($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Card::onUpdate', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onCardUpdated($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Card::onDelete', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onCardDeleted($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareNew', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onBoardShares($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareEdit', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onBoardShares($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareDelete', function (Event $e) use ($server) { - $fullTextSearchService = $server->get(FullTextSearchService::class); - $fullTextSearchService->onBoardShares($e); - } - ); - } -} diff --git a/lib/AppInfo/ApplicationLegacy.php b/lib/AppInfo/ApplicationLegacy.php deleted file mode 100644 index 9f85d6017..000000000 --- a/lib/AppInfo/ApplicationLegacy.php +++ /dev/null @@ -1,249 +0,0 @@ - - * - * @author Julius Härtl - * - * @license GNU AGPL version 3 or any later version - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * 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 - * along with this program. If not, see . - * - */ - -namespace OCA\Deck\AppInfo; - -use Exception; -use OCA\Deck\Activity\CommentEventHandler; -use OCA\Deck\Capabilities; -use OCA\Deck\Collaboration\Resources\ResourceProvider; -use OCA\Deck\Collaboration\Resources\ResourceProviderCard; -use OCA\Deck\Db\Acl; -use OCA\Deck\Db\AclMapper; -use OCA\Deck\Db\AssignmentMapper; -use OCA\Deck\Db\BoardMapper; -use OCA\Deck\Db\CardMapper; -use OCA\Deck\Middleware\DefaultBoardMiddleware; -use OCA\Deck\Middleware\ExceptionMiddleware; -use OCA\Deck\Notification\Notifier; -use OCA\Deck\Service\FullTextSearchService; -use OCA\Deck\Service\PermissionService; -use OCP\AppFramework\App; -use OCP\Collaboration\Resources\IManager; -use OCP\Collaboration\Resources\IProviderManager; -use OCP\Comments\CommentsEntityEvent; -use OCP\EventDispatcher\Event; -use OCP\EventDispatcher\IEventDispatcher; -use OCP\FullTextSearch\IFullTextSearchManager; -use OCP\IGroup; -use OCP\IServerContainer; -use OCP\IUser; -use OCP\IUserManager; -use OCP\Util; - -if ((@include_once __DIR__ . '/../../vendor/autoload.php') === false) { - throw new Exception('Cannot include autoload. Did you run install dependencies using composer?'); -} - -class ApplicationLegacy extends App { - public const APP_ID = 'deck'; - - public const COMMENT_ENTITY_TYPE = 'deckCard'; - - /** @var IServerContainer */ - private $server; - - /** @var FullTextSearchService */ - private $fullTextSearchService; - - /** @var IFullTextSearchManager */ - private $fullTextSearchManager; - - public function __construct(array $urlParams = []) { - parent::__construct('deck', $urlParams); - - $container = $this->getContainer(); - $server = $this->getContainer()->getServer(); - - $this->server = $server; - - $container->registerCapability(Capabilities::class); - $container->registerMiddleWare(ExceptionMiddleware::class); - $container->registerMiddleWare(DefaultBoardMiddleware::class); - - $container->registerService('databaseType', static function () use ($server) { - return $server->getConfig()->getSystemValue('dbtype', 'sqlite'); - }); - $container->registerService('database4ByteSupport', static function () use ($server) { - return $server->getDatabaseConnection()->supports4ByteText(); - }); - - $this->register(); - } - - public function register(): void { - $this->registerUserGroupHooks(); - $this->registerNotifications(); - $this->registerCommentsEntity(); - $this->registerFullTextSearch(); - $this->registerCollaborationResources(); - } - - private function registerUserGroupHooks(): void { - $container = $this->getContainer(); - // Delete user/group acl entries when they get deleted - /** @var IUserManager $userManager */ - $userManager = $this->server->getUserManager(); - $userManager->listen('\OC\User', 'postDelete', static function (IUser $user) use ($container) { - // delete existing acl entries for deleted user - /** @var AclMapper $aclMapper */ - $aclMapper = $container->query(AclMapper::class); - $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_USER, $user->getUID()); - foreach ($acls as $acl) { - $aclMapper->delete($acl); - } - // delete existing user assignments - $assignmentMapper = $container->query(AssignmentMapper::class); - $assignments = $assignmentMapper->findByParticipant($user->getUID()); - foreach ($assignments as $assignment) { - $assignmentMapper->delete($assignment); - } - - /** @var BoardMapper $boardMapper */ - $boardMapper = $container->query(BoardMapper::class); - $boards = $boardMapper->findAllByOwner($user->getUID()); - foreach ($boards as $board) { - $boardMapper->delete($board); - } - }); - - /** @var IUserManager $userManager */ - $groupManager = $this->server->getGroupManager(); - $groupManager->listen('\OC\Group', 'postDelete', static function (IGroup $group) use ($container) { - /** @var AclMapper $aclMapper */ - $aclMapper = $container->query(AclMapper::class); - $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); - $acls = $aclMapper->findByParticipant(Acl::PERMISSION_TYPE_GROUP, $group->getGID()); - foreach ($acls as $acl) { - $aclMapper->delete($acl); - } - }); - } - - public function registerNotifications(): void { - $notificationManager = $this->server->getNotificationManager(); - $notificationManager->registerNotifierService(Notifier::class); - } - - public function registerCommentsEntity(): void { - $this->server->getEventDispatcher()->addListener(CommentsEntityEvent::EVENT_ENTITY, function (CommentsEntityEvent $event) { - $event->addEntityCollection(self::COMMENT_ENTITY_TYPE, function ($name) { - /** @var CardMapper */ - $cardMapper = $this->getContainer()->query(CardMapper::class); - $permissionService = $this->getContainer()->query(PermissionService::class); - - try { - return $permissionService->checkPermission($cardMapper, (int) $name, Acl::PERMISSION_READ); - } catch (\Exception $e) { - return false; - } - }); - }); - $this->registerCommentsEventHandler(); - } - - /** - */ - protected function registerCommentsEventHandler(): void { - $this->server->getCommentsManager()->registerEventHandler(function () { - return $this->getContainer()->query(CommentEventHandler::class); - }); - } - - protected function registerCollaborationResources(): void { - $version = \OCP\Util::getVersion()[0]; - if ($version < 16) { - return; - } - - /** - * Register Collaboration ResourceProvider - * - * @Todo: Remove if min-version is 18 - */ - if ($version < 18) { - /** @var IManager $resourceManager */ - $resourceManager = $this->getContainer()->query(IManager::class); - } else { - /** @var IProviderManager $resourceManager */ - $resourceManager = $this->getContainer()->query(IProviderManager::class); - } - $resourceManager->registerResourceProvider(ResourceProvider::class); - $resourceManager->registerResourceProvider(ResourceProviderCard::class); - - $this->server->getEventDispatcher()->addListener('\OCP\Collaboration\Resources::loadAdditionalScripts', static function () { - Util::addScript('deck', 'collections'); - }); - } - - public function registerFullTextSearch(): void { - if (Util::getVersion()[0] < 16) { - return; - } - - $c = $this->getContainer(); - try { - $this->fullTextSearchService = $c->query(FullTextSearchService::class); - $this->fullTextSearchManager = $c->query(IFullTextSearchManager::class); - } catch (Exception $e) { - return; - } - - if (!$this->fullTextSearchManager->isAvailable()) { - return; - } - - /** @var IEventDispatcher $eventDispatcher */ - $eventDispatcher = $this->server->query(IEventDispatcher::class); - $eventDispatcher->addListener( - '\OCA\Deck\Card::onCreate', function (Event $e) { - $this->fullTextSearchService->onCardCreated($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Card::onUpdate', function (Event $e) { - $this->fullTextSearchService->onCardUpdated($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Card::onDelete', function (Event $e) { - $this->fullTextSearchService->onCardDeleted($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareNew', function (Event $e) { - $this->fullTextSearchService->onBoardShares($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareEdit', function (Event $e) { - $this->fullTextSearchService->onBoardShares($e); - } - ); - $eventDispatcher->addListener( - '\OCA\Deck\Board::onShareDelete', function (Event $e) { - $this->fullTextSearchService->onBoardShares($e); - } - ); - } -} diff --git a/lib/Event/FTSEvent.php b/lib/Event/AAclEvent.php similarity index 61% rename from lib/Event/FTSEvent.php rename to lib/Event/AAclEvent.php index bcccc1e54..e5534f743 100644 --- a/lib/Event/FTSEvent.php +++ b/lib/Event/AAclEvent.php @@ -1,6 +1,6 @@ +/* + * @copyright Copyright (c) 2021 Julius Härtl * * @author Julius Härtl * @@ -21,31 +21,24 @@ * */ +declare(strict_types=1); + + namespace OCA\Deck\Event; +use OCA\Deck\Db\Acl; use OCP\EventDispatcher\Event; -/** - * This is a class to keep compatibility for currently used events in full text search integration - */ -class FTSEvent extends Event { - - /** - * @var array - */ - private $arguments; - - public function __construct($subject, $arguments = []) { +abstract class AAclEvent extends Event { + private $acl; + + public function __construct(Acl $acl) { parent::__construct(); - $this->arguments = $arguments; + $this->acl = $acl; } - public function getArgument($key) { - if (isset($this->arguments[$key])) { - return $this->arguments[$key]; - } - - throw new \InvalidArgumentException(sprintf('Argument "%s" not found.', $key)); + public function getAcl(): Acl { + return $this->acl; } } diff --git a/lib/Event/ACardEvent.php b/lib/Event/ACardEvent.php new file mode 100644 index 000000000..a1cbf1363 --- /dev/null +++ b/lib/Event/ACardEvent.php @@ -0,0 +1,44 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +use OCA\Deck\Db\Card; +use OCP\EventDispatcher\Event; + +abstract class ACardEvent extends Event { + private $card; + + public function __construct(Card $card) { + parent::__construct(); + + $this->card = $card; + } + + public function getCard(): Card { + return $this->card; + } +} diff --git a/lib/Event/AclCreatedEvent.php b/lib/Event/AclCreatedEvent.php new file mode 100644 index 000000000..1d80b9d7a --- /dev/null +++ b/lib/Event/AclCreatedEvent.php @@ -0,0 +1,9 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +class AclDeletedEvent extends AAclEvent { +} diff --git a/lib/Event/AclUpdatedEvent.php b/lib/Event/AclUpdatedEvent.php new file mode 100644 index 000000000..94d3acd62 --- /dev/null +++ b/lib/Event/AclUpdatedEvent.php @@ -0,0 +1,30 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +class AclUpdatedEvent extends AAclEvent { +} diff --git a/lib/Event/CardCreatedEvent.php b/lib/Event/CardCreatedEvent.php new file mode 100644 index 000000000..d04c13e9e --- /dev/null +++ b/lib/Event/CardCreatedEvent.php @@ -0,0 +1,30 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +class CardCreatedEvent extends ACardEvent { +} diff --git a/lib/Event/CardDeletedEvent.php b/lib/Event/CardDeletedEvent.php new file mode 100644 index 000000000..e265c5c82 --- /dev/null +++ b/lib/Event/CardDeletedEvent.php @@ -0,0 +1,30 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +class CardDeletedEvent extends ACardEvent { +} diff --git a/lib/Event/CardUpdatedEvent.php b/lib/Event/CardUpdatedEvent.php new file mode 100644 index 000000000..5e991691f --- /dev/null +++ b/lib/Event/CardUpdatedEvent.php @@ -0,0 +1,30 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Event; + +class CardUpdatedEvent extends ACardEvent { +} diff --git a/lib/Listeners/FullTextSearchEventListener.php b/lib/Listeners/FullTextSearchEventListener.php new file mode 100644 index 000000000..4759e4019 --- /dev/null +++ b/lib/Listeners/FullTextSearchEventListener.php @@ -0,0 +1,104 @@ + + * + * @author Julius Härtl + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see . + * + */ + +declare(strict_types=1); + + +namespace OCA\Deck\Listeners; + +use OCA\Deck\Db\Card; +use OCA\Deck\Event\AAclEvent; +use OCA\Deck\Event\ACardEvent; +use OCA\Deck\Event\CardCreatedEvent; +use OCA\Deck\Event\CardDeletedEvent; +use OCA\Deck\Event\CardUpdatedEvent; +use OCA\Deck\Provider\DeckProvider; +use OCA\Deck\Service\FullTextSearchService; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\FullTextSearch\IFullTextSearchManager; +use OCP\FullTextSearch\Model\IIndex; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; + +class FullTextSearchEventListener implements IEventListener { + + /** @var string|null */ + private $userId; + /** @var IFullTextSearchManager|null */ + private $manager; + /** @var FullTextSearchService|null */ + private $service; + /** @var LoggerInterface */ + private $logger; + + public function __construct(ContainerInterface $container, $userId) { + $this->userId = $userId; + $this->logger = $container->get(LoggerInterface::class); + try { + $this->manager = $container->get(IFullTextSearchManager::class); + $this->service = $container->get(FullTextSearchService::class); + } catch (\Exception $e) { + // skipping in case FTS is not available + } + } + + public function handle(Event $event): void { + if (!$event instanceof ACardEvent && !$event instanceof AAclEvent) { + return; + } + + try { + if ($event instanceof CardCreatedEvent) { + $this->manager->createIndex( + DeckProvider::DECK_PROVIDER_ID, (string)$event->getCard()->getId(), $this->userId + ); + } + if ($event instanceof CardUpdatedEvent) { + $this->manager->updateIndexStatus( + DeckProvider::DECK_PROVIDER_ID, (string)$event->getCard()->getId(), IIndex::INDEX_CONTENT + ); + } + if ($event instanceof CardDeletedEvent) { + $this->manager->updateIndexStatus( + DeckProvider::DECK_PROVIDER_ID, (string)$event->getCard()->getId(), IIndex::INDEX_REMOVE + ); + } + + if ($event instanceof AAclEvent) { + $acl = $event->getAcl(); + $cards = array_map( + static function (Card $card) { + return (string)$card->getId(); + }, + $this->service->getCardsFromBoard($acl->getBoardId()) + ); + $this->manager->updateIndexesStatus( + DeckProvider::DECK_PROVIDER_ID, $cards, IIndex::INDEX_META + ); + } + } catch (\Exception $e) { + $this->logger->error('Error when handling deck full text search event', ['exception' => $e]); + } + } +} diff --git a/lib/Service/AssignmentService.php b/lib/Service/AssignmentService.php index 805ae176b..f78e383a9 100644 --- a/lib/Service/AssignmentService.php +++ b/lib/Service/AssignmentService.php @@ -31,7 +31,7 @@ use OCA\Deck\Db\Assignment; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\ChangeHelper; -use OCA\Deck\Event\FTSEvent; +use OCA\Deck\Event\CardUpdatedEvent; use OCA\Deck\NoPermissionException; use OCA\Deck\NotFoundException; use OCA\Deck\Notification\NotificationHelper; @@ -151,9 +151,7 @@ class AssignmentService { $this->changeHelper->cardChanged($cardId); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_USER_ASSIGN, ['assigneduser' => $userId]); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $cardId, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $assignment; } @@ -187,9 +185,7 @@ class AssignmentService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_USER_UNASSIGN, ['assigneduser' => $userId]); $this->changeHelper->cardChanged($cardId); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $cardId, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $assignment; } diff --git a/lib/Service/BoardService.php b/lib/Service/BoardService.php index 321d69ba4..cc05ba474 100644 --- a/lib/Service/BoardService.php +++ b/lib/Service/BoardService.php @@ -24,7 +24,6 @@ namespace OCA\Deck\Service; -use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Activity\ChangeSet; use OCA\Deck\AppInfo\Application; @@ -36,9 +35,13 @@ use OCA\Deck\Db\IPermissionMapper; use OCA\Deck\Db\Label; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; +use OCA\Deck\Event\AclCreatedEvent; +use OCA\Deck\Event\AclDeletedEvent; +use OCA\Deck\Event\AclUpdatedEvent; use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; use OCP\AppFramework\Db\DoesNotExistException; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IGroupManager; use OCP\IL10N; @@ -47,7 +50,6 @@ use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; use OCP\IUserManager; use OCA\Deck\BadRequestException; -use Symfony\Component\EventDispatcher\GenericEvent; class BoardService { private $boardMapper; @@ -83,7 +85,7 @@ class BoardService { IUserManager $userManager, IGroupManager $groupManager, ActivityManager $activityManager, - SymfonyAdapter $eventDispatcher, + IEventDispatcher $eventDispatcher, ChangeHelper $changeHelper, $userId ) { @@ -327,13 +329,6 @@ class BoardService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $new_board, ActivityManager::SUBJECT_BOARD_CREATE, [], $userId); $this->changeHelper->boardChanged($new_board->getId()); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onCreate', - new GenericEvent( - null, ['id' => $new_board->getId(), 'userId' => $userId, 'board' => $new_board] - ) - ); - return $new_board; } @@ -360,10 +355,6 @@ class BoardService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $board, ActivityManager::SUBJECT_BOARD_DELETE); $this->changeHelper->boardChanged($board->getId()); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onDelete', new GenericEvent(null, ['id' => $id]) - ); - return $board; } @@ -386,10 +377,6 @@ class BoardService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_BOARD, $board, ActivityManager::SUBJECT_BOARD_RESTORE); $this->changeHelper->boardChanged($board->getId()); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onUpdate', new GenericEvent(null, ['id' => $id, 'board' => $board]) - ); - return $board; } @@ -410,10 +397,6 @@ class BoardService { $board = $this->find($id); $delete = $this->boardMapper->delete($board); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onDelete', new GenericEvent(null, ['id' => $id]) - ); - return $delete; } @@ -457,10 +440,6 @@ class BoardService { $this->activityManager->triggerUpdateEvents(ActivityManager::DECK_OBJECT_BOARD, $changes, ActivityManager::SUBJECT_BOARD_UPDATE); $this->changeHelper->boardChanged($board->getId()); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onUpdate', new GenericEvent(null, ['id' => $id, 'board' => $board]) - ); - return $board; } @@ -541,18 +520,13 @@ class BoardService { $this->changeHelper->boardChanged($boardId); // TODO: use the dispatched event for this - $version = \OCP\Util::getVersion()[0]; - if ($version >= 16) { - try { - $resourceProvider = \OC::$server->query(\OCA\Deck\Collaboration\Resources\ResourceProvider::class); - $resourceProvider->invalidateAccessCache($boardId); - } catch (\Exception $e) { - } + try { + $resourceProvider = \OC::$server->query(\OCA\Deck\Collaboration\Resources\ResourceProvider::class); + $resourceProvider->invalidateAccessCache($boardId); + } catch (\Exception $e) { } - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onShareNew', new GenericEvent(null, ['id' => $newAcl->getId(), 'acl' => $newAcl, 'boardId' => $boardId]) - ); + $this->eventDispatcher->dispatchTyped(new AclCreatedEvent($acl)); return $newAcl; } @@ -597,9 +571,7 @@ class BoardService { $board = $this->aclMapper->update($acl); $this->changeHelper->boardChanged($acl->getBoardId()); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onShareEdit', new GenericEvent(null, ['id' => $id, 'boardId' => $acl->getBoardId(), 'acl' => $acl]) - ); + $this->eventDispatcher->dispatchTyped(new AclUpdatedEvent($acl)); return $board; } @@ -640,9 +612,7 @@ class BoardService { } $delete = $this->aclMapper->delete($acl); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Board::onShareDelete', new GenericEvent(null, ['id' => $id, 'boardId' => $acl->getBoardId(), 'acl' => $acl]) - ); + $this->eventDispatcher->dispatchTyped(new AclDeletedEvent($acl)); return $delete; } diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php index e0961151a..c67172d50 100644 --- a/lib/Service/CardService.php +++ b/lib/Service/CardService.php @@ -35,7 +35,9 @@ use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\Acl; use OCA\Deck\Db\ChangeHelper; use OCA\Deck\Db\StackMapper; -use OCA\Deck\Event\FTSEvent; +use OCA\Deck\Event\CardCreatedEvent; +use OCA\Deck\Event\CardDeletedEvent; +use OCA\Deck\Event\CardUpdatedEvent; use OCA\Deck\Notification\NotificationHelper; use OCA\Deck\Db\BoardMapper; use OCA\Deck\Db\LabelMapper; @@ -222,15 +224,10 @@ class CardService { $card->setDescription($description); $card->setDuedate($duedate); $card = $this->cardMapper->insert($card); + $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_CREATE); $this->changeHelper->cardChanged($card->getId(), false); - - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onCreate', - new FTSEvent( - null, ['id' => $card->getId(), 'card' => $card, 'userId' => $owner, 'stackId' => $stackId] - ) - ); + $this->eventDispatcher->dispatchTyped(new CardCreatedEvent($card)); return $card; } @@ -256,12 +253,10 @@ class CardService { $card = $this->cardMapper->find($id); $card->setDeletedAt(time()); $this->cardMapper->update($card); + $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_CARD_DELETE); $this->changeHelper->cardChanged($card->getId(), false); - - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onDelete', new FTSEvent(null, ['id' => $id, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardDeletedEvent($card)); return $card; } @@ -360,9 +355,7 @@ class CardService { $card = $this->cardMapper->update($card); $this->changeHelper->cardChanged($card->getId(), true); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $id, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $card; } @@ -402,9 +395,7 @@ class CardService { $this->changeHelper->cardChanged($card->getId(), false); $update = $this->cardMapper->update($card); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $id, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $update; } @@ -501,9 +492,7 @@ class CardService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_ARCHIVE); $this->changeHelper->cardChanged($id, false); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $id, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $newCard; } @@ -532,9 +521,7 @@ class CardService { $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $newCard, ActivityManager::SUBJECT_CARD_UPDATE_UNARCHIVE); $this->changeHelper->cardChanged($id, false); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $id, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); return $newCard; } @@ -570,9 +557,7 @@ class CardService { $this->changeHelper->cardChanged($cardId); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_LABEL_ASSIGN, ['label' => $label]); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $cardId, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); } /** @@ -606,9 +591,7 @@ class CardService { $this->changeHelper->cardChanged($cardId); $this->activityManager->triggerEvent(ActivityManager::DECK_OBJECT_CARD, $card, ActivityManager::SUBJECT_LABEL_UNASSING, ['label' => $label]); - $this->eventDispatcher->dispatch( - '\OCA\Deck\Card::onUpdate', new FTSEvent(null, ['id' => $cardId, 'card' => $card]) - ); + $this->eventDispatcher->dispatchTyped(new CardUpdatedEvent($card)); } /** diff --git a/lib/Service/FullTextSearchService.php b/lib/Service/FullTextSearchService.php index dc56073ec..504d8a11d 100644 --- a/lib/Service/FullTextSearchService.php +++ b/lib/Service/FullTextSearchService.php @@ -37,14 +37,10 @@ use OCA\Deck\Db\Card; use OCA\Deck\Db\CardMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; -use OCA\Deck\Event\FTSEvent; use OCA\Deck\Provider\DeckProvider; use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\MultipleObjectsReturnedException; -use OCP\FullTextSearch\Exceptions\FullTextSearchAppNotAvailableException; -use OCP\FullTextSearch\IFullTextSearchManager; use OCP\FullTextSearch\Model\IDocumentAccess; -use OCP\FullTextSearch\Model\IIndex; use OCP\FullTextSearch\Model\IIndexDocument; /** @@ -63,98 +59,15 @@ class FullTextSearchService { /** @var CardMapper */ private $cardMapper; - - /** @var IFullTextSearchManager */ - private $fullTextSearchManager; - - - /** - * FullTextSearchService constructor. - * - * @param BoardMapper $boardMapper - * @param StackMapper $stackMapper - * @param CardMapper $cardMapper - * @param IFullTextSearchManager $fullTextSearchManager - */ + public function __construct( - BoardMapper $boardMapper, StackMapper $stackMapper, CardMapper $cardMapper, - IFullTextSearchManager $fullTextSearchManager + BoardMapper $boardMapper, StackMapper $stackMapper, CardMapper $cardMapper ) { $this->boardMapper = $boardMapper; $this->stackMapper = $stackMapper; $this->cardMapper = $cardMapper; - - $this->fullTextSearchManager = $fullTextSearchManager; } - - /** - * @param FTSEvent $e - */ - public function onCardCreated(FTSEvent $e) { - $cardId = $e->getArgument('id'); - $userId = $e->getArgument('userId'); - - try { - $this->fullTextSearchManager->createIndex( - DeckProvider::DECK_PROVIDER_ID, (string)$cardId, $userId, IIndex::INDEX_FULL - ); - } catch (FullTextSearchAppNotAvailableException $e) { - } - } - - - /** - * @param FTSEvent $e - */ - public function onCardUpdated(FTSEvent $e) { - $cardId = $e->getArgument('id'); - - try { - $this->fullTextSearchManager->updateIndexStatus( - DeckProvider::DECK_PROVIDER_ID, (string)$cardId, IIndex::INDEX_CONTENT - ); - } catch (FullTextSearchAppNotAvailableException $e) { - } - } - - - /** - * @param FTSEvent $e - */ - public function onCardDeleted(FTSEvent $e) { - $cardId = $e->getArgument('id'); - - try { - $this->fullTextSearchManager->updateIndexStatus( - DeckProvider::DECK_PROVIDER_ID, (string)$cardId, IIndex::INDEX_REMOVE - ); - } catch (FullTextSearchAppNotAvailableException $e) { - } - } - - - /** - * @param FTSEvent $e - */ - public function onBoardShares(FTSEvent $e) { - $boardId = (int)$e->getArgument('boardId'); - - $cards = array_map( - function (Card $item) { - return $item->getId(); - }, - $this->getCardsFromBoard($boardId) - ); - try { - $this->fullTextSearchManager->updateIndexesStatus( - DeckProvider::DECK_PROVIDER_ID, $cards, IIndex::INDEX_META - ); - } catch (FullTextSearchAppNotAvailableException $e) { - } - } - - /** * @param Card $card * @@ -175,11 +88,9 @@ class FullTextSearchService { * @throws MultipleObjectsReturnedException */ public function fillIndexDocument(IIndexDocument $document) { - /** @var Card $card */ $card = $this->cardMapper->find((int)$document->getId()); - - $document->setTitle(($card->getTitle() === null) ? '' : $card->getTitle()); - $document->setContent(($card->getDescription() === null) ? '' : $card->getDescription()); + $document->setTitle(!empty($card->getTitle()) ? $card->getTitle() : ''); + $document->setContent(!empty($card->getDescription()) ? $card->getDescription() : ''); $document->setAccess($this->generateDocumentAccessFromCardId((int)$card->getId())); } diff --git a/lib/Service/StackService.php b/lib/Service/StackService.php index 6bca4a4ce..d8baedcae 100644 --- a/lib/Service/StackService.php +++ b/lib/Service/StackService.php @@ -24,7 +24,6 @@ namespace OCA\Deck\Service; -use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Activity\ChangeSet; use OCA\Deck\BadRequestException; @@ -37,7 +36,6 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; use OCA\Deck\StatusException; -use Symfony\Component\EventDispatcher\GenericEvent; class StackService { private $stackMapper; @@ -64,7 +62,6 @@ class StackService { AssignmentMapper $assignedUsersMapper, AttachmentService $attachmentService, ActivityManager $activityManager, - SymfonyAdapter $eventDispatcher, ChangeHelper $changeHelper ) { $this->stackMapper = $stackMapper; @@ -77,7 +74,6 @@ class StackService { $this->assignedUsersMapper = $assignedUsersMapper; $this->attachmentService = $attachmentService; $this->activityManager = $activityManager; - $this->symfonyAdapter = $eventDispatcher; $this->changeHelper = $changeHelper; } @@ -225,11 +221,6 @@ class StackService { ); $this->changeHelper->boardChanged($boardId); - $this->symfonyAdapter->dispatch( - '\OCA\Deck\Stack::onCreate', - new GenericEvent(null, ['id' => $stack->getId(), 'stack' => $stack]) - ); - return $stack; } @@ -259,10 +250,6 @@ class StackService { $this->changeHelper->boardChanged($stack->getBoardId()); $this->enrichStackWithCards($stack); - $this->symfonyAdapter->dispatch( - '\OCA\Deck\Stack::onDelete', new GenericEvent(null, ['id' => $id, 'stack' => $stack]) - ); - return $stack; } @@ -314,10 +301,6 @@ class StackService { ); $this->changeHelper->boardChanged($stack->getBoardId()); - $this->symfonyAdapter->dispatch( - '\OCA\Deck\Stack::onUpdate', new GenericEvent(null, ['id' => $id, 'stack' => $stack]) - ); - return $stack; } diff --git a/tests/unit/Service/BoardServiceTest.php b/tests/unit/Service/BoardServiceTest.php index a1c177b05..d0893ef46 100644 --- a/tests/unit/Service/BoardServiceTest.php +++ b/tests/unit/Service/BoardServiceTest.php @@ -23,7 +23,6 @@ namespace OCA\Deck\Service; -use OC\EventDispatcher\SymfonyAdapter; use OC\L10N\L10N; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Db\Acl; @@ -37,11 +36,11 @@ use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\StackMapper; use OCA\Deck\NoPermissionException; use OCA\Deck\Notification\NotificationHelper; +use OCP\EventDispatcher\IEventDispatcher; use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; use OCP\IGroupManager; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use \Test\TestCase; class BoardServiceTest extends TestCase { @@ -72,7 +71,7 @@ class BoardServiceTest extends TestCase { private $activityManager; /** @var ChangeHelper */ private $changeHelper; - /** @var EventDispatcherInterface */ + /** @var IEventDispatcher */ private $eventDispatcher; private $userId = 'admin'; @@ -91,7 +90,7 @@ class BoardServiceTest extends TestCase { $this->groupManager = $this->createMock(IGroupManager::class); $this->activityManager = $this->createMock(ActivityManager::class); $this->changeHelper = $this->createMock(ChangeHelper::class); - $this->eventDispatcher = $this->createMock(SymfonyAdapter::class); + $this->eventDispatcher = $this->createMock(IEventDispatcher::class); $this->service = new BoardService( $this->boardMapper, diff --git a/tests/unit/Service/StackServiceTest.php b/tests/unit/Service/StackServiceTest.php index 36f8a5463..79e04eca3 100644 --- a/tests/unit/Service/StackServiceTest.php +++ b/tests/unit/Service/StackServiceTest.php @@ -23,7 +23,6 @@ namespace OCA\Deck\Service; -use OC\EventDispatcher\SymfonyAdapter; use OCA\Deck\Activity\ActivityManager; use OCA\Deck\Db\AssignmentMapper; use OCA\Deck\Db\Card; @@ -34,7 +33,6 @@ use OCA\Deck\Db\Label; use OCA\Deck\Db\LabelMapper; use OCA\Deck\Db\Stack; use OCA\Deck\Db\StackMapper; -use Symfony\Component\EventDispatcher\EventDispatcherInterface; use \Test\TestCase; /** @@ -69,8 +67,6 @@ class StackServiceTest extends TestCase { private $activityManager; /** @var ChangeHelper|\PHPUnit\Framework\MockObject\MockObject */ private $changeHelper; - /** @var EventDispatcherInterface */ - private $eventDispatcher; public function setUp(): void { parent::setUp(); @@ -85,7 +81,6 @@ class StackServiceTest extends TestCase { $this->labelMapper = $this->createMock(LabelMapper::class); $this->activityManager = $this->createMock(ActivityManager::class); $this->changeHelper = $this->createMock(ChangeHelper::class); - $this->eventDispatcher = $this->createMock(SymfonyAdapter::class); $this->stackService = new StackService( $this->stackMapper, @@ -98,7 +93,6 @@ class StackServiceTest extends TestCase { $this->assignedUsersMapper, $this->attachmentService, $this->activityManager, - $this->eventDispatcher, $this->changeHelper ); } From 174d74c4835ff861ed3e7f9e9edc4e99631ef090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julius=20H=C3=A4rtl?= Date: Tue, 13 Apr 2021 11:05:02 +0200 Subject: [PATCH 2/2] Update psalm baseline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Julius Härtl --- tests/psalm-baseline.xml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/tests/psalm-baseline.xml b/tests/psalm-baseline.xml index ed9525ce8..0881083d7 100644 --- a/tests/psalm-baseline.xml +++ b/tests/psalm-baseline.xml @@ -1,5 +1,5 @@ - + $message !== null @@ -11,11 +11,6 @@ - - Application - - - method_exists($shareManager, 'registerShareProvider')