Skip to content

Commit

Permalink
[Workflow] Introduce a Workflow interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Amrouche Hamza committed Dec 4, 2017
1 parent bf4b09f commit e8351d8
Show file tree
Hide file tree
Showing 15 changed files with 314 additions and 47 deletions.
7 changes: 7 additions & 0 deletions UPGRADE-4.1.md
Expand Up @@ -16,3 +16,10 @@ Translation

* The `FileDumper::setBackup()` method is deprecated and will be removed in 5.0.
* The `TranslationWriter::disableBackup()` method is deprecated and will be removed in 5.0.

Workflow
--------

* Deprecated the `add` method in favor of the `addWorkflow` method in `Workflow\Registry`.
* Deprecated `SupportStrategyInterface` in favor of `WorkflowSupportStrategyInterface`.
* Deprecated the class `ClassInstanceSupportStrategy` in favor of the class `InstanceOfSupportStrategy`.
7 changes: 7 additions & 0 deletions UPGRADE-5.0.md
Expand Up @@ -16,3 +16,10 @@ Translation

* The `FileDumper::setBackup()` method has been removed.
* The `TranslationWriter::disableBackup()` method has been removed.

Workflow
--------

* `add` method has been removed use `addWorkflow` method in `Workflow\Registry` instead.
* `SupportStrategyInterface` has been removed, use `WorkflowSupportStrategyInterface` instead.
* `ClassInstanceSupportStrategy` has been removed, use `InstanceOfSupportStrategy` instead.
41 changes: 39 additions & 2 deletions src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php
Expand Up @@ -15,7 +15,7 @@
use Symfony\Bridge\Twig\Extension\WorkflowExtension;
use Symfony\Component\Workflow\Definition;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy;
use Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy;
use Symfony\Component\Workflow\Transition;
use Symfony\Component\Workflow\Workflow;

Expand All @@ -38,11 +38,48 @@ protected function setUp()
$workflow = new Workflow($definition);

$registry = new Registry();
$registry->add($workflow, new ClassInstanceSupportStrategy(\stdClass::class));
$registry->addWorkflow($workflow, new InstanceOfSupportStrategy(\stdClass::class));

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

