Releases: dereuromark/cakephp-workflow
0.2.2
Fixes
- Fail hard on a stuck automatic branch under
strictMode, plus validate detection (#35) - Restore hidden checkbox field in the timeout bulk form
Improvements
- Add embeddable workflow diagram helper suite (#42)
- Add workflow helper diagram rendering options (#41)
- Add PNG export option for workflow widgets (#44)
- Improve workflow component ergonomics and SVG export (#43)
- Split widget exports from the GraphViz draw renderer (#45)
- Improve Mermaid helper bootstrap options (#40)
- Cover string polymorphic workflow keys without changing integer defaults (#39)
Full Changelog: 0.2.1...0.2.2
0.2.1
Breaking changes
-
Polymorphic reference columns renamed to the CakePHP ecosystem convention (as used by cakephp-comments / cakephp-favorites / cakephp-file-storage):
entity_table→modelandentity_id→foreign_key, onworkflow_transitions,workflow_locks, andworkflow_timeouts. (#34)Upgrade: run
bin/cake migrations migrate --plugin Workflow— theRenamePolymorphicColumnsmigration renames the columns in place, preserving data (and is a safe no-op on fresh installs). If you passed theentityTableoption when attaching the behavior, rename that key tomodel.
Improvements
- The
foreign_keyvalidation no longer caps at 36 characters, so longer string primary keys are accepted under thestring/uuidcolumn types. (#34)
Since we just released the new major, this should still fit in, and there is an upgrade path to smooth things over.
Full Changelog: 0.2.0...0.2.1
0.2.0
Fixes
- Lock and timeout timestamps are now written and compared in the same (app) timezone, so scheduled timeouts and lock expiry no longer fire early/late on a non-UTC application timezone. (#31)
WorkflowBatchServicenow persists each transition — it previously applied them in memory only, so batch runs reported success without saving. (#27)
Improvements
- Optimistic (lock-free) concurrency — a new
useOptimisticLockmode that persists the state change with a compare-and-set (claimed before commands run, so a lost race executes no side effects), as an alternative to the pessimistic lock table. (#30) - Automatic / conditional transitions via attributes —
#[Transition(automatic: true)]gated by the new#[Condition]attribute, bringing config-only auto-transitions to attribute-defined workflows. (#28) - Time-in-state tracking — stamps a
state_changed_atcolumn on every state change (auto-applied only when the column exists; configurable), enabling aging/SLA queries. (#29) - New
workflow applyCLI command to run a single transition from the command line (with--reason/--user/--dry-run). (#23) - New
workflow batchCLI command to apply a transition to all records currently in a given state (with--state/--limit/--stop-on-failure/--dry-run). (#27) workflow init --migrationnow scaffolds the state-column migration alongside the workflow classes. (#25)- Drop-in
panel()view helper rendering a state badge plus CSRF-protected POST transition buttons. (#24) - Entity and table convenience traits for ergonomic, statically-typed workflow access without reaching through
getBehavior(). (#22) - Native-PHP single-file workflow loader — define a whole workflow in one
config/workflows/*.phpfile with no extra parser dependency. (#26) entity_iddefaults tointeger(CakePHP's default PK type) and follows the sharedPolymorphic.typeconfig key —bigintegerfor large-id apps,uuid/binaryuuidfor non-integer keys; signedness followsMigrations.unsigned_primary_keys. (#19, #21, #32)
Full Changelog: 0.1.3...0.2.0
0.1.3
Fixes
- Restore admin actor capture for apps still using legacy
Auth.User.idsession auth, and record the operator on forced transitions and orphan fixes (#11) - Concurrent transitions no longer double-execute — transition locking is now a real mutex that prevents acting on stale state (#13)
- Timeout transitions are applied through the behavior, fixing timeouts that could get stuck and never fire (#14)
- The idempotency-key check now works correctly and is concurrency-safe (#15)
workflow timeoutsnow skips and marks timeouts whose entity was deleted, instead of erroring on every run (#18)
Improvements
- Drift safety for workflow definition changes: records left in a state that no longer exists no longer crash reads, display, or the admin UI. Find them via the admin Orphans view or
workflow validate --check-data, and move them forward withworkflow migrate --map(#16) - Idempotency keys are stored in a dedicated indexed column for more robust, portable duplicate detection (#17)
- Generic typing of
Workflow/AbstractStateover the entity type for stronger static analysis and IDE support (#9)
Full Changelog: 0.1.2...0.1.3
0.1.2
Fixes
- Reject GET on state-mutating admin actions.
WorkflowsController::forceTransition()andOrphansController::fix()previously rendered on GET and processed mutations on POST through the same action — the framework would still accept a state-changing GET if a legacy bookmark, prefetcher, or server-sideHtml->link()hit the URL. Added$this->request->allowMethod(['post'])inside the POST branch of each action; render-on-GET path is preserved but mutation now requires an explicit POST. Defense-in-depth alongside the framework's CSRF middleware.
Improvements
- Capture operator identity on admin-driven audit-log rows.
logForcedTransition(),logOrphanFix(), andTimeoutsController::execute()previously wrote audit rows with nouser_id— multi-admin deployments lost the most useful piece of audit data on exactly the actions where it matters most. The newWorkflowAppController::getCurrentUserId()helper resolves the request identity (with fallback to the legacyAuth.User.idsession) and is wired into all three sites; both the column-leveluser_idand the JSONcontext(user_id+client_ip) now carry operator identity. - Configurable Back-to-App link in the admin sidebar.
- Ship
resources/locales/workflow.pot(2 unique msgids). The plugin already used__d('workflow', ...)consistently throughout — only the POT was missing, so translators had nothing to base a language pack on.
Full Changelog: 0.1.1...0.1.2
0.1.1
Important
Action required when upgrading: Host applications must configure Workflow.adminAccess as a Closure that returns literal true for permitted requests. Without it, the admin UI responds with HTTP 403 (default-deny).
Security
- Added
Workflow.adminAccessClosure gate for the bundled admin controllers (#6)- The admin UI can rewrite workflow definitions and trigger transitions, so unguarded access has real blast radius. The plugin controllers extend the bare
Cake\Controller\Controller(not the host'sAppController), so per-controller auth wired through the hostAppControllerwould never run. - Anything other than a
Closurereturning literaltrue(unset, non-Closure, returningfalseor a truthy non-bool, or throwing) yields a 403. - Calls
Authorization::skipAuthorization()when thecakephp/authorizationplugin is loaded, so the gate IS the authorization decision for these controllers and the plugin will not double-reject.
- The admin UI can rewrite workflow definitions and trigger transitions, so unguarded access has real blast radius. The plugin controllers extend the bare
Full Changelog: 0.1.0...0.1.1
0.1.0
Initial Pre-Release
State machine and workflow engine for CakePHP with PHP 8 Attributes, YAML/NEON config support, and admin UI.
Features
- Workflow Definitions: PHP 8 Attributes (recommended) or NEON/YAML configuration files
- State Management: Guards, commands, and lifecycle callbacks (OnEnter, OnExit)
- Audit Logging: Full transition history with user tracking and metadata
- Concurrency Safety: Pessimistic locking and transactional safety for concurrent transitions
- Automatic Timeouts: Configurable timeout orchestration for persisted transitions
- Admin UI: Built-in admin panel with Mermaid.js workflow diagrams
- Visual Designer: Interactive workflow designer for creating and editing workflows
- CLI Tools: Commands for initialization, listing, validation, and workflow inspection
- WorkflowBehavior: Table behavior for easy integration with CakePHP models
- WorkflowComponent: Controller component for handling transitions with flash messages
- Batch Operations: WorkflowBatchService for bulk state transitions
- Workflow Object Pattern: Symfony-style API for direct workflow manipulation
