This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | namespace Kaylyu\Alipay\Traits; |
||
4 | |||
5 | use Kaylyu\Alipay\Kernel\Clauses\Clause; |
||
6 | use Kaylyu\Alipay\Kernel\Contracts\EventHandlerInterface; |
||
7 | use Kaylyu\Alipay\Kernel\Decorators\FinallyResult; |
||
8 | use Kaylyu\Alipay\Kernel\Decorators\TerminateResult; |
||
9 | use Kaylyu\Alipay\Kernel\Exceptions\InvalidArgumentException; |
||
10 | use Kaylyu\Alipay\Kernel\ServiceContainer; |
||
11 | |||
12 | |||
13 | /** |
||
14 | * Trait Observable. |
||
15 | */ |
||
16 | trait Observable |
||
17 | { |
||
18 | /** |
||
19 | * @var array |
||
20 | */ |
||
21 | protected $handlers = []; |
||
22 | |||
23 | /** |
||
24 | * @var array |
||
25 | */ |
||
26 | protected $clauses = []; |
||
27 | |||
28 | /** |
||
29 | * @param \Closure|EventHandlerInterface|string $handler |
||
30 | * @param \Closure|EventHandlerInterface|string $condition |
||
31 | * |
||
32 | * @return \Kaylyu\Alipay\Kernel\Clauses\Clause |
||
33 | * |
||
34 | * @throws \Kaylyu\Alipay\Kernel\Exceptions\InvalidArgumentException |
||
35 | * @throws \ReflectionException |
||
36 | */ |
||
37 | View Code Duplication | public function push($handler, $condition = '*') |
|
0 ignored issues
–
show
|
|||
38 | { |
||
39 | list($handler, $condition) = $this->resolveHandlerAndCondition($handler, $condition); |
||
40 | |||
41 | if (!isset($this->handlers[$condition])) { |
||
42 | $this->handlers[$condition] = []; |
||
43 | } |
||
44 | |||
45 | array_push($this->handlers[$condition], $handler); |
||
46 | |||
47 | return $this->newClause($handler); |
||
48 | } |
||
49 | |||
50 | /** |
||
51 | * @param \Closure|EventHandlerInterface|string $handler |
||
52 | * @param \Closure|EventHandlerInterface|string $condition |
||
53 | * |
||
54 | * @return \Kaylyu\Alipay\Kernel\Clauses\Clause |
||
55 | * |
||
56 | * @throws \Kaylyu\Alipay\Kernel\Exceptions\InvalidArgumentException |
||
57 | * @throws \ReflectionException |
||
58 | */ |
||
59 | View Code Duplication | public function unshift($handler, $condition = '*') |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
60 | { |
||
61 | list($handler, $condition) = $this->resolveHandlerAndCondition($handler, $condition); |
||
62 | |||
63 | if (!isset($this->handlers[$condition])) { |
||
64 | $this->handlers[$condition] = []; |
||
65 | } |
||
66 | |||
67 | array_unshift($this->handlers[$condition], $handler); |
||
68 | |||
69 | return $this->newClause($handler); |
||
70 | } |
||
71 | |||
72 | /** |
||
73 | * @param string $condition |
||
74 | * @param \Closure|EventHandlerInterface|string $handler |
||
75 | * |
||
76 | * @return \Kaylyu\Alipay\Kernel\Clauses\Clause |
||
77 | * |
||
78 | * @throws \Kaylyu\Alipay\Kernel\Exceptions\InvalidArgumentException |
||
79 | */ |
||
80 | public function observe($condition, $handler) |
||
81 | { |
||
82 | return $this->push($handler, $condition); |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * @param string $condition |
||
87 | * @param \Closure|EventHandlerInterface|string $handler |
||
88 | * |
||
89 | * @return \Kaylyu\Alipay\Kernel\Clauses\Clause |
||
90 | * |
||
91 | * @throws \Kaylyu\Alipay\Kernel\Exceptions\InvalidArgumentException |
||
92 | */ |
||
93 | public function on($condition, $handler) |
||
94 | { |
||
95 | return $this->push($handler, $condition); |
||
96 | } |
||
97 | |||
98 | /** |
||
99 | * @param string|int $event |
||
100 | * @param mixed ...$payload |
||
101 | * |
||
102 | * @return mixed|null |
||
103 | */ |
||
104 | public function dispatch($event, $payload) |
||
105 | { |
||
106 | return $this->notify($event, $payload); |
||
107 | } |
||
108 | |||
109 | /** |
||
110 | * @param string|int $event |
||
111 | * @param mixed ...$payload |
||
112 | * |
||
113 | * @return mixed|null |
||
114 | */ |
||
115 | public function notify($event, $payload) |
||
116 | { |
||
117 | $result = null; |
||
118 | |||
119 | foreach ($this->handlers as $condition => $handlers) { |
||
120 | if ('*' === $condition || ($condition & $event) === $event) { |
||
121 | foreach ($handlers as $handler) { |
||
122 | if ($clause = $this->clauses[spl_object_hash((object) $handler)] ?? null) { |
||
123 | if ($clause->intercepted($payload)) { |
||
124 | continue; |
||
125 | } |
||
126 | } |
||
127 | $response = $this->callHandler($handler, $payload); |
||
128 | |||
129 | switch (true) { |
||
130 | case $response instanceof TerminateResult: |
||
131 | return $response->content; |
||
132 | case true === $response: |
||
133 | continue 2; |
||
134 | case false === $response: |
||
135 | break 2; |
||
136 | case !empty($response) && !($result instanceof FinallyResult): |
||
137 | $result = $response; |
||
138 | } |
||
139 | } |
||
140 | } |
||
141 | } |
||
142 | |||
143 | return $result instanceof FinallyResult ? $result->content : $result; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * @return array |
||
148 | */ |
||
149 | public function getHandlers() |
||
150 | { |
||
151 | return $this->handlers; |
||
152 | } |
||
153 | |||
154 | /** |
||
155 | * @param mixed $handler |
||
156 | * |
||
157 | * @return \Kaylyu\Alipay\Kernel\Clauses\Clause |
||
158 | */ |
||
159 | protected function newClause($handler): Clause |
||
160 | { |
||
161 | return $this->clauses[spl_object_hash((object) $handler)] = new Clause(); |
||
162 | } |
||
163 | |||
164 | /** |
||
165 | * @param callable $handler |
||
166 | * @param mixed $payload |
||
167 | * |
||
168 | * @return mixed |
||
169 | */ |
||
170 | protected function callHandler(callable $handler, $payload) |
||
171 | { |
||
172 | try { |
||
173 | return $handler($payload); |
||
174 | } catch (\Exception $e) { |
||
175 | if (property_exists($this, 'app') && $this->app instanceof ServiceContainer) { |
||
176 | $this->app['logger']->error($e->getCode().': '.$e->getMessage(), [ |
||
0 ignored issues
–
show
The property
app does not exist. Did you maybe forget to declare it?
In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code: class MyClass { }
$x = new MyClass();
$x->foo = true;
Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion: class MyClass {
public $foo;
}
$x = new MyClass();
$x->foo = true;
![]() |
|||
177 | 'code' => $e->getCode(), |
||
178 | 'message' => $e->getMessage(), |
||
179 | 'file' => $e->getFile(), |
||
180 | 'line' => $e->getLine(), |
||
181 | ]); |
||
182 | } |
||
183 | } |
||
184 | } |
||
185 | |||
186 | /** |
||
187 | * @param $handler |
||
188 | * @author kaylv <[email protected]> |
||
189 | * @return \Closure |
||
190 | * @throws InvalidArgumentException |
||
191 | */ |
||
192 | protected function makeClosure($handler) |
||
193 | { |
||
194 | if (is_callable($handler)) { |
||
195 | return $handler; |
||
196 | } |
||
197 | |||
198 | if (is_string($handler)) { |
||
199 | if (!class_exists($handler)) { |
||
200 | throw new InvalidArgumentException(sprintf('Class "%s" not exists.', $handler)); |
||
201 | } |
||
202 | |||
203 | if (!in_array(EventHandlerInterface::class, (new \ReflectionClass($handler))->getInterfaceNames(), true)) { |
||
204 | throw new InvalidArgumentException(sprintf('Class "%s" not an instance of "%s".', $handler, EventHandlerInterface::class)); |
||
205 | } |
||
206 | |||
207 | return function ($payload) use ($handler) { |
||
208 | return (new $handler($this->app ?? null))->handle($payload); |
||
209 | }; |
||
210 | } |
||
211 | |||
212 | if ($handler instanceof EventHandlerInterface) { |
||
213 | return function () use ($handler) { |
||
214 | return $handler->handle(...func_get_args()); |
||
215 | }; |
||
216 | } |
||
217 | |||
218 | throw new InvalidArgumentException('No valid handler is found in arguments.'); |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * @param $handler |
||
223 | * @param $condition |
||
224 | * |
||
225 | * @return array |
||
226 | * |
||
227 | * @throws \Kaylyu\Alipay\Exceptions\InvalidArgumentException |
||
228 | * @throws \ReflectionException |
||
229 | */ |
||
230 | protected function resolveHandlerAndCondition($handler, $condition): array |
||
231 | { |
||
232 | if (is_int($handler) || (is_string($handler) && !class_exists($handler))) { |
||
233 | list($handler, $condition) = [$condition, $handler]; |
||
234 | } |
||
235 | |||
236 | return [$this->makeClosure($handler), $condition]; |
||
237 | } |
||
238 | } |
||
239 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.