From dac0cdd1c8f1a79d2aa362d95daef88ebac13626 Mon Sep 17 00:00:00 2001 From: Willem Oostendorp Date: Thu, 27 Aug 2020 11:48:05 +0200 Subject: [PATCH 1/4] Add support for Laravel 7 --- composer.json | 12 +- src/Commands/WorkflowDumpCommand.php | 2 +- src/WorkflowRegistry.php | 41 +++++-- tests/Fixtures/TestObject.php | 16 +++ tests/TestCase.php | 27 +++++ tests/WorkflowDumpCommandTest.php | 2 +- tests/WorkflowRegistryTest.php | 132 ++++++++++++++------- tests/WorkflowSubscriberTest.php | 171 +++++++++++++-------------- 8 files changed, 249 insertions(+), 154 deletions(-) create mode 100644 tests/TestCase.php diff --git a/composer.json b/composer.json index 8b2e0a3..bcaca1e 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,15 @@ { "name": "brexis/laravel-workflow", "description": "Integerate Symfony Workflow component into Laravel.", - "keywords": ["workflow", "symfony", "laravel", "laravel5", "laravel6"], + "keywords": ["workflow", "symfony", "laravel", "laravel5", "laravel6", "laravel7"], "license": "MIT", "require": { "php": ">=5.5.9", - "symfony/workflow": "^3.3 || ^4.0", - "symfony/process": "^3.3 || ^4.0", - "symfony/event-dispatcher": "^3.3 || ^4.0", - "illuminate/console": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.*", - "illuminate/support": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.*" + "symfony/workflow": "^3.3 || ^4.0 || ^5.0", + "symfony/process": "^3.3 || ^4.0 || ^5.0", + "symfony/event-dispatcher": "^3.3 || ^4.0 || ^5.0", + "illuminate/console": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.* || 7.*", + "illuminate/support": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.* || 7.*" }, "autoload": { "psr-4": { diff --git a/src/Commands/WorkflowDumpCommand.php b/src/Commands/WorkflowDumpCommand.php index fa008e1..ab1a1c1 100644 --- a/src/Commands/WorkflowDumpCommand.php +++ b/src/Commands/WorkflowDumpCommand.php @@ -62,7 +62,7 @@ public function handle() $dotCommand = "dot -T$format -o $workflowName.$format"; - $process = new Process($dotCommand); + $process = Process::fromShellCommandline($dotCommand); $process->setInput($dumper->dump($definition)); $process->mustRun(); } diff --git a/src/WorkflowRegistry.php b/src/WorkflowRegistry.php index a1c9d88..2b97e5a 100644 --- a/src/WorkflowRegistry.php +++ b/src/WorkflowRegistry.php @@ -3,12 +3,12 @@ namespace Brexis\LaravelWorkflow; use Brexis\LaravelWorkflow\Events\WorkflowSubscriber; +use phpDocumentor\Reflection\DocBlock\Tags\Param; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Workflow\Definition; use Symfony\Component\Workflow\DefinitionBuilder; use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface; -use Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore; -use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore; +use Symfony\Component\Workflow\MarkingStore\MethodMarkingStore; use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\StateMachine; use Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy; @@ -58,8 +58,8 @@ public function __construct(array $config) /** * Return the $subject workflow * - * @param object $subject - * @param string $workflowName + * @param object $subject + * @param string|null $workflowName * @return Workflow */ public function get($subject, $workflowName = null) @@ -144,18 +144,37 @@ protected function getWorkflowInstance( protected function getMarkingStoreInstance(array $workflowData) { $markingStoreData = isset($workflowData['marking_store']) ? $workflowData['marking_store'] : []; - $arguments = isset($markingStoreData['arguments']) ? $markingStoreData['arguments'] : []; + $arguments = $this->getMarkingStoreArguments($markingStoreData); if (isset($markingStoreData['class'])) { $className = $markingStoreData['class']; - } elseif (isset($markingStoreData['type']) && $markingStoreData['type'] === 'multiple_state') { - $className = MultipleStateMarkingStore::class; - } else { - $className = SingleStateMarkingStore::class; + + $class = new \ReflectionClass($className); + + return $class->newInstanceArgs($arguments); } - $class = new \ReflectionClass($className); + return new MethodMarkingStore(...$arguments); + } + + /** + * Get the arguments for the marking store + * + * @param array $markingStoreData + * @return array + */ + protected function getMarkingStoreArguments(array $markingStoreData) + { + $arguments = isset($markingStoreData['arguments']) ? $markingStoreData['arguments'] : []; + + if (isset($markingStoreData['class']) || empty($arguments) || is_bool($arguments[0])) { + return $arguments; + } + + $singleState = isset($markingStoreData['type']) && $markingStoreData['type'] === 'single_state'; + + array_unshift($arguments, $singleState); - return $class->newInstanceArgs($arguments); + return $arguments; } } diff --git a/tests/Fixtures/TestObject.php b/tests/Fixtures/TestObject.php index 50301de..c05dacd 100644 --- a/tests/Fixtures/TestObject.php +++ b/tests/Fixtures/TestObject.php @@ -4,4 +4,20 @@ class TestObject { public $marking; + + /** + * @return mixed + */ + public function getMarking() + { + return $this->marking; + } + + /** + * @param mixed $marking + */ + public function setMarking($marking) + { + $this->marking = $marking; + } } diff --git a/tests/TestCase.php b/tests/TestCase.php new file mode 100644 index 0000000..7265715 --- /dev/null +++ b/tests/TestCase.php @@ -0,0 +1,27 @@ + [ - 'supports' => ['Tests\Fixtures\TestObject'], - 'places' => ['a', 'b', 'c'], - 'transitions' => [ + $config = [ + 'straight' => [ + 'supports' => ['Tests\Fixtures\TestObject'], + 'places' => ['a', 'b', 'c'], + 'transitions' => [ 't1' => [ 'from' => 'a', - 'to' => 'b', + 'to' => 'b', ], 't2' => [ 'from' => 'b', - 'to' => 'c', + 'to' => 'c', ] ], ] ]; - $registry = new WorkflowRegistry($config); - $subject = new TestObject; - $workflow = $registry->get($subject); + $registry = new WorkflowRegistry($config); + $subject = new TestObject; + $workflow = $registry->get($subject); $markingStoreProp = new ReflectionProperty(Workflow::class, 'markingStore'); $markingStoreProp->setAccessible(true); @@ -41,35 +39,36 @@ public function testIfWorkflowIsRegistered() $markingStore = $markingStoreProp->getValue($workflow); $this->assertTrue($workflow instanceof Workflow); - $this->assertTrue($markingStore instanceof SingleStateMarkingStore); + $this->assertTrue($markingStore instanceof MethodMarkingStore); } public function testIfStateMachineIsRegistered() { - $config = [ - 'straight' => [ - 'type' => 'state_machine', + $config = [ + 'straight' => [ + 'type' => 'state_machine', 'marking_store' => [ - 'type' => 'multiple_state', + 'type' => 'multiple_state', + 'arguments' => ['marking'], ], - 'supports' => ['Tests\Fixtures\TestObject'], - 'places' => ['a', 'b', 'c'], - 'transitions' => [ + 'supports' => ['Tests\Fixtures\TestObject'], + 'places' => ['a', 'b', 'c'], + 'transitions' => [ 't1' => [ 'from' => 'a', - 'to' => 'b', + 'to' => 'b', ], 't2' => [ 'from' => 'b', - 'to' => 'c', + 'to' => 'c', ] ], ] ]; - $registry = new WorkflowRegistry($config); - $subject = new TestObject; - $workflow = $registry->get($subject); + $registry = new WorkflowRegistry($config); + $subject = new TestObject; + $workflow = $registry->get($subject); $markingStoreProp = new ReflectionProperty(Workflow::class, 'markingStore'); $markingStoreProp->setAccessible(true); @@ -77,38 +76,38 @@ public function testIfStateMachineIsRegistered() $markingStore = $markingStoreProp->getValue($workflow); $this->assertTrue($workflow instanceof StateMachine); - $this->assertTrue($markingStore instanceof MultipleStateMarkingStore); + $this->assertTrue($markingStore instanceof MethodMarkingStore); } - public function testIfTransitionsWithSameNameCanBothBeUsed() - { + public function testIfTransitionsWithSameNameCanBothBeUsed() + { $config = [ 'straight' => [ - 'type' => 'state_machine', - 'supports' => ['Tests\Fixtures\TestObject'], - 'places' => ['a', 'b', 'c'], + 'type' => 'state_machine', + 'supports' => ['Tests\Fixtures\TestObject'], + 'places' => ['a', 'b', 'c'], 'transitions' => [ [ 'name' => 't1', 'from' => 'a', - 'to' => 'b', + 'to' => 'b', ], [ 'name' => 't1', 'from' => 'c', - 'to' => 'b', + 'to' => 'b', ], [ 'name' => 't2', 'from' => 'b', - 'to' => 'c', + 'to' => 'c', ] ], ] ]; $registry = new WorkflowRegistry($config); - $subject = new TestObject; + $subject = new TestObject; $workflow = $registry->get($subject); $markingStoreProp = new ReflectionProperty(Workflow::class, 'markingStore'); @@ -117,7 +116,7 @@ public function testIfTransitionsWithSameNameCanBothBeUsed() $markingStore = $markingStoreProp->getValue($workflow); $this->assertTrue($workflow instanceof StateMachine); - $this->assertTrue($markingStore instanceof SingleStateMarkingStore); + $this->assertTrue($markingStore instanceof MethodMarkingStore); $this->assertTrue($workflow->can($subject, 't1')); $workflow->apply($subject, 't1'); @@ -130,14 +129,14 @@ public function testWhenMultipleFromIsUsed() { $config = [ 'straight' => [ - 'type' => 'state_machine', - 'supports' => ['Tests\Fixtures\TestObject'], - 'places' => ['a', 'b', 'c'], + 'type' => 'state_machine', + 'supports' => ['Tests\Fixtures\TestObject'], + 'places' => ['a', 'b', 'c'], 'transitions' => [ [ 'name' => 't1', 'from' => 'a', - 'to' => 'b', + 'to' => 'b', ], [ 'name' => 't2', @@ -145,7 +144,7 @@ public function testWhenMultipleFromIsUsed() 'a', 'b' ], - 'to' => 'c', + 'to' => 'c', ], ], ], @@ -161,8 +160,55 @@ public function testWhenMultipleFromIsUsed() $markingStore = $markingStoreProp->getValue($workflow); $this->assertTrue($workflow instanceof StateMachine); - $this->assertTrue($markingStore instanceof SingleStateMarkingStore); + $this->assertTrue($markingStore instanceof MethodMarkingStore); $this->assertTrue($workflow->can($subject, 't1')); $this->assertTrue($workflow->can($subject, 't2')); } + + public function testMethodMarkingStoreArgumentsCanBeUsed() + { + $config = [ + 'straight' => [ + 'marking_store' => [ + 'arguments' => [true, 'marking'], + ], + 'supports' => ['Tests\Fixtures\TestObject'], + 'places' => ['a', 'b', 'c'], + 'transitions' => [ + 't1' => [ + 'from' => 'a', + 'to' => 'b', + ], + 't2' => [ + 'from' => 'b', + 'to' => 'c', + ] + ], + ] + ]; + + $registry = new WorkflowRegistry($config); + $subject = new TestObject; + $workflow = $registry->get($subject); + + $markingStoreProp = new ReflectionProperty(Workflow::class, 'markingStore'); + $markingStoreProp->setAccessible(true); + + $markingStore = $markingStoreProp->getValue($workflow); + + $singleStateProp = new ReflectionProperty(MethodMarkingStore::class, 'singleState'); + $singleStateProp->setAccessible(true); + + $singleState = $singleStateProp->getValue($markingStore); + + $propertyProp = new ReflectionProperty(MethodMarkingStore::class, 'property'); + $propertyProp->setAccessible(true); + + $property = $propertyProp->getValue($markingStore); + + $this->assertTrue($workflow instanceof Workflow); + $this->assertTrue($markingStore instanceof MethodMarkingStore); + $this->assertTrue($singleState); + $this->assertSame('marking', $property); + } } diff --git a/tests/WorkflowSubscriberTest.php b/tests/WorkflowSubscriberTest.php index 8cb7bb6..16e9221 100644 --- a/tests/WorkflowSubscriberTest.php +++ b/tests/WorkflowSubscriberTest.php @@ -1,99 +1,86 @@ [ - 'supports' => [TestObject::class], - 'places' => ['a', 'b', 'c'], - 'transitions' => [ - 't1' => [ - 'from' => 'a', - 'to' => 'b', - ], - 't2' => [ - 'from' => 'b', - 'to' => 'c', - ], - ], - ], - ]; - - $registry = new WorkflowRegistry($config); - $object = new TestObject; - $workflow = $registry->get($object); - - $workflow->apply($object, 't1'); - - $this->assertCount(31, $events); - - $this->assertInstanceOf(EnteredEvent::class, $events[0]); - $this->assertEquals('workflow.entered', $events[1]); - $this->assertEquals('workflow.straight.entered', $events[2]); - - $this->assertInstanceOf(GuardEvent::class, $events[3]); - $this->assertEquals('workflow.guard', $events[4]); - $this->assertEquals('workflow.straight.guard', $events[5]); - $this->assertEquals('workflow.straight.guard.t1', $events[6]); - - $this->assertInstanceOf(LeaveEvent::class, $events[7]); - $this->assertEquals('workflow.leave', $events[8]); - $this->assertEquals('workflow.straight.leave', $events[9]); - $this->assertEquals('workflow.straight.leave.a', $events[10]); - - $this->assertInstanceOf(TransitionEvent::class, $events[11]); - $this->assertEquals('workflow.transition', $events[12]); - $this->assertEquals('workflow.straight.transition', $events[13]); - $this->assertEquals('workflow.straight.transition.t1', $events[14]); - - $this->assertInstanceOf(EnterEvent::class, $events[15]); - $this->assertEquals('workflow.enter', $events[16]); - $this->assertEquals('workflow.straight.enter', $events[17]); - $this->assertEquals('workflow.straight.enter.b', $events[18]); - - $this->assertInstanceOf(EnteredEvent::class, $events[19]); - $this->assertEquals('workflow.entered', $events[20]); - $this->assertEquals('workflow.straight.entered', $events[21]); - $this->assertEquals('workflow.straight.entered.b', $events[22]); - - $this->assertInstanceOf(CompletedEvent::class, $events[23]); - $this->assertEquals('workflow.completed', $events[24]); - $this->assertEquals('workflow.straight.completed', $events[25]); - $this->assertEquals('workflow.straight.completed.t1', $events[26]); - - $this->assertInstanceOf(GuardEvent::class, $events[27]); - $this->assertEquals('workflow.guard', $events[28]); - $this->assertEquals('workflow.straight.guard', $events[29]); - $this->assertEquals('workflow.straight.guard.t2', $events[30]); - } - } -} - -namespace { + global $events; - $events = null; + $events = []; - function event($ev) - { - global $events; - $events[] = $ev; + $config = [ + 'straight' => [ + 'supports' => [TestObject::class], + 'places' => ['a', 'b', 'c'], + 'transitions' => [ + 't1' => [ + 'from' => 'a', + 'to' => 'b', + ], + 't2' => [ + 'from' => 'b', + 'to' => 'c', + ], + ], + ], + ]; + + $registry = new WorkflowRegistry($config); + $object = new TestObject; + $workflow = $registry->get($object); + + $workflow->apply($object, 't1'); + + $this->assertCount(31, $events); + + $this->assertInstanceOf(EnteredEvent::class, $events[0]); + $this->assertEquals('workflow.entered', $events[1]); + $this->assertEquals('workflow.straight.entered', $events[2]); + + $this->assertInstanceOf(GuardEvent::class, $events[3]); + $this->assertEquals('workflow.guard', $events[4]); + $this->assertEquals('workflow.straight.guard', $events[5]); + $this->assertEquals('workflow.straight.guard.t1', $events[6]); + + $this->assertInstanceOf(LeaveEvent::class, $events[7]); + $this->assertEquals('workflow.leave', $events[8]); + $this->assertEquals('workflow.straight.leave', $events[9]); + $this->assertEquals('workflow.straight.leave.a', $events[10]); + + $this->assertInstanceOf(TransitionEvent::class, $events[11]); + $this->assertEquals('workflow.transition', $events[12]); + $this->assertEquals('workflow.straight.transition', $events[13]); + $this->assertEquals('workflow.straight.transition.t1', $events[14]); + + $this->assertInstanceOf(EnterEvent::class, $events[15]); + $this->assertEquals('workflow.enter', $events[16]); + $this->assertEquals('workflow.straight.enter', $events[17]); + $this->assertEquals('workflow.straight.enter.b', $events[18]); + + $this->assertInstanceOf(EnteredEvent::class, $events[19]); + $this->assertEquals('workflow.entered', $events[20]); + $this->assertEquals('workflow.straight.entered', $events[21]); + $this->assertEquals('workflow.straight.entered.b', $events[22]); + + $this->assertInstanceOf(CompletedEvent::class, $events[23]); + $this->assertEquals('workflow.completed', $events[24]); + $this->assertEquals('workflow.straight.completed', $events[25]); + $this->assertEquals('workflow.straight.completed.t1', $events[26]); + + $this->assertInstanceOf(GuardEvent::class, $events[27]); + $this->assertEquals('workflow.guard', $events[28]); + $this->assertEquals('workflow.straight.guard', $events[29]); + $this->assertEquals('workflow.straight.guard.t2', $events[30]); } } From 8f694351b5048af7abb7df9e5acfdd3218ce570d Mon Sep 17 00:00:00 2001 From: Willem Oostendorp Date: Wed, 26 May 2021 14:17:50 +0200 Subject: [PATCH 2/4] Add support for Laravel 8 --- composer.json | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/composer.json b/composer.json index bcaca1e..b68acf0 100644 --- a/composer.json +++ b/composer.json @@ -4,12 +4,16 @@ "keywords": ["workflow", "symfony", "laravel", "laravel5", "laravel6", "laravel7"], "license": "MIT", "require": { - "php": ">=5.5.9", - "symfony/workflow": "^3.3 || ^4.0 || ^5.0", - "symfony/process": "^3.3 || ^4.0 || ^5.0", - "symfony/event-dispatcher": "^3.3 || ^4.0 || ^5.0", - "illuminate/console": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.* || 7.*", - "illuminate/support": "5.3.* || 5.4.* || 5.5.* || 5.6.* || 5.7.* || 5.8.* || 6.* || 7.*" + "php": ">=7.2.5", + "symfony/workflow": "^5.0", + "symfony/process": "^5.0", + "symfony/event-dispatcher": "^5.0", + "illuminate/console": "6.* || 7.* || 8.*", + "illuminate/support": "6.* || 7.* || 8.*" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^8.0 || ^9.0" }, "autoload": { "psr-4": { @@ -33,9 +37,5 @@ "Workflow": "Brexis\\LaravelWorkflow\\Facades\\WorkflowFacade" } } - }, - "require-dev": { - "mockery/mockery": "^1.0", - "phpunit/phpunit": "^6.0 || ~7.0 || ^8.0" } } From ed7c373ff5be276198692929c3746f5d4e4a42f9 Mon Sep 17 00:00:00 2001 From: Willem Oostendorp Date: Mon, 20 Jun 2022 14:03:42 +0200 Subject: [PATCH 3/4] Add support for Laravel 9 --- .travis.yml | 16 ---------------- composer.json | 8 ++++---- 2 files changed, 4 insertions(+), 20 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 9dd51e9..0000000 --- a/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -language: php - -php: - - 7.1 - - 7.2 -before_install: - - sudo apt-get update -q - - sudo apt-get autoremove graphviz -y - - sudo apt-get install graphviz -y - -before_script: - - composer self-update - - composer install --no-interaction - -script: - - vendor/bin/phpunit diff --git a/composer.json b/composer.json index b68acf0..0c6dad5 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,15 @@ { "name": "brexis/laravel-workflow", "description": "Integerate Symfony Workflow component into Laravel.", - "keywords": ["workflow", "symfony", "laravel", "laravel5", "laravel6", "laravel7"], + "keywords": ["workflow", "symfony", "laravel", "laravel8", "laravel9"], "license": "MIT", "require": { - "php": ">=7.2.5", + "php": "^8.0.2", "symfony/workflow": "^5.0", "symfony/process": "^5.0", "symfony/event-dispatcher": "^5.0", - "illuminate/console": "6.* || 7.* || 8.*", - "illuminate/support": "6.* || 7.* || 8.*" + "illuminate/console": "8.* || 9.*", + "illuminate/support": "8.* || 9.*" }, "require-dev": { "mockery/mockery": "^1.0", From bafcec461538eab875fb8504411b6c1060782f82 Mon Sep 17 00:00:00 2001 From: Willem Oostendorp Date: Mon, 20 Jun 2022 14:44:53 +0200 Subject: [PATCH 4/4] Upgrade Symfony dependencies --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 0c6dad5..1b3e472 100644 --- a/composer.json +++ b/composer.json @@ -5,8 +5,8 @@ "license": "MIT", "require": { "php": "^8.0.2", - "symfony/workflow": "^5.0", - "symfony/process": "^5.0", + "symfony/workflow": "^6.0", + "symfony/process": "^6.0", "symfony/event-dispatcher": "^5.0", "illuminate/console": "8.* || 9.*", "illuminate/support": "8.* || 9.*"