diff --git a/apps/workflowengine/lib/Entity/File.php b/apps/workflowengine/lib/Entity/File.php index 4f98a3e5cad0e9e3eeeb277812fd75195cf62c17..8daeaae64260ddb8d374d6b5f69297cca634ace8 100644 --- a/apps/workflowengine/lib/Entity/File.php +++ b/apps/workflowengine/lib/Entity/File.php @@ -34,18 +34,21 @@ use OCP\Files\NotFoundException; use OCP\IL10N; use OCP\ILogger; use OCP\IURLGenerator; +use OCP\IUser; +use OCP\IUserManager; use OCP\IUserSession; use OCP\Share\IManager as ShareManager; use OCP\SystemTag\ISystemTag; use OCP\SystemTag\ISystemTagManager; use OCP\SystemTag\MapperEvent; +use OCP\WorkflowEngine\EntityContext\IContextPortation; use OCP\WorkflowEngine\EntityContext\IDisplayText; use OCP\WorkflowEngine\EntityContext\IUrl; use OCP\WorkflowEngine\GenericEntityEvent; use OCP\WorkflowEngine\IEntity; use OCP\WorkflowEngine\IRuleMatcher; -class File implements IEntity, IDisplayText, IUrl { +class File implements IEntity, IDisplayText, IUrl, IContextPortation { private const EVENT_NAMESPACE = '\OCP\Files::'; /** @var IL10N */ @@ -66,7 +69,12 @@ class File implements IEntity, IDisplayText, IUrl { private $userSession; /** @var ISystemTagManager */ private $tagManager; - + /** @var ?Node */ + private $node; + /** @var ?IUser */ + private $actingUser = null; + /** @var IUserManager */ + private $userManager; public function __construct( IL10N $l10n, @@ -75,7 +83,8 @@ class File implements IEntity, IDisplayText, IUrl { ILogger $logger, ShareManager $shareManager, IUserSession $userSession, - ISystemTagManager $tagManager + ISystemTagManager $tagManager, + IUserManager $userManager ) { $this->l10n = $l10n; $this->urlGenerator = $urlGenerator; @@ -84,6 +93,7 @@ class File implements IEntity, IDisplayText, IUrl { $this->shareManager = $shareManager; $this->userSession = $userSession; $this->tagManager = $tagManager; + $this->userManager = $userManager; } public function getName(): string { @@ -112,6 +122,7 @@ class File implements IEntity, IDisplayText, IUrl { } $this->eventName = $eventName; $this->event = $event; + $this->actingUser = $this->actingUser ?? $this->userSession->getUser(); try { $node = $this->getNode(); $ruleMatcher->setEntitySubject($this, $node); @@ -138,6 +149,9 @@ class File implements IEntity, IDisplayText, IUrl { * @throws NotFoundException */ protected function getNode(): Node { + if ($this->node) { + return $this->node; + } if (!$this->event instanceof GenericEvent && !$this->event instanceof MapperEvent) { throw new NotFoundException(); } @@ -155,8 +169,9 @@ class File implements IEntity, IDisplayText, IUrl { throw new NotFoundException(); } $nodes = $this->root->getById((int)$this->event->getObjectId()); - if (is_array($nodes) && !empty($nodes)) { - return array_shift($nodes); + if (is_array($nodes) && isset($nodes[0])) { + $this->node = $nodes[0]; + return $this->node; } break; } @@ -164,7 +179,6 @@ class File implements IEntity, IDisplayText, IUrl { } public function getDisplayText(int $verbosity = 0): string { - $user = $this->userSession->getUser(); try { $node = $this->getNode(); } catch (NotFoundException $e) { @@ -172,7 +186,7 @@ class File implements IEntity, IDisplayText, IUrl { } $options = [ - $user ? $user->getDisplayName() : $this->l10n->t('Someone'), + $this->actingUser ? $this->actingUser->getDisplayName() : $this->l10n->t('Someone'), $node->getName() ]; @@ -220,4 +234,40 @@ class File implements IEntity, IDisplayText, IUrl { return ''; } } + + /** + * @inheritDoc + */ + public function exportContextIDs(): array { + $nodeOwner = $this->getNode()->getOwner(); + $actingUserId = null; + if ($this->actingUser instanceof IUser) { + $actingUserId = $this->actingUser->getUID(); + } elseif ($this->userSession->getUser() instanceof IUser) { + $actingUserId = $this->userSession->getUser()->getUID(); + } + return [ + 'eventName' => $this->eventName, + 'nodeId' => $this->getNode()->getId(), + 'nodeOwnerId' => $nodeOwner ? $nodeOwner->getUID() : null, + 'actingUserId' => $actingUserId, + ]; + } + + /** + * @inheritDoc + */ + public function importContextIDs(array $contextIDs): void { + $this->eventName = $contextIDs['eventName']; + if ($contextIDs['nodeOwnerId'] !== null) { + $userFolder = $this->root->getUserFolder($contextIDs['nodeOwnerId']); + $nodes = $userFolder->getById($contextIDs['nodeId']); + } else { + $nodes = $this->root->getById($contextIDs['nodeId']); + } + $this->node = $nodes[0] ?? null; + if ($contextIDs['actingUserId']) { + $this->actingUser = $this->userManager->get($contextIDs['actingUserId']); + } + } } diff --git a/apps/workflowengine/tests/ManagerTest.php b/apps/workflowengine/tests/ManagerTest.php index 512d5dc1f61012c3d763a1ba315ce25c5da7646d..0022fc37cb91535e255249b9a28d1c1f939c7fc2 100644 --- a/apps/workflowengine/tests/ManagerTest.php +++ b/apps/workflowengine/tests/ManagerTest.php @@ -33,6 +33,7 @@ use OCP\IL10N; use OCP\ILogger; use OCP\IServerContainer; use OCP\IURLGenerator; +use OCP\IUserManager; use OCP\IUserSession; use OCP\SystemTag\ISystemTagManager; use OCP\WorkflowEngine\ICheck; @@ -295,7 +296,8 @@ class ManagerTest extends TestCase { $this->createMock(ILogger::class), $this->createMock(\OCP\Share\IManager::class), $this->createMock(IUserSession::class), - $this->createMock(ISystemTagManager::class) + $this->createMock(ISystemTagManager::class), + $this->createMock(IUserManager::class), ]) ->setMethodsExcept(['getEvents']) ->getMock(); diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index 0a64301f13bbde835c20b8900bb31107774b2d40..254840b3542dd137efb0ca36e2e752fa0efda6b1 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -527,6 +527,7 @@ return array( 'OCP\\User\\Events\\UserLoggedInWithCookieEvent' => $baseDir . '/lib/public/User/Events/UserLoggedInWithCookieEvent.php', 'OCP\\User\\Events\\UserLoggedOutEvent' => $baseDir . '/lib/public/User/Events/UserLoggedOutEvent.php', 'OCP\\Util' => $baseDir . '/lib/public/Util.php', + 'OCP\\WorkflowEngine\\EntityContext\\IContextPortation' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IContextPortation.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayName' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IDisplayName.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayText' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IDisplayText.php', 'OCP\\WorkflowEngine\\EntityContext\\IIcon' => $baseDir . '/lib/public/WorkflowEngine/EntityContext/IIcon.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 43c45b2fe834f4798f2e41c0006329cb69dd6178..45bf93241d5fa933928fbcb5022d470233f47a5a 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -556,6 +556,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\User\\Events\\UserLoggedInWithCookieEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserLoggedInWithCookieEvent.php', 'OCP\\User\\Events\\UserLoggedOutEvent' => __DIR__ . '/../../..' . '/lib/public/User/Events/UserLoggedOutEvent.php', 'OCP\\Util' => __DIR__ . '/../../..' . '/lib/public/Util.php', + 'OCP\\WorkflowEngine\\EntityContext\\IContextPortation' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IContextPortation.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayName' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IDisplayName.php', 'OCP\\WorkflowEngine\\EntityContext\\IDisplayText' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IDisplayText.php', 'OCP\\WorkflowEngine\\EntityContext\\IIcon' => __DIR__ . '/../../..' . '/lib/public/WorkflowEngine/EntityContext/IIcon.php', diff --git a/lib/public/WorkflowEngine/EntityContext/IContextPortation.php b/lib/public/WorkflowEngine/EntityContext/IContextPortation.php new file mode 100644 index 0000000000000000000000000000000000000000..9c63fb048c39c59c5aefdc8c53d0597e9dd947c0 --- /dev/null +++ b/lib/public/WorkflowEngine/EntityContext/IContextPortation.php @@ -0,0 +1,59 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2020 Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @author Arthur Schiwon <blizzz@arthur-schiwon.de> + * + * @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 w ill 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 <http://www.gnu.org/licenses/>. + * + */ + +namespace OCP\WorkflowEngine\EntityContext; + +/** + * Interface IContextPortation + * + * Occasionally an IEntity needs to be reused not in the same, but a new + * request. As IEntities receive custom context information during a flow + * cycle, sometimes it might be necessary to export context identifiers to + * be able to recreate the state at a later point. For example: handling + * translations in a notification INotifier. + * + * @package OCP\WorkflowEngine\EntityContext + * + * @since 20.0.0 + */ +interface IContextPortation { + + /** + * All relevant context identifiers that are needed to restore the state + * of an entity shall be returned with this method. The resulting array + * must be JSON-serializable. + * + * @since 20.0.0 + */ + public function exportContextIDs(): array; + + /** + * This method receives the array as returned by `exportContextIDs()` in + * order to restore the state of the IEntity if necessary. + * + * @since 20.0.0 + */ + public function importContextIDs(array $contextIDs): void; +}