8000 feature #21334 [Workflow] Introduce concept of SupportStrategyInterf… · symfony/symfony@4491eb6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 4491eb6

Browse files
committed
feature #21334 [Workflow] Introduce concept of SupportStrategyInterface (andesk, lyrixx)
This PR was merged into the 3.3-dev branch. Discussion ---------- [Workflow] Introduce concept of SupportStrategyInterface | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #20751 | License | MIT | Doc PR | - Commits ------- 134a58b [Workflow] Fixed code and tests 1843012 [Workflow] Introduce concept of SupprtStrategyInterface to allow other support checks than class instance
2 parents d0da74e + 134a58b commit 4491eb6

19 files changed

+355
-30
lines changed

UPGRADE-3.3.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,9 @@ TwigBridge
5959

6060
* The `TwigRendererEngine::setEnvironment()` method has been deprecated and will be removed
6161
in 4.0. Pass the Twig Environment as second argument of the constructor instead.
62+
63+
Workflow
64+
--------
65+
66+
* Deprecated class name support in `WorkflowRegistry::add()` as second parameter.
67+
Wrap the class name in an instance of ClassInstanceSupportStrategy instead.

UPGRADE-4.0.md

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ FrameworkBundle
154154
* The `framework.serializer.cache` option and the services
155155
`serializer.mapping.cache.apc` and `serializer.mapping.cache.doctrine.apc`
156156
have been removed. APCu should now be automatically used when available.
157-
157+
158158
* The `Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\AddConsoleCommandPass` has been removed. Use `Symfony\Component\Console\DependencyInjection\AddConsoleCommandPass` instead.
159159

