Machine   A
last analyzed

Complexity

Total Complexity 8

Size/Duplication

Total Lines 93
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 27
c 2
b 0
f 0
dl 0
loc 93
ccs 31
cts 31
cp 1
rs 10
wmc 8

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getBlueprint() 0 3 1
A getCurrentState() 0 3 1
A dispatchEvent() 0 3 1
A apply() 0 26 3
A can() 0 6 1
A __construct() 0 4 1
1
<?php
2
/**
3
 * @author: RunnerLee
4
 * @email: [email protected]
5
 * @time: 2018-02
6
 */
7
8
namespace Runner\Heshen;
9
10
use Runner\Heshen\Event\Event;
11
use Runner\Heshen\Support\StateEvents;
12
use Runner\Heshen\Exceptions\LogicException;
13
use Runner\Heshen\Contracts\StatefulInterface;
14
use Runner\Heshen\Exceptions\SetStateFailedException;
15
16
class Machine
17
{
18
    /**
19
     * @var StatefulInterface
20
     */
21
    protected $stateful;
22
23
    /**
24
     * @var Blueprint
25
     */
26
    protected $blueprint;
27
28
    /**
29
     * Machine constructor.
30
     *
31
     * @param StatefulInterface $stateful
32
     * @param Blueprint         $blueprint
33
     */
34 6
    public function __construct(StatefulInterface $stateful, Blueprint $blueprint)
35
    {
36 6
        $this->stateful = $stateful;
37 6
        $this->blueprint = $blueprint;
38 6
    }
39
40
    /**
41
     * @return string
42
     */
43 2
    public function getCurrentState(): string
44
    {
45 2
        return $this->stateful->getState();
46
    }
47
48
    /**
49
     * @param $transitionName
50
     * @param array $parameters
51
     *
52
     * @return bool
53
     */
54 4
    public function can($transitionName, array $parameters = []): bool
55
    {
56
        return $this
57 4
            ->blueprint
58 4
            ->getTransition($transitionName)
59 4
            ->can($this->stateful, $parameters);
60
    }
61
62
    /**
63
     * @param $transitionName
64
     * @param array $parameters
65
     */
66 3
    public function apply($transitionName, array $parameters = []): void
67
    {
68 3
        if (!$this->can($transitionName, $parameters)) {
69 1
            throw new LogicException(sprintf(
70 1
                'The "%s" transition can not be applied to the "%s" state of object "%s"',
71 1
                $transitionName,
72 1
                $this->stateful->getState(),
73 1
                get_class($this->stateful)
74
            ));
75
        }
76
77 2
        $this->dispatchEvent(StateEvents::PRE_TRANSITION . $transitionName, $parameters);
78
79 2
        $transition = $this->blueprint->getTransition($transitionName);
80
81 2
        $this->stateful->setState($transition->getToState()->getName());
82
83 2
        if ($this->stateful->getState() !== $transition->getToState()->getName()) {
84 1
            throw new SetStateFailedException(sprintf(
85 1
                'Failed to set the "%s" state for object "%s"',
86 1
                $transition->getToState()->getName(),
87 1
                get_class($this->stateful)
88
            ));
89
        }
90
91 1
        $this->dispatchEvent(StateEvents::POST_TRANSITION . $transitionName, $parameters);
92 1
    }
93
94
    /**
95
     * @return Blueprint
96
     */
97 1
    public function getBlueprint(): Blueprint
98
    {
99 1
        return $this->blueprint;
100
    }
101
102
    /**
103
     * @param $event
104
     * @param array $parameters
105
     */
106 2
    protected function dispatchEvent($event, array $parameters = []): void
107
    {
108 2
        $this->blueprint->getDispatcher()->dispatch($event, new Event($this->stateful, $parameters));
109 2
    }
110
}
111