Issues (2)

src/Blueprint.php (1 issue)

1
<?php
2
/**
3
 * @author: RunnerLee
4
 * @email: [email protected]
5
 * @time: 2018-02
6
 */
7
8
namespace Runner\Heshen;
9
10
use Closure;
11
use Runner\Heshen\Event\Event;
12
use Runner\Heshen\Support\Str;
13
use Runner\Heshen\Support\StateEvents;
14
use Runner\Heshen\Exceptions\LogicException;
15
use Runner\Heshen\Exceptions\StateNotFoundException;
16
use Symfony\Component\EventDispatcher\EventDispatcher;
17
use Runner\Heshen\Exceptions\TransitionNotFoundException;
18
19
class Blueprint
20
{
21
    /**
22
     * @var State[]
23
     */
24
    protected $states = [];
25
26
    /**
27
     * @var Transition[]
28
     */
29
    protected $transitions = [];
30
31
    /**
32
     * @var EventDispatcher
33
     */
34
    protected $dispatcher;
35
36
    /**
37
     * Blueprint constructor.
38
     */
39 11
    public function __construct()
40
    {
41 11
        $this->dispatcher = new EventDispatcher();
42
43 11
        $this->configure();
44 11
    }
45
46
    /**
47
     * @param $name
48
     *
49
     * @return Transition
50
     */
51 6
    public function getTransition(string $name): Transition
52
    {
53 6
        if (array_key_exists($name, $this->transitions)) {
54 5
            return $this->transitions[$name];
55
        }
56
57 1
        throw new TransitionNotFoundException($name);
58
    }
59
60
    /**
61
     * @param $name
62
     *
63
     * @return State
64
     */
65 10
    public function getState(string $name): State
66
    {
67 10
        if (array_key_exists($name, $this->states)) {
68 10
            return $this->states[$name];
69
        }
70
71 1
        throw new StateNotFoundException($name);
72
    }
73
74
    /**
75
     * @return EventDispatcher
76
     */
77 3
    public function getDispatcher(): EventDispatcher
78
    {
79 3
        return $this->dispatcher;
80
    }
81
82
    /**
83
     * @param string $name
84
     * @param string $type
85
     *
86
     * @return Blueprint
87
     */
88 10
    protected function addState(string $name, string $type): self
89
    {
90 10
        $this->states[$name] = new State($name, $type);
91
92 10
        return $this;
93
    }
94
95
    /**
96
     * @param string       $name
97
     * @param string|array $from
98
     * @param string       $to
99
     * @param null         $checker
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $checker is correct as it would always require null to be passed?
Loading history...
100
     *
101
     * @return $this
102
     */
103 10
    protected function addTransition(string $name, $from, string $to, $checker = null): self
104
    {
105 10
        $from = (array) $from;
106 10
        $fromStates = array_map(function ($state) {
107 10
            return $this->getState($state);
108 10
        }, $from);
109 10
        $this->transitions[$name] = new Transition(
110 10
            $name,
111 10
            $fromStates,
112 10
            $this->getState($to),
113 10
            $checker
114
        );
115
116 10
        $preMethod = Str::studly("pre{$name}");
117 10
        $postMethod = Str::studly("post{$name}");
118
119 10
        if (method_exists($this, $preMethod)) {
120 10
            $this->dispatcher->addListener(
121 10
                StateEvents::PRE_TRANSITION . $name,
122 10
                $this->eventListener($preMethod)
123
            );
124
        }
125
126 10
        if (method_exists($this, $postMethod)) {
127 10
            $this->dispatcher->addListener(
128 10
                StateEvents::POST_TRANSITION . $name,
129 10
                $this->eventListener($postMethod)
130
            );
131
        }
132
133 10
        return $this;
134
    }
135
136
    /**
137
     * @param $method
138
     *
139
     * @return Closure
140
     */
141
    protected function eventListener($method): Closure
142
    {
143 10
        return function (Event $event) use ($method) {
144 1
            return call_user_func([$this, $method], $event->getStateful(), $event->getParameters());
145 10
        };
146
    }
147
148 1
    protected function configure(): void
149
    {
150 1
        throw new LogicException('you must overwrite the configure method in the concrete blueprint class');
151
    }
152
}
153