@@ -289,6 +289,214 @@ what actions are allowed on a blog post::
289289 // See a specific available transition for the post in the current state
290290 $transition = $workflow->getEnabledTransition($post, 'publish');
291291
292+ Using Enums as Workflow Places
293+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294+
295+ When using a state machine, you can use PHP backend enums as places in your workflows:
296+
297+ .. versionadded :: 7.4
298+
299+ The support for PHP backed enums as workflow places was introduced with Symfony 7.4.
300+
301+ First, define your enum with backed values::
302+
303+ // src/Enumeration/BlogPostStatus.php
304+ namespace App\Enumeration;
305+
306+ enum BlogPostStatus: string
307+ {
308+ case Draft = 'draft';
309+ case Reviewed = 'reviewed';
310+ case Published = 'published';
311+ case Rejected = 'rejected';
312+ }
313+
314+ Then configure the workflow using the enum cases as places, initial marking,
315+ and transitions:
316+
317+ .. configuration-block ::
318+
319+ .. code-block :: yaml
320+
321+ # config/packages/workflow.yaml
322+ framework :
323+ workflows :
324+ blog_publishing :
325+ type : ' workflow'
326+ marking_store :
327+ type : ' method'
328+ property : ' status'
329+ supports :
330+ - App\Entity\BlogPost
331+ initial_marking : !php/enum App\Enumeration\BlogPostStatus::Draft
332+ places : !php/enum App\Enumeration\BlogPostStatus
333+ transitions :
334+ to_review :
335+ from : !php/enum App\Enumeration\BlogPostStatus::Draft
336+ to : !php/enum App\Enumeration\BlogPostStatus::Reviewed
337+ publish :
338+ from : !php/enum App\Enumeration\BlogPostStatus::Reviewed
339+ to : !php/enum App\Enumeration\BlogPostStatus::Published
340+ reject :
341+ from : !php/enum App\Enumeration\BlogPostStatus::Reviewed
342+ to : !php/enum App\Enumeration\BlogPostStatus::Rejected
343+
344+ .. code-block :: xml
345+
346+ <!-- config/packages/workflow.xml -->
347+ <?xml version =" 1.0" encoding =" UTF-8" ?>
348+ <container xmlns =" http://symfony.com/schema/dic/services"
349+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
350+ xmlns : framework =" http://symfony.com/schema/dic/symfony"
351+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
352+ https://symfony.com/schema/dic/services/services-1.0.xsd
353+ http://symfony.com/schema/dic/symfony
354+ https://symfony.com/schema/dic/symfony/symfony-1.0.xsd" >
355+
356+ <framework : config >
357+ <!-- or type="state_machine" -->
358+ <framework : workflow name =" blog_publishing" type =" workflow" places =" App\Enumeration\BlogPostStatus::*" >
359+ <framework : marking-store type =" single_state" >
360+ <framework : argument >status</framework : argument >
361+ </framework : marking-store >
362+ <framework : support >App\Entity\BlogPost</framework : support >
363+ <framework : initial-marking >draft</framework : initial-marking >
364+
365+ <framework : transition name =" to_review" >
366+ <framework : from >draft</framework : from >
367+ <framework : to >reviewed</framework : to >
368+ </framework : transition >
369+ <framework : transition name =" publish" >
370+ <framework : from >reviewed</framework : from >
371+ <framework : to >published</framework : to >
372+ </framework : transition >
373+ <framework : transition name =" reject" >
374+ <framework : from >reviewed</framework : from >
375+ <framework : to >rejected</framework : to >
376+ </framework : transition >
377+ </framework : workflow >
378+ </framework : config >
379+ </container >
380+
381+ .. code-block :: php
382+
383+ // config/packages/workflow.php
384+ use App\Entity\BlogPost;
385+ use App\Enumeration\BlogPostStatus;
386+ use Symfony\Config\FrameworkConfig;
387+
388+ return static function (FrameworkConfig $framework): void {
389+ $blogPublishing = $framework->workflows()->workflows('blog_publishing');
390+ $blogPublishing
391+ ->type('workflow')
392+ ->supports([BlogPost::class])
393+ ->initialMarking([BlogPostStatus::Draft]);
394+
395+ $blogPublishing->markingStore()
396+ ->type('method')
397+ ->property('status');
398+
399+ $blogPublishing->places(BlogPostStatus::cases());
400+
401+ $blogPublishing->transition()
402+ ->name('to_review')
403+ ->from(BlogPostStatus::Draft)
404+ ->to([BlogPostStatus::Reviewed]);
405+
406+ $blogPublishing->transition()
407+ ->name('publish')
408+ ->from([BlogPostStatus::Reviewed])
409+ ->to([BlogPostStatus::Published]);
410+
411+ $blogPublishing->transition()
412+ ->name('reject')
413+ ->from([BlogPostStatus::Reviewed])
414+ ->to([BlogPostStatus::Rejected]);
415+ };
416+
417+ The component will now transparently cast the enum to its backing value
418+ when needed and vice-versa when working with your objects::
419+
420+ // src/Entity/BlogPost.php
421+ namespace App\Entity;
422+
423+ class BlogPost
424+ {
425+ private BlogPostStatus $status;
426+
427+ public function getStatus(): BlogPostStatus
428+ {
429+ return $this->status;
430+ }
431+
432+ public function setStatus(BlogPostStatus $status): void
433+ {
434+ $this->status = $status;
435+ }
436+ }
437+
438+ .. tip ::
439+
440+ You can also use `glob patterns `_ of PHP constants and enums to list the places:
441+
442+ .. configuration-block ::
443+
444+ .. code-block :: yaml
445+
446+ # config/packages/workflow.yaml
447+ framework :
448+ workflows :
449+ my_workflow_name :
450+ # with constants:
451+ places : ' App\Workflow\MyWorkflow::PLACE_*'
452+
453+ # with enums:
454+ places : !php/enum App\Workflow\Places
455+
456+ # ...
457+
458+ .. code-block :: xml
459+
460+ <!-- config/packages/workflow.xml -->
461+ <?xml version =" 1.0" encoding =" UTF-8" ?>
462+ <container xmlns =" http://symfony.com/schema/dic/services"
463+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
464+ xmlns : framework =" http://symfony.com/schema/dic/symfony"
465+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
466+ https://symfony.com/schema/dic/services/services-1.0.xsd
467+ http://symfony.com/schema/dic/symfony
468+ https://symfony.com/schema/dic/symfony/symfony-1.0.xsd" >
469+
470+ <framework : config >
471+ <framework : workflow name =" my_workflow_name" type =" ..."
472+ <!-- with constants: -->
473+ places="App\Workflow\MyWorkflow::PLACE_*"
474+ <!-- with enums: -->
475+ places="App\Enumeration\BlogPostStatus::*">
476+ <!-- ... -->
477+ </framework : workflow >
478+ </framework : config >
479+ </container >
480+
481+ .. code-block :: php
482+
483+ // config/packages/workflow.php
484+ use App\Entity\BlogPost;
485+ use App\Enumeration\BlogPostStatus;
486+ use Symfony\Config\FrameworkConfig;
487+
488+ return static function (FrameworkConfig $framework): void {
489+ $blogPublishing = $framework->workflows()->workflows('my_workflow_name');
490+
491+ // with constants:
492+ $blogPublishing->places('App\Workflow\MyWorkflow::PLACE_*');
493+
494+ // with enums:
495+ $blogPublishing->places(BlogPostStatus::cases());
496+
497+ // ...
498+ };
499+
292500 Using a multiple state marking store
293501~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294502
@@ -1373,3 +1581,5 @@ Learn more
13731581
13741582 /workflow/workflow-and-state-machine
13751583 /workflow/dumping-workflows
1584+
1585+ .. _`glob patterns` : https://php.net/glob
0 commit comments