survos / workflow-extras-bundle
Metadata conveniences and next-transition selection for native Symfony workflows
Package info
github.com/survos/workflow-extras-bundle
Type:symfony-bundle
pkg:composer/survos/workflow-extras-bundle
Fund package maintenance!
Requires
- php: ^8.5
- survos/kit-bundle: ^2.5
- symfony/config: 8.2.*@dev
- symfony/dependency-injection: 8.2.*@dev
- symfony/http-kernel: 8.2.*@dev
- symfony/workflow: 8.2.*@dev
Requires (Dev)
- phpunit/phpunit: ^13.0
Suggests
- survos/workflow-async-bundle: Execute transitions marked async through Symfony Messenger
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-10-09 15:20:48 UTC
README
Small conveniences on top of native Symfony 8.2 workflow attributes. Symfony continues to discover and register the workflow, validate its definition and execute its transitions. There is no Survos definition reader or registrar here.
Experimental 0.1 scaffold, requiring PHP 8.5 and 8.2.*@dev integration
packages. This is not a drop-in replacement for state-bundle yet.
Attributes
use Survos\WorkflowExtrasBundle\Attribute\AsWorkflow; use Survos\WorkflowExtrasBundle\Attribute\Place; use Survos\WorkflowExtrasBundle\Attribute\Transition; #[AsWorkflow(name: 'packages', supports: Package::class, description: 'Enrich packages')] final class PackageWorkflow { #[Place('Package discovered', initial: true, next: [self::LOAD])] public const DISCOVERED = 'discovered'; #[Place('Package metadata loaded')] public const LOADED = 'loaded'; #[Transition( self::DISCOVERED, self::LOADED, 'Fetch package metadata', async: true, transport: 'package_metadata', )] public const LOAD = 'load'; }
These classes extend Symfony's corresponding attributes, enabled by merged
Symfony #66687.
Place(initial: true) is now native through
#66722, not an extras policy.
Both transition endpoints reference declared place constants, so each stored place
name is defined once. We explicitly declare and describe every place and
transition instead of relying on inferred places, making the definition useful
to humans and tools. Native backed enum cases and Arc arguments remain usable;
enums are optional.
| Attribute | Convenience arguments |
|---|---|
AsWorkflow |
Native argument order plus optional description: at the end. |
Place |
description, initial, metadata, next. |
Transition |
Required from, to, then description, guard, metadata, next, optional async and transport. |
Descriptions and ordered next lists become ordinary metadata. Non-null typed
values override their matching metadata keys; null leaves metadata unchanged.
All other metadata is preserved. Next lists must contain non-empty strings.
Native parent properties remain readonly, and Transition remains repeatable.
Do not apply both a native and derived Place/AsWorkflow to the same target;
Symfony rejects that ambiguity.
Description-first Place follows the convenience of Console's Argument and
Option. #66726 proposes native
descriptions; it is independent of this package's implementation. If core adopts
these conveniences, extras can delegate and eventually deprecate its equivalent.
Next selection, without automatic chaining
$next = $resolver->firstEnabled($workflow, $subject, ['validate', 'reject']); if ($next !== null) { // Apply synchronously, or persist/commit and explicitly dispatch through async. }
Inject Survos\WorkflowExtrasBundle\Service\NextTransitionResolver. It validates
the entire candidate list, then selects the first transition enabled by native
guards. It does not apply, enqueue, flush or commit anything. Native can() can
initialize marking and run guard listeners, so selection is not guaranteed to be
side-effect-free. This scaffold intentionally has no automatic entered/completed
listener: safe persistence and chaining are a later integration milestone.
Installation
After publication, in an application whose Symfony constraints allow 8.2-dev:
composer config minimum-stability dev composer config prefer-stable true composer require 'survos/workflow-extras-bundle:dev-main' --with-all-dependencies
Review and lock the resolved versions. Enable
Survos\WorkflowExtrasBundle\SurvosWorkflowExtrasBundle if Flex has not done so.
It requires WorkflowBundle and Survos Kit, not FrameworkBundle, Doctrine ORM,
Twig or Messenger. Kit itself requires PHP 8.5 and HttpKernel.
Async metadata in the example has no execution effect by itself. Install
workflow-async-bundle
and explicitly dispatch to get queued execution. Extras does not require async;
async does not require extras. Their integration is through native metadata.
Extras accepts async: true, transport: 'package_metadata' as typed conveniences
and writes the native metadata consumed by workflow-async-bundle. Omitted options
preserve existing metadata; conflicting typed values are rejected. The runtime is
an optional dependency: install both bundles for queued transitions, or extras
alone for descriptions and next selection. If a native definition contains
async: true without the async runtime enabled, container compilation fails with
an installation/configuration hint. Installing the package alone is insufficient:
enable the bundle and configure a subject store and consumable Messenger transport.
You may also use async's typed Transition with extras' AsWorkflow and Place, putting a transition description in its native metadata argument.
Current scope and roadmap
| Capability | Status |
|---|---|
| Derived AsWorkflow/Place/Transition and metadata conveniences | Implemented |
| Ordered first-enabled transition selection | Implemented |
Automatic next chaining after safe persistence |
Planned |
Workflow iteration command (state:iterate successor) |
Planned here, not in async |
| Explorer, place/transition tables, diagram icons and Twig helpers | Planned optional integration |
| State-bundle migration and deprecation | After validated replacements and migration documentation |
The first example is the packages workflow: metadata and README fetching on separate queues, with ordinary validation between them. Start with the example in mono. Its test suite also runs this bundle's tests. The next application checkpoints are packages, searchbench and harvest; these applications have not been migrated by this scaffold.
From a standalone bundle checkout, composer install followed by composer test
runs its focused attribute/selector tests. The mono example additionally tests
native discovery and real Messenger execution with both bundles enabled.