Skip to content

Commit 4a9dfe1

Browse files
committed
Merge branch '7.4' into 8.0
* 7.4: Tweaks [Workflow] Document backed enum support
2 parents 5fac27f + ef045c6 commit 4a9dfe1

File tree

1 file changed

+210
-0
lines changed

1 file changed

+210
-0
lines changed

workflow.rst

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)