PHPackages                             solution-forest/workflow-engine-core - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. solution-forest/workflow-engine-core

ActiveLibrary

solution-forest/workflow-engine-core
====================================

Framework-agnostic workflow engine for PHP applications

v0.0.3-alpha(2mo ago)722021MITPHPPHP ^8.3CI passing

Since May 29Pushed 1mo agoCompare

[ Source](https://github.com/solutionforest/workflow-engine-core)[ Packagist](https://packagist.org/packages/solution-forest/workflow-engine-core)[ GitHub Sponsors](https://github.com/solutionforest)[ RSS](/packages/solution-forest-workflow-engine-core/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (3)Dependencies (5)Versions (5)Used By (1)

Workflow Engine Core
====================

[](#workflow-engine-core)

[![PHPStan](https://camo.githubusercontent.com/8cc6e2903f988614e36ec87d0691439ef8f51c5b44c3d50d38ba14051b31ab97/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6c7574696f6e666f726573742f776f726b666c6f772d656e67696e652d636f72652f7068707374616e2e796d6c3f6272616e63683d6d61696e266c6162656c3d7068707374616e267374796c653d666c61742d737175617265)](https://github.com/solutionforest/workflow-engine-core/actions?query=workflow%3Aphpstan+branch%3Amain)[![GitHub Tests Action Status](https://camo.githubusercontent.com/eb6fd25202a2fe9204b91776081bb21e30d5f5fda3f235d6f5b16cf7cdfaca83/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6c7574696f6e666f726573742f776f726b666c6f772d656e67696e652d636f72652f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d54657374267374796c653d666c61742d737175617265)](https://github.com/solutionforest/workflow-engine-core/actions?query=workflow%3Arun-tests+branch%3Amain)[![GitHub Code Style Action Status](https://camo.githubusercontent.com/6d0f8490095cdb27f5bd8c8881f3f70832593920fae441c278556a33e632d3c7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f736f6c7574696f6e666f726573742f776f726b666c6f772d656e67696e652d636f72652f6669782d7068702d636f64652d7374796c652d6973737565732e796d6c3f6272616e63683d6d61696e266c6162656c3d636f64652532307374796c65267374796c653d666c61742d737175617265)](https://github.com/solutionforest/workflow-engine-core/actions?query=workflow%3A%22Fix+PHP+code+style+issues%22+branch%3Amain)[![Latest Version on Packagist](https://camo.githubusercontent.com/25b761ddc3007b028cd6be2406aa67d5ac62c5129af155a5a7450a48fe869e89/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f736f6c7574696f6e2d666f726573742f776f726b666c6f772d656e67696e652d636f72652e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/solution-forest/workflow-engine-core)

A powerful, framework-agnostic workflow engine for PHP applications. This core library provides comprehensive workflow definition, execution, and state management capabilities without any framework dependencies.

> ⚠️ **WARNING: DEVELOPMENT STATUS**⚠️
>
> This package is currently under active development and is **NOT READY FOR PRODUCTION USE**.
>
> Features may be incomplete, APIs might change, and there could be breaking changes. Use at your own risk in development environments only.

📋 Requirements
--------------

[](#-requirements)

- **PHP 8.3+** - Leverages modern PHP features for type safety and performance
- **Composer** - For dependency management
- **No framework dependencies** - Works with any PHP project

✨ Features
----------

[](#-features)

- **🚀 Framework Agnostic**: Works with any PHP framework or standalone applications
- **🔒 Type Safe**: Full PHP 8.3+ type safety with strict typing and generics
- **🔧 Extensible**: Plugin architecture for custom actions and storage adapters
- **📊 State Management**: Robust workflow instance state tracking and persistence
- **⚡ Performance**: Optimized for high-throughput workflow execution
- **🛡️ Error Handling**: Comprehensive exception handling with detailed context
- **🔄 Retry Logic**: Built-in retry mechanisms with configurable strategies
- **⏱️ Timeouts**: Step-level timeout controls for reliable execution
- **📋 Conditions**: Conditional workflow execution based on runtime data
- **🎯 Events**: Rich event system for monitoring and integration
- **🧪 Well Tested**: Comprehensive test suite with 93 tests and 224+ assertions

📦 Installation
--------------

[](#-installation)

### For Production Use

[](#for-production-use)

```
composer require solution-forest/workflow-engine-core
```

### For Development

[](#for-development)

```
# Clone the repository
git clone https://github.com/solution-forest/workflow-engine-core.git
cd workflow-engine-core

# Install dependencies
composer install

# Run quality checks
composer ci
```

🚀 Quick Start
-------------

[](#-quick-start)

### Basic Workflow Definition

[](#basic-workflow-definition)

```
use SolutionForest\WorkflowEngine\Core\WorkflowBuilder;
use SolutionForest\WorkflowEngine\Core\WorkflowEngine;
use SolutionForest\WorkflowEngine\Core\WorkflowContext;
use SolutionForest\WorkflowEngine\Core\ActionResult;
use SolutionForest\WorkflowEngine\Actions\BaseAction;

// Define custom actions
class ValidateOrderAction extends BaseAction
{
    public function execute(WorkflowContext $context): ActionResult
    {
        $orderId = $context->getData('order_id');

        // Your validation logic here
        if ($this->isValidOrder($orderId)) {
            return ActionResult::success(['validated' => true]);
        }

        return ActionResult::failure('Invalid order');
    }
}

// Build a workflow definition
$definition = WorkflowBuilder::create('order-processing')
    ->description('Process customer orders')
    ->addStep('validate', ValidateOrderAction::class)
    ->addStep('payment', ProcessPaymentAction::class, timeout: 300, retryAttempts: 3)
    ->addStep('fulfillment', FulfillOrderAction::class)
    ->build();

// Create engine with storage adapter and event dispatcher
$engine = new WorkflowEngine($storageAdapter, $eventDispatcher);

// Start and run the workflow
$instanceId = $engine->start(
    'order-processing',
    $definition->toArray(),
    ['order_id' => 123, 'customer_id' => 456]
);

// Check the result
$instance = $engine->getInstance($instanceId);
echo $instance->getState()->value; // "completed"
```

### Advanced Workflow Builder

[](#advanced-workflow-builder)

```
use SolutionForest\WorkflowEngine\Core\WorkflowBuilder;

$workflow = WorkflowBuilder::create('order-flow')
    ->description('Process customer orders')
    ->addStep('validate', ValidateOrderAction::class)
    ->when('order.total > 1000', function ($builder) {
        $builder->addStep('fraud_check', FraudCheckAction::class);
    })
    ->addStep('payment', ProcessPaymentAction::class, timeout: 300, retryAttempts: 3)
    ->email('order-confirmation', 'customer@example.com', 'Order Confirmed')
    ->build();

// Quick templates for common patterns
$workflow = WorkflowBuilder::quick()->userOnboarding();
$workflow = WorkflowBuilder::quick()->orderProcessing();
$workflow = WorkflowBuilder::quick()->documentApproval();
```

### PHP 8.3+ Attributes

[](#php-83-attributes)

> **Note:** Attributes are currently metadata annotations for documentation and tooling. They are not yet auto-parsed by the engine at runtime — use the builder API (`timeout:`, `retryAttempts:`, `when()`) or step config to apply these behaviors. Attribute-driven execution is planned for a future release.

Use native PHP attributes to annotate actions with retry, timeout, and conditions:

#### Retry Logic

[](#retry-logic)

```
use SolutionForest\WorkflowEngine\Attributes\Retry;

#[Retry(attempts: 3, backoff: 'exponential', delay: 1000)]
class ReliableApiAction extends BaseAction
{
    public function execute(WorkflowContext $context): ActionResult
    {
        // Retries up to 3 times with exponential backoff starting at 1s
        return ActionResult::success();
    }
}
```

#### Timeouts

[](#timeouts)

```
use SolutionForest\WorkflowEngine\Attributes\Timeout;

#[Timeout(seconds: 30)]
class TimedAction extends BaseAction
{
    public function execute(WorkflowContext $context): ActionResult
    {
        // Will timeout after 30 seconds
        return ActionResult::success();
    }
}
```

#### Conditional Execution

[](#conditional-execution)

```
use SolutionForest\WorkflowEngine\Attributes\Condition;

#[Condition('order.amount > 100')]
class PremiumProcessingAction extends BaseAction
{
    public function execute(WorkflowContext $context): ActionResult
    {
        // Only executes when order.amount > 100
        return ActionResult::success();
    }
}
```

#### Step Metadata

[](#step-metadata)

```
use SolutionForest\WorkflowEngine\Attributes\WorkflowStep;

#[WorkflowStep(id: 'send_email', name: 'Send Welcome Email', description: 'Sends a welcome email to the new user')]
class SendWelcomeEmailAction extends BaseAction
{
    public function execute(WorkflowContext $context): ActionResult
    {
        return ActionResult::success();
    }
}
```

### Retry, Timeout &amp; Conditions via Builder

[](#retry-timeout--conditions-via-builder)

These features can also be configured through the fluent builder API:

```
// Steps with retry and timeout configured via builder
$workflow = WorkflowBuilder::create('reliable-flow')
    ->addStep('fetch_data', FetchDataAction::class, timeout: 30, retryAttempts: 3)
    ->addStep('process', ProcessAction::class, timeout: 60)
    ->build();

// Conditional steps evaluated at runtime
$workflow = WorkflowBuilder::create('conditional-flow')
    ->addStep('validate', ValidateAction::class)
    ->when('order.total > 1000', function ($builder) {
        $builder->addStep('fraud_check', FraudCheckAction::class);
    })
    ->addStep('complete', CompleteAction::class)
    ->build();
```

### Workflow Lifecycle Management

[](#workflow-lifecycle-management)

```
// Start, resume, cancel
$instanceId = $engine->start('my-workflow', $definition->toArray(), ['key' => 'value']);
$instance = $engine->getInstance($instanceId);
$engine->resume($instanceId);
$engine->cancel($instanceId, 'No longer needed');

// Track progress
$progress = $instance->getProgress(); // 0.0 to 100.0
$summary = $instance->getStatusSummary();

// Query instances with filters
$instances = $engine->getInstances([
    'state' => 'running',
    'definition_name' => 'order-processing',
    'created_after' => new \DateTime('-7 days'),
    'limit' => 50,
    'offset' => 0,
]);
```

### SimpleWorkflow Helper

[](#simpleworkflow-helper)

For quick workflow execution without manual engine setup:

```
use SolutionForest\WorkflowEngine\Support\SimpleWorkflow;

$simple = new SimpleWorkflow($storageAdapter);

// Run actions sequentially
$instanceId = $simple->sequential('user-onboarding', [
    SendWelcomeEmailAction::class,
    CreateUserProfileAction::class,
    AssignDefaultRoleAction::class,
], ['user_id' => 123]);

// Run a single action as a workflow
$instanceId = $simple->runAction(SendEmailAction::class, [
    'to' => 'user@example.com',
    'subject' => 'Welcome!',
]);

// Execute from a builder
$builder = WorkflowBuilder::create('custom-flow')
    ->addStep('validate', ValidateAction::class)
    ->addStep('process', ProcessAction::class);
$instanceId = $simple->executeBuilder($builder, $context);

// Check status
$status = $simple->getStatus($instanceId);
// Returns: id, state, current_step, progress, completed_steps, failed_steps, error_message, ...
```

🏗️ Architecture
---------------

[](#️-architecture)

The workflow engine follows a clean architecture with clear separation of concerns:

```
WorkflowBuilder → WorkflowDefinition → WorkflowEngine → Executor → Actions
                                              ↓
                                        StateManager → StorageAdapter
                                              ↓
                                        EventDispatcher

```

### Core Components

[](#core-components)

ComponentPurpose**WorkflowBuilder**Fluent API for constructing workflow definitions with `addStep()`, `when()`, `email()`, `delay()`, `http()`**WorkflowDefinition**Immutable blueprint containing steps, transitions, conditions, and metadata**WorkflowEngine**Central orchestrator — `start()`, `resume()`, `cancel()`, `getInstance()`, `getInstances()`, `getStatus()`**Executor**Runs steps sequentially with retry logic, timeout enforcement, and condition evaluation**StateManager**Coordinates persistence through StorageAdapter**EventDispatcher**Broadcasts 7 event types during workflow lifecycle### State Machine

[](#state-machine)

```
PENDING → RUNNING → COMPLETED
    ↓         ↓ ↑
  FAILED   WAITING
    ↑         ↓ ↑
  FAILED ← PAUSED
    ↑
CANCELLED ← (any non-terminal state)

```

**Valid transitions:**

- `PENDING` → `RUNNING`, `FAILED`, `CANCELLED`
- `RUNNING` → `WAITING`, `PAUSED`, `COMPLETED`, `FAILED`, `CANCELLED`
- `WAITING` → `RUNNING`, `FAILED`, `CANCELLED`
- `PAUSED` → `RUNNING`, `FAILED`, `CANCELLED`
- Terminal states (`COMPLETED`, `FAILED`, `CANCELLED`) → no further transitions

State transitions are validated at runtime — invalid transitions throw `InvalidWorkflowStateException`.

### Namespace Map

[](#namespace-map)

NamespaceContents`Core\`WorkflowEngine, WorkflowBuilder, Executor, StateManager, WorkflowInstance, WorkflowDefinition, WorkflowContext, ActionResult, Step, DefinitionParser, ActionResolver`Actions\`BaseAction, LogAction, EmailAction, HttpAction, DelayAction, ConditionAction`Contracts\`WorkflowAction, StorageAdapter, EventDispatcher, Logger`Attributes\`WorkflowStep, Retry, Timeout, Condition`Events\`WorkflowStartedEvent, WorkflowCompletedEvent, WorkflowFailedEvent, WorkflowCancelledEvent, StepCompletedEvent, StepFailedEvent, StepRetriedEvent`Exceptions\`WorkflowException, InvalidWorkflowDefinitionException, InvalidWorkflowStateException, ActionNotFoundException, StepExecutionException, WorkflowInstanceNotFoundException`Support\`NullLogger, NullEventDispatcher, SimpleWorkflow, Uuid, Timeout, ConditionEvaluator, Arr### Built-in Actions

[](#built-in-actions)

Six ready-to-use actions are included:

ActionPurposeConfig Keys**LogAction**Log messages with placeholder replacement (`{user.name}`)`message`, `level` (debug/info/warning/error)**EmailAction**Mock email sending with template support`to`, `subject`, `body`, `template`**HttpAction**HTTP requests with `{{ variable }}` template variables`url`, `method`, `headers`, `body`**DelayAction**Pause execution for a specified duration`seconds`, `minutes`, `hours`**ConditionAction**Evaluate boolean expressions and branch (`on_true`/`on_false`)`condition`, `on_true`, `on_false`**BaseAction**Abstract base class for custom actions—### WorkflowState Helpers

[](#workflowstate-helpers)

The `WorkflowState` enum provides utility methods for UI and logic:

```
$state = $instance->getState();

$state->isActive();        // true for PENDING, RUNNING, WAITING, PAUSED
$state->isFinished();      // true for COMPLETED, FAILED, CANCELLED
$state->isSuccessful();    // true for COMPLETED
$state->isError();         // true for FAILED
$state->label();           // "Running"
$state->description();     // "The workflow is actively executing steps..."
$state->color();           // "blue" (gray, blue, yellow, orange, green, red, purple)
$state->icon();            // "▶️"
$state->canTransitionTo(WorkflowState::COMPLETED); // bool
$state->getValidTransitions(); // [WorkflowState::WAITING, ...]
```

🔧 Configuration
---------------

[](#-configuration)

### Storage Adapters

[](#storage-adapters)

Implement the `StorageAdapter` interface for custom persistence:

```
use SolutionForest\WorkflowEngine\Contracts\StorageAdapter;

class DatabaseStorageAdapter implements StorageAdapter
{
    public function save(WorkflowInstance $instance): void { /* ... */ }
    public function load(string $id): WorkflowInstance { /* ... */ }
    public function findInstances(array $criteria = []): array { /* ... */ }
    public function delete(string $id): void { /* ... */ }
    public function exists(string $id): bool { /* ... */ }
    public function updateState(string $id, array $updates): void { /* ... */ }
}
```

### Event Handling

[](#event-handling)

Listen to workflow events — 7 event types are dispatched during execution:

```
use SolutionForest\WorkflowEngine\Contracts\EventDispatcher;
use SolutionForest\WorkflowEngine\Events\WorkflowStartedEvent;
use SolutionForest\WorkflowEngine\Events\WorkflowCompletedEvent;
use SolutionForest\WorkflowEngine\Events\WorkflowFailedEvent;
use SolutionForest\WorkflowEngine\Events\WorkflowCancelledEvent;
use SolutionForest\WorkflowEngine\Events\StepCompletedEvent;
use SolutionForest\WorkflowEngine\Events\StepFailedEvent;
use SolutionForest\WorkflowEngine\Events\StepRetriedEvent;

class CustomEventDispatcher implements EventDispatcher
{
    public function dispatch(object $event): void
    {
        match ($event::class) {
            WorkflowStartedEvent::class => $this->onWorkflowStarted($event),
            WorkflowCompletedEvent::class => $this->onWorkflowCompleted($event),
            WorkflowFailedEvent::class => $this->onWorkflowFailed($event),
            StepCompletedEvent::class => $this->onStepCompleted($event),
            StepFailedEvent::class => $this->onStepFailed($event),
            StepRetriedEvent::class => $this->onStepRetried($event),
            default => null,
        };
    }
}
```

### Logging

[](#logging)

Provide a custom logging implementation (PSR-3 style):

```
use SolutionForest\WorkflowEngine\Contracts\Logger;

class CustomLogger implements Logger
{
    public function info(string $message, array $context = []): void { /* ... */ }
    public function warning(string $message, array $context = []): void { /* ... */ }
    public function error(string $message, array $context = []): void { /* ... */ }
    public function debug(string $message, array $context = []): void { /* ... */ }
}
```

🧪 Development
-------------

[](#-development)

### Testing

[](#testing)

Run the test suite:

```
# Run all tests
composer test

# Run tests with coverage
composer test:coverage

# Run specific test file
vendor/bin/pest tests/Unit/WorkflowEngineTest.php

# Run tests with detailed output
vendor/bin/pest --verbose
```

### Code Quality

[](#code-quality)

We use several tools to maintain high code quality:

```
# Static analysis with PHPStan
composer analyze

# Code formatting with Laravel Pint
composer pint

# Check code formatting without making changes
composer pint --test

# Run all quality checks
composer pint && composer analyze && composer test
```

### Development Tools

[](#development-tools)

- **[Pest](https://pestphp.com/)** - Testing framework with expressive syntax
- **[Pest Architecture Testing](https://pestphp.com/docs/arch-testing)** - Architectural constraints and code quality rules
- **[PHPStan](https://phpstan.org/)** - Static analysis tool for catching bugs
- **[Laravel Pint](https://laravel.com/docs/pint)** - Code style fixer built on PHP-CS-Fixer
- **Framework-agnostic** - No Laravel dependencies in the core library

### Configuration Files

[](#configuration-files)

- `phpstan.neon.dist` - PHPStan configuration for static analysis
- `pint.json` - Laravel Pint configuration for code formatting
- `phpunit.xml.dist` - PHPUnit configuration for testing
- `.github/workflows/run-tests.yml` - CI/CD pipeline configuration

### Quality Standards

[](#quality-standards)

We maintain high code quality through:

- **100% PHPStan Level 6** - Static analysis with zero errors across 46 source files
- **Laravel Pint** - Consistent code formatting following Laravel standards
- **Comprehensive Testing** - 93 tests with 224+ assertions covering unit, integration, and real-world scenarios
- **Architecture Tests** - Automated checks preventing debug functions in source code
- **State Transition Validation** - Runtime enforcement of valid workflow state transitions
- **Type Safety** - Full PHP 8.3+ type declarations throughout
- **Continuous Integration** - Automated quality checks on every commit (PHP 8.3/8.4 matrix)

📚 Framework Integrations
------------------------

[](#-framework-integrations)

This core library is framework-agnostic. For specific framework integrations:

- **Laravel**: Use [`solution-forest/workflow-engine-laravel`](https://packagist.org/packages/solution-forest/workflow-engine-laravel)
- **Symfony**: Coming soon
- **Other frameworks**: Easily integrate using the provided interfaces

🤝 Contributing
--------------

[](#-contributing)

We welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

📄 License
---------

[](#-license)

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.

🙏 Credits
---------

[](#-credits)

- **Solution Forest Team** - Initial development and maintenance
- **Contributors** - Thank you to all contributors who have helped improve this project

🔗 Links
-------

[](#-links)

- [Issues](https://github.com/solutionforest/workflow-engine-core/issues)
- [Changelog](https://github.com/solutionforest/workflow-engine-core/blob/main/CHANGELOG.md)
- [Laravel Integration](https://github.com/solutionforest/workflow-engine-laravel)

###  Health Score

42

—

FairBetter than 90% of packages

Maintenance88

Actively maintained with recent releases

Popularity18

Limited adoption so far

Community14

Small or concentrated contributor base

Maturity41

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~133 days

Total

3

Last Release

89d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/9499120912b47a170291b3b795ea0255f060d8500bd2988535e4e6faccee5c8d?d=identicon)[solutionforest](/maintainers/solutionforest)

---

Top Contributors

[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (34 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (26 commits)")[![lam0819](https://avatars.githubusercontent.com/u/68211972?v=4)](https://github.com/lam0819 "lam0819 (25 commits)")[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (6 commits)")

---

Tags

automationbusiness-logicbusiness-processphpphp-workflowprocess-automationstate-machineworkflow-engineworkflow-managementphpautomationworkflowstate-machinebusiness-process

###  Code Quality

TestsPest

Static AnalysisPHPStan

Code StyleLaravel Pint

Type Coverage Yes

### Embed Badge

![Health badge](/badges/solution-forest-workflow-engine-core/health.svg)

```
[![Health](https://phpackages.com/badges/solution-forest-workflow-engine-core/health.svg)](https://phpackages.com/packages/solution-forest-workflow-engine-core)
```

###  Alternatives

[zoon/puphpeteer

A Puppeteer bridge for PHP, supporting the entire API.

204192.9k1](/packages/zoon-puphpeteer)[godbout/alfred-workflow-scriptfilter

Generate Alfred 3 or 4 Workflow Results in PHP with a laugh.

173.7k1](/packages/godbout-alfred-workflow-scriptfilter)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
