Completed
Branch master (755019)
by Oliver
04:40
created

SetupHelper::addTransition()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2.032

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 8
ccs 4
cts 5
cp 0.8
rs 9.4286
cc 2
eloc 5
nc 2
nop 2
crap 2.032
1
<?php
2
3
namespace Metabor\Statemachine\Util;
4
5
use Metabor\Statemachine\Command;
6
use Metabor\Statemachine\State;
7
use Metabor\Statemachine\StateCollection;
8
use Metabor\Statemachine\Transition;
9
use MetaborStd\Statemachine\ConditionInterface;
10
use MetaborStd\Statemachine\StateCollectionInterface;
11
use MetaborStd\Statemachine\StateInterface;
12
use MetaborStd\Statemachine\TransitionInterface;
13
14
/**
15
 * @author Oliver Tischlinger
16
 */
17
class SetupHelper
18
{
19
    /**
20
     * @var StateCollectionInterface
21
     */
22
    protected $stateCollection;
23
24
    /**
25
     * @param StateCollectionInterface $stateCollection
26
     */
27 4
    public function __construct(StateCollectionInterface $stateCollection)
28
    {
29 4
        $this->stateCollection = $stateCollection;
30 4
    }
31
32
    /**
33
     * @param $name
34
     *
35
     * @return \MetaborStd\Statemachine\StateInterface
36
     *
37
     * @throws \Exception
38
     */
39 4
    public function findOrCreateState($name)
40
    {
41 4
        if (!$this->stateCollection->hasState($name)) {
42 4
            if ($this->stateCollection instanceof StateCollection) {
43 4
                $this->stateCollection->addState(new State($name));
44
            } else {
45
                throw new \InvalidArgumentException('Overwrite this method to implement a different type!');
46
            }
47
        }
48
49 4
        return $this->stateCollection->getState($name);
50
    }
51
52
    /**
53
     * @param StateInterface     $sourceState
54
     * @param StateInterface     $targetState
55
     * @param string             $eventName
56
     * @param ConditionInterface $condition
57
     *
58
     * @return TransitionInterface
59
     */
60 4
    protected function findTransition(StateInterface $sourceState, StateInterface $targetState, $eventName = null, ConditionInterface $condition = null)
61
    {
62 4
        $conditionName = $condition ? $condition->getName() : null;
63
        /* @var $transition TransitionInterface */
64 4
        foreach ($sourceState->getTransitions() as $transition) {
65 1
            $hasSameTargetState = ($transition->getTargetState() === $targetState);
66 1
            $hasSameCondition = ($transition->getConditionName() == $conditionName);
67 1
            $hasSameEvent = ($transition->getEventName() == $eventName);
68 1
            if ($hasSameTargetState && $hasSameCondition && $hasSameEvent) {
69 1
                return $transition;
70
            }
71
        }
72 4
    }
73
74
    /**
75
     * @param StateInterface      $sourceState
76
     * @param TransitionInterface $sourceTransition
77
     *
78
     * @throws \InvalidArgumentException
79
     */
80 4
    protected function addTransition(StateInterface $sourceState, TransitionInterface $sourceTransition)
81
    {
82 4
        if ($sourceState instanceof State) {
83 4
            $sourceState->addTransition($sourceTransition);
84
        } else {
85
            throw new \InvalidArgumentException('Overwrite this method to implement a different type!');
86
        }
87 4
    }
88
89
    /**
90
     * @param string             $sourceStateName
91
     * @param string             $targetStateName
92
     * @param string             $eventName
93
     * @param ConditionInterface $condition
94
     *
95
     * @return TransitionInterface
96
     */
97 4
    public function findOrCreateTransition($sourceStateName, $targetStateName, $eventName = null, ConditionInterface $condition = null)
98
    {
99 4
        $sourceState = $this->findOrCreateState($sourceStateName);
100 4
        $targetState = $this->findOrCreateState($targetStateName);
101 4
        $transition = $this->findTransition($sourceState, $targetState, $eventName, $condition);
102 4
        if (!$transition) {
103 4
            $transition = new Transition($targetState, $eventName, $condition);
104 4
            $this->addTransition($sourceState, $transition);
105
        }
106
107 4
        return $transition;
108
    }
109
110
    /**
111
     * If there is no Transition from the SourceState with this Event use addCommandAndSelfTransition().
112
     *
113
     * @param $sourceStateName
114
     * @param string  $eventName
115
     * @param Command $command
116
     */
117
    public function addCommand($sourceStateName, $eventName, Command $command)
118
    {
119
        $sourceState = $this->findOrCreateState($sourceStateName);
120
        $sourceState->getEvent($eventName)->attach($command);
121
    }
122
123
    /**
124
     * @param $sourceStateName
125
     * @param string  $eventName
126
     * @param Command $command
127
     */
128
    public function addCommandAndSelfTransition($sourceStateName, $eventName, Command $command)
129
    {
130
        $this->addCommand($sourceStateName, $eventName, $command);
131
        $this->findOrCreateTransition($sourceStateName, $sourceStateName, $eventName);
132
    }
133
}
134