160160
SecurityBundle
@@ -216,7 +216,7 @@ Serializer
216216
* The ability to pass a Doctrine `Cache` instance to the `ClassMetadataFactory`
217217
class has been removed. You should use the `CacheClassMetadataFactory` class
218218
instead.
219-
219+
220220
* Not defining the 6th argument `$format = null` of the
221221
`AbstractNormalizer::instantiateObject()` method when overriding it is not
222222
supported anymore.
@@ -294,9 +294,9 @@ Validator
294294
// ...
295295
}
296296
```
297-
297+
298298
* The default value of the strict option of the `Choice` Constraint has been
299-
changed to `true` as of 4.0. If you need the previous behaviour ensure to
299+
changed to `true` as of 4.0. If you need the previous behaviour ensure to
300300
set the option to `false`.
301301

302302
Yaml
@@ -393,5 +393,10 @@ Yaml
393393

394394
Ldap
395395
----
396-
397-
* The `RenameEntryInterface` has been deprecated, and merged with `EntryManagerInterface`
396+
397+
* The `RenameEntryInterface` has been deprecated, and merged with `EntryManagerInterface`
398+
399+
Workflow
400+
--------
401+
402+
* Removed class name support in `WorkflowRegistry::add()` as second parameter.

src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use Symfony\Component\Workflow\Definition;
1616
use Symfony\Component\Workflow\Marking;
1717
use Symfony\Component\Workflow\Registry;
18+
use Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy;
1819
use Symfony\Component\Workflow\Transition;
1920
use Symfony\Component\Workflow\Workflow;
2021

@@ -37,7 +38,7 @@ protected function setUp()
3738
$workflow = new Workflow($definition);
3839

3940
$registry = new Registry();
40-
$registry->add($workflow, \stdClass::class);
41+
$registry->add($workflow, new ClassInstanceSupportStrategy(\stdClass::class));
4142

4243
$this->extension = new WorkflowExtension($registry);
4344
}

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

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,6 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
280280
->end()
281281
->end()
282282
->arrayNode('supports')
283-
->isRequired()
284283
->beforeNormalization()
285284
->ifString()
286285
->then(function ($v) { return array($v); })
@@ -293,7 +292,12 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
293292
->end()
294293
->end()
295294
->end()
296-
->scalarNode('initial_place')->defaultNull()->end()
295+
->scalarNode('support_strategy')
296+
->cannotBeEmpty()
297+
->end()
298+
->scalarNode('initial_place')
299+
->defaultNull()
300+
->end()
297301
->arrayNode('places')
298302
->isRequired()
299303
->requiresAtLeastOneElement()
@@ -353,6 +357,18 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
353357
->end()
354358
->end()
355359
->end()
360+
->validate()
361+
->ifTrue(function ($v) {
362+
return $v['supports'] && isset($v['support_strategy']);
363+
})
364+
->thenInvalid('"supports" and "support_strategy" cannot be used together.')
365+
->end()
366+
->validate()
367+
->ifTrue(function ($v) {
368+
return !$v['supports'] && !isset($v['support_strategy']);
369+
})
370+
->thenInvalid('"supports" or "support_strategy" should be configured.')
371+
->end()
356372
->end()
357373
->end()
358374
->end()

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
3737
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
3838
use Symfony\Component\Workflow;
39+
use Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy;
3940
use Symfony\Component\Yaml\Yaml;
4041

4142
/**
@@ -475,8 +476,14 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
475476
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
476477

477478
// Add workflow to Registry
478-
foreach ($workflow['supports'] as $supportedClass) {
479-
$registryDefinition->addMethodCall('add', array(new Reference($workflowId), $supportedClass));
479+
if ($workflow['supports']) {
480+
foreach ($workflow['supports'] as $supportedClassName) {
481+
$strategyDefinition = new Definition(ClassInstanceSupportStrategy::class, array($supportedClassName));
482+
$strategyDefinition->setPublic(false);
483+
$registryDefinition->addMethodCall('add', array(new Reference($workflowId), $strategyDefinition));
484+
}
485+
} elseif (isset($workflow['support_strategy'])) {
486+
$registryDefinition->addMethodCall('add', array(new Reference($workflowId), new Reference($workflow['support_strategy'])));
480487
}
481488
}
482489
}

src/Symfony/Bundle/FrameworkBundle/Resources/config/schema/symfony-1.0.xsd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,13 +232,14 @@
232232
<xsd:complexType name="workflow">
233233
<xsd:sequence>
234234
<xsd:element name="marking-store" type="marking_store" />
235-
<xsd:element name="support" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
235+
<xsd:element name="support" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
236236
<xsd:element name="place" type="xsd:string" minOccurs="1" maxOccurs="unbounded" />
237237
<xsd:element name="transition" type="transition" minOccurs="1" maxOccurs="unbounded" />
238238
</xsd:sequence>
239239
<xsd:attribute name="name" type="xsd:string" use="required" />
240240
<xsd:attribute name="type" type="workflow_type" />
241241
<xsd:attribute name="initial-place" type="xsd:string" />
242+
<xsd:attribute name="support-strategy" type="xsd:string" />
242243
</xsd:complexType>
243244

244245
<xsd:complexType name="marking_store">
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest;
4+
5+
$container->loadFromExtension('framework', array(
6+
'workflows' => array(
7+
'my_workflow' => array(
8+
'marking_store' => array(
9+
'type' => 'multiple_state',
10+
),
11+
'supports' => array(
12+
FrameworkExtensionTest::class,
13+
),
14+
'support_strategy' => 'foobar',
15+
'places' => array(
16+
'first',
17+
'last',
18+
),
19+
'transitions' => array(
20+
'go' => array(
21+
'from' => array(
22+
'first',
23+
),
24+
'to' => array(
25+
'last',
26+
),
27+
),
28+
),
29+
),
30+
),
31+
));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
use Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest;
4+
5+
$container->loadFromExtension('framework', array(
6+
'workflows' => array(
7+
'my_workflow' => array(
8+
'marking_store' => array(
9+
'type' => 'multiple_state',
10+
),
11+
'places' => array(
12+
'first',
13+
'last',
14+
),
15+
'transitions' => array(
16+
'go' => array(
17+
'from' => array(
18+
'first',
19+
),
20+
'to 10000 9; => array(
21+
'last',
22+
),
23+
),
24+
),
25+
),
26+
),
27+
));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
8+
9+
<framework:config>
10+
<framework:workflow name="my_workflow" support-strategy="foobar">
11+
<framework:marking-store type="multiple_state"/>
12+
<framework:support>Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest</framework:support>
13+
<framework:place>first</framework:place>
14+
<framework:place>last</framework:place>
15+
<framework:transition name="foobar">
16+
<framework:from>a</framework:from>
17+
<framework:to>a</framework:to>
18+
</framework:transition>
19+
</framework:workflow>
20+
</framework:config>
21+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?xml version="1.0" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:framework="http://symfony.com/schema/dic/symfony"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/symfony http://symfony.com/schema/dic/symfony/symfony-1.0.xsd">
8+
9+
<framework:config>
10+
<framework:workflow name="my_workflow">
11+
<framework:marking-store type="multiple_state"/>
12+
<framework:place>first</framework:place>
13+
<framework:place>last</framework:place>
14+
<framework:transition name="foobar">
15+
<framework:from>a</framework:from>
16+
<framework:to>a</framework:to>
17+
</framework:transition>
18+
</framework:workflow>
19+
</framework:config>
20+
</container>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
framework:
2+
workflows:
3+
my_workflow:
4+
marking_store:
5+
type: multiple_state
6+
supports:
7+
- Symfony\Bundle\FrameworkBundle\Tests\DependencyInjection\FrameworkExtensionTest
8+
support_strategy: foobar
9+
places:
10+
- first
11+
- last
12+
transitions:
13+
go:
14+
from:
15+
- first
16+
to:
17+
- last
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
framework:
2+
workflows:
3+
my_workflow:
4+
marking_store:
5+
type: multiple_state
6+
places:
7+
- first
8+
- last
9+
transitions:
10+
go:
11+
from:
12+
- first
13+
to:
14+
- last

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,10 @@ public function testWorkflows()
173173
$markingStoreRef = $serviceMarkingStoreWorkflowDefinition->getArgument(1);
174174
$this->assertInstanceOf(Reference::class, $markingStoreRef);
175175
$this->assertEquals('workflow_service', (string) $markingStoreRef);
176+
177+
$this->assertTrue($container->hasDefinition('workflow.registry', 'Workflow registry is registered as a service'));
178+
$registryDefinition = $container->getDefinition('workflow.registry');
179+
$this->assertGreaterThan(0, count($registryDefinition->getMethodCalls()));
176180
}
177181

178182
/**
@@ -184,6 +188,24 @@ public function testWorkflowCannotHaveBothTypeAndService()
184188
$this->createContainerFromFile('workflow_with_type_and_service');
185189
}
186190

191+
/**
192+
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
193+
* @expectedExceptionMessage "supports" and "support_strategy" cannot be used together.
194+
*/
195+
public function testWorkflowCannotHaveBothSupportsAndSupportStrategy()
196+
{
197+
$this->createContainerFromFile('workflow_with_support_and_support_strategy');
198+
}
199+
200+
/**
201+
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
202+
* @expectedExceptionMessage "supports" or "support_strategy" should be configured.
203+
*/
204+
public function testWorkflowShouldHaveOneOfSupportsAndSupportStrategy()
205+
{
206+
$this->createContainerFromFile('workflow_without_support_and_support_strategy');
207+
}
208+
187209
/**
188210
* @expectedException \Symfony\Component\Config\Definition\Exception\InvalidConfigurationException
189211
* @expectedExceptionMessage "arguments" and "service" cannot be used together.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
CHANGELOG
22
=========
3+
4+
3.3.0
5+
-----
6+
7+
* Deprecated class name support in `WorkflowRegistry::add()` as second parameter.
8+
Wrap the class name in an instance of ClassInstanceSupportStrategy instead.

src/Symfony/Component/Workflow/Registry.php

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
namespace Symfony\Component\Workflow;
1313

1414
use Symfony\Component\Workflow\Exception\InvalidArgumentException;
15+
use Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy;
16+
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
1517

1618
/**
1719
* @author Fabien Potencier <fabien@symfony.com>
@@ -22,12 +24,18 @@ class Registry
2224
private $workflows = array();
2325

2426
/**
25-
* @param Workflow $workflow
26-
* @param string $className
27+
* @param Workflow $workflow
28+
* @param string|SupportStrategyInterface $supportStrategy
341A 2729
*/
28-
public function add(Workflow $workflow, $className)
30+
public function add(Workflow $workflow, $supportStrategy)
2931
{
30-
$this->workflows[] = array($workflow, $className);
32+
if (!$supportStrategy instanceof SupportStrategyInterface) {
33+
@trigger_error('Support of class name string was deprecated after version 3.2 and won\'t work anymore in 4.0.', E_USER_DEPRECATED);
34+
35+
$supportStrategy = new Cl 107E7 assInstanceSupportStrategy($supportStrategy);
36+
}
37+
38+
$this->workflows[] = array($workflow, $supportStrategy);
3139
}
3240

3341
/**
@@ -40,8 +48,8 @@ public function get($subject, $workflowName = null)
4048
{
4149
$matched = null;
4250

43-
foreach ($this->workflows as list($workflow, $className)) {
44-
if ($this->supports($workflow, $className, $subject, $workflowName)) {
51+
foreach ($this->workflows as list($workflow, $supportStrategy)) {
52+
if ($this->supports($workflow, $supportStrategy, $subject, $workflowName)) {
4553
if ($matched) {
4654
throw new InvalidArgumentException('At least two workflows match this subject. Set a different name on each and use the second (name) argument of this method.');
4755
}
@@ -56,16 +64,12 @@ public function get($subject, $workflowName = null)
5664
return $matched;
5765
}
5866

59-
private function supports(Workflow $workflow, $className, $subject, $name)
67+
private function supports(Workflow $workflow, $supportStrategy, $subject, $workflowName)
6068
{
61-
if (!$subject instanceof $className) {
69+
if (null !== $workflowName && $workflowName !== $workflow->getName()) {
6270
return false;
6371
}
6472

65-
if (null === $name) {
66-
return true;
67-
}
68-
69-
return $name === $workflow->getName();
73+
return $supportStrategy->supports($workflow, $subject);
7074
}
7175
}

0 commit comments

Comments
 (0)
0