Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 5b38e17

Browse files
committed
feature #29146 [Workflow] Added a context to Workflow::apply() (lyrixx)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Workflow] Added a context to `Workflow::apply()` | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #27925 (maybe #28253 and #28266) | License | MIT | Doc PR | Commits ------- 7d5b7a3 [Workflow] Added a context to `Workflow::apply()`
2 parents f8664e7 + 7d5b7a3 commit 5b38e17

File tree

13 files changed

+176
-13
lines changed

13 files changed

+176
-13
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
268268
->fixXmlConfig('argument')
269269
->children()
270270
->enumNode('type')
271-
->values(['multiple_state', 'single_state'])
271+
->values(['multiple_state', 'single_state', 'method'])
272272
->end()
273273
->arrayNode('arguments')
274274
->beforeNormalization()

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,8 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
614614
$definitionDefinition->addTag('workflow.definition', [
615615
'name' => $name,
616616
'type' => $type,
617-
'marking_store' => isset($workflow['marking_store']['type']) ? $workflow['marking_store']['type'] : null,
617+
'marking_store' => $workflow['marking_store']['type'] ?? null,
618+
'single_state' => 'method' === ($workflow['marking_store']['type'] ?? null) && ($workflow['marking_store']['arguments'][0] ?? false),
618619
]);
619620

620621
// Create MarkingStore

src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
<service id="workflow.marking_store.multiple_state" class="Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore" abstract="true" />
2424
<service id="workflow.marking_store.single_state" class="Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore" abstract="true" />
25+
<service id="workflow.marking_store.method" class="Symfony\Component\Workflow\MarkingStore\MethodMarkingStore" abstract="true" />
2526

2627
<service id="workflow.registry" class="Symfony\Component\Workflow\Registry" />
2728
<service id="Symfony\Component\Workflow\Registry" alias="workflow.registry" />

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ public function testWorkflows()
215215
$workflowDefinition->getArgument(0),
216216
'Places are passed to the workflow definition'
217217
);
218-
$this->assertSame(['workflow.definition' => [['name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state']]], $workflowDefinition->getTags());
218+
$this->assertSame(['workflow.definition' => [['name' => 'article', 'type' => 'workflow', 'marking_store' => 'multiple_state', 'single_state' => false]]], $workflowDefinition->getTags());
219219
$this->assertCount(4, $workflowDefinition->getArgument(1));
220220
$this->assertSame('draft', $workflowDefinition->getArgument(2));
221221

@@ -237,7 +237,7 @@ public function testWorkflows()
237237
$stateMachineDefinition->getArgument(0),
238238
'Places are passed to the state machine definition'
239239
);
240-
$this->assertSame(['workflow.definition' => [['name' => 'pull_request', 'type' => 'state_machine', 'marking_store' => 'single_state']]], $stateMachineDefinition->getTags());
240+
$this->assertSame(['workflow.definition' => [['name' => 'pull_request', 'type' => 'state_machine', 'marking_store' => 'single_state', 'single_state' => false]]], $stateMachineDefinition->getTags());
241241
$this->assertCount(9, $stateMachineDefinition->getArgument(1));
242242
$this->assertSame('start', $stateMachineDefinition->getArgument(2));
243243

src/Symfony/Component/Workflow/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* Trigger `entered` event for subject entering in the Workflow for the first time
8+
* Added a context to `Workflow::apply()`. The `MethodMarkingStore` could be used to leverage this feature.
89

910
4.1.0
1011
-----

src/Symfony/Component/Workflow/DependencyInjection/ValidateWorkflowsPass.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ private function createValidator($tag)
5959
return new WorkflowValidator(true);
6060
}
6161

62-
return new WorkflowValidator();
62+
if ('multiple_state' === $tag['marking_store']) {
63+
return new WorkflowValidator(false);
64+
}
65+
66+
return new WorkflowValidator($tag['single_state'] ?? false);
6367
}
6468
}