/**
* @group legacy
*/
protected function setUpLegacyAdd()
{
if (!class_exists(Workflow::class)) {
$this->markTestSkipped('The Workflow component is needed to run tests for this extension.');
}

$places = array('ordered', 'waiting_for_payment', 'processed');
$transitions = array(
new Transition('t1', 'ordered', 'waiting_for_payment'),
new Transition('t2', 'waiting_for_payment', 'processed'),
);
$definition = new Definition($places, $transitions);
$workflow = new Workflow($definition);

$registry = new Registry();
$registry->add($workflow, new InstanceOfSupportStrategy(\stdClass::class));

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

/**
* @group legacy
* @expectedDeprecation Symfony\Component\Workflow\Registry::add is deprecated since Symfony 4.1. Use addWorkflow() instead.
*/
public function testCanTransitionLegacy()
{
$this->setUpLegacyAdd();
$subject = new \stdClass();
$subject->marking = array();

$this->assertTrue($this->extension->canTransition($subject, 't1'));
$this->assertFalse($this->extension->canTransition($subject, 't2'));
}

public function testCanTransition()
{
$subject = new \stdClass();
Expand Down
Expand Up @@ -498,7 +498,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $
// Add workflow to Registry
if ($workflow['supports']) {
foreach ($workflow['supports'] as $supportedClassName) {
$strategyDefinition = new Definition(Workflow\SupportStrategy\ClassInstanceSupportStrategy::class, array($supportedClassName));
$strategyDefinition = new Definition(Workflow\SupportStrategy\InstanceOfSupportStrategy::class, array($supportedClassName));
$strategyDefinition->setPublic(false);
$registryDefinition->addMethodCall('add', array(new Reference($workflowId), $strategyDefinition));
}
Expand Down
8 changes: 8 additions & 0 deletions src/Symfony/Component/Workflow/CHANGELOG.md
@@ -1,6 +1,14 @@
CHANGELOG
=========

4.1.0
-----

* Deprecate the usage of `add(Workflow $workflow, $supportStrategy)` in `Workflow/Registry`, use `addWorkflow(WorkflowInterface, $supportStrategy)` instead.
* Deprecate the usage of `SupportStrategyInterface`, use `WorkflowSupportStrategyInterface` instead.
* The `Workflow` class now implements `WorkflowInterface`.
* Deprecated the class `ClassInstanceSupportStrategy` in favor of the class `InstanceOfSupportStrategy`.

4.0.0
-----

Expand Down
13 changes: 9 additions & 4 deletions src/Symfony/Component/Workflow/Registry.php
Expand Up @@ -13,6 +13,7 @@

use Symfony\Component\Workflow\Exception\InvalidArgumentException;
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
use Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface;

/**
* @author Fabien Potencier <fabien@symfony.com>
Expand All @@ -25,13 +26,17 @@ class Registry
/**
* @param Workflow $workflow
* @param SupportStrategyInterface $supportStrategy
*
* @deprecated since version 4.1, to be removed in 5.0. Use addWorkflow() instead.
*/
public function add(Workflow $workflow, $supportStrategy)
{
if (!$supportStrategy instanceof SupportStrategyInterface) {
throw new \InvalidArgumentException('The "supportStrategy" is not an instance of SupportStrategyInterface.');
}
@trigger_error(sprintf('%s is deprecated since Symfony 4.1. Use addWorkflow() instead.', __METHOD__), E_USER_DEPRECATED);
$this->workflows[] = array($workflow, $supportStrategy);
}

public function addWorkflow(WorkflowInterface $workflow, WorkflowSupportStrategyInterface $supportStrategy)
{
$this->workflows[] = array($workflow, $supportStrategy);
}

Expand Down Expand Up @@ -61,7 +66,7 @@ public function get($subject, $workflowName = null)
return $matched;
}

private function supports(Workflow $workflow, SupportStrategyInterface $supportStrategy, $subject, $workflowName): bool
private function supports(WorkflowInterface $workflow, $supportStrategy, $subject, $workflowName): bool
{
if (null !== $workflowName && $workflowName !== $workflow->getName()) {
return false;
Expand Down
@@ -1,11 +1,24 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\SupportStrategy;

@trigger_error(sprintf('"%s" is deprecated since Symfony 4.1. Use "%s" instead.', ClassInstanceSupportStrategy::class, InstanceOfSupportStrategy::class), E_USER_DEPRECATED);

use Symfony\Component\Workflow\Workflow;

/**
* @author Andreas Kleemann <akleemann@inviqa.com>
*
* @deprecated since version 4.1, to be removed in 5.0. Use InstanceOfSupportStrategy instead
*/
final class ClassInstanceSupportStrategy implements SupportStrategyInterface
{
Expand Down
@@ -0,0 +1,41 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\SupportStrategy;

use Symfony\Component\Workflow\WorkflowInterface;

/**
* @author Andreas Kleemann <akleemann@inviqa.com>
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
*/
final class InstanceOfSupportStrategy implements WorkflowSupportStrategyInterface
{
private $className;

public function __construct(string $className)
{
$this->className = $className;
}

/**
* {@inheritdoc}
*/
public function supports(WorkflowInterface $workflow, $subject): bool
{
return $subject instanceof $this->className;
}

public function getClassName(): string
{
return $this->className;
}
}
Expand Up @@ -15,6 +15,8 @@

/**
* @author Andreas Kleemann <akleemann@inviqa.com>
*
* @deprecated since version 4.1, to be removed in 5.0. Use WorkflowSupportStrategyInterface instead
*/
interface SupportStrategyInterface
{
Expand Down
@@ -0,0 +1,22 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Component\Workflow\SupportStrategy;

use Symfony\Component\Workflow\WorkflowInterface;

/**
* @author Amrouche Hamza <hamza.simperfit@gmail.com>
*/
interface WorkflowSupportStrategyInterface
{
public function supports(WorkflowInterface $workflow, $subject): bool;
}
33 changes: 30 additions & 3 deletions src/Symfony/Component/Workflow/Tests/RegistryTest.php
Expand Up @@ -8,6 +8,7 @@
use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface;
use Symfony\Component\Workflow\Registry;
use Symfony\Component\Workflow\SupportStrategy\SupportStrategyInterface;
use Symfony\Component\Workflow\SupportStrategy\WorkflowSupportStrategyInterface;
use Symfony\Component\Workflow\Workflow;

class RegistryTest extends TestCase
Expand All @@ -18,16 +19,25 @@ protected function setUp()
{
$this->registry = new Registry();

$this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow1'), $this->createSupportStrategy(Subject1::class));
$this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow2'), $this->createSupportStrategy(Subject2::class));
$this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow3'), $this->createSupportStrategy(Subject2::class));
$this->registry->addWorkflow(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow1'), $this->createWorkflowSupportStrategy(Subject1::class));
$this->registry->addWorkflow(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow2'), $this->createWorkflowSupportStrategy(Subject2::class));
$this->registry->addWorkflow(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow3'), $this->createWorkflowSupportStrategy(Subject2::class));
}

protected function tearDown()
{
$this->registry = null;
}

/**
* @group legacy
* @expectedDeprecation Symfony\Component\Workflow\Registry::add is deprecated since Symfony 4.1. Use addWorkflow() instead.
*/
public function testAddIsDeprecated()
{
$this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow1'), $this->createSupportStrategy(Subject1::class));
}

public function testGetWithSuccess()
{
$workflow = $this->registry->get(new Subject1());
Expand Down Expand Up @@ -65,6 +75,9 @@ public function testGetWithNoMatch()
$this->assertSame('workflow1', $w1->getName());
}

/**
* @group legacy
*/
private function createSupportStrategy($supportedClassName)
{
$strategy = $this->getMockBuilder(SupportStrategyInterface::class)->getMock();
Expand All @@ -75,6 +88,20 @@ private function createSupportStrategy($supportedClassName)

return $strategy;
}

/**
* @group legacy
*/
private function createWorkflowSupportStrategy($supportedClassName)
{
$strategy = $this->getMockBuilder(WorkflowSupportStrategyInterface::class)->getMock();
$strategy->expects($this->any())->method('supports')
->will($this->returnCallback(function ($workflow, $subject) use ($supportedClassName) {
return $subject instanceof $supportedClassName;
}));

return $strategy;
}
}

class Subject1
Expand Down
Expand Up @@ -6,8 +6,14 @@
use Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy;
use Symfony\Component\Workflow\Workflow;

/**
* @group legacy
*/
class ClassInstanceSupportStrategyTest extends TestCase
{
/**
* @expectedDeprecation "Symfony\Component\Workflow\SupportStrategy\ClassInstanceSupportStrategy" is deprecated since Symfony 4.1. Use "Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy" instead.
*/
public function testSupportsIfClassInstance()
{
$strategy = new ClassInstanceSupportStrategy('Symfony\Component\Workflow\Tests\SupportStrategy\Subject1');
Expand All @@ -29,10 +35,3 @@ private function createWorkflow()
->getMock();
}
}

class Subject1
{
}
class Subject2
{
}
@@ -0,0 +1,38 @@
<?php

namespace Symfony\Component\Workflow\Tests\SupportStrategy;

use PHPUnit\Framework\TestCase;
use Symfony\Component\Workflow\SupportStrategy\InstanceOfSupportStrategy;
use Symfony\Component\Workflow\Workflow;

class InstanceOfSupportStrategyTest extends TestCase
{
public function testSupportsIfClassInstance()
{
$strategy = new InstanceOfSupportStrategy(Subject1::class);

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

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

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

private function createWorkflow()
{
return $this->getMockBuilder(Workflow::class)
->disableOriginalConstructor()
->getMock();
}
}

class Subject1
{
}
class Subject2
{
}

0 comments on commit e8351d8

Please sign in to comment.