From 7be6124f6b19941c7387d046b62187a199680bb6 Mon Sep 17 00:00:00 2001 From: omasn Date: Fri, 12 May 2023 23:42:06 +0300 Subject: [PATCH 1/2] Supported "Marking" enum php --- src/Symfony/Component/Workflow/Marking.php | 58 +++++++++++++------ .../MarkingStore/MethodMarkingStore.php | 36 +++++++++--- .../Component/Workflow/Tests/MarkingEnum.php | 17 ++++++ .../MarkingStore/MethodMarkingStoreTest.php | 23 ++++++++ .../Component/Workflow/Tests/Subject.php | 2 +- 5 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 src/Symfony/Component/Workflow/Tests/MarkingEnum.php diff --git a/src/Symfony/Component/Workflow/Marking.php b/src/Symfony/Component/Workflow/Marking.php index 95a83f0cfd243..528017a3d692b 100644 --- a/src/Symfony/Component/Workflow/Marking.php +++ b/src/Symfony/Component/Workflow/Marking.php @@ -18,11 +18,15 @@ */ class Marking { + /** + * @var array + */ private array $places = []; + private array $enumPlaces = []; private ?array $context = null; /** - * @param int[] $representation Keys are the place name and values should be 1 + * @param array $representation Keys are the place name and values should be 1 */ public function __construct(array $representation = []) { @@ -31,36 +35,43 @@ public function __construct(array $representation = []) } } - /** - * @return void - */ - public function mark(string $place) + public function mark(string|\UnitEnum $place): void + { + $key = $this->placeToKey($place); + $this->places[$key] = 1; + if ($place instanceof \UnitEnum) { + $this->enumPlaces[$key] = $place; + } + } + + public function unmark(string|\UnitEnum $place): void { - $this->places[$place] = 1; + $key = $this->placeToKey($place); + unset( + $this->places[$key], + $this->enumPlaces[$key] + ); } - /** - * @return void - */ - public function unmark(string $place) + public function has(string|\UnitEnum $place): bool { - unset($this->places[$place]); + return isset($this->places[$this->placeToKey($place)]); } /** - * @return bool + * @return array */ - public function has(string $place) + public function getPlaces(): array { - return isset($this->places[$place]); + return $this->places; } /** - * @return array + * @return array */ - public function getPlaces() + public function getEnumPlaces(): array { - return $this->places; + return $this->enumPlaces; } /** @@ -78,4 +89,17 @@ public function getContext(): ?array { return $this->context; } + + private function placeToKey(string|\UnitEnum $place): string + { + if (is_string($place)) { + return $place; + } + + if ($place instanceof \BackedEnum) { + return (string)$place->value; + } + + return $place->name; + } } diff --git a/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php index 78d3307e6ac6c..f413b7dfd0b0f 100644 --- a/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php +++ b/src/Symfony/Component/Workflow/MarkingStore/MethodMarkingStore.php @@ -66,20 +66,42 @@ public function getMarking(object $subject): Marking } if ($this->singleState) { - $marking = [(string) $marking => 1]; - } elseif (!\is_array($marking)) { + $result = new Marking(); + $result->mark($marking); + + return $result; + } + + if (!\is_array($marking)) { throw new LogicException(sprintf('The method "%s::%s()" did not return an array and the Workflow\'s Marking store is instantiated with $singleState=false.', get_debug_type($subject), $method)); } - return new Marking($marking); + $result = new Marking(); + foreach ($marking as $place => $nbTokenOrEnum) { + if ($nbTokenOrEnum instanceof \UnitEnum) { + $result->mark($nbTokenOrEnum); + } else { + $result->mark($place); + } + } + + return $result; } public function setMarking(object $subject, Marking $marking, array $context = []): void { - $marking = $marking->getPlaces(); - - if ($this->singleState) { - $marking = key($marking); + $enumPlaces = $marking->getEnumPlaces(); + if ([] !== $enumPlaces) { + if ($this->singleState) { + $marking = array_values($enumPlaces)[0]; + } else { + $marking = $enumPlaces; + } + } else { + $marking = $marking->getPlaces(); + if ($this->singleState) { + $marking = key($marking); + } } $method = 'set'.ucfirst($this->property); diff --git a/src/Symfony/Component/Workflow/Tests/MarkingEnum.php b/src/Symfony/Component/Workflow/Tests/MarkingEnum.php new file mode 100644 index 0000000000000..0b2cc9e7f70a1 --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/MarkingEnum.php @@ -0,0 +1,17 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\Tests; + +enum MarkingEnum: int +{ + case FIRST_PLACE = 1; +} diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php index 34dbd3bd2d24f..83f6114482d4d 100644 --- a/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php +++ b/src/Symfony/Component/Workflow/Tests/MarkingStore/MethodMarkingStoreTest.php @@ -14,6 +14,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Workflow\Marking; use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore; +use Symfony\Component\Workflow\Tests\MarkingEnum; use Symfony\Component\Workflow\Tests\Subject; class MethodMarkingStoreTest extends TestCase @@ -111,6 +112,28 @@ public function testGetMarkingWithUninitializedProperty2() $markingStore->getMarking($subject); } + public function testGetSetMarkingWithSingleEnumState() + { + $subject = new Subject(); + + $markingStore = new MethodMarkingStore(true); + + $marking = $markingStore->getMarking($subject); + + $this->assertInstanceOf(Marking::class, $marking); + $this->assertCount(0, $marking->getPlaces()); + + $marking->mark(MarkingEnum::FIRST_PLACE); + + $markingStore->setMarking($subject, $marking); + + $this->assertSame(MarkingEnum::FIRST_PLACE, $subject->getMarking()); + + $marking2 = $markingStore->getMarking($subject); + + $this->assertEquals($marking, $marking2); + } + private function createValueObject(string $markingValue): object { return new class($markingValue) { diff --git a/src/Symfony/Component/Workflow/Tests/Subject.php b/src/Symfony/Component/Workflow/Tests/Subject.php index 6dd76e1ec51b7..59d56b811b133 100644 --- a/src/Symfony/Component/Workflow/Tests/Subject.php +++ b/src/Symfony/Component/Workflow/Tests/Subject.php @@ -22,7 +22,7 @@ public function __construct($marking = null) $this->context = []; } - public function getMarking(): string|array|null + public function getMarking(): string|array|null|MarkingEnum { return $this->marking; } From 9db3a3219e2f806277cd45818701572db80c8a40 Mon Sep 17 00:00:00 2001 From: omasn Date: Sat, 13 May 2023 00:12:02 +0300 Subject: [PATCH 2/2] Refactor Marking.php name and types --- src/Symfony/Component/Workflow/Marking.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Symfony/Component/Workflow/Marking.php b/src/Symfony/Component/Workflow/Marking.php index 528017a3d692b..e4ca1a5f4e0da 100644 --- a/src/Symfony/Component/Workflow/Marking.php +++ b/src/Symfony/Component/Workflow/Marking.php @@ -22,6 +22,9 @@ class Marking * @var array */ private array $places = []; + /** + * @var array + */ private array $enumPlaces = []; private ?array $context = null; @@ -37,7 +40,7 @@ public function __construct(array $representation = []) public function mark(string|\UnitEnum $place): void { - $key = $this->placeToKey($place); + $key = $this->enumOrStringToKey($place); $this->places[$key] = 1; if ($place instanceof \UnitEnum) { $this->enumPlaces[$key] = $place; @@ -46,7 +49,7 @@ public function mark(string|\UnitEnum $place): void public function unmark(string|\UnitEnum $place): void { - $key = $this->placeToKey($place); + $key = $this->enumOrStringToKey($place); unset( $this->places[$key], $this->enumPlaces[$key] @@ -55,7 +58,7 @@ public function unmark(string|\UnitEnum $place): void public function has(string|\UnitEnum $place): bool { - return isset($this->places[$this->placeToKey($place)]); + return isset($this->places[$this->enumOrStringToKey($place)]); } /** @@ -67,7 +70,7 @@ public function getPlaces(): array } /** - * @return array + * @return array */ public function getEnumPlaces(): array { @@ -90,7 +93,7 @@ public function getContext(): ?array return $this->context; } - private function placeToKey(string|\UnitEnum $place): string + private function enumOrStringToKey(string|\UnitEnum $place): string { if (is_string($place)) { return $place;