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 Dazzle\Promise\Partial; |
||
4 | |||
5 | use Dazzle\Promise\Helper\CancellationQueue; |
||
6 | use Dazzle\Promise\Promise; |
||
7 | use Dazzle\Promise\PromiseCancelled; |
||
8 | use Dazzle\Promise\PromiseFulfilled; |
||
9 | use Dazzle\Promise\PromiseInterface; |
||
10 | use Dazzle\Promise\PromiseRejected; |
||
11 | use Dazzle\Throwable\Exception\Runtime\UnderflowException; |
||
12 | |||
13 | trait PromiseTrait |
||
14 | { |
||
15 | /** |
||
16 | * Resolve Promise or value. |
||
17 | * |
||
18 | * @param PromiseInterface|mixed $promiseOrValue |
||
19 | * @return PromiseInterface |
||
20 | * @resolves mixed |
||
21 | * @rejects Error|Exception|string|null |
||
22 | * @cancels Error|Exception|string|null |
||
23 | */ |
||
24 | 302 | public static function doResolve($promiseOrValue = null) |
|
25 | { |
||
26 | 302 | if (!$promiseOrValue instanceof PromiseInterface) |
|
27 | { |
||
28 | 302 | return new PromiseFulfilled($promiseOrValue); |
|
29 | } |
||
30 | |||
31 | 198 | return $promiseOrValue; |
|
32 | } |
||
33 | |||
34 | /** |
||
35 | * Reject Promise or value. |
||
36 | * |
||
37 | * @param PromiseInterface|mixed $promiseOrValue |
||
38 | * @return PromiseInterface |
||
39 | * @rejects Error|Exception|string|null |
||
40 | */ |
||
41 | 143 | View Code Duplication | public static function doReject($promiseOrValue = null) |
0 ignored issues
–
show
|
|||
42 | { |
||
43 | 143 | if (!$promiseOrValue instanceof PromiseInterface) |
|
44 | { |
||
45 | 139 | return new PromiseRejected($promiseOrValue); |
|
46 | } |
||
47 | |||
48 | return self::doResolve($promiseOrValue)->then(function($value) { |
||
49 | 3 | return new PromiseRejected($value); |
|
50 | 6 | }); |
|
51 | } |
||
52 | |||
53 | /** |
||
54 | * Cancel Promise or value. |
||
55 | * |
||
56 | * @param PromiseInterface|mixed $promiseOrValue |
||
57 | * @return PromiseInterface |
||
58 | * @cancels Error|Exception|string|null |
||
59 | */ |
||
60 | 127 | View Code Duplication | public static function doCancel($promiseOrValue = null) |
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. ![]() |
|||
61 | { |
||
62 | 127 | if (!$promiseOrValue instanceof PromiseInterface) |
|
63 | { |
||
64 | 127 | return new PromiseCancelled($promiseOrValue); |
|
65 | } |
||
66 | |||
67 | 4 | return self::doResolve($promiseOrValue) |
|
68 | 4 | ->then( |
|
69 | function($value) { |
||
70 | 2 | return new PromiseCancelled($value); |
|
71 | 4 | }, |
|
72 | function($value) { |
||
73 | 2 | return new PromiseCancelled($value); |
|
74 | 4 | } |
|
75 | ); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Return Promise that will resolve only once all the items in $promisesOrValues have resolved. |
||
80 | * |
||
81 | * Return Promise that will resolve only once all the items in $promisesOrValues have resolved. The resolution |
||
82 | * value of the returned promise will be an array containing the resolution values of each of the items in |
||
83 | * $promisesOrValues. |
||
84 | * |
||
85 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
86 | * @return PromiseInterface |
||
87 | * @resolves mixed |
||
88 | * @rejects Error|Exception|string|null |
||
89 | * @cancels Error|Exception|string|null |
||
90 | */ |
||
91 | 4 | public static function all($promisesOrValues) |
|
92 | { |
||
93 | return self::map($promisesOrValues, function($val) { |
||
94 | 3 | return $val; |
|
95 | 4 | }); |
|
96 | } |
||
97 | |||
98 | /** |
||
99 | * Initiate a competitive race that allows one winner. |
||
100 | * |
||
101 | * Initiate a competitive race that allows one winner. Returns a promise which is resolved in the same way |
||
102 | * the first settled promise resolves. |
||
103 | * |
||
104 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
105 | * @return PromiseInterface |
||
106 | * @resolves mixed |
||
107 | * @rejects Error|Exception|string|null |
||
108 | * @cancels Error|Exception|string|null |
||
109 | */ |
||
110 | 7 | public static function race($promisesOrValues) |
|
111 | { |
||
112 | 7 | $cancellationQueue = new CancellationQueue(); |
|
113 | |||
114 | return new Promise(function($resolve, $reject, $cancel) use($promisesOrValues, $cancellationQueue) { |
||
115 | 7 | self::doResolve($promisesOrValues) |
|
116 | ->done(function($array) use($resolve, $reject, $cancel, $cancellationQueue) { |
||
117 | 7 | if (!is_array($array) || !$array) |
|
0 ignored issues
–
show
The expression
$array of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
118 | { |
||
119 | 1 | $resolve(); |
|
120 | 1 | return; |
|
121 | } |
||
122 | |||
123 | $fulfiller = function($value) use($resolve, $cancellationQueue) { |
||
124 | 3 | $resolve($value); |
|
125 | 3 | $cancellationQueue(); |
|
126 | 6 | }; |
|
127 | |||
128 | $rejecter = function($reason) use($reject, $cancellationQueue) { |
||
129 | 2 | $reject($reason); |
|
130 | 2 | $cancellationQueue(); |
|
131 | 6 | }; |
|
132 | |||
133 | 6 | foreach ($array as $promiseOrValue) |
|
134 | { |
||
135 | 6 | $cancellationQueue->enqueue($promiseOrValue); |
|
136 | |||
137 | 6 | self::doResolve($promiseOrValue) |
|
138 | 6 | ->done($fulfiller, $rejecter, $cancel); |
|
139 | } |
||
140 | 7 | }, $reject, $cancel); |
|
141 | 7 | }, $cancellationQueue); |
|
142 | } |
||
143 | |||
144 | /** |
||
145 | * Return a promise that will resolve when any one of the items in $promisesOrValues resolves. |
||
146 | * |
||
147 | * Return a promise that will resolve when any one of the items in $promisesOrValues resolves. The resolution value |
||
148 | * of the returned promise will be the resolution value of the triggering item. |
||
149 | * |
||
150 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
151 | * @return PromiseInterface |
||
152 | * @resolves mixed |
||
153 | * @rejects Error|Exception|string|null |
||
154 | * @cancels Error|Exception|string|null |
||
155 | */ |
||
156 | 7 | public static function any($promisesOrValues) |
|
157 | { |
||
158 | 7 | return self::some($promisesOrValues, 1) |
|
159 | ->then(function($val) { |
||
160 | 4 | return array_shift($val); |
|
161 | 7 | }); |
|
162 | } |
||
163 | |||
164 | /** |
||
165 | * Return Promise that will resolve when $howMany of the supplied items in $promisesOrValues resolve. |
||
166 | * |
||
167 | * Return Promise that will resolve when $howMany of the supplied items in $promisesOrValues resolve. The resolution |
||
168 | * value of the returned promise will be an array of length $howMany containing the resolution values of |
||
169 | * the triggering items. |
||
170 | * |
||
171 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
172 | * @param int $howMany |
||
173 | * @return PromiseInterface |
||
174 | * @resolves mixed |
||
175 | * @rejects Error|Exception|string|null |
||
176 | * @cancels Error|Exception|string|null |
||
177 | */ |
||
178 | 18 | public static function some($promisesOrValues, $howMany) |
|
179 | { |
||
180 | 18 | $cancellationQueue = new CancellationQueue(); |
|
181 | |||
182 | return new Promise(function($resolve, $reject, $cancel) use($promisesOrValues, $howMany, $cancellationQueue) { |
||
183 | 18 | self::doResolve($promisesOrValues) |
|
184 | ->done(function($array) use($resolve, $reject, $cancel, $howMany, $cancellationQueue) { |
||
185 | 18 | if (!is_array($array) || $howMany < 1) |
|
186 | { |
||
187 | 1 | $resolve([]); |
|
188 | 1 | return; |
|
189 | } |
||
190 | |||
191 | 17 | $len = count($array); |
|
192 | |||
193 | 17 | if ($len < $howMany) |
|
194 | { |
||
195 | 3 | throw new UnderflowException( |
|
196 | 3 | sprintf('Input array must contain at least %d items but contains only %s items.', $howMany, $len) |
|
197 | ); |
||
198 | } |
||
199 | |||
200 | 14 | $toResolve = $howMany; |
|
201 | 14 | $toReject = ($len - $toResolve) + 1; |
|
202 | 14 | $values = []; |
|
203 | 14 | $reasons = []; |
|
204 | |||
205 | 14 | foreach ($array as $i=>$promiseOrValue) |
|
206 | { |
||
207 | View Code Duplication | $fulfiller = function($val) use($i, &$values, &$toResolve, $toReject, $resolve, $cancellationQueue) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
208 | 10 | if ($toResolve < 1 || $toReject < 1) |
|
209 | { |
||
210 | 5 | return; |
|
211 | } |
||
212 | |||
213 | 10 | $values[$i] = $val; |
|
214 | |||
215 | 10 | if (0 === --$toResolve) |
|
216 | { |
||
217 | 9 | $resolve($values); |
|
218 | 9 | $cancellationQueue(); |
|
219 | } |
||
220 | 14 | }; |
|
221 | |||
222 | View Code Duplication | $rejecter = function($reason) use($i, &$reasons, &$toReject, $toResolve, $reject, $cancellationQueue) { |
|
0 ignored issues
–
show
This code seems to be duplicated across 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. ![]() |
|||
223 | 4 | if ($toResolve < 1 || $toReject < 1) |
|
224 | { |
||
225 | 1 | return; |
|
226 | } |
||
227 | |||
228 | 4 | $reasons[$i] = $reason; |
|
229 | |||
230 | 4 | if (0 === --$toReject) |
|
231 | { |
||
232 | 3 | $reject($reasons); |
|
233 | 3 | $cancellationQueue(); |
|
234 | } |
||
235 | 14 | }; |
|
236 | |||
237 | 14 | $canceller = $cancel; |
|
238 | |||
239 | 14 | $cancellationQueue->enqueue($promiseOrValue); |
|
240 | |||
241 | 14 | self::doResolve($promiseOrValue) |
|
242 | 14 | ->done($fulfiller, $rejecter, $canceller); |
|
243 | } |
||
244 | 18 | }, $reject, $cancel); |
|
245 | 18 | }, $cancellationQueue); |
|
246 | } |
||
247 | |||
248 | /** |
||
249 | * Map promises and/or values using specified $mapFunc. |
||
250 | * |
||
251 | * @see array_map |
||
252 | * |
||
253 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
254 | * @param callable $mapFunc |
||
255 | * @return PromiseInterface |
||
256 | * @resolves mixed |
||
257 | * @rejects Error|Exception|string|null |
||
258 | * @cancels Error|Exception|string|null |
||
259 | */ |
||
260 | 10 | public static function map($promisesOrValues, callable $mapFunc) |
|
261 | { |
||
262 | 10 | $cancellationQueue = new CancellationQueue(); |
|
263 | |||
264 | return new Promise(function($resolve, $reject, $cancel) use($promisesOrValues, $mapFunc, $cancellationQueue) { |
||
265 | 10 | self::doResolve($promisesOrValues) |
|
266 | ->done(function($array) use($resolve, $reject, $cancel, $mapFunc, $cancellationQueue) { |
||
267 | 10 | if (!is_array($array) || !$array) |
|
0 ignored issues
–
show
The expression
$array of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
|||
268 | { |
||
269 | 1 | $resolve([]); |
|
270 | 1 | return; |
|
271 | } |
||
272 | |||
273 | 9 | $toResolve = count($array); |
|
274 | 9 | $values = []; |
|
275 | |||
276 | 9 | foreach ($array as $i=>$promiseOrValue) |
|
277 | { |
||
278 | 9 | $cancellationQueue->enqueue($promiseOrValue); |
|
279 | |||
280 | 9 | self::doResolve($promiseOrValue) |
|
281 | 9 | ->then($mapFunc) |
|
282 | 9 | ->done( |
|
283 | function($mapped) use($i, &$values, &$toResolve, $resolve) { |
||
284 | 8 | $values[$i] = $mapped; |
|
285 | 8 | if (0 === --$toResolve) |
|
286 | { |
||
287 | 6 | $resolve($values); |
|
288 | } |
||
289 | 9 | }, |
|
290 | 9 | $reject, |
|
291 | 9 | $cancel |
|
292 | ); |
||
293 | } |
||
294 | 10 | }, $reject, $cancel); |
|
295 | 10 | }, $cancellationQueue); |
|
296 | } |
||
297 | |||
298 | /** |
||
299 | * Reduce Promises and/or values using $reduceFunc with $initialValue being Promise or primitive value. |
||
300 | * |
||
301 | * @see array_reduce |
||
302 | * |
||
303 | * @param PromiseInterface[]|mixed[] $promisesOrValues |
||
304 | * @param callable $reduceFunc |
||
305 | * @param PromiseInterface|mixed|null $initialValue |
||
306 | * @return PromiseInterface |
||
307 | * @resolves mixed |
||
308 | * @rejects Error|Exception|string|null |
||
309 | * @cancels Error|Exception|string|null |
||
310 | */ |
||
311 | 15 | public static function reduce($promisesOrValues, callable $reduceFunc, $initialValue = null) |
|
312 | { |
||
313 | 15 | $cancellationQueue = new CancellationQueue(); |
|
314 | |||
315 | return new Promise(function($resolve, $reject, $cancel) use($promisesOrValues, $reduceFunc, $initialValue, $cancellationQueue) { |
||
316 | 15 | self::doResolve($promisesOrValues) |
|
317 | ->done(function($array) use($reduceFunc, $initialValue, $resolve, $reject, $cancel, $cancellationQueue) { |
||
318 | 15 | if (!is_array($array)) |
|
319 | { |
||
320 | $array = []; |
||
321 | } |
||
322 | |||
323 | 15 | $total = count($array); |
|
324 | 15 | $i = 0; |
|
325 | |||
326 | // Wrap the supplied $reduceFunc with one that handles promises and then delegates to the supplied. |
||
327 | // |
||
328 | $wrappedReduceFunc = function(PromiseInterface $current, $val) use($reduceFunc, $cancellationQueue, $total, &$i) { |
||
329 | 12 | $cancellationQueue->enqueue($val); |
|
330 | return $current |
||
331 | ->then(function($c) use($reduceFunc, $total, &$i, $val) { |
||
332 | 12 | return self::doResolve($val) |
|
333 | 12 | ->then(function($value) use($reduceFunc, $total, &$i, $c) { |
|
334 | 11 | return $reduceFunc($c, $value, $i++, $total); |
|
335 | 12 | }); |
|
336 | 12 | }); |
|
337 | 15 | }; |
|
338 | |||
339 | 15 | $initialValue = self::doResolve($initialValue); |
|
0 ignored issues
–
show
Consider using a different name than the imported variable
$initialValue , or did you forget to import by reference?
It seems like you are assigning to a variable which was imported through a For clarity, we suggest to use a different name or import by reference depending on whether you would like to have the change visibile in outer-scope. Change not visible in outer-scope$x = 1;
$callable = function() use ($x) {
$x = 2; // Not visible in outer scope. If you would like this, how
// about using a different variable name than $x?
};
$callable();
var_dump($x); // integer(1)
Change visible in outer-scope$x = 1;
$callable = function() use (&$x) {
$x = 2;
};
$callable();
var_dump($x); // integer(2)
![]() |
|||
340 | |||
341 | 15 | $cancellationQueue->enqueue($initialValue); |
|
342 | |||
343 | 15 | array_reduce($array, $wrappedReduceFunc, $initialValue) |
|
344 | 15 | ->done($resolve, $reject, $cancel); |
|
345 | |||
346 | 15 | }, $reject, $cancel); |
|
347 | 15 | }, $cancellationQueue); |
|
348 | } |
||
349 | } |
||
350 |
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.