Skip to content

Commit ffaeba3

Browse files
Nyholmlyrixx
authored andcommitted
[Workflow] Added Definition builder
1 parent c6b664c commit ffaeba3

File tree

10 files changed

+237
-80
lines changed

10 files changed

+237
-80
lines changed

src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -66,23 +66,13 @@ protected function execute(InputInterface $input, OutputInterface $output)
6666
throw new \InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $serviceId));
6767
}
6868

69-
$definition = $this->getProperty($workflow, 'definition');
70-
7169
$dumper = new GraphvizDumper();
72-
7370
$marking = new Marking();
71+
7472
foreach ($input->getArgument('marking') as $place) {
7573
$marking->mark($place);
7674
}
7775

78-
$output->writeln($dumper->dump($definition, $marking));
79-
}
80-
81-
private function getProperty($object, $property)
82-
{
83-
$reflectionProperty = new \ReflectionProperty(Workflow::class, $property);
84-
$reflectionProperty->setAccessible(true);
85-
86-
return $reflectionProperty->getValue($object);
76+
$output->writeln($dumper->dump($workflow->getDefinition(), $marking));
8777
}
8878
}

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

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -406,20 +406,32 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
406406
foreach ($workflows as $name => $workflow) {
407407
$type = $workflow['type'];
408408

409-
$definitionDefinition = new Definition(Workflow\Definition::class);
410-
$definitionDefinition->addMethodCall('addPlaces', array($workflow['places']));
409+
// Create a DefinitionBuilder
410+
$definitionBuilderDefinition = new Definition(Workflow\DefinitionBuilder::class);
411+
$definitionBuilderDefinition->addMethodCall('addPlaces', array($workflow['places']));
411412
foreach ($workflow['transitions'] as $transitionName => $transition) {
412413
if ($type === 'workflow') {
413-
$definitionDefinition->addMethodCall('addTransition', array(new Definition(Workflow\Transition::class, array($transitionName, $transition['from'], $transition['to']))));
414+
$definitionBuilderDefinition->addMethodCall('addTransition', array(new Definition(Workflow\Transition::class, array($transitionName, $transition['from'], $transition['to']))));
414415
} elseif ($type === 'state_machine') {
415416
foreach ($transition['from'] as $from) {
416417
foreach ($transition['to'] as $to) {
417-
$definitionDefinition->addMethodCall('addTransition', array(new Definition(Workflow\Transition::class, array($transitionName, $from, $to))));
418+
$definitionBuilderDefinition->addMethodCall('addTransition', array(new Definition(Workflow\Transition::class, array($transitionName, $from, $to))));
418419
}
419420
}
420421
}
421422
}
422423

424+
// Create a Definition
425+
$definitionDefinition = new Definition(Workflow\Definition::class);
426+
$definitionDefinition->setPublic(false);
427+
$definitionDefinition->setFactory(array($definitionBuilderDefinition, 'build'));
428+
$definitionDefinition->addTag('workflow.definition', array(
429+
'name' => $name,
430+
'type' => $type,
431+
'marking_store' => isset($workflow['marking_store']['type']) ? $workflow['marking_store']['type'] : null,
432+
));
433+
434+
// Create MarkingStore
423435
if (isset($workflow['marking_store']['type'])) {
424436
$markingStoreDefinition = new DefinitionDecorator('workflow.marking_store.'.$workflow['marking_store']['type']);
425437
foreach ($workflow['marking_store']['arguments'] as $argument) {
@@ -429,25 +441,20 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde
429441
$markingStoreDefinition = new Reference($workflow['marking_store']['service']);
430442
}
431443

432-
$definitionDefinition->addTag('workflow.definition', array(
433-
'name' => $name,
434-
'type' => $type,
435-
'marking_store' => isset($workflow['marking_store']['type']) ? $workflow['marking_store']['type'] : null,
436-
));
437-
$definitionDefinition->setPublic(false);
438-
444+
// Create Workflow
439445
$workflowDefinition = new DefinitionDecorator(sprintf('%s.abstract', $type));
440446
$workflowDefinition->replaceArgument(0, $definitionDefinition);
441447
if (isset($markingStoreDefinition)) {
442448
$workflowDefinition->replaceArgument(1, $markingStoreDefinition);
443449
}
444450
$workflowDefinition->replaceArgument(3, $name);
445451

452+
// Store to container
446453
$workflowId = sprintf('%s.%s', $type, $name);
447-
448-
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
449454
$container->setDefinition($workflowId, $workflowDefinition);
455+
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
450456

457+
// Add workflow to Registry
451458
foreach ($workflow['supports'] as $supportedClass) {
452459
$registryDefinition->addMethodCall('add', array(new Reference($workflowId), $supportedClass));
453460
}

src/Symfony/Component/Workflow/Definition.php

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@
1717
/**
1818
* @author Fabien Potencier <fabien@symfony.com>
1919
* @author Grégoire Pineau <lyrixx@lyrixx.info>
20+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
2021
*/
21-
class Definition
22+
final class Definition
2223
{
2324
private $places = array();
2425
private $transitions = array();
@@ -29,18 +30,28 @@ class Definition
2930
*
3031
* @param string[] $places
3132
* @param Transition[] $transitions
33+
* @param string|null $initialPlace
3234
*/
33-
public function __construct(array $places = array(), array $transitions = array())
35+
public function __construct(array $places, array $transitions, $initialPlace = null)
3436
{
3537
$this->addPlaces($places);
36-
$this->addTransitions($transitions);
38+
$this->setInitialPlace($initialPlace);
39+
foreach ($transitions as $transition) {
40+
$this->addTransition($transition);
41+
}
3742
}
3843

44+
/**
45+
* @return string|null
46+
*/
3947
public function getInitialPlace()
4048
{
4149
return $this->initialPlace;
4250
}
4351

52+
/**
53+
* @return string[]
54+
*/
4455
public function getPlaces()
4556
{
4657
return $this->places;
@@ -54,16 +65,20 @@ public function getTransitions()
5465
return $this->transitions;
5566
}
5667

57-
public function setInitialPlace($place)
68+
private function setInitialPlace($place)
5869
{
70+
if (null === $place) {
71+
return;
72+
}
73+
5974
if (!isset($this->places[$place])) {
6075
throw new LogicException(sprintf('Place "%s" cannot be the initial place as it does not exist.', $place));
6176
}
6277

6378
$this->initialPlace = $place;
6479
}
6580

66-
public function addPlace($place)
81+
private function addPlace($place)
6782
{
6883
if (!preg_match('{^[\w\d_-]+$}', $place)) {
6984
throw new InvalidArgumentException(sprintf('The place "%s" contains invalid characters.', $place));
@@ -76,21 +91,14 @@ public function addPlace($place)
7691
$this->places[$place] = $place;
7792
}
7893

79-
public function addPlaces(array $places)
94+
private function addPlaces(array $places)
8095
{
8196
foreach ($places as $place) {
8297
$this->addPlace($place);
8398
}
8499
}
85100

86-
public function addTransitions(array $transitions)
87-
{
88-
foreach ($transitions as $transition) {
89-
$this->addTransition($transition);
90-
}
91-
}
92-
93-
public function addTransition(Transition $transition)
101+
private function addTransition(Transition $transition)
94102
{
95103
$name = $transition->getName();
96104

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
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;
13+
14+
use Symfony\Component\Workflow\Exception\InvalidArgumentException;
15+
16+
/**
17+
* Builds a definition.
18+
*
19+
* @author Fabien Potencier <fabien@symfony.com>
20+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
21+
* @author Tobias Nyholm <tobias.nyholm@gmail.com>
22+
*/
23+
class DefinitionBuilder
24+
{
25+
private $places = array();
26+
private $transitions = array();
27+
private $initialPlace;
28+
29+
/**
30+
* @param string[] $places
31+
* @param Transition[] $transitions
32+
*/
33+
public function __construct(array $places = array(), array $transitions = array())
34+
{
35+
$this->addPlaces($places);
36+
$this->addTransitions($transitions);
37+
}
38+
39+
/**
40+
* @return Definition
41+
*/
42+
public function build()
43+
{
44+
return new Definition($this->places, $this->transitions, $this->initialPlace);
45+
}
46+
47+
/**
48+
* Clear all data in the builder.
49+
*/
50+
public function reset()
51+
{
52+
$this->places = array();
53+
$this->transitions = array();
54+
$this->initialPlace = null;
55+
}
56+
57+
public function setInitialPlace($place)
58+
{
59+
$this->initialPlace = $place;
60+
}
61+
62+
public function addPlace($place)
63+
{
64+
if (!preg_match('{^[\w\d_-]+$}', $place)) {
65+
throw new InvalidArgumentException(sprintf('The place "%s" contains invalid characters.', $place));
66+
}
67+
68+
if (!$this->places) {
69+
$this->initialPlace = $place;
70+
}
71+
72+
$this->places[$place] = $place;
73+
}
74+
75+
public function addPlaces(array $places)
76+
{
77+
foreach ($places as $place) {
78+
$this->addPlace($place);
79+
}
80+
}
81+
82+
public function addTransitions(array $transitions)
83+
{
84+
foreach ($transitions as $transition) {
85+
$this->addTransition($transition);
86+
}
87+
}
88+
89+
public function addTransition(Transition $transition)
90+
{
91+
$this->transitions[] = $transition;
92+
}
93+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace Symfony\Component\Workflow\Tests;
4+
5+
use Symfony\Component\Workflow\DefinitionBuilder;
6+
use Symfony\Component\Workflow\Transition;
7+
8+
class DefinitionBuilderTest extends \PHPUnit_Framework_TestCase
9+
{
10+
/**
11+
* @expectedException \Symfony\Component\Workflow\Exception\InvalidArgumentException
12+
*/
13+
public function testAddPlaceInvalidName()
14+
{
15+
$builder = new DefinitionBuilder(array('a"', 'b'));
16+
}
17+
18+
public function testSetInitialPlace()
19+
{
20+
$builder = new DefinitionBuilder(array('a', 'b'));
21+
$builder->setInitialPlace('b');
22+
$definition = $builder->build();
23+
24+
$this->assertEquals('b', $definition->getInitialPlace());
25+
}
26+
27+
public function testAddTransition()
28+
{
29+
$places = range('a', 'b');
30+
31+
$transition0 = new Transition('name0', $places[0], $places[1]);
32+
$transition1 = new Transition('name1', $places[0], $places[1]);
33+
$builder = new DefinitionBuilder($places, array($transition0));
34+
$builder->addTransition($transition1);
35+
36+
$definition = $builder->build();
37+
38+
$this->assertCount(2, $definition->getTransitions());
39+
$this->assertSame($transition0, $definition->getTransitions()[0]);
40+
$this->assertSame($transition1, $definition->getTransitions()[1]);
41+
}
42+
43+
public function testAddPlace()
44+
{
45+
$builder = new DefinitionBuilder(array('a'), array());
46+
$builder->addPlace('b');
47+
48+
$definition = $builder->build();
49+
50+
$this->assertCount(2, $definition->getPlaces());
51+
$this->assertEquals('a', $definition->getPlaces()['a']);
52+
$this->assertEquals('b', $definition->getPlaces()['b']);
53+
}
54+
}

src/Symfony/Component/Workflow/Tests/DefinitionTest.php

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ class DefinitionTest extends \PHPUnit_Framework_TestCase
1010
public function testAddPlaces()
1111
{
1212
$places = range('a', 'e');
13-
$definition = new Definition($places);
13+
$definition = new Definition($places, array());
1414

1515
$this->assertCount(5, $definition->getPlaces());
1616

@@ -23,15 +23,13 @@ public function testAddPlaces()
2323
public function testAddPlacesInvalidArgument()
2424
{
2525
$places = array('a"', 'e"');
26-
$definition = new Definition($places);
26+
$definition = new Definition($places, array());
2727
}
2828

2929
public function testSetInitialPlace()
3030
{
3131
$places = range('a', 'e');
32-
$definition = new Definition($places);
33-
34-
$definition->setInitialPlace($places[3]);
32+
$definition = new Definition($places, array(), $places[3]);
3533

3634
$this->assertEquals($places[3], $definition->getInitialPlace());
3735
}
@@ -42,9 +40,7 @@ public function testSetInitialPlace()
4240
*/
4341
public function testSetInitialPlaceAndPlaceIsNotDefined()
4442
{
45-
$definition = new Definition();
46-
47-
$definition->setInitialPlace('d');
43+
$definition = new Definition(array(), array(), 'd');
4844
}
4945

5046
public function testAddTransition()

0 commit comments

Comments
 (0)