@@ -289,6 +289,214 @@ what actions are allowed on a blog post::
289
289
// See a specific available transition for the post in the current state
290
290
$transition = $workflow->getEnabledTransition($post, 'publish');
291
291
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
+
292
500
Using a multiple state marking store
293
501
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
294
502
@@ -1373,3 +1581,5 @@ Learn more
1373
1581
1374
1582
/workflow/workflow-and-state-machine
1375
1583
/workflow/dumping-workflows
1584
+
1585
+ .. _`glob patterns` : https://php.net/glob
0 commit comments