@@ -294,6 +294,154 @@ what actions are allowed on a blog post::
294294 // See a specific available transition for the post in the current state
295295 $transition = $workflow->getEnabledTransition($post, 'publish');
296296
297+ .. tip ::
298+
299+ In some specific cases, using PHP enums as places in your workflows might
300+ make sense and one can use them seamlessly with the Workflow component if
301+ they uses backed enumerations.
302+
303+ .. versionadded :: 7.4
304+
305+ The support for PHP Backed enumerations as Workflow places was
306+ introduced with Symfony 7.4.
307+
308+ First, define your enum with backed values::
309+
310+ // src/Enumeration/BlogPostStatus.php
311+ namespace App\Enumeration;
312+
313+ enum BlogPostStatus: string
314+ {
315+ case Draft = 'draft';
316+ case Reviewed = 'reviewed';
317+ case Published = 'published';
318+ case Rejected = 'rejected';
319+ }
320+
321+ Then configure the workflow using the enum cases as places, initial
322+ marking, and transitions:
323+
324+ .. configuration-block ::
325+
326+ .. code-block :: yaml
327+
328+ # config/packages/workflow.yaml
329+ framework :
330+ workflows :
331+ blog_publishing :
332+ type : ' workflow'
333+ marking_store :
334+ type : ' method'
335+ property : ' status'
336+ supports :
337+ - App\Entity\BlogPost
338+ initial_marking : !php/enum App\Enumeration\BlogPostStatus::Draft
339+ places : !php/enum App\Enumeration\BlogPostStatus
340+ transitions :
341+ to_review :
342+ from : !php/enum App\Enumeration\BlogPostStatus::Draft
343+ to : !php/enum App\Enumeration\BlogPostStatus::Reviewed
344+ publish :
345+ from : !php/enum App\Enumeration\BlogPostStatus::Reviewed
346+ to : !php/enum App\Enumeration\BlogPostStatus::Published
347+ reject :
348+ from : !php/enum App\Enumeration\BlogPostStatus::Reviewed
349+ to : !php/enum App\Enumeration\BlogPostStatus::Rejected
350+
351+ .. code-block :: xml
352+
353+ <!-- config/packages/workflow.xml -->
354+ <?xml version =" 1.0" encoding =" UTF-8" ?>
355+ <container xmlns =" http://symfony.com/schema/dic/services"
356+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
357+ xmlns : framework =" http://symfony.com/schema/dic/symfony"
358+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
359+ https://symfony.com/schema/dic/services/services-1.0.xsd
360+ http://symfony.com/schema/dic/symfony
361+ https://symfony.com/schema/dic/symfony/symfony-1.0.xsd" >
362+
363+ <framework : config >
364+ <!-- or type="state_machine" -->
365+ <framework : workflow name =" blog_publishing" type =" workflow" places =" App\Enumeration\BlogPostStatus::*" >
366+ <framework : marking-store type =" single_state" >
367+ <framework : argument >status</framework : argument >
368+ </framework : marking-store >
369+ <framework : support >App\Entity\BlogPost</framework : support >
370+ <framework : initial-marking >draft</framework : initial-marking >
371+
372+ <framework : transition name =" to_review" >
373+ <framework : from >draft</framework : from >
374+ <framework : to >reviewed</framework : to >
375+ </framework : transition >
376+ <framework : transition name =" publish" >
377+ <framework : from >reviewed</framework : from >
378+ <framework : to >published</framework : to >
379+ </framework : transition >
380+ <framework : transition name =" reject" >
381+ <framework : from >reviewed</framework : from >
382+ <framework : to >rejected</framework : to >
383+ </framework : transition >
384+ </framework : workflow >
385+ </framework : config >
386+ </container >
387+
388+ .. code-block :: php
389+
390+ // config/packages/workflow.php
391+ use App\Entity\BlogPost;
392+ use App\Enumeration\BlogPostStatus;
393+ use Symfony\Config\FrameworkConfig;
394+
395+ return static function (FrameworkConfig $framework): void {
396+ $blogPublishing = $framework->workflows()->workflows('blog_publishing');
397+ $blogPublishing
398+ ->type('workflow')
399+ ->supports([BlogPost::class])
400+ ->initialMarking([BlogPostStatus::Draft]);
401+
402+ $blogPublishing->markingStore()
403+ ->type('method')
404+ ->property('status');
405+
406+ $blogPublishing->places(BlogPostStatus::cases());
407+
408+ $blogPublishing->transition()
409+ ->name('to_review')
410+ ->from(BlogPostStatus::Draft)
411+ ->to([BlogPostStatus::Reviewed]);
412+
413+ $blogPublishing->transition()
414+ ->name('publish')
415+ ->from([BlogPostStatus::Reviewed])
416+ ->to([BlogPostStatus::Published]);
417+
418+ $blogPublishing->transition()
419+ ->name('reject')
420+ ->from([BlogPostStatus::Reviewed])
421+ ->to([BlogPostStatus::Rejected]);
422+ };
423+
424+ The component will now transparently cast the enum to its backing value
425+ when needed and vice-versa when working with your objects::
426+
427+ // src/Entity/BlogPost.php
428+ namespace App\Entity;
429+
430+ class BlogPost
431+ {
432+ private BlogPostStatus $status;
433+
434+ public function getStatus(): BlogPostStatus
435+ {
436+ return $this->status;
437+ }
438+
439+ public function setStatus(BlogPostStatus $status): void
440+ {
441+ $this->status = $status;
442+ }
443+ }
444+
297445Using a multiple state marking store
298446~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
299447
0 commit comments