/** * @return StateMachineInterface */ public function build() { $stateMachineBuilder = new StateMachineBuilder('registration'); $stateMachineBuilder->addState('input'); $stateMachineBuilder->addState('confirmation'); $stateMachineBuilder->addState('success'); $stateMachineBuilder->setStartState('input'); $stateMachineBuilder->addTransition('input', 'confirmation', 'confirmation'); $stateMachineBuilder->addTransition('confirmation', 'success', 'success'); $stateMachineBuilder->addTransition('confirmation', 'input', 'input'); $stateMachineBuilder->setEndState('success', StateInterface::STATE_FINAL); return $stateMachineBuilder->getStateMachine(); }
/** * Configures a PageFlow object from the specified definition. * * @return \Piece\Flow\PageFlow\PageFlowInterface * @throws \Piece\Flow\PageFlow\ProtectedStateException */ public function generate() { $definition = $this->readDefinition(); if (in_array($definition['firstState'], array(StateInterface::STATE_INITIAL, StateInterface::STATE_FINAL))) { throw new ProtectedStateException("The state [ {$definition['firstState']} ] cannot be used in flow definitions."); } foreach ($definition['viewState'] as $state) { if (in_array($state['name'], array(StateInterface::STATE_INITIAL, StateInterface::STATE_FINAL))) { throw new ProtectedStateException("The state [ {$state['name']} ] cannot be used in flow definitions."); } $this->addState(new ViewState($state['name'])); } foreach ($definition['actionState'] as $state) { if (in_array($state['name'], array(StateInterface::STATE_INITIAL, StateInterface::STATE_FINAL))) { throw new ProtectedStateException("The state [ {$state['name']} ] cannot be used in flow definitions."); } $this->addState(new ActionState($state['name'])); } if (!empty($definition['lastState'])) { if (in_array($definition['lastState']['name'], array(StateInterface::STATE_INITIAL, StateInterface::STATE_FINAL))) { throw new ProtectedStateException("The state [ {$definition['lastState']['name']} ] cannot be used in flow definitions."); } $this->addState(new ViewState($definition['lastState']['name'])); } if (empty($definition['initial'])) { $this->stateMachineBuilder->setStartState($definition['firstState']); } else { $this->stateMachineBuilder->setStartState($definition['firstState'], $this->wrapAction($definition['initial'])); } if (!empty($definition['lastState'])) { if (empty($definition['final'])) { $this->stateMachineBuilder->setEndState($definition['lastState']['name'], PageFlowInterface::EVENT_END); } else { $this->stateMachineBuilder->setEndState($definition['lastState']['name'], PageFlowInterface::EVENT_END, $this->wrapAction($definition['final'])); } $this->configureViewState($definition['lastState']); $this->stateMachineBuilder->getStateMachine()->getState($definition['lastState']['name'])->setView($definition['lastState']['view']); } $this->configureViewStates($definition['viewState']); $this->configureActionStates($definition['actionState']); return $this->pageFlow; }
/** * @test */ public function dispatchesSystemEventsToListenersIfTheEventDispatcherHasBeenSet() { $events = array(); $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener(StateMachineEvents::EVENT_PROCESS, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_EXIT, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_TRANSITION, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_ENTRY, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $eventDispatcher->addListener(StateMachineEvents::EVENT_DO, function (StateMachineEvent $event, $eventName, EventDispatcherInterface $eventDispatcher) use(&$events) { $events[] = array('name' => $eventName, 'event' => $event); }); $stateMachineBuilder = new StateMachineBuilder(); $stateMachineBuilder->addState('locked'); $stateMachineBuilder->addState('unlocked'); $stateMachineBuilder->setStartState('locked'); $stateMachineBuilder->addTransition('locked', 'insertCoin', 'unlocked'); $stateMachineBuilder->addTransition('unlocked', 'pass', 'locked'); $stateMachine = $stateMachineBuilder->getStateMachine(); $stateMachine->setEventDispatcher($eventDispatcher); $stateMachine->start(); $stateMachine->triggerEvent('insertCoin'); $this->assertThat(count($events), $this->equalTo(10)); $this->assertThat($events[0]['name'], $this->equalTo(StateMachineEvents::EVENT_PROCESS)); $this->assertThat($events[0]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[0]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[0]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[0]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_START)); $this->assertThat($events[1]['name'], $this->equalTo(StateMachineEvents::EVENT_EXIT)); $this->assertThat($events[1]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[1]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[1]['event']->getEvent(), $this->isNull()); $this->assertThat($events[2]['name'], $this->equalTo(StateMachineEvents::EVENT_TRANSITION)); $this->assertThat($events[2]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[2]['event']->getState()->getStateId(), $this->equalTo(StateInterface::STATE_INITIAL)); $this->assertThat($events[2]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[2]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_START)); $this->assertThat($events[3]['name'], $this->equalTo(StateMachineEvents::EVENT_ENTRY)); $this->assertThat($events[3]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[3]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[3]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[3]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_ENTRY)); $this->assertThat($events[4]['name'], $this->equalTo(StateMachineEvents::EVENT_DO)); $this->assertThat($events[4]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[4]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[4]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[4]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_DO)); $this->assertThat($events[5]['name'], $this->equalTo(StateMachineEvents::EVENT_PROCESS)); $this->assertThat($events[5]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[5]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[5]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[5]['event']->getEvent()->getEventId(), $this->equalTo('insertCoin')); $this->assertThat($events[6]['name'], $this->equalTo(StateMachineEvents::EVENT_EXIT)); $this->assertThat($events[6]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[6]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[6]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[6]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_EXIT)); $this->assertThat($events[7]['name'], $this->equalTo(StateMachineEvents::EVENT_TRANSITION)); $this->assertThat($events[7]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[7]['event']->getState()->getStateId(), $this->equalTo('locked')); $this->assertThat($events[7]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\TransitionEventInterface')); $this->assertThat($events[7]['event']->getEvent()->getEventId(), $this->equalTo('insertCoin')); $this->assertThat($events[8]['name'], $this->equalTo(StateMachineEvents::EVENT_ENTRY)); $this->assertThat($events[8]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[8]['event']->getState()->getStateId(), $this->equalTo('unlocked')); $this->assertThat($events[8]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[8]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_ENTRY)); $this->assertThat($events[9]['name'], $this->equalTo(StateMachineEvents::EVENT_DO)); $this->assertThat($events[9]['event']->getStateMachine(), $this->identicalTo($stateMachine)); $this->assertThat($events[9]['event']->getState()->getStateId(), $this->equalTo('unlocked')); $this->assertThat($events[9]['event']->getEvent(), $this->isInstanceOf('Stagehand\\FSM\\Event\\EventInterface')); $this->assertThat($events[9]['event']->getEvent()->getEventId(), $this->equalTo(EventInterface::EVENT_DO)); }