https://github.com/dereuromark/cakephp-workflow
Batteries-included state machine plugin for CakePHP with PHP 8 Attributes, YAML config, audit trails, and visual admin dashboard
https://github.com/dereuromark/cakephp-workflow
cakephp cakephp-plugin finite-state-machine graph php statemachine transitions workflow
Last synced: 25 days ago
JSON representation
Batteries-included state machine plugin for CakePHP with PHP 8 Attributes, YAML config, audit trails, and visual admin dashboard
- Host: GitHub
- URL: https://github.com/dereuromark/cakephp-workflow
- Owner: dereuromark
- License: mit
- Created: 2026-03-28T18:27:51.000Z (3 months ago)
- Default Branch: master
- Last Pushed: 2026-05-21T17:26:33.000Z (27 days ago)
- Last Synced: 2026-05-21T22:40:42.353Z (27 days ago)
- Topics: cakephp, cakephp-plugin, finite-state-machine, graph, php, statemachine, transitions, workflow
- Language: PHP
- Homepage: https://dereuromark.github.io/cakephp-workflow/
- Size: 333 KB
- Stars: 1
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
- awesome-cakephp - Workflow plugin - Batteries-included state machine plugin with PHP 8 attributes, YAML config, audit trails, and visual admin dashboard. (Plugins / Miscellaneous)
README
# CakePHP Workflow Plugin
[](https://github.com/dereuromark/cakephp-workflow/actions/workflows/ci.yml?query=branch%3Amaster)
[](https://codecov.io/gh/dereuromark/cakephp-workflow)
[](https://packagist.org/packages/dereuromark/cakephp-workflow)
[](https://php.net/)
[](LICENSE)
[](https://github.com/php-collective/code-sniffer)
This branch is for **CakePHP 5.2+**. See [version map](https://github.com/dereuromark/cakephp-workflow/wiki#cakephp-version-map) for details.
State machine and workflow engine for CakePHP with PHP 8 Attributes, YAML/NEON config support, and admin UI.
> [!TIP]
> Try the live demo:
## Requirements
- CakePHP 5.2+
## Installation
```bash
composer require dereuromark/cakephp-workflow
```
Load the plugin:
```bash
bin/cake plugin load Workflow
```
Run migrations:
```bash
bin/cake migrations migrate --plugin Workflow
```
The generic `entity_id` column is polymorphic and defaults to `integer`; set the shared
`Polymorphic.type` key to `biginteger` for large-id apps, or `uuid` / `binaryuuid` for
non-integer keys. **UUID / char primary keys are fully supported** — no code changes needed. See
[Installation: Entity id type](https://dereuromark.github.io/cakephp-workflow/guide/installation#using-uuid-char-primary-keys).
## Configuration
Configure the plugin in your `config/app.php`:
```php
'Workflow' => [
'adminAccess' => function (\Cake\Http\ServerRequest $request): bool {
$identity = $request->getAttribute('identity');
return $identity !== null && in_array('admin', (array)$identity->roles, true);
},
'loader' => [
'namespaces' => [
'App\\Workflow',
],
'configPath' => CONFIG . 'workflows' . DS,
],
'logging' => true,
'locking' => true,
'timeouts' => true,
'lockDuration' => 30,
'adminBackUrl' => ['plugin' => false, 'controller' => 'Dashboard', 'action' => 'index'],
'adminActorResolver' => function (string $userId, ?\Workflow\Model\Entity\WorkflowTransition $transition = null): string {
return 'Admin #' . $userId;
},
],
```
The admin UI is fail-closed by default: you must provide `Workflow.adminAccess`
to expose `/admin/workflow/...`. Manual admin actions also record actor and
context metadata; when you still rely on legacy session auth, the admin logger
falls back to `Auth.User.id` automatically.
## Defining Workflows
### Using PHP 8 Attributes (Recommended)
Create state classes in your namespace:
```php
getEntity()?->get('total') > 0
? true
: 'Order total must be positive';
}
#[Command('pay')]
public function markPaymentCaptured(): void
{
$this->getEntity()?->set('payment_captured', true);
}
}
```
```php
addBehavior('Workflow.Workflow', [
'workflow' => 'order',
]);
}
```
Apply transitions:
```php
$behavior = $this->Orders->getBehavior('Workflow');
if ($behavior->canTransition($order, 'pay')) {
// Atomic: applies transition, saves entity, logs - all in one transaction
$result = $behavior->transition($order, 'pay', ['user_id' => $userId]);
}
```
See the [documentation](https://dereuromark.github.io/cakephp-workflow/) for the full API.
## Drift Safety
Changing a workflow while records exist can leave records in a state that no
longer exists. This is handled out of the box, with no configuration:
- **Graceful degradation:** orphaned records never crash reads, display, or the
admin UI — they render as a neutral "unknown" state, and transitioning one
returns a clear blocked result.
- **Detection:** the admin Orphans view (`/admin/workflow/orphans`) and
`workflow validate --check-data` list records whose state is no longer defined.
- **Remediation:** move them forward interactively, or headlessly:
```bash
bin/cake workflow validate order --check-data # report orphaned records
bin/cake workflow migrate order --map legacy:pending # move orphaned records forward
```
See [Drift Safety](https://dereuromark.github.io/cakephp-workflow/guide/versioning) for details.
## CLI Commands
```bash
bin/cake workflow init order Orders # Scaffold new workflow
bin/cake workflow list # List all workflows
bin/cake workflow show order # Show workflow details
bin/cake workflow validate # Validate definitions
bin/cake workflow migrate order # Move orphaned records to valid states
```
## Features
- PHP 8 Attributes or NEON/YAML definitions
- Guards, commands, and lifecycle callbacks
- Audit logging with user tracking
- Pessimistic locking for concurrent transitions
- Automatic timeouts
- Drift safety: orphaned records never crash, with detection and forward migration
- Admin UI with Mermaid.js diagrams
- CLI tools for management and validation
## Documentation
Full documentation: https://dereuromark.github.io/cakephp-workflow/