From 62740c8752fda1c00d03dedf9112cab8d329be3a Mon Sep 17 00:00:00 2001 From: Nicolas Rigaud Date: Thu, 14 Mar 2024 16:33:10 +0100 Subject: [PATCH] [Workflow] Add EventNameTrait to compute event name strings --- .../Workflow/Event/AnnounceEvent.php | 3 + .../Workflow/Event/CompletedEvent.php | 4 ++ .../Component/Workflow/Event/EnterEvent.php | 3 + .../Component/Workflow/Event/EnteredEvent.php | 3 + .../Workflow/Event/EventNameTrait.php | 52 +++++++++++++++ .../Component/Workflow/Event/GuardEvent.php | 4 ++ .../Component/Workflow/Event/LeaveEvent.php | 3 + .../Workflow/Event/TransitionEvent.php | 3 + .../Tests/Event/EventNameTraitTest.php | 64 +++++++++++++++++++ 9 files changed, 139 insertions(+) create mode 100644 src/Symfony/Component/Workflow/Event/EventNameTrait.php create mode 100644 src/Symfony/Component/Workflow/Tests/Event/EventNameTraitTest.php diff --git a/src/Symfony/Component/Workflow/Event/AnnounceEvent.php b/src/Symfony/Component/Workflow/Event/AnnounceEvent.php index 0c675a4854dcd..6fc7c8f85ea87 100644 --- a/src/Symfony/Component/Workflow/Event/AnnounceEvent.php +++ b/src/Symfony/Component/Workflow/Event/AnnounceEvent.php @@ -18,6 +18,9 @@ final class AnnounceEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForTransition as public get; + } public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Event/CompletedEvent.php b/src/Symfony/Component/Workflow/Event/CompletedEvent.php index 63a5e44836b2c..cc702c2f03562 100644 --- a/src/Symfony/Component/Workflow/Event/CompletedEvent.php +++ b/src/Symfony/Component/Workflow/Event/CompletedEvent.php @@ -18,6 +18,10 @@ final class CompletedEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForTransition as public get; + } + public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Event/EnterEvent.php b/src/Symfony/Component/Workflow/Event/EnterEvent.php index 46213d48ff466..4c088c71e56e8 100644 --- a/src/Symfony/Component/Workflow/Event/EnterEvent.php +++ b/src/Symfony/Component/Workflow/Event/EnterEvent.php @@ -18,6 +18,9 @@ final class EnterEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForPlace as public get; + } public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Event/EnteredEvent.php b/src/Symfony/Component/Workflow/Event/EnteredEvent.php index 17529b8a4d801..19368373ed08b 100644 --- a/src/Symfony/Component/Workflow/Event/EnteredEvent.php +++ b/src/Symfony/Component/Workflow/Event/EnteredEvent.php @@ -18,6 +18,9 @@ final class EnteredEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForPlace as public get; + } public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Event/EventNameTrait.php b/src/Symfony/Component/Workflow/Event/EventNameTrait.php new file mode 100644 index 0000000000000..f03a203f4bd6c --- /dev/null +++ b/src/Symfony/Component/Workflow/Event/EventNameTrait.php @@ -0,0 +1,52 @@ + + */ +trait EventNameTrait +{ + /** + * Get the event name as lowercase string. + * + * Example: EnterEvent => enter + * + * @return string + */ + public static function getName(): string + { + return \strtolower(\substr(\substr(static::class, \strrpos(static::class, '\\') + 1), 0, -5)); + } + + /** + * Get event name for workflow and transition. + * + * @throws InvalidArgumentException If $transitionName is provided without $workflowName + */ + private static function getNameForTransition(string|null $workflowName, string|null $transitionName): string + { + return self::computeName($workflowName, $transitionName); + } + + /** + * Get event name for workflow and place. + * + * @throws InvalidArgumentException If $placeName is provided without $workflowName + */ + private static function getNameForPlace(string|null $workflowName, string|null $placeName): string + { + return self::computeName($workflowName, $placeName); + } + + private static function computeName(string|null $workflowName, string|null $transitionOrPlaceName): string + { + if (null !== $transitionOrPlaceName && null === $workflowName) { + throw new \InvalidArgumentException('Missing workflow name.'); + } + + return implode('.', \array_filter(['workflow', $workflowName, self::getName(), $transitionOrPlaceName], \is_string(...))); + } +} \ No newline at end of file diff --git a/src/Symfony/Component/Workflow/Event/GuardEvent.php b/src/Symfony/Component/Workflow/Event/GuardEvent.php index 68a57a979b503..e4b6a38ac1e79 100644 --- a/src/Symfony/Component/Workflow/Event/GuardEvent.php +++ b/src/Symfony/Component/Workflow/Event/GuardEvent.php @@ -23,6 +23,10 @@ */ final class GuardEvent extends Event { + use EventNameTrait { + getNameForTransition as public get; + } + private TransitionBlockerList $transitionBlockerList; public function __construct(object $subject, Marking $marking, Transition $transition, ?WorkflowInterface $workflow = null) diff --git a/src/Symfony/Component/Workflow/Event/LeaveEvent.php b/src/Symfony/Component/Workflow/Event/LeaveEvent.php index ca7ff1aa1af0a..b5d4fc4d5214d 100644 --- a/src/Symfony/Component/Workflow/Event/LeaveEvent.php +++ b/src/Symfony/Component/Workflow/Event/LeaveEvent.php @@ -18,6 +18,9 @@ final class LeaveEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForPlace as public get; + } public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Event/TransitionEvent.php b/src/Symfony/Component/Workflow/Event/TransitionEvent.php index 6bae1595c86f3..332df48e02812 100644 --- a/src/Symfony/Component/Workflow/Event/TransitionEvent.php +++ b/src/Symfony/Component/Workflow/Event/TransitionEvent.php @@ -18,6 +18,9 @@ final class TransitionEvent extends Event { use HasContextTrait; + use EventNameTrait { + getNameForTransition as public get; + } public function __construct(object $subject, Marking $marking, ?Transition $transition = null, ?WorkflowInterface $workflow = null, array $context = []) { diff --git a/src/Symfony/Component/Workflow/Tests/Event/EventNameTraitTest.php b/src/Symfony/Component/Workflow/Tests/Event/EventNameTraitTest.php new file mode 100644 index 0000000000000..9d84fe6e0153e --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/Event/EventNameTraitTest.php @@ -0,0 +1,64 @@ +assertEquals($expected, $name); + } + + public static function getEvents(): iterable + { + yield [AnnounceEvent::class, null, null, 'workflow.announce']; + yield [AnnounceEvent::class, 'post', null, 'workflow.post.announce']; + yield [AnnounceEvent::class, 'post', 'publish', 'workflow.post.announce.publish']; + + yield [CompletedEvent::class, null, null, 'workflow.completed']; + yield [CompletedEvent::class, 'post', null, 'workflow.post.completed']; + yield [CompletedEvent::class, 'post', 'publish', 'workflow.post.completed.publish']; + + yield [EnteredEvent::class, null, null, 'workflow.entered']; + yield [EnteredEvent::class, 'post', null, 'workflow.post.entered']; + yield [EnteredEvent::class, 'post', 'published', 'workflow.post.entered.published']; + + yield [EnterEvent::class, null, null, 'workflow.enter']; + yield [EnterEvent::class, 'post', null, 'workflow.post.enter']; + yield [EnterEvent::class, 'post', 'published', 'workflow.post.enter.published']; + + yield [GuardEvent::class, null, null, 'workflow.guard']; + yield [GuardEvent::class, 'post', null, 'workflow.post.guard']; + yield [GuardEvent::class, 'post', 'publish', 'workflow.post.guard.publish']; + + yield [LeaveEvent::class, null, null, 'workflow.leave']; + yield [LeaveEvent::class, 'post', null, 'workflow.post.leave']; + yield [LeaveEvent::class, 'post', 'published', 'workflow.post.leave.published']; + + yield [TransitionEvent::class, null, null, 'workflow.transition']; + yield [TransitionEvent::class, 'post', null, 'workflow.post.transition']; + yield [TransitionEvent::class, 'post', 'publish', 'workflow.post.transition.publish']; + } + + public function testInvalidArgumentExceptionIsThrownIfWorkflowNameIsMissing() + { + $this->expectException(\InvalidArgumentException::class); + + EnterEvent::get(null, 'place'); + } +} \ No newline at end of file