src/Symfony/Component/Workflow/MarkingStore/MarkingStoreInterface.php

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ public function getMarking($subject);
3636
/**
3737
* Sets a Marking to a subject.
3838
*
39-
* @param object $subject A subject
40-
* @param Marking $marking A marking
39+
* @param object $subject A subject
4140
*/
42-
public function setMarking($subject, Marking $marking);
41+
public function setMarking($subject, Marking $marking, array $context = []);
4342
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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+
namespace Symfony\Component\Workflow\MarkingStore;
13+
14+
use Symfony\Component\Workflow\Exception\LogicException;
15+
use Symfony\Component\Workflow\Marking;
16+
17+
/**
18+
* MethodMarkingStore stores the marking with a subject's method.
19+
*
20+
* This store deals with a "single state" or "multiple state" Marking.
21+
*
22+
* @author Grégoire Pineau <[email protected]>
23+
*/
24+
class MethodMarkingStore implements MarkingStoreInterface
25+
{
26+
private $singleState;
27+
private $property;
28+
29+
/**
30+
* @param string $property Used to determine methods to call
31+
* The `getMarking` method will use `$subject->getProperty()`
32+
* The `setMarking` method will use `$subject->setProperty(string|array $places, array $context = array())`
33+
*/
34+
public function __construct(bool $singleState = false, string $property = 'marking')
35+
{
36+
$this->singleState = $singleState;
37+
$this->property = $property;
38+
}
39+
40+
/**
41+
* {@inheritdoc}
42+
*/
43+
public function getMarking($subject)
44+
{
45+
$method = 'get'.ucfirst($this->property);
46+
47+
if (!method_exists($subject, $method)) {
48+
throw new LogicException(sprintf('The method "%s::%s()" does not exists.', \get_class($subject), $method));
49+
}
50+
51+
$marking = $subject->{$method}();
52+
53+
if (!$marking) {
54+
return new Marking();
55+
}
56+
57+
if ($this->singleState) {
58+
$marking = [$marking => 1];
59+
}
60+
61+
return new Marking($marking);
62+
}
63+
64+
/**
65+
* {@inheritdoc}
66+
*/
67+
public function setMarking($subject, Marking $marking, array $context = [])
68+
{
69+
$marking = $marking->getPlaces();
70+
71+
if ($this->singleState) {
72+
$marking = key($marking);
73+
}
74+
75+
$method = 'set'.ucfirst($this->property);
76+
77+
if (!method_exists($subject, $method)) {
78+
throw new LogicException(sprintf('The method "%s::%s()" does not exists.', \get_class($subject), $method));
79+
}
80+
81+
$subject->{$method}($marking, $context);
82+
}
83+
}

src/Symfony/Component/Workflow/MarkingStore/MultipleStateMarkingStore.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public function getMarking($subject)
4646
/**
4747
* {@inheritdoc}
4848
*/
49-
public function setMarking($subject, Marking $marking)
49+
public function setMarking($subject, Marking $marking, array $context = [])
5050
{
5151
$this->propertyAccessor->setValue($subject, $this->property, $marking->getPlaces());
5252
}

src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function getMarking($subject)
5151
/**
5252
* {@inheritdoc}
5353
*/
54-
public function setMarking($subject, Marking $marking)
54+
public function setMarking($subject, Marking $marking, array $context = [])
5555
{
5656
$this->propertyAccessor->setValue($subject, $this->property, key($marking->getPlaces()));
5757
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
namespace Symfony\Component\Workflow\Tests\MarkingStore;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use Symfony\Component\Workflow\Marking;
7+
use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore;
8+
9+
class MethodMarkingStoreTest extends TestCase
10+
{
11+
public function testGetSetMarkingWithMultipleState()
12+
{
13+
$subject = new Subject();
14+
15+
$markingStore = new MethodMarkingStore(false);
16+
17+
$marking = $markingStore->getMarking($subject);
18+
19+
$this->assertInstanceOf(Marking::class, $marking);
20+
$this->assertCount(0, $marking->getPlaces());
21+
22+
$marking->mark('first_place');
23+
24+
$markingStore->setMarking($subject, $marking);
25+
26+
$this->assertSame(['first_place' => 1], $subject->getMarking());
27+
28+
$marking2 = $markingStore->getMarking($subject);
29+
30+
$this->assertEquals($marking, $marking2);
31+
}
32+
33+
public function testGetSetMarkingWithSingleState()
34+
{
35+
$subject = new Subject();
36+
37+
$markingStore = new MethodMarkingStore(true);
38+
39+
$marking = $markingStore->getMarking($subject);
40+
41+
$this->assertInstanceOf(Marking::class, $marking);
42+
$this->assertCount(0, $marking->getPlaces());
43+
44+
$marking->mark('first_place');
45+
46+
$markingStore->setMarking($subject, $marking);
47+
48+
$this->assertSame('first_place', $subject->getMarking());
49+
50+
$marking2 = $markingStore->getMarking($subject);
51+
52+
$this->assertEquals($marking, $marking2);
53+
}
54+
}
55+
56+
final class Subject
57+
{
58+
private $marking;
59+
60+
public function __construct($marking = null)
61+
{
62+
$this->marking = $marking;
63+
}
64+
65+
public function getMarking()
66+
{
67+
return $this->marking;
68+
}
69+
70+
public function setMarking($marking)
71+
{
72+
$this->marking = $marking;
73+
}
74+
}

src/Symfony/Component/Workflow/Workflow.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ public function buildTransitionBlockerList($subject, string $transitionName): Tr
143143
/**
144144
* {@inheritdoc}
145145
*/
146-
public function apply($subject, $transitionName)
146+
public function apply($subject, $transitionName, array $context = [])
147147
{
148148
$marking = $this->getMarking($subject);
149149

@@ -172,7 +172,7 @@ public function apply($subject, $transitionName)
172172

173173
$this->enter($subject, $transition, $marking);
174174

175-
$this->markingStore->setMarking($subject, $marking);
175+
$this->markingStore->setMarking($subject, $marking, $context);
176176

177177
$this->entered($subject, $transition, $marking);
178178

src/Symfony/Component/Workflow/WorkflowInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public function buildTransitionBlockerList($subject, string $transitionName): Tr
5858
*
5959
* @throws LogicException If the transition is not applicable
6060
*/
61-
public function apply($subject, $transitionName);
61+
public function apply($subject, $transitionName, array $context = []);
6262

6363
/**
6464
* Returns all enabled transitions.

0 commit comments

Comments
 (0)