-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
564 additions
and
275 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PHPWorkflow\Step; | ||
|
||
use PHPWorkflow\State\WorkflowContainer; | ||
use PHPWorkflow\State\WorkflowState; | ||
use PHPWorkflow\WorkflowControl; | ||
|
||
class Loop implements WorkflowStep | ||
{ | ||
use StepExecutionTrait; | ||
|
||
protected array $steps = []; | ||
protected LoopControl $loopControl; | ||
|
||
public function __construct(LoopControl $loopControl) | ||
{ | ||
$this->loopControl = $loopControl; | ||
} | ||
|
||
public function addStep(WorkflowStep $step): self | ||
{ | ||
$this->steps[] = $step; | ||
|
||
return $this; | ||
} | ||
|
||
public function getDescription(): string | ||
{ | ||
return $this->loopControl->getDescription(); | ||
} | ||
|
||
public function run(WorkflowControl $control, WorkflowContainer $container) | ||
{ | ||
$iteration = 0; | ||
|
||
while ($this->loopControl->executeNextIteration($iteration, $control, $container)) { | ||
foreach ($this->steps as $step) { | ||
$this->wrapStepExecution($step, WorkflowState::getRunningWorkflow()); | ||
} | ||
|
||
WorkflowState::getRunningWorkflow()->addExecutionLog(sprintf("Loop iteration #%s", ++$iteration)); | ||
} | ||
|
||
$control->attachStepInfo(sprintf("Loop finished after %s iterations", $iteration)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PHPWorkflow\Step; | ||
|
||
use PHPWorkflow\State\WorkflowContainer; | ||
use PHPWorkflow\WorkflowControl; | ||
|
||
interface LoopControl | ||
{ | ||
/** | ||
* Describe in a few words what this loop does | ||
*/ | ||
public function getDescription(): string; | ||
|
||
/** | ||
* Return true if the next iteration of the loop shall be executed. Return false to break the loop | ||
*/ | ||
public function executeNextIteration(int $iteration, WorkflowControl $control, WorkflowContainer $container): bool; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PHPWorkflow\Step; | ||
|
||
use Exception; | ||
use PHPWorkflow\Exception\WorkflowControl\FailStepException; | ||
use PHPWorkflow\Exception\WorkflowControl\SkipStepException; | ||
use PHPWorkflow\Exception\WorkflowControl\SkipWorkflowException; | ||
use PHPWorkflow\State\ExecutionLog\ExecutionLog; | ||
use PHPWorkflow\State\WorkflowState; | ||
|
||
trait StepExecutionTrait | ||
{ | ||
protected function wrapStepExecution(WorkflowStep $step, WorkflowState $workflowState): void { | ||
try { | ||
($this->resolveMiddleware($step, $workflowState))(); | ||
} catch (SkipStepException | FailStepException $exception) { | ||
$workflowState->addExecutionLog( | ||
$step->getDescription(), | ||
$exception instanceof FailStepException ? ExecutionLog::STATE_FAILED : ExecutionLog::STATE_SKIPPED, | ||
$exception->getMessage(), | ||
); | ||
|
||
if ($exception instanceof FailStepException) { | ||
// cancel the workflow during preparation | ||
if ($workflowState->getStage() <= WorkflowState::STAGE_PROCESS) { | ||
throw $exception; | ||
} | ||
|
||
$workflowState->getExecutionLog()->addWarning(sprintf('Step failed (%s)', get_class($step)), true); | ||
} | ||
|
||
return; | ||
} catch (Exception $exception) { | ||
$workflowState->addExecutionLog( | ||
$step->getDescription(), | ||
$exception instanceof SkipWorkflowException ? ExecutionLog::STATE_SKIPPED : ExecutionLog::STATE_FAILED, | ||
$exception->getMessage(), | ||
); | ||
|
||
// cancel the workflow during preparation | ||
if ($workflowState->getStage() <= WorkflowState::STAGE_PROCESS) { | ||
throw $exception; | ||
} | ||
|
||
if (!($exception instanceof SkipWorkflowException)) { | ||
$workflowState->getExecutionLog()->addWarning(sprintf('Step failed (%s)', get_class($step)), true); | ||
} | ||
|
||
return; | ||
} | ||
|
||
$workflowState->addExecutionLog($step->getDescription()); | ||
} | ||
|
||
private function resolveMiddleware(WorkflowStep $step, WorkflowState $workflowState): callable | ||
{ | ||
$tip = fn () => $step->run($workflowState->getWorkflowControl(), $workflowState->getWorkflowContainer()); | ||
|
||
foreach ($workflowState->getMiddlewares() as $middleware) { | ||
$tip = fn () => $middleware( | ||
$tip, | ||
$workflowState->getWorkflowControl(), | ||
$workflowState->getWorkflowContainer(), | ||
); | ||
} | ||
|
||
return $tip; | ||
} | ||
} |
Oops, something went wrong.