Merge pull request #22112 from nextcloud/enh/noid/flow-entity-recreatable-state

Allow Flow entity state to be recreated
This commit is contained in:
Morris Jobke 2020-08-06 09:36:32 +02:00 committed by GitHub
commit 3f1c48598d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 121 additions and 8 deletions

View File

@ -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']);
}
}
}

View File

@ -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();

View File

@ -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',

View File

@ -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',

View File

@ -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;
}