Skip to content

[Workflow] make $registry->get(Entity::class) consistent with the doctrine way (by using class name) #37883

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Symfony/Component/Workflow/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ CHANGELOG
* Dispatch an event when the subject enters in the workflow for the very first time
* Added a default context to the previous event
* Added support for specifying which events should be dispatched when calling `workflow->apply()`
* It is now possible to retrieve a workflow by using a class name

5.1.0
-----
Expand Down
19 changes: 15 additions & 4 deletions src/Symfony/Component/Workflow/Registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public function has(object $subject, string $workflowName = null): bool
/**
* @return Workflow
*/
public function get(object $subject, string $workflowName = null)
public function get($subject, string $workflowName = null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC break as the class is not final.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still a BC break.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oups, I deleted my comment unintentionally.

Anyway, I'm new to this. I don't understand what kind of path you want me to take.

Should I, for example :

  1. create another method
  2. deprecate this one

And that case, how can I have the consistency I am looking for (which only goes through this BC Breaks) ?

{
$matched = [];

Expand All @@ -51,16 +51,21 @@ public function get(object $subject, string $workflowName = null)
}
}

if (\is_string($subject)) {
$type = $subject;
} else {
$type = get_debug_type($subject);
}
if (!$matched) {
throw new InvalidArgumentException(sprintf('Unable to find a workflow for class "%s".', get_debug_type($subject)));
throw new InvalidArgumentException(sprintf('Unable to find a workflow for class "%s".', $type));
}

if (2 <= \count($matched)) {
$names = array_map(static function (WorkflowInterface $workflow): string {
return $workflow->getName();
}, $matched);

throw new InvalidArgumentException(sprintf('Too many workflows (%s) match this subject (%s); set a different name on each and use the second (name) argument of this method.', implode(', ', $names), get_debug_type($subject)));
throw new InvalidArgumentException(sprintf('Too many workflows (%s) match this subject (%s); set a different name on each and use the second (name) argument of this method.', implode(', ', $names), $type));
}

return $matched[0];
Expand All @@ -81,12 +86,18 @@ public function all(object $subject): array
return $matched;
}

private function supports(WorkflowInterface $workflow, WorkflowSupportStrategyInterface $supportStrategy, object $subject, ?string $workflowName): bool
private function supports(WorkflowInterface $workflow, WorkflowSupportStrategyInterface $supportStrategy, $subject, ?string $workflowName): bool
{
if (null !== $workflowName && $workflowName !== $workflow->getName()) {
return false;
}

if (\is_string($subject)) {
$stdClass = new \stdClass();
$stdClass->class = $subject;
$subject = $stdClass;
}

return $supportStrategy->supports($workflow, $subject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\Workflow\WorkflowInterface;

/**
* @author Carlos Pereira De Amorim <carlos@shauri.fr>
* @author Andreas Kleemann <akleemann@inviqa.com>
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
*/
Expand All @@ -31,6 +32,10 @@ public function __construct(string $className)
*/
public function supports(WorkflowInterface $workflow, object $subject): bool
{
if ($subject instanceof \stdClass && property_exists($subject, 'class')) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really worth it?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consistency is part of a good programming. Unfortunately, it is not PHP's strong suit.

I'm not a big fan of this.

Might not be worth it, indeed.

return $subject->class === $this->className;
}

return $subject instanceof $this->className;
}

Expand Down
13 changes: 12 additions & 1 deletion src/Symfony/Component/Workflow/Tests/RegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ public function testGetWithSuccess()
$this->assertSame('workflow2', $workflow->getName());
}

public function testGetWithSuccessFromClassName()
{
$workflow = $this->registry->get(Subject1::class);
$this->assertInstanceOf(Workflow::class, $workflow);
$this->assertSame('workflow1', $workflow->getName());
}

public function testGetWithMultipleMatch()
{
$this->expectException('Symfony\Component\Workflow\Exception\InvalidArgumentException');
Expand Down Expand Up @@ -102,7 +109,11 @@ private function createWorkflowSupportStrategy($supportedClassName)
{
$strategy = $this->getMockBuilder(WorkflowSupportStrategyInterface::class)->getMock();
$strategy->expects($this->any())->method('supports')
->willReturnCallback(function ($workflow, $subject) use ($supportedClassName) {
->willReturnCallback(function ($workflow, object $subject) use ($supportedClassName) {
if ($subject instanceof \stdClass && property_exists($subject, 'class')) {
return $subject->class === $supportedClassName;
}

return $subject instanceof $supportedClassName;
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,21 @@ public function testSupportsIfClassInstance()
$strategy = new InstanceOfSupportStrategy(Subject1::class);

$this->assertTrue($strategy->supports($this->createWorkflow(), new Subject1()));

$stdClass = new \StdClass();
$stdClass->class = Subject1::class;
$this->assertTrue($strategy->supports($this->createWorkflow(), $stdClass));
}

public function testSupportsIfNotClassInstance()
{
$strategy = new InstanceOfSupportStrategy(Subject2::class);

$this->assertFalse($strategy->supports($this->createWorkflow(), new Subject1()));

$stdClass = new \StdClass();
$stdClass->class = Subject1::class;
$this->assertFalse($strategy->supports($this->createWorkflow(), $stdClass));
}

private function createWorkflow()
Expand Down