Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit54af6fa

Browse files
committed
[Workflow] Add support for Backed Enum inMethodMarkingStore
| Q | A| ------------- | ---| Branch? | 7.3| Bug fix? | no| New feature? | yes| Deprecations? | no| Issues | Kind of relates to#44211| License | MITSupporting Enums in Workflow (and overall in Symfony) is a highly debated topic. While using Enums is not always a good choice, I personally found that Backed Enums are really suited for status and places because they ensure type safety in your model and naturally validate the set of allowed values. This is why I think supporting them in Workflow could be nice if not too complicated.While trying to implementing this in my current project using custom code, I figured we could go with a really narrow scope to support them out-of-the-box (but only for Single State Machine): in such case only `MethodMarkingStore` has to support Enums. In my mind, the way the workflow uses strings internally in the `Marking` is an implementation detail and what really matters to users is being able to control the values stored in their objects.Also, I don’t believe supporting enums for transitions is necessary as they are mostly configuration and validating transitions is already part of the component’s job (and in such case I would recommend using constants anyway).Finally, supporting Enum values in the configuration is not a target at the moment either because it can already be done as one can use `!php/enum` if they are using yaml files or use PHP config and directly use the enums. And improving this experience can be done later on if deemed necessary.Supporting this use case currently requires some boilerplate in the user project (with a dedicated getter for instance). Or completely reimplementing a marking store.Therefore I’m sharing what is in my mind a small patch that can greatly improve the situation for users as it allows them to use Backed Enums in their model right away with their getters (ideally we would not need this patch but as PHP will not allow Enums to implement `\Stringable` soon we need to do it ourself).The complicated part could be the setters but now that PHP supports union types we can only document how users can support them:```phpclass MyObject { // ... private ObjectStatus $status = ObjectStatus::Draft; public function getStatus(): ObjectStatus { return $this->status; } public function setStatus(ObjectStatus|string $status): static { if (\is_string($status)) { $status = ObjectStatus::from($status); } $this->status = $status; return $this; }}```
1 parent1a8b82e commit54af6fa

File tree

5 files changed

+50
-2
lines changed

5 files changed

+50
-2
lines changed

‎src/Symfony/Component/Workflow/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
CHANGELOG
22
=========
33

4+
7.3
5+
---
6+
* Add support for Backed Enum in`MethodMarkingStore`
7+
48
7.1
59
---
610

‎src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ public function getMarking(object $subject): Marking
6464
}
6565

6666
if ($this->singleState) {
67+
if ($markinginstanceof \BackedEnum) {
68+
$marking =$marking->value;
69+
}
70+
6771
$marking = [(string)$marking =>1];
6872
}elseif (!\is_array($marking)) {
6973
thrownewLogicException(\sprintf('The marking stored in "%s::$%s" is not an array and the Workflow\'s Marking store is instantiated with $singleState=false.',get_debug_type($subject),$this->property));

‎src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
usePHPUnit\Framework\TestCase;
1515
useSymfony\Component\Workflow\MarkingStore\MethodMarkingStore;
1616
useSymfony\Component\Workflow\Tests\Subject;
17+
useSymfony\Component\Workflow\Tests\TestEnum;
1718

1819
class MethodMarkingStoreTestextends TestCase
1920
{
@@ -84,6 +85,24 @@ public function testGetMarkingWithValueObject()
8485
$this->assertSame('first_place', (string)$subject->getMarking());
8586
}
8687

88+
publicfunctiontestGetMarkingWithBackedEnum()
89+
{
90+
$subject =newSubject(TestEnum::Foo);
91+
92+
$markingStore =newMethodMarkingStore(true);
93+
94+
$marking =$markingStore->getMarking($subject);
95+
96+
$this->assertCount(1,$marking->getPlaces());
97+
$this->assertSame(['foo' =>1],$marking->getPlaces());
98+
99+
$marking->mark('bar');
100+
$marking->unmark('foo');
101+
$markingStore->setMarking($subject,$marking);
102+
103+
$this->assertSame(TestEnum::Bar,$subject->getMarking());
104+
}
105+
87106
publicfunctiontestGetMarkingWithUninitializedProperty()
88107
{
89108
$subject =newSubjectWithType();

‎src/Symfony/Component/Workflow/Tests/Subject.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,21 +13,24 @@
1313

1414
finalclass Subject
1515
{
16-
privatestring|array|null$marking;
16+
privatestring|array|\BackedEnum|null$marking;
1717
privatearray$context = [];
1818

1919
publicfunction__construct($marking =null)
2020
{
2121
$this->marking =$marking;
2222
}
2323

24-
publicfunctiongetMarking():string|array|null
24+
publicfunctiongetMarking():string|array|\BackedEnum|null
2525
{
2626
return$this->marking;
2727
}
2828

2929
publicfunctionsetMarking($marking,array$context = []):void
3030
{
31+
if (\is_string($marking) &&$newMarking = TestEnum::tryFrom($marking)) {
32+
$marking =$newMarking;
33+
}
3134
$this->marking =$marking;
3235
$this->context =$context;
3336
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespaceSymfony\Component\Workflow\Tests;
13+
14+
enum TestEnum:string
15+
{
16+
case Foo ='foo';
17+
case Bar ='bar';
18+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp