adachsoft / workflow
Simple, plugin-based workflow engine
Requires
- php: ^8.2
- adachsoft/collection: ^3.0
Requires (Dev)
- adachsoft/php-code-style: ^0.4.2
- friendsofphp/php-cs-fixer: ^3.94
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^13.0
- rector/rector: ^2.3
README
Simple, plugin-based workflow engine for PHP.
Requirements
- PHP 8.2+
adachsoft/collection^3.0
Installation
composer require adachsoft/workflow
Overview
The library provides two engines built around three central contracts:
WorkflowDefinitionRepositoryInterfaceWorkflowRunRepositoryInterfaceStepRegistryInterface
Available engines:
WorkflowEngineInterfacefor synchronous workflow executionDebugEngineInterfacefor step-by-step workflow debugging
You can build ready-to-use default in-memory engines with:
WorkflowEngineBuilderDebugEngineBuilder
Main Concepts
Step
A workflow step implements StepInterface and exposes its metadata through the #[StepType] attribute.
Workflow definition
A workflow definition is represented by WorkflowDefinitionVo. It stores workflow step configuration and determines the first step by the first defined key.
Workflow run
A workflow run is represented by WorkflowRunVo. It stores the current step, input, output, completion state, and optional debug state.
Payload
PayloadVo is an immutable value object used for step input, step config, and step output.
Basic Usage
use AdachSoft\Workflow\Attribute\StepType;
use AdachSoft\Workflow\Builder\WorkflowEngineBuilder;
use AdachSoft\Workflow\Contracts\StepInterface;
use AdachSoft\Workflow\Engine\PayloadVo;
use AdachSoft\Workflow\Engine\StepContextDto;
use AdachSoft\Workflow\Engine\StepResultDto;
use AdachSoft\Workflow\Engine\WorkflowDefinitionVo;
use AdachSoft\Workflow\Repository\InMemoryWorkflowDefinitionRepository;
use AdachSoft\Workflow\Repository\InMemoryWorkflowRunRepository;
#[StepType(type: 'finish', description: 'Ends the workflow')]
final class FinishStep implements StepInterface
{
public function execute(StepContextDto $stepContextDto): StepResultDto
{
return StepResultDto::end(new PayloadVo(['status' => 'done']));
}
}
$definitionRepository = new InMemoryWorkflowDefinitionRepository();
$runRepository = new InMemoryWorkflowRunRepository();
$workflowEngine = WorkflowEngineBuilder::create()
->withWorkflowDefinitionRepository($definitionRepository)
->withWorkflowRunRepository($runRepository)
->build();
$stepRegistry = (new ReflectionClass($workflowEngine))
->getProperty('stepRegistry')
->getValue($workflowEngine);
$stepRegistry->register(FinishStep::class);
$definitionRepository->save(new WorkflowDefinitionVo('example', [
'finish' => new PayloadVo([
'type' => 'finish',
'config' => new PayloadVo(),
]),
]));
$runId = $workflowEngine->start('example', PayloadVo::empty());
$run = $runRepository->get($runId);
Builders
WorkflowEngineBuilder and DebugEngineBuilder provide two usage modes:
- build a default in-memory engine
- build an engine with custom repositories and a custom step registry
Example:
use AdachSoft\Workflow\Builder\DebugEngineBuilder;
$debugEngine = DebugEngineBuilder::create()->build();
Built-in Steps
The package currently provides these built-in steps in src/Steps:
RunWorkflowStep— starts another workflow and forwards the current input as outputSleepStep— pauses execution for a number of seconds within a configured limit
Builders can register the built-in steps for you:
$workflowEngine = WorkflowEngineBuilder::create()
->withStandardSteps()
->build();
Debug Engine
DebugEngineInterface supports:
- starting a workflow in paused mode
- starting from a selected step
- executing one step at a time
- pausing and resuming a run
- reading the current run state
Step Metadata
The registry can expose all registered step definitions through StepRegistryInterface::getAllDefinitions().
This returns StepDefinitionCollection, which can be serialized to JSON with toJson().
Design Notes
- Engines depend on contracts for repositories and the step registry.
- Workflow execution is synchronous.
- The debug engine executes one step at a time.
- Public API uses value objects and collections instead of raw arrays where it matters.
- Step metadata is centralized in the
#[StepType]attribute.
Development
Available Composer scripts:
composer test
composer phpstan
composer cs-fix
composer cs-check