protected function setUp() { $this->env = new \Twig_Environment( new \Twig_Loader_Array( array( 'state' => '{{ finite_state(object) }}', 'transitions' => '{% for transition in finite_transitions(object) %}{{ transition }}{% endfor %}', 'properties' => '{% for property, val in finite_properties(object) %}{{ property }}{% endfor %}', 'has' => '{{ finite_has(object, property) ? "yes" : "no" }}', 'can' => '{{ finite_can(object, transition) ? "yes" : "no" }}' ) ) ); $container = new \Pimple(array( 'state_machine' => function() { $sm = new StateMachine; $sm->addState(new State('s1', State::TYPE_INITIAL, array(), array('foo' => true, 'bar' => false))); $sm->addTransition('t12', 's1', 's2'); $sm->addTransition('t23', 's2', 's3'); return $sm; } )); $this->context = new Context(new PimpleFactory($container, 'state_machine'));; $this->env->addExtension(new FiniteExtension($this->context)); }
protected function initialize() { $this->addStates(); $this->addTransitions(); $this->object->setObject($this->getStatefulObjectMock()); $this->object->initialize(); }
public function testLoadWithCustomStateAccessor() { $sa = $this->getMock('Finite\\State\\Accessor\\PropertyPathStateAccessor', array(), array(), 'CustomAccessor'); $sm = new StateMachine(); $sm->setStateAccessor($sa); $this->object->load($sm); $this->assertAttributeInstanceOf('CustomAccessor', 'stateAccessor', $sm); }
protected function setUp() { $container = new \Pimple(array('state_machine' => function () { $sm = new StateMachine(); $sm->addTransition('t12', 's1', 's2'); $sm->addTransition('t23', 's2', 's3'); return $sm; })); $this->object = new PimpleFactory($container, 'state_machine'); }
public function setUp() { $this->accessor = $accessor = $this->getMock('Finite\\State\\Accessor\\StateAccessorInterface'); $container = new \Pimple(array('state_machine' => function () use($accessor) { $sm = new StateMachine(null, null, $accessor); $sm->addTransition('t12', 's1', 's2'); $sm->addTransition('t23', 's2', 's3'); return $sm; })); $this->object = new PimpleFactory($container, 'state_machine'); }
/** * Configures $stateMachine according to selected object * * @param \Illuminate\Database\Eloquent\Model $object * @throws \Finite\Exception\ObjectException */ private function setStateMachine(\Illuminate\Database\Eloquent\Model $object) { $config = array_merge(['class' => get_class($object)], $object->getFiniteConfig()); if (!$object->finiteStates->isEmpty()) { $object->setFiniteState($object->latestFiniteState); } $loader = new ArrayLoader($config); $loader->load($this->stateMachine); $this->stateMachine->setObject($object); $this->stateMachine->initialize(); }
public function setUp() { $container = new \Pimple(array('state_machine' => function () { $sm = new StateMachine(); $sm->addState(new State('s1', State::TYPE_INITIAL, array(), array('foo' => true, 'bar' => false))); $sm->addTransition('t12', 's1', 's2'); $sm->addTransition('t23', 's2', 's3'); return $sm; })); $this->object = new Context(new PimpleFactory($container, 'state_machine')); }
public function setUp() { $this->accessor = $accessor = $this->getMock('Finite\\State\\Accessor\\StateAccessorInterface'); $container = new \Pimple(array('state_machine' => function () use($accessor) { $sm = new StateMachine(null, null, $accessor); $sm->addState(new State('s1', State::TYPE_INITIAL, array(), array('foo' => true, 'bar' => false))); $sm->addTransition('t12', 's1', 's2'); $sm->addTransition('t23', 's2', 's3'); return $sm; })); $this->object = new Context(new PimpleFactory($container, 'state_machine')); }
public function test() { $this->callbacksMock->expects($this->once())->method('afterItWasProposed'); $this->callbacksMock->expects($this->exactly(2))->method('afterItWasProposedOrReviewed'); $this->callbacksMock->expects($this->exactly(2))->method('afterItWasAnythingButProposed'); $this->callbacksMock->expects($this->once())->method('onReview'); $this->callbacksMock->expects($this->once())->method('afterItLeavesReviewed'); $this->stateMachine->apply('propose'); $this->stateMachine->apply('review'); $this->stateMachine->apply('publish'); $this->alternativeStateMachine->apply('propose'); $this->alternativeStateMachine->apply('review'); $this->alternativeStateMachine->apply('publish'); }
public function testSkipEdgeException() { $visitor = $this->mockVisitor(); $visitor->expects($this->once())->method('getEdgeAttributes')->willThrowException(new SkipElementException()); $g = $this->providerGraphviz(); $sm = new StateMachine(); $sm->addState(new State('s1', State::TYPE_INITIAL)); $sm->addState(new State('s2', State::TYPE_FINAL)); $sm->addTransition('t12', 's1', 's2'); $g->addVisitor($visitor); $dot = $g->render($sm); $this->assertNotContains('"t12"', $dot); $this->assertContains('"s1"', $dot); $this->assertContains('"s2"', $dot); }
/** * @{inheritDoc} */ public function can($transition) { $transition = $transition instanceof TransitionInterface ? $transition : $this->getTransition($transition); if (!$this->securityContext->isGranted($transition->getName(), $this->getObject())) { return false; } return parent::can($transition); }
/** * {@inheritdoc} */ public function can($transition, array $parameters = array()) { $transition = $transition instanceof TransitionInterface ? $transition : $this->getTransition($transition); if (!$this->authorizationChecker->isGranted($transition->getName(), $this->getObject())) { return false; } return parent::can($transition, $parameters); }
/** * Loads a issue state machine. * * @param \Kreta\Component\Issue\Model\Interfaces\IssueInterface $issue The issue * @param \Kreta\Component\Workflow\Model\Interfaces\StatusInterface[] $statuses A collection of * statuses * @param \Kreta\Component\Workflow\Model\Interfaces\StatusTransitionInterface[] $transitions A collection of * transitions * * @return $this self Object */ public function load(IssueInterface $issue, $statuses, $transitions) { $this->statuses = $statuses; $this->transitions = $transitions; parent::__construct($issue, null); $this->createLoader()->load($this); $this->initialize(); return $this; }
public function __construct(\Akzo\Scheme $scheme) { $this->_scheme = $scheme; parent::__construct($this->_scheme); $stateMachineDescription = array('class' => '\\Akzo\\Scheme', 'states' => array(\Akzo\Scheme\State::CREATED => array('type' => \Finite\State\StateInterface::TYPE_INITIAL, 'properties' => array('deletable' => true, 'editable' => true)), \Akzo\Scheme\State::STAGED => array('type' => \Finite\State\StateInterface::TYPE_NORMAL, 'properties' => array('deletable' => true, 'editable' => true)), \Akzo\Scheme\State::TO_BE_REVIEWED => array('type' => \Finite\State\StateInterface::TYPE_NORMAL, 'properties' => array('deletable' => false, 'editable' => false)), \Akzo\Scheme\State::TO_BE_APPROVED => array('type' => \Finite\State\StateInterface::TYPE_NORMAL, 'properties' => array('deletable' => false, 'editable' => false)), \Akzo\Scheme\State::APPROVED => array('type' => \Finite\State\StateInterface::TYPE_FINAL, 'properties' => array('deletable' => false, 'editable' => false)), \Akzo\Scheme\State::UPDATE_REQUESTED => array('type' => \Finite\State\StateInterface::TYPE_NORMAL, 'properties' => array('deletable' => true, 'editable' => true))), 'transitions' => array(\Akzo\Scheme\StateTransition::STAGE_SCHEME => array('from' => array(\Akzo\Scheme\State::CREATED), 'to' => \Akzo\Scheme\State::STAGED), \Akzo\Scheme\StateTransition::UPDATE_STAGED_SCHEME => array('from' => array(\Akzo\Scheme\State::STAGED), 'to' => \Akzo\Scheme\State::STAGED), \Akzo\Scheme\StateTransition::INITIATE_CREATED_SCHEME => array('from' => array(\Akzo\Scheme\State::CREATED), 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED), \Akzo\Scheme\StateTransition::INITIATE_STAGED_SCHEME => array('from' => array(\Akzo\Scheme\State::STAGED), 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED), \Akzo\Scheme\StateTransition::REVIEW_SCHEME => array('from' => array(\Akzo\Scheme\State::TO_BE_REVIEWED), 'to' => \Akzo\Scheme\State::TO_BE_APPROVED), \Akzo\Scheme\StateTransition::APPROVE_SCHEME => array('from' => array(\Akzo\Scheme\State::TO_BE_APPROVED), 'to' => \Akzo\Scheme\State::APPROVED), \Akzo\Scheme\StateTransition::REQUEST_SCHEME_UPDATE => array('from' => array(\Akzo\Scheme\State::TO_BE_REVIEWED, \Akzo\Scheme\State::TO_BE_APPROVED), 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED), \Akzo\Scheme\StateTransition::REQUEST_SCHEME_REVIEW => array('from' => array(\Akzo\Scheme\State::TO_BE_APPROVED), 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED), \Akzo\Scheme\StateTransition::UPDATE_SCHEME => array('from' => array(\Akzo\Scheme\State::UPDATE_REQUESTED), 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED), \Akzo\Scheme\StateTransition::INITIATE_UPDATED_SCHEME => array('from' => array(\Akzo\Scheme\State::UPDATE_REQUESTED), 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED), \Akzo\Scheme\StateTransition::EDIT_APPROVED_SCHEME => array('from' => array(\Akzo\Scheme\State::APPROVED), 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED)), 'callbacks' => array('after' => array(array('from' => \Akzo\Scheme\State::CREATED, 'to' => \Akzo\Scheme\State::STAGED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->createSaveScheme($scheme); }), array('from' => \Akzo\Scheme\State::STAGED, 'to' => \Akzo\Scheme\State::STAGED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->updateSaveScheme($scheme); }), array('from' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->updateSaveScheme($scheme); }), array('from' => \Akzo\Scheme\State::CREATED, 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->createSaveScheme($scheme); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::STAGED, 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->updateSaveScheme($scheme); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'do' => function ($scheme, $event) { \Akzo\Scheme\Service::getInstance()->updateSaveScheme($scheme); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'to' => \Akzo\Scheme\State::TO_BE_APPROVED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::TO_BE_APPROVED, 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::TO_BE_APPROVED, 'to' => \Akzo\Scheme\State::TO_BE_REVIEWED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::TO_BE_APPROVED, 'to' => \Akzo\Scheme\State::APPROVED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); $schemeID = $scheme->code; $schemeService = \Akzo\Scheme\Service::getInstance(); $schemeService->initiatePDFCreation($schemeID); // Send notification to initiator, reviewer, approver for intimating that scheme has been approved \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); }), array('from' => \Akzo\Scheme\State::APPROVED, 'to' => \Akzo\Scheme\State::UPDATE_REQUESTED, 'do' => function ($scheme, $event) { // Just update the state of scheme in the database $scheme->save(); // TODO: Merge this will the below savePublicTransition function // Send notification to initiator, reviewer, approver for sending request for re-review of scheme \Akzo\Scheme\Notifier::sendNotification($scheme, $event->getTransition()); // TODO: Merge this will the above sendNotification function // Save the state transition \Akzo\Scheme\Service::getInstance()->savePublicTransition($scheme, $event->getTransition()); })))); $loader = new \Finite\Loader\ArrayLoader($stateMachineDescription); $loader->load($this); $this->initialize(); }
/** * @param $name * * @return mixed * @throws \Finite\Exception\StateException */ public function transition($name) { return $this->stateMachine->apply($name); }
<?php use App\Things\Thing; use Finite\State\State; use Finite\State\StateInterface; use Finite\StateMachine\StateMachine; // Composer Autoloader require_once '../vendor/autoload.php'; // Create a new State Machine $stateMachine = new StateMachine(); // define some States $stateMachine->addState(new State('state1', StateInterface::TYPE_INITIAL)); $stateMachine->addState(new State('state2')); $stateMachine->addState(new State('state3')); $stateMachine->addState(new State('state4', StateInterface::TYPE_FINAL)); $thing = new Thing(); // add some transitions $stateMachine->addTransition('from_1_to_2', 'state1', 'state2'); $stateMachine->addTransition('from_2_to_3', 'state2', 'state3'); $stateMachine->addTransition('from_3_to_4', 'state3', 'state4'); $stateMachine->addTransition('from_4_to_2', 'state4', 'state2'); // add stateful object into state machine $stateMachine->setObject($thing); $stateMachine->initialize(); // current state echo $stateMachine->getCurrentState(); // can transition to a valid state var_dump($stateMachine->can('from_1_to_2')); // can transition to a invalid state var_dump($stateMachine->can('from_2_to_3')); // switch state
/** * Apply a transition. * * @param string $transitionName * @param array $parameters * * @return mixed * @throws StateException */ public function apply($transitionName, array $parameters = []) { return $this->stateMachine->apply($transitionName, $parameters); }