From 3c7d7aa3b5b9eb82292112c9d2792ff0704a8549 Mon Sep 17 00:00:00 2001 From: David Callizaya Date: Tue, 25 Jun 2024 22:19:41 -0400 Subject: [PATCH] Implement Demo behavior for Exclusive Gateways --- .../Bpmn/ConditionedExclusiveTransition.php | 12 +++- .../Nayra/Bpmn/DefaultTransition.php | 10 +++ .../Nayra/Bpmn/ExclusiveGatewayTransition.php | 4 +- .../Bpmn/ForceGatewayTransitionTrait.php | 47 +++++++++++++ .../Bpmn/PauseOnGatewayTransitionTrait.php | 21 ++++++ .../Nayra/Engine/DemoModeTrait.php | 70 +++++++++++++++++++ src/ProcessMaker/Nayra/Engine/EngineTrait.php | 2 + .../Nayra/Engine/ExecutionInstanceTrait.php | 10 +++ 8 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 src/ProcessMaker/Nayra/Bpmn/ForceGatewayTransitionTrait.php create mode 100644 src/ProcessMaker/Nayra/Bpmn/PauseOnGatewayTransitionTrait.php create mode 100644 src/ProcessMaker/Nayra/Engine/DemoModeTrait.php diff --git a/src/ProcessMaker/Nayra/Bpmn/ConditionedExclusiveTransition.php b/src/ProcessMaker/Nayra/Bpmn/ConditionedExclusiveTransition.php index eb3b0eb1..42171742 100644 --- a/src/ProcessMaker/Nayra/Bpmn/ConditionedExclusiveTransition.php +++ b/src/ProcessMaker/Nayra/Bpmn/ConditionedExclusiveTransition.php @@ -16,6 +16,7 @@ class ConditionedExclusiveTransition implements TransitionInterface, ConditionedTransitionInterface { use TransitionTrait; + use ForceGatewayTransitionTrait; /** * @var callable @@ -33,6 +34,15 @@ class ConditionedExclusiveTransition implements TransitionInterface, Conditioned public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) { try { + // If debug mode is enabled, the transition is triggered only if it is selected + if ($executionInstance && $this->shouldDebugTriggerThisTransition($executionInstance)) { + return true; + } + // If debug mode is enabled, the transition is not triggered if it is not selected + if ($executionInstance && $this->shouldDebugSkipThisTransition($executionInstance)) { + return false; + } + $result = false; $myIndex = $this->owner->getConditionedTransitions()->indexOf($this); $condition = $this->condition; @@ -60,7 +70,7 @@ public function assertCondition(TokenInterface $token = null, ExecutionInstanceI return $result; } catch (Throwable $exception) { - throw new RuntimeException($exception->getMessage(), $exception->getCode(), $exception, $this->owner); + throw new RuntimeException($exception->getMessage(), $exception->getCode(), null, $this->owner); } } diff --git a/src/ProcessMaker/Nayra/Bpmn/DefaultTransition.php b/src/ProcessMaker/Nayra/Bpmn/DefaultTransition.php index 05f73bed..64d86af4 100644 --- a/src/ProcessMaker/Nayra/Bpmn/DefaultTransition.php +++ b/src/ProcessMaker/Nayra/Bpmn/DefaultTransition.php @@ -13,6 +13,7 @@ class DefaultTransition implements TransitionInterface { use TransitionTrait; + use ForceGatewayTransitionTrait; /** * Returns true if the condition of the transition is met with the DataStore of the passed execution instance @@ -24,6 +25,15 @@ class DefaultTransition implements TransitionInterface */ public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) { + // If debug mode is enabled, the transition is triggered only if it is selected + if ($this->shouldDebugTriggerThisTransition($executionInstance)) { + return true; + } + // If debug mode is enabled, the transition is not triggered if it is not selected + if ($this->shouldDebugSkipThisTransition($executionInstance)) { + return false; + } + $executeDefaultTransition = true; foreach ($this->owner->getConditionedTransitions() as $transition) { if ($transition->assertCondition($token, $executionInstance)) { diff --git a/src/ProcessMaker/Nayra/Bpmn/ExclusiveGatewayTransition.php b/src/ProcessMaker/Nayra/Bpmn/ExclusiveGatewayTransition.php index fa683fdb..42fad4ef 100644 --- a/src/ProcessMaker/Nayra/Bpmn/ExclusiveGatewayTransition.php +++ b/src/ProcessMaker/Nayra/Bpmn/ExclusiveGatewayTransition.php @@ -12,6 +12,7 @@ class ExclusiveGatewayTransition implements TransitionInterface { use TransitionTrait; + use PauseOnGatewayTransitionTrait; /** * Initialize the tokens consumed property, the Exclusive Gateway consumes @@ -34,7 +35,8 @@ protected function initExclusiveGatewayTransition() */ public function assertCondition(TokenInterface $token = null, ExecutionInstanceInterface $executionInstance = null) { - return true; + // Execution is paused if Engine is in demo mode and the gateway choose is not selected + return !$this->shouldPauseGatewayTransition($executionInstance); } /** diff --git a/src/ProcessMaker/Nayra/Bpmn/ForceGatewayTransitionTrait.php b/src/ProcessMaker/Nayra/Bpmn/ForceGatewayTransitionTrait.php new file mode 100644 index 00000000..aceb582a --- /dev/null +++ b/src/ProcessMaker/Nayra/Bpmn/ForceGatewayTransitionTrait.php @@ -0,0 +1,47 @@ +getEngine(); + $demoMode = $engine->isDemoMode(); + $gateway = $this->getOwner(); + $connection = $this->outgoing()->item(0); + $targetEntrypoint = $connection->target()->getOwner(); + return $demoMode && $engine->getSelectedDemoFlow($gateway)->getTarget() === $targetEntrypoint; + } + + /** + * Check if the transition should be skipped in debug mode. + * + * @param ExecutionInstanceInterface $executionInstance + * + * @return bool + */ + function shouldDebugSkipThisTransition(ExecutionInstanceInterface $executionInstance) + { + $engine = $executionInstance->getEngine(); + $demoMode = $engine->isDemoMode(); + $gateway = $this->getOwner(); + $connection = $this->outgoing()->item(0); + $targetEntrypoint = $connection->target()->getOwner(); + return $demoMode && $engine->getSelectedDemoFlow($gateway)->getTarget() !== $targetEntrypoint; + } +} diff --git a/src/ProcessMaker/Nayra/Bpmn/PauseOnGatewayTransitionTrait.php b/src/ProcessMaker/Nayra/Bpmn/PauseOnGatewayTransitionTrait.php new file mode 100644 index 00000000..8e9e453c --- /dev/null +++ b/src/ProcessMaker/Nayra/Bpmn/PauseOnGatewayTransitionTrait.php @@ -0,0 +1,21 @@ +getEngine(); + $demoMode = $engine->isDemoMode(); + $gateway = $this->getOwner(); + return $demoMode && !$engine->getSelectedDemoFlow($gateway); + } +} diff --git a/src/ProcessMaker/Nayra/Engine/DemoModeTrait.php b/src/ProcessMaker/Nayra/Engine/DemoModeTrait.php new file mode 100644 index 00000000..789de5e1 --- /dev/null +++ b/src/ProcessMaker/Nayra/Engine/DemoModeTrait.php @@ -0,0 +1,70 @@ +demoMode; + } + + /** + * Set if the engine is in demo mode. + * + * @param bool $value + */ + public function setDemoMode(bool $value) + { + $this->demoMode = $value; + } + + /** + * Retrieves the selected flow by the user in demo mode. + * + * @param GatewayInterface $gateway + * + * @return FlowInterface|null + */ + public function getSelectedDemoFlow(GatewayInterface $gateway) + { + return $this->selectedFlow[$gateway->getId()] ?? null; + } + + /** + * Set the selected flow by the user in demo mode. + * + * @param GatewayInterface $gateway + * @param bool $value + */ + public function setSelectedDemoFlow( + GatewayInterface $gateway, + FlowInterface $selectedFlow = null + ) { + $this->selectedFlow[$gateway->getId()] = $selectedFlow; + } +} diff --git a/src/ProcessMaker/Nayra/Engine/EngineTrait.php b/src/ProcessMaker/Nayra/Engine/EngineTrait.php index dc2adc7b..9f772d40 100755 --- a/src/ProcessMaker/Nayra/Engine/EngineTrait.php +++ b/src/ProcessMaker/Nayra/Engine/EngineTrait.php @@ -22,6 +22,8 @@ */ trait EngineTrait { + use DemoModeTrait; + /** * Instances of process. * diff --git a/src/ProcessMaker/Nayra/Engine/ExecutionInstanceTrait.php b/src/ProcessMaker/Nayra/Engine/ExecutionInstanceTrait.php index 1bef5e0c..c5ff986b 100644 --- a/src/ProcessMaker/Nayra/Engine/ExecutionInstanceTrait.php +++ b/src/ProcessMaker/Nayra/Engine/ExecutionInstanceTrait.php @@ -200,4 +200,14 @@ public function getTokens() { return $this->tokens; } + + /** + * Get the engine. + * + * @return EngineInterface + */ + public function getEngine() + { + return $this->getProcess()->getEngine(); + } }