From 7c47114695d7b30407c424911bd3ec0419adff77 Mon Sep 17 00:00:00 2001 From: Jules Pietri Date: Fri, 11 Nov 2016 18:02:29 +0100 Subject: [PATCH] [Workflow] Made StateMachine supports only SingleStateMarkingStore --- .../Command/WorkflowDumpCommand.php | 7 +- .../DependencyInjection/Configuration.php | 1 + .../FrameworkExtension.php | 11 +- .../Resources/config/workflow.xml | 3 +- .../Exception/InvalidMarkingException.php | 30 ++++ .../InvalidMarkingStrategyException.php | 29 ++++ src/Symfony/Component/Workflow/Marking.php | 50 +++--- .../Workflow/MarkingStore/MarkingStore.php | 162 ++++++++++++++++++ .../MarkingStore/MarkingStoreInterface.php | 43 ----- .../MultipleStateMarkingStore.php | 57 ------ .../PropertyAccessMarkingStore.php | 80 +++++++++ .../MarkingStore/SingleStateMarkingStore.php | 62 ------- .../Workflow/MultipleStateMarking.php | 49 ++++++ src/Symfony/Component/Workflow/Registry.php | 8 + .../Component/Workflow/SingleStateMarking.php | 53 ++++++ .../Component/Workflow/StateMachine.php | 16 +- .../Tests/Dumper/GraphvizDumperTest.php | 6 +- .../EventListener/AuditTrailListenerTest.php | 4 +- .../Tests/MarkingStore/MarkingStoreTest.php | 18 ++ .../MultipleStateMarkingStoreTest.php | 32 ---- .../PropertyAccessMarkingStoreTest.php | 92 ++++++++++ .../SingleStateMarkingStoreTest.php | 32 ---- .../Component/Workflow/Tests/MarkingTest.php | 12 +- .../Component/Workflow/Tests/RegistryTest.php | 11 +- .../Workflow/Tests/StateMachineTest.php | 11 +- .../SinglePlaceWorkflowValidatorTest.php | 2 - .../Component/Workflow/Tests/WorkflowTest.php | 35 ++-- src/Symfony/Component/Workflow/Workflow.php | 12 +- 28 files changed, 624 insertions(+), 304 deletions(-) create mode 100644 src/Symfony/Component/Workflow/Exception/InvalidMarkingException.php create mode 100644 src/Symfony/Component/Workflow/Exception/InvalidMarkingStrategyException.php create mode 100644 src/Symfony/Component/Workflow/MarkingStore/MarkingStore.php delete mode 100644 src/Symfony/Component/Workflow/MarkingStore/MarkingStoreInterface.php delete mode 100644 src/Symfony/Component/Workflow/MarkingStore/MultipleStateMarkingStore.php create mode 100644 src/Symfony/Component/Workflow/MarkingStore/PropertyAccessMarkingStore.php delete mode 100644 src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php create mode 100644 src/Symfony/Component/Workflow/MultipleStateMarking.php create mode 100644 src/Symfony/Component/Workflow/SingleStateMarking.php create mode 100644 src/Symfony/Component/Workflow/Tests/MarkingStore/MarkingStoreTest.php delete mode 100644 src/Symfony/Component/Workflow/Tests/MarkingStore/MultipleStateMarkingStoreTest.php create mode 100644 src/Symfony/Component/Workflow/Tests/MarkingStore/PropertyAccessMarkingStoreTest.php delete mode 100644 src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php index ddfb987ff1937..b6834733064e1 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php +++ b/src/Symfony/Bundle/FrameworkBundle/Command/WorkflowDumpCommand.php @@ -15,8 +15,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Workflow\Dumper\GraphvizDumper; -use Symfony\Component\Workflow\Marking; -use Symfony\Component\Workflow\Workflow; +use Symfony\Component\Workflow\MultipleStateMarking; +use Symfony\Component\Workflow\SingleStateMarking; +use Symfony\Component\Workflow\StateMachine; /** * @author Grégoire Pineau @@ -67,7 +68,7 @@ protected function execute(InputInterface $input, OutputInterface $output) } $dumper = new GraphvizDumper(); - $marking = new Marking(); + $marking = $workflow instanceof StateMachine ? new SingleStateMarking() : new MultipleStateMarking(); foreach ($input->getArgument('marking') as $place) { $marking->mark($place); diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php index 708e84ad1f766..e45e76eda3825 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php @@ -244,6 +244,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode) ->children() ->enumNode('type') ->values(array('multiple_state', 'single_state')) + ->defaultValue('multiple_state') ->end() ->arrayNode('arguments') ->beforeNormalization() diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php index 666ba03b0e54e..75459e0ecf4f2 100644 --- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php +++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php @@ -431,13 +431,16 @@ private function registerWorkflowConfiguration(array $workflows, ContainerBuilde )); // Create MarkingStore - if (isset($workflow['marking_store']['type'])) { - $markingStoreDefinition = new DefinitionDecorator('workflow.marking_store.'.$workflow['marking_store']['type']); + if (isset($workflow['marking_store']['service'])) { + $markingStoreDefinition = new Reference($workflow['marking_store']['service']); + } else { + $markingStoreDefinition = new DefinitionDecorator('workflow.marking_store.property_access'); foreach ($workflow['marking_store']['arguments'] as $argument) { $markingStoreDefinition->addArgument($argument); } - } elseif (isset($workflow['marking_store']['service'])) { - $markingStoreDefinition = new Reference($workflow['marking_store']['service']); + + $markingStrategy = 'state_machine' === $type ? 'single_state' : $workflow['marking_store']['type']; + $markingStoreDefinition->replaceArgument(2, $markingStrategy); } // Create Workflow diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml index 76592087a2260..317588a956c59 100644 --- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml +++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/workflow.xml @@ -18,8 +18,7 @@ - - + diff --git a/src/Symfony/Component/Workflow/Exception/InvalidMarkingException.php b/src/Symfony/Component/Workflow/Exception/InvalidMarkingException.php new file mode 100644 index 0000000000000..f1c4cd57ac984 --- /dev/null +++ b/src/Symfony/Component/Workflow/Exception/InvalidMarkingException.php @@ -0,0 +1,30 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\Exception; + +/** + * An InvalidMarkingException is thrown when a Marking does not + * match the current workflow. + * + * @author Jules Pietri + */ +class InvalidMarkingException extends LogicException +{ + /** + * @param string $expectedClass + * @param mixed $marking + */ + public function __construct($expectedClass, $marking) + { + $this->message = sprintf('Marking must be an instance of "%", but got "%"', $expectedClass, is_object($marking) ? get_class($marking) : gettype($marking)); + } +} diff --git a/src/Symfony/Component/Workflow/Exception/InvalidMarkingStrategyException.php b/src/Symfony/Component/Workflow/Exception/InvalidMarkingStrategyException.php new file mode 100644 index 0000000000000..01744e529c600 --- /dev/null +++ b/src/Symfony/Component/Workflow/Exception/InvalidMarkingStrategyException.php @@ -0,0 +1,29 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\Exception; + +/** + * An InvalidMarkingStrategyException is thrown when the marking strategy + * does not match the Marking instance. + * + * @author Jules Pietri + */ +class InvalidMarkingStrategyException extends LogicException +{ + /** + * @param string $markingStoreClass + */ + public function __construct($markingStoreClass) + { + $this->message = sprintf('The marking store has no strategy set. Did you forgot to call "%::__construct()"?', $markingStoreClass); + } +} diff --git a/src/Symfony/Component/Workflow/Marking.php b/src/Symfony/Component/Workflow/Marking.php index 0d8bab25b7fe3..4007e44c63c7f 100644 --- a/src/Symfony/Component/Workflow/Marking.php +++ b/src/Symfony/Component/Workflow/Marking.php @@ -12,41 +12,45 @@ namespace Symfony\Component\Workflow; /** - * Marking contains the place of every tokens. + * A base Marking which contains the state of the + * state of a Workflow or a StateMachine a representation + * by places with tokens. * * @author Grégoire Pineau + * @author Jules Pietri */ -class Marking +abstract class Marking { - private $places = array(); + const STRATEGY_SINGLE_STATE = 'single_state'; + const STRATEGY_MULTIPLE_STATE = 'multiple_state'; + + protected $places = array(); /** - * @param string[] $representation Keys are the place name and values should be 1 + * @param string $place + * + * @return bool */ - public function __construct(array $representation = array()) - { - foreach ($representation as $place => $nbToken) { - $this->mark($place); - } - } - - public function mark($place) - { - $this->places[$place] = 1; - } - - public function unmark($place) - { - unset($this->places[$place]); - } - - public function has($place) + final public function has($place) { return isset($this->places[$place]); } - public function getPlaces() + /** + * @return int[] An array of places as keys and token counts as values. + */ + final public function getState() { return $this->places; } + + /** + * @param string $place + */ + abstract public function mark($place); + + /** + * @param string $place + */ + abstract public function unmark($place); } diff --git a/src/Symfony/Component/Workflow/MarkingStore/MarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/MarkingStore.php new file mode 100644 index 0000000000000..b4aa8354a55a8 --- /dev/null +++ b/src/Symfony/Component/Workflow/MarkingStore/MarkingStore.php @@ -0,0 +1,162 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\MarkingStore; + +use Symfony\Component\Workflow\Exception\InvalidArgumentException; +use Symfony\Component\Workflow\Exception\InvalidMarkingException; +use Symfony\Component\Workflow\Exception\InvalidMarkingStrategyException; +use Symfony\Component\Workflow\Marking; +use Symfony\Component\Workflow\MultipleStateMarking; +use Symfony\Component\Workflow\SingleStateMarking; + +/** + * A MarkingStore is the interface between the Workflow Component and a + * plain old PHP object: the subject. + * + * It converts the Marking into something understandable by the subject and vice + * versa. + * + * @author Grégoire Pineau + * @author Jules Pietri + */ +abstract class MarkingStore +{ + private $strategy; + + /** + * @param string $strategy A Marking constant + */ + public function __construct($strategy = Marking::STRATEGY_MULTIPLE_STATE) + { + $strategies = array(Marking::STRATEGY_SINGLE_STATE, Marking::STRATEGY_MULTIPLE_STATE); + if (!in_array($strategy, $strategies, true)) { + throw new InvalidArgumentException(sprintf('Marking strategy must be one of "%s", but got "%".', implode('" or "', $strategies), $strategy)); + } + + $this->strategy = $strategy; + } + + /** + * Returns the strategy used for marking. + * + * @return string A Marking constant + */ + final public function getStrategy() + { + return $this->strategy; + } + + /** + * Gets a Marking from a subject. + * + * @param object $subject A subject + * + * @return Marking The marking + * + * @throws InvalidMarkingException When the marking does not match the strategy + * @throws InvalidMarkingStrategyException When the strategy in unknown + */ + public function getMarking($subject) + { + if (Marking::STRATEGY_MULTIPLE_STATE === $this->strategy) { + $marking = $this->getMultipleStateMarking($subject); + + if (!$marking instanceof MultipleStateMarking) { + throw new InvalidMarkingException(MultipleStateMarking::class, $marking); + } + + return $marking; + } + + if (Marking::STRATEGY_SINGLE_STATE === $this->strategy) { + $marking = $this->getSingleStateMarking($subject); + + if (!$marking instanceof SingleStateMarking) { + throw new InvalidMarkingException(SingleStateMarking::class, $marking); + } + + return $marking; + } + + throw new InvalidMarkingStrategyException(static::class); + } + + /** + * Sets a Marking to a subject. + * + * Must return an + * + * @param object $subject A subject + * @param Marking $marking A marking + * + * @throws InvalidMarkingException When the marking does not match the strategy + * @throws InvalidMarkingStrategyException When the strategy in unknown + */ + public function setMarking($subject, Marking $marking) + { + if (Marking::STRATEGY_MULTIPLE_STATE === $this->strategy) { + if (!$marking instanceof MultipleStateMarking) { + throw new InvalidMarkingException(MultipleStateMarking::class, $marking); + } + + $this->setMultipleStateMarking($subject, $marking); + + return; + } + + if (Marking::STRATEGY_SINGLE_STATE === $this->strategy) { + if (!$marking instanceof SingleStateMarking) { + throw new InvalidMarkingException(SingleStateMarking::class, $marking); + } + + $this->setSingleStateMarking($subject, $marking); + + return; + } + + throw new InvalidMarkingStrategyException(static::class); + } + + /** + * Gets a SingleStateMarking from a subject. + * + * @param object $subject A subject + * + * @return SingleStateMarking The marking + */ + abstract protected function getSingleStateMarking($subject); + + /** + * Sets a SingleStateMarking to a subject. + * + * @param object $subject + * @param SingleStateMarking $marking + */ + abstract protected function setSingleStateMarking($subject, SingleStateMarking $marking); + + /** + * Gets a MultipleStateMarking from a subject. + * + * @param object $subject A subject + * + * @return MultipleStateMarking The marking + */ + abstract protected function getMultipleStateMarking($subject); + + /** + * Sets a MultipleStateMarking to a subject. + * + * @param object $subject + * @param MultipleStateMarking $marking + */ + abstract protected function setMultipleStateMarking($subject, MultipleStateMarking $marking); +} diff --git a/src/Symfony/Component/Workflow/MarkingStore/MarkingStoreInterface.php b/src/Symfony/Component/Workflow/MarkingStore/MarkingStoreInterface.php deleted file mode 100644 index 76df9cc0d2160..0000000000000 --- a/src/Symfony/Component/Workflow/MarkingStore/MarkingStoreInterface.php +++ /dev/null @@ -1,43 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Workflow\MarkingStore; - -use Symfony\Component\Workflow\Marking; - -/** - * MarkingStoreInterface is the interface between the Workflow Component and a - * plain old PHP object: the subject. - * - * It converts the Marking into something understandable by the subject and vice - * versa. - * - * @author Grégoire Pineau - */ -interface MarkingStoreInterface -{ - /** - * Gets a Marking from a subject. - * - * @param object $subject A subject - * - * @return Marking The marking - */ - public function getMarking($subject); - - /** - * Sets a Marking to a subject. - * - * @param object $subject A subject - * @param Marking $marking A marking - */ - public function setMarking($subject, Marking $marking); -} diff --git a/src/Symfony/Component/Workflow/MarkingStore/MultipleStateMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/MultipleStateMarkingStore.php deleted file mode 100644 index 874d1fb5134a5..0000000000000 --- a/src/Symfony/Component/Workflow/MarkingStore/MultipleStateMarkingStore.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Workflow\MarkingStore; - -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; -use Symfony\Component\Workflow\Marking; - -/** - * MultipleStateMarkingStore stores the marking into a property of the - * subject. - * - * This store deals with a "multiple state" Marking. It means a subject can be - * in many states at the same time. - * - * @author Grégoire Pineau - */ -class MultipleStateMarkingStore implements MarkingStoreInterface -{ - private $property; - private $propertyAccessor; - - /** - * @param string $property - * @param PropertyAccessorInterface|null $propertyAccessor - */ - public function __construct($property = 'marking', PropertyAccessorInterface $propertyAccessor = null) - { - $this->property = $property; - $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); - } - - /** - * {@inheritdoc} - */ - public function getMarking($subject) - { - return new Marking($this->propertyAccessor->getValue($subject, $this->property) ?: array()); - } - - /** - * {@inheritdoc} - */ - public function setMarking($subject, Marking $marking) - { - $this->propertyAccessor->setValue($subject, $this->property, $marking->getPlaces()); - } -} diff --git a/src/Symfony/Component/Workflow/MarkingStore/PropertyAccessMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/PropertyAccessMarkingStore.php new file mode 100644 index 0000000000000..7626d20183089 --- /dev/null +++ b/src/Symfony/Component/Workflow/MarkingStore/PropertyAccessMarkingStore.php @@ -0,0 +1,80 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow\MarkingStore; + +use Symfony\Component\PropertyAccess\PropertyAccess; +use Symfony\Component\PropertyAccess\PropertyAccessorInterface; +use Symfony\Component\Workflow\Marking; +use Symfony\Component\Workflow\MultipleStateMarking; +use Symfony\Component\Workflow\SingleStateMarking; + +/** + * PropertyAccessMarkingStore stores the marking into a property of the subject using + * a PropertyAccessor. + * + * This store deals with both "single state" and "multiple state" Marking. It means a subject + * can be in one or many states at the same time depending of the marking strategy. + * + * @author Grégoire Pineau + * @author Jules Pietri + */ +class PropertyAccessMarkingStore extends MarkingStore +{ + private $property; + private $propertyAccessor; + + /** + * @param string $strategy + * @param string $property + * @param PropertyAccessorInterface|null $propertyAccessor + * @param string $strategy A Marking constant + */ + public function __construct($property = 'marking', PropertyAccessorInterface $propertyAccessor = null, $strategy = Marking::STRATEGY_MULTIPLE_STATE) + { + parent::__construct($strategy); + + $this->property = $property; + $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); + } + + /** + * {@inheritdoc} + */ + public function getSingleStateMarking($subject) + { + return new SingleStateMarking($this->propertyAccessor->getValue($subject, $this->property)); + } + + /** + * {@inheritdoc} + */ + public function getMultipleStateMarking($subject) + { + return new MultipleStateMarking($this->propertyAccessor->getValue($subject, $this->property) ?: array()); + } + + /** + * {@inheritdoc} + */ + public function setSingleStateMarking($subject, SingleStateMarking $marking) + { + $this->propertyAccessor->setValue($subject, $this->property, key($marking->getState())); + } + + /** + * {@inheritdoc} + */ + public function setMultipleStateMarking($subject, MultipleStateMarking $marking) + { + $this->propertyAccessor->setValue($subject, $this->property, $marking->getState()); + } +} diff --git a/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php b/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php deleted file mode 100644 index 99adf1671bab1..0000000000000 --- a/src/Symfony/Component/Workflow/MarkingStore/SingleStateMarkingStore.php +++ /dev/null @@ -1,62 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Symfony\Component\Workflow\MarkingStore; - -use Symfony\Component\PropertyAccess\PropertyAccess; -use Symfony\Component\PropertyAccess\PropertyAccessorInterface; -use Symfony\Component\Workflow\Marking; - -/** - * SingleStateMarkingStore stores the marking into a property of the subject. - * - * This store deals with a "single state" Marking. It means a subject can be in - * one and only one state at the same time. - * - * @author Grégoire Pineau - */ -class SingleStateMarkingStore implements MarkingStoreInterface -{ - private $property; - private $propertyAccessor; - - /** - * @param string $property - * @param PropertyAccessorInterface|null $propertyAccessor - */ - public function __construct($property = 'marking', PropertyAccessorInterface $propertyAccessor = null) - { - $this->property = $property; - $this->propertyAccessor = $propertyAccessor ?: PropertyAccess::createPropertyAccessor(); - } - - /** - * {@inheritdoc} - */ - public function getMarking($subject) - { - $placeName = $this->propertyAccessor->getValue($subject, $this->property); - - if (!$placeName) { - return new Marking(); - } - - return new Marking(array($placeName => 1)); - } - - /** - * {@inheritdoc} - */ - public function setMarking($subject, Marking $marking) - { - $this->propertyAccessor->setValue($subject, $this->property, key($marking->getPlaces())); - } -} diff --git a/src/Symfony/Component/Workflow/MultipleStateMarking.php b/src/Symfony/Component/Workflow/MultipleStateMarking.php new file mode 100644 index 0000000000000..997aaab17db61 --- /dev/null +++ b/src/Symfony/Component/Workflow/MultipleStateMarking.php @@ -0,0 +1,49 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow; + +/** + * MultipleStateMarking contains the place of every tokens. + * + * @author Grégoire Pineau + * @author Jules Pietri + */ +class MultipleStateMarking extends Marking +{ + /** + * @param string[] $representation Keys are the place name and values should be the number of tokens + */ + public function __construct(array $representation = array()) + { + foreach ($representation as $place => $nbToken) { + $this->mark($place); + } + } + + /** + * {@inheritdoc} + */ + public function mark($place) + { + if (!isset($this->places[$place])) { + $this->places[$place] = 1; + } + } + + /** + * {@inheritdoc} + */ + public function unmark($place) + { + unset($this->places[$place]); + } +} diff --git a/src/Symfony/Component/Workflow/Registry.php b/src/Symfony/Component/Workflow/Registry.php index 619ed5f66a5b1..99ab6db38d5f5 100644 --- a/src/Symfony/Component/Workflow/Registry.php +++ b/src/Symfony/Component/Workflow/Registry.php @@ -30,6 +30,14 @@ public function add(Workflow $workflow, $className) $this->workflows[] = array($workflow, $className); } + /** + * @param string $subject + * @param string|null $workflowName + * + * @return Workflow + * + * @throws InvalidArgumentException When no workflow is matched + */ public function get($subject, $workflowName = null) { $matched = null; diff --git a/src/Symfony/Component/Workflow/SingleStateMarking.php b/src/Symfony/Component/Workflow/SingleStateMarking.php new file mode 100644 index 0000000000000..7017e5937efcd --- /dev/null +++ b/src/Symfony/Component/Workflow/SingleStateMarking.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\Workflow; + +use Symfony\Component\Workflow\Exception\InvalidArgumentException; + +/** + * SingleStateMarking contains the place of one token. + * + * @author Grégoire Pineau + * @author Jules Pietri + */ +class SingleStateMarking extends Marking +{ + /** + * @param mixed $place A scalar as only place or null + */ + public function __construct($place = null) + { + if (null !== $place && !is_scalar($place)) { + throw new InvalidArgumentException(sprintf('"%s" instances only accept scalar or null as single place, but got "%s".', __CLASS__, is_object($place) ? get_class($place) : gettype($place))); + } + + if ($place) { + $this->mark($place); + } + } + + /** + * {@inheritdoc} + */ + public function mark($place) + { + $this->places = array($place => 1); + } + + /** + * {@inheritdoc} + */ + public function unmark($place) + { + unset($this->places[$place]); + } +} diff --git a/src/Symfony/Component/Workflow/StateMachine.php b/src/Symfony/Component/Workflow/StateMachine.php index 00cfdac7d493a..4edb6a32196ee 100644 --- a/src/Symfony/Component/Workflow/StateMachine.php +++ b/src/Symfony/Component/Workflow/StateMachine.php @@ -3,16 +3,24 @@ namespace Symfony\Component\Workflow; use Symfony\Component\EventDispatcher\EventDispatcherInterface; -use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface; -use Symfony\Component\Workflow\MarkingStore\SingleStateMarkingStore; +use Symfony\Component\Workflow\Exception\InvalidArgumentException; +use Symfony\Component\Workflow\MarkingStore\MarkingStore; +use Symfony\Component\Workflow\MarkingStore\PropertyAccessMarkingStore; /** * @author Tobias Nyholm + * @author Jules Pietri */ class StateMachine extends Workflow { - public function __construct(Definition $definition, MarkingStoreInterface $markingStore = null, EventDispatcherInterface $dispatcher = null, $name = 'unnamed') + public function __construct(Definition $definition, MarkingStore $markingStore = null, EventDispatcherInterface $dispatcher = null, $name = 'unnamed') { - parent::__construct($definition, $markingStore ?: new SingleStateMarkingStore(), $dispatcher, $name); + if (null !== $markingStore && Marking::STRATEGY_SINGLE_STATE !== $strategy = $markingStore->getStrategy()) { + throw new InvalidArgumentException(sprintf('"%s" class only supports strategy "%s" for marking, but got "%s". Consider using the "%s" class instead.', __CLASS__, Marking::STRATEGY_SINGLE_STATE, $strategy, parent::class)); + } + + $markingStore = $markingStore ?: new PropertyAccessMarkingStore('marking', null, Marking::STRATEGY_SINGLE_STATE); + + parent::__construct($definition, $markingStore, $dispatcher, $name); } } diff --git a/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php b/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php index f24bb003a892a..4ca33dd7572e3 100644 --- a/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php +++ b/src/Symfony/Component/Workflow/Tests/Dumper/GraphvizDumperTest.php @@ -4,8 +4,8 @@ use Symfony\Component\Workflow\DefinitionBuilder; use Symfony\Component\Workflow\Dumper\GraphvizDumper; -use Symfony\Component\Workflow\Marking; use Symfony\Component\Workflow\Transition; +use Symfony\Component\Workflow\MultipleStateMarking; class GraphvizDumperTest extends \PHPUnit_Framework_TestCase { @@ -40,13 +40,13 @@ public function provideWorkflowDefinitionWithMarking() { yield array( $this->provideComplexWorkflowDefinition(), - new Marking(array('b' => 1)), + new MultipleStateMarking(array('b' => 1)), $this->createComplexWorkflowDumpWithMarking(), ); yield array( $this->provideSimpleWorkflowDefinition(), - new Marking(array('c' => 1, 'd' => 1)), + new MultipleStateMarking(array('c' => 1, 'd' => 1)), $this->createSimpleWorkflowDumpWithMarking(), ); } diff --git a/src/Symfony/Component/Workflow/Tests/EventListener/AuditTrailListenerTest.php b/src/Symfony/Component/Workflow/Tests/EventListener/AuditTrailListenerTest.php index c3982f1787608..729842eb8e9ce 100644 --- a/src/Symfony/Component/Workflow/Tests/EventListener/AuditTrailListenerTest.php +++ b/src/Symfony/Component/Workflow/Tests/EventListener/AuditTrailListenerTest.php @@ -6,7 +6,7 @@ use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\Workflow\Definition; use Symfony\Component\Workflow\EventListener\AuditTrailListener; -use Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore; +use Symfony\Component\Workflow\MarkingStore\PropertyAccessMarkingStore; use Symfony\Component\Workflow\Transition; use Symfony\Component\Workflow\Workflow; @@ -29,7 +29,7 @@ public function testItWorks() $ed = new EventDispatcher(); $ed->addSubscriber(new AuditTrailListener($logger)); - $workflow = new Workflow($definition, new MultipleStateMarkingStore(), $ed); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore(), $ed); $workflow->apply($object, 't1'); diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/MarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/MarkingStoreTest.php new file mode 100644 index 0000000000000..5c923c89d27f9 --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/MarkingStore/MarkingStoreTest.php @@ -0,0 +1,18 @@ +getClass(); + $markingStore = new $markingStoreClass(); + + $this->assertSame(Marking::STRATEGY_MULTIPLE_STATE, $markingStore->getStrategy()); + } + + abstract public function getClass(); +} diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/MultipleStateMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/MultipleStateMarkingStoreTest.php deleted file mode 100644 index 7e324c530eff8..0000000000000 --- a/src/Symfony/Component/Workflow/Tests/MarkingStore/MultipleStateMarkingStoreTest.php +++ /dev/null @@ -1,32 +0,0 @@ -myMarks = null; - - $markingStore = new MultipleStateMarkingStore('myMarks'); - - $marking = $markingStore->getMarking($subject); - - $this->assertInstanceOf(Marking::class, $marking); - $this->assertCount(0, $marking->getPlaces()); - - $marking->mark('first_place'); - - $markingStore->setMarking($subject, $marking); - - $this->assertSame(array('first_place' => 1), $subject->myMarks); - - $marking2 = $markingStore->getMarking($subject); - - $this->assertEquals($marking, $marking2); - } -} diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/PropertyAccessMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/PropertyAccessMarkingStoreTest.php new file mode 100644 index 0000000000000..77ad8083cddeb --- /dev/null +++ b/src/Symfony/Component/Workflow/Tests/MarkingStore/PropertyAccessMarkingStoreTest.php @@ -0,0 +1,92 @@ +myMarks = null; + + $markingStore = new PropertyAccessMarkingStore('myMarks', null, Marking::STRATEGY_SINGLE_STATE); + + $marking = $markingStore->getMarking($subject); + + $this->assertInstanceOf(SingleStateMarking::class, $marking); + $this->assertSame(array(), $marking->getState()); + + $marking->mark('first_place'); + + $markingStore->setMarking($subject, $marking); + + $this->assertSame('first_place', $subject->myMarks); + + $marking2 = $markingStore->getMarking($subject); + + $this->assertEquals($marking, $marking2); + + $marking2->mark('second_place'); + + $markingStore->setMarking($subject, $marking2); + + $this->assertSame('second_place', $subject->myMarks); + + $marking3 = $markingStore->getMarking($subject); + + $this->assertEquals($marking2, $marking3); + + $marking3->unmark('second_place'); + + $markingStore->setMarking($subject, $marking3); + + $this->assertNull($subject->myMarks); + + $marking4 = $markingStore->getMarking($subject); + + $this->assertEquals($marking3, $marking4); + } + + public function testGetSetMultipleStateMarking() + { + $subject = new \stdClass(); + $subject->myMarks = null; + + $markingStore = new PropertyAccessMarkingStore('myMarks'); + + $marking = $markingStore->getMarking($subject); + + $this->assertInstanceOf(MultipleStateMarking::class, $marking); + $this->assertCount(0, $marking->getState()); + + $marking->mark('first_place'); + + $markingStore->setMarking($subject, $marking); + + $this->assertSame(array('first_place' => 1), $subject->myMarks); + + $marking2 = $markingStore->getMarking($subject); + + $this->assertEquals($marking, $marking2); + + $marking2->mark('second_place'); + + $markingStore->setMarking($subject, $marking2); + + $this->assertSame(array('first_place' => 1, 'second_place' => 1), $subject->myMarks); + + $marking3 = $markingStore->getMarking($subject); + + $this->assertEquals($marking2, $marking3); + } +} diff --git a/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php b/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php deleted file mode 100644 index ad3fae189aca5..0000000000000 --- a/src/Symfony/Component/Workflow/Tests/MarkingStore/SingleStateMarkingStoreTest.php +++ /dev/null @@ -1,32 +0,0 @@ -myMarks = null; - - $markingStore = new SingleStateMarkingStore('myMarks'); - - $marking = $markingStore->getMarking($subject); - - $this->assertInstanceOf(Marking::class, $marking); - $this->assertCount(0, $marking->getPlaces()); - - $marking->mark('first_place'); - - $markingStore->setMarking($subject, $marking); - - $this->assertSame('first_place', $subject->myMarks); - - $marking2 = $markingStore->getMarking($subject); - - $this->assertEquals($marking, $marking2); - } -} diff --git a/src/Symfony/Component/Workflow/Tests/MarkingTest.php b/src/Symfony/Component/Workflow/Tests/MarkingTest.php index 026ca607bee13..2fe026bdd5081 100644 --- a/src/Symfony/Component/Workflow/Tests/MarkingTest.php +++ b/src/Symfony/Component/Workflow/Tests/MarkingTest.php @@ -2,34 +2,34 @@ namespace Symfony\Component\Workflow\Tests; -use Symfony\Component\Workflow\Marking; +use Symfony\Component\Workflow\MultipleStateMarking; class MarkingTest extends \PHPUnit_Framework_TestCase { public function testMarking() { - $marking = new Marking(array('a' => 1)); + $marking = new MultipleStateMarking(array('a' => 1)); $this->assertTrue($marking->has('a')); $this->assertFalse($marking->has('b')); - $this->assertSame(array('a' => 1), $marking->getPlaces()); + $this->assertSame(array('a' => 1), $marking->getState()); $marking->mark('b'); $this->assertTrue($marking->has('a')); $this->assertTrue($marking->has('b')); - $this->assertSame(array('a' => 1, 'b' => 1), $marking->getPlaces()); + $this->assertSame(array('a' => 1, 'b' => 1), $marking->getState()); $marking->unmark('a'); $this->assertFalse($marking->has('a')); $this->assertTrue($marking->has('b')); - $this->assertSame(array('b' => 1), $marking->getPlaces()); + $this->assertSame(array('b' => 1), $marking->getState()); $marking->unmark('b'); $this->assertFalse($marking->has('a')); $this->assertFalse($marking->has('b')); - $this->assertSame(array(), $marking->getPlaces()); + $this->assertSame(array(), $marking->getState()); } } diff --git a/src/Symfony/Component/Workflow/Tests/RegistryTest.php b/src/Symfony/Component/Workflow/Tests/RegistryTest.php index 90b537c4b99c1..36ec9aeac4ba8 100644 --- a/src/Symfony/Component/Workflow/Tests/RegistryTest.php +++ b/src/Symfony/Component/Workflow/Tests/RegistryTest.php @@ -4,12 +4,15 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\Workflow\Definition; -use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface; +use Symfony\Component\Workflow\MarkingStore\MarkingStore; use Symfony\Component\Workflow\Registry; use Symfony\Component\Workflow\Workflow; class RegistryTest extends \PHPUnit_Framework_TestCase { + /** + * @var Registry + */ private $registry; protected function setUp() @@ -18,9 +21,9 @@ 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'), Subject1::class); - $this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow2'), Subject2::class); - $this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow3'), Subject2::class); + $this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStore::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow1'), Subject1::class); + $this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStore::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow2'), Subject2::class); + $this->registry->add(new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStore::class)->getMock(), $this->getMockBuilder(EventDispatcherInterface::class)->getMock(), 'workflow3'), Subject2::class); } protected function tearDown() diff --git a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php index 6aa3c60fc1cc6..73d121422e09d 100644 --- a/src/Symfony/Component/Workflow/Tests/StateMachineTest.php +++ b/src/Symfony/Component/Workflow/Tests/StateMachineTest.php @@ -3,12 +3,21 @@ namespace Symfony\Component\Workflow\Tests; use Symfony\Component\Workflow\Definition; -use Symfony\Component\Workflow\Marking; +use Symfony\Component\Workflow\MarkingStore\PropertyAccessMarkingStore; use Symfony\Component\Workflow\StateMachine; use Symfony\Component\Workflow\Transition; class StateMachineTest extends \PHPUnit_Framework_TestCase { + /** + * @expectedException \Symfony\Component\Workflow\Exception\InvalidArgumentException + * @expectedExceptionMessage "Symfony\Component\Workflow\StateMachine" class only supports strategy "single_state" for marking, but got "multiple_state". Consider using the "Symfony\Component\Workflow\Workflow" class instead. + */ + public function testWithInvalidMarkingStoreStore() + { + $stateMachine = new StateMachine(new Definition(array(), array()), new PropertyAccessMarkingStore()); + } + public function testCan() { $places = array('a', 'b', 'c', 'd'); diff --git a/src/Symfony/Component/Workflow/Tests/Validator/SinglePlaceWorkflowValidatorTest.php b/src/Symfony/Component/Workflow/Tests/Validator/SinglePlaceWorkflowValidatorTest.php index db433ff0b6dee..d051b666c6a8a 100644 --- a/src/Symfony/Component/Workflow/Tests/Validator/SinglePlaceWorkflowValidatorTest.php +++ b/src/Symfony/Component/Workflow/Tests/Validator/SinglePlaceWorkflowValidatorTest.php @@ -3,11 +3,9 @@ namespace Symfony\Component\Workflow\Tests\Validator; use Symfony\Component\Workflow\Definition; -use Symfony\Component\Workflow\Marking; use Symfony\Component\Workflow\Tests\WorkflowTest; use Symfony\Component\Workflow\Transition; use Symfony\Component\Workflow\Validator\SinglePlaceWorkflowValidator; -use Symfony\Component\Workflow\Workflow; class SinglePlaceWorkflowValidatorTest extends WorkflowTest { diff --git a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php index f5141c0fffba1..1b26e5a959500 100644 --- a/src/Symfony/Component/Workflow/Tests/WorkflowTest.php +++ b/src/Symfony/Component/Workflow/Tests/WorkflowTest.php @@ -6,9 +6,8 @@ use Symfony\Component\Workflow\Definition; use Symfony\Component\Workflow\DefinitionBuilder; use Symfony\Component\Workflow\Event\GuardEvent; -use Symfony\Component\Workflow\Marking; -use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface; -use Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore; +use Symfony\Component\Workflow\MarkingStore\PropertyAccessMarkingStore; +use Symfony\Component\Workflow\MultipleStateMarking; use Symfony\Component\Workflow\Transition; use Symfony\Component\Workflow\Workflow; @@ -22,7 +21,7 @@ public function testGetMarkingWithInvalidStoreReturn() { $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow(new Definition(array(), array()), $this->getMockBuilder(MarkingStoreInterface::class)->getMock()); + $workflow = new Workflow(new Definition(array(), array()), $this->getMockBuilder(PropertyAccessMarkingStore::class)->getMock()); $workflow->getMarking($subject); } @@ -35,7 +34,7 @@ public function testGetMarkingWithEmptyDefinition() { $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow(new Definition(array(), array()), new MultipleStateMarkingStore()); + $workflow = new Workflow(new Definition(array(), array()), new PropertyAccessMarkingStore()); $workflow->getMarking($subject); } @@ -49,7 +48,7 @@ public function testGetMarkingWithImpossiblePlace() $subject = new \stdClass(); $subject->marking = null; $subject->marking = array('nope' => true); - $workflow = new Workflow(new Definition(array(), array()), new MultipleStateMarkingStore()); + $workflow = new Workflow(new Definition(array(), array()), new PropertyAccessMarkingStore()); $workflow->getMarking($subject); } @@ -59,11 +58,11 @@ public function testGetMarkingWithEmptyInitialMarking() $definition = $this->createComplexWorkflow(); $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $marking = $workflow->getMarking($subject); - $this->assertInstanceOf(Marking::class, $marking); + $this->assertInstanceOf(MultipleStateMarking::class, $marking); $this->assertTrue($marking->has('a')); $this->assertSame(array('a' => 1), $subject->marking); } @@ -74,11 +73,11 @@ public function testGetMarkingWithExistingMarking() $subject = new \stdClass(); $subject->marking = null; $subject->marking = array('b' => 1, 'c' => 1); - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $marking = $workflow->getMarking($subject); - $this->assertInstanceOf(Marking::class, $marking); + $this->assertInstanceOf(MultipleStateMarking::class, $marking); $this->assertTrue($marking->has('b')); $this->assertTrue($marking->has('c')); } @@ -92,7 +91,7 @@ public function testCanWithUnexistingTransition() $definition = $this->createComplexWorkflow(); $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $workflow->can($subject, 'foobar'); } @@ -102,7 +101,7 @@ public function testCan() $definition = $this->createComplexWorkflow(); $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $this->assertTrue($workflow->can($subject, 't1')); $this->assertFalse($workflow->can($subject, 't2')); @@ -117,7 +116,7 @@ public function testCanWithGuard() $eventDispatcher->addListener('workflow.workflow_name.guard.t1', function (GuardEvent $event) { $event->setBlocked(true); }); - $workflow = new Workflow($definition, new MultipleStateMarkingStore(), $eventDispatcher, 'workflow_name'); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore(), $eventDispatcher, 'workflow_name'); $this->assertFalse($workflow->can($subject, 't1')); } @@ -131,7 +130,7 @@ public function testApplyWithImpossibleTransition() $definition = $this->createComplexWorkflow(); $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $workflow->apply($subject, 't2'); } @@ -141,11 +140,11 @@ public function testApply() $definition = $this->createComplexWorkflow(); $subject = new \stdClass(); $subject->marking = null; - $workflow = new Workflow($definition, new MultipleStateMarkingStore()); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore()); $marking = $workflow->apply($subject, 't1'); - $this->assertInstanceOf(Marking::class, $marking); + $this->assertInstanceOf(MultipleStateMarking::class, $marking); $this->assertFalse($marking->has('a')); $this->assertTrue($marking->has('b')); $this->assertTrue($marking->has('c')); @@ -157,7 +156,7 @@ public function testApplyWithEventDispatcher() $subject = new \stdClass(); $subject->marking = null; $eventDispatcher = new EventDispatcherMock(); - $workflow = new Workflow($definition, new MultipleStateMarkingStore(), $eventDispatcher, 'workflow_name'); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore(), $eventDispatcher, 'workflow_name'); $eventNameExpected = array( 'workflow.guard', @@ -194,7 +193,7 @@ public function testGetEnabledTransitions() $eventDispatcher->addListener('workflow.workflow_name.guard.t1', function (GuardEvent $event) { $event->setBlocked(true); }); - $workflow = new Workflow($definition, new MultipleStateMarkingStore(), $eventDispatcher, 'workflow_name'); + $workflow = new Workflow($definition, new PropertyAccessMarkingStore(), $eventDispatcher, 'workflow_name'); $this->assertEmpty($workflow->getEnabledTransitions($subject)); diff --git a/src/Symfony/Component/Workflow/Workflow.php b/src/Symfony/Component/Workflow/Workflow.php index b66cc85f51d90..4a83320922274 100644 --- a/src/Symfony/Component/Workflow/Workflow.php +++ b/src/Symfony/Component/Workflow/Workflow.php @@ -15,8 +15,8 @@ use Symfony\Component\Workflow\Event\Event; use Symfony\Component\Workflow\Event\GuardEvent; use Symfony\Component\Workflow\Exception\LogicException; -use Symfony\Component\Workflow\MarkingStore\MarkingStoreInterface; -use Symfony\Component\Workflow\MarkingStore\MultipleStateMarkingStore; +use Symfony\Component\Workflow\MarkingStore\MarkingStore; +use Symfony\Component\Workflow\MarkingStore\PropertyAccessMarkingStore; /** * @author Fabien Potencier @@ -30,10 +30,10 @@ class Workflow private $dispatcher; private $name; - public function __construct(Definition $definition, MarkingStoreInterface $markingStore = null, EventDispatcherInterface $dispatcher = null, $name = 'unnamed') + public function __construct(Definition $definition, MarkingStore $markingStore = null, EventDispatcherInterface $dispatcher = null, $name = 'unnamed') { $this->definition = $definition; - $this->markingStore = $markingStore ?: new MultipleStateMarkingStore(); + $this->markingStore = $markingStore ?: new PropertyAccessMarkingStore(); $this->dispatcher = $dispatcher; $this->name = $name; } @@ -56,7 +56,7 @@ public function getMarking($subject) } // check if the subject is already in the workflow - if (!$marking->getPlaces()) { + if (!$marking->getState()) { if (!$this->definition->getInitialPlace()) { throw new LogicException(sprintf('The Marking is empty and there is no initial place for workflow "%s".', $this->name)); } @@ -65,7 +65,7 @@ public function getMarking($subject) // check that the subject has a known place $places = $this->definition->getPlaces(); - foreach ($marking->getPlaces() as $placeName => $nbToken) { + foreach ($marking->getState() as $placeName => $nbToken) { if (!isset($places[$placeName])) { $message = sprintf('Place "%s" is not valid for workflow "%s".', $placeName, $this->name); if (!$places) {