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 namespace Tarsana\Functional; |
||
2 | /** |
||
3 | * This file contains common internal functions. |
||
4 | * Caution: Code written here may seems stupid because it |
||
5 | * contains a lot of duplications and low level optimisation, |
||
6 | * but this is needed to make the library as efficient as possible. |
||
7 | * @file |
||
8 | */ |
||
9 | |||
10 | /** |
||
11 | * Adds the `Tarsana\Functional` namespace to a function name. |
||
12 | * This is useful to pass non-curried functions as parameter. |
||
13 | * ```php |
||
14 | * F\_f('foo'); //=> 'Tarsana\Functional\foo' |
||
15 | * ``` |
||
16 | * |
||
17 | * @signature String -> Sring |
||
18 | * @param string $name |
||
19 | * @return string |
||
20 | */ |
||
21 | function _f($name) { |
||
22 | $name = "Tarsana\\Functional\\{$name}"; |
||
23 | return $name; |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * Gets the number of arguments of a function. |
||
28 | * ```php |
||
29 | * F\_number_of_args(function($x, $y){}); //=> 2 |
||
30 | * ``` |
||
31 | * |
||
32 | * @signature (* -> *) -> Number |
||
33 | * @param callable $fn |
||
34 | * @return int |
||
35 | */ |
||
36 | function _number_of_args($fn) { |
||
37 | $reflector = is_array($fn) ? |
||
38 | new \ReflectionMethod($fn[0], $fn[1]) : |
||
39 | new \ReflectionFunction($fn); |
||
40 | return $reflector->getNumberOfRequiredParameters(); |
||
41 | } |
||
42 | |||
43 | /** |
||
44 | * Non curried version of apply for internal use. |
||
45 | * |
||
46 | * ```php |
||
47 | * $sum = function() { |
||
48 | * return F\sum(func_get_args()); |
||
49 | * }; |
||
50 | * F\_apply($sum, [1, 2, 3, 4, 5]); //=> 15 |
||
51 | * F\_apply($sum, [1, 2, 3, 4, 5, 6]); //=> 21 |
||
52 | * ``` |
||
53 | * |
||
54 | * @param callable $fn |
||
55 | * @param array $args |
||
56 | * @return mixed |
||
57 | */ |
||
58 | function _apply($fn, $args) { |
||
59 | switch (count($args)) { |
||
60 | case 0: return $fn(); |
||
0 ignored issues
–
show
Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
61 | case 1: return $fn($args[0]); |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
62 | case 2: return $fn($args[0], $args[1]); |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
63 | case 3: return $fn($args[0], $args[1], $args[2]); |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
64 | View Code Duplication | case 4: return $fn($args[0], $args[1], $args[2], $args[3]); |
|
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. ![]() The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
65 | View Code Duplication | case 5: return $fn($args[0], $args[1], $args[2], $args[3], $args[4]); |
|
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. ![]() The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
66 | } |
||
67 | return call_user_func_array($fn, $args); |
||
68 | } |
||
69 | |||
70 | /** |
||
71 | * Checks if `$a` is an argument placeholder. |
||
72 | * ```php |
||
73 | * F\_is_placeholder(F\__()); //=> true |
||
74 | * F\_is_placeholder('other thing'); //=> false |
||
75 | * ``` |
||
76 | * |
||
77 | * @signature * -> Boolean |
||
78 | * @param mixed $a |
||
79 | * @return boolean |
||
80 | */ |
||
81 | function _is_placeholder($a) { |
||
82 | return $a instanceof Placeholder; |
||
83 | } |
||
84 | |||
85 | /** |
||
86 | * Curry an unary function. |
||
87 | * |
||
88 | * @ignore |
||
89 | * @signature (a -> b) -> (a -> b) |
||
90 | * @param callable $fn |
||
91 | * @return callable |
||
92 | */ |
||
93 | function _curry_one($fn) { |
||
94 | return function() use($fn) { |
||
95 | $args = func_get_args(); |
||
96 | return (count($args) > 0 && ! _is_placeholder($args[0])) |
||
97 | ? $fn($args[0]) |
||
98 | : _curry_one($fn); |
||
99 | }; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Curry an binary function. |
||
104 | * |
||
105 | * ```php |
||
106 | * $add = F\_curry_two(function($x, $y) { |
||
107 | * return $x + $y; |
||
108 | * }); |
||
109 | * |
||
110 | * $addOne = $add(1, F\__()); |
||
111 | * $addOne(2); //=> 3 |
||
112 | * ``` |
||
113 | * |
||
114 | * @signature (a,b -> c) -> (a -> b -> c) |
||
115 | * @param callable $fn |
||
116 | * @return callable |
||
117 | */ |
||
118 | function _curry_two($fn) { |
||
119 | return function() use($fn) { |
||
120 | $args = func_get_args(); |
||
121 | $n = count($args); |
||
122 | while ($n > 0 && _is_placeholder($args[$n - 1])) |
||
123 | $n --; |
||
124 | if ($n == 0) |
||
125 | return _curry_two($fn); |
||
126 | if ($n == 1) { |
||
127 | $a = &$args[0]; |
||
128 | if (_is_placeholder($a)) |
||
129 | return _curry_two($fn); |
||
130 | return _curry_one(function($b) use($fn, &$a) { |
||
131 | return $fn($a, $b); |
||
132 | }); |
||
133 | } |
||
134 | $a = &$args[0]; |
||
135 | $b = &$args[1]; |
||
136 | if (_is_placeholder($a) && _is_placeholder($b)) |
||
137 | return _curry_two($fn); |
||
138 | if (_is_placeholder($a)) |
||
139 | return _curry_one(function($_a) use($fn, &$b) { |
||
140 | return $fn($_a, $b); |
||
141 | }); |
||
142 | return $fn($args[0], $args[1]); |
||
143 | }; |
||
144 | } |
||
145 | |||
146 | /** |
||
147 | * Curry a function with 3 arguments. |
||
148 | * |
||
149 | * ```php |
||
150 | * $add = F\_curry_three(function($x, $y, $z) { |
||
151 | * return $x + $y + $z; |
||
152 | * }); |
||
153 | * |
||
154 | * $add(1, 2, 3); //=> 6 |
||
155 | * $f = $add(F\__(), 2, F\__()); |
||
156 | * $f(1, 3); //=> 6 |
||
157 | * $g = $add(1, F\__(), 3); |
||
158 | * $g(2); //=> 6 |
||
159 | * $h = $add(F\__(), F\__(), 3); |
||
160 | * $h(1, 2); //=> 6 |
||
161 | * $i = $add(F\__(), 2, 3); |
||
162 | * $i(1); //=> 6 |
||
163 | * ``` |
||
164 | * |
||
165 | * @signature (a,b,c -> d) -> (a -> b -> c -> d) |
||
166 | * @param callable $fn |
||
167 | * @return callable |
||
168 | */ |
||
169 | function _curry_three($fn) { |
||
170 | return function() use($fn) { |
||
171 | $args = func_get_args(); |
||
172 | $n = count($args); |
||
173 | while ($n > 0 && _is_placeholder($args[$n - 1])) |
||
174 | $n --; |
||
175 | if ($n == 0) |
||
176 | return _curry_three($fn); |
||
177 | if ($n == 1) { |
||
178 | $a = &$args[0]; |
||
179 | return _curry_two(function($b, $c) use($fn, &$a) { |
||
180 | return $fn($a, $b, $c); |
||
181 | }); |
||
182 | } |
||
183 | if ($n == 2) { |
||
184 | $a = &$args[0]; $b = &$args[1]; |
||
185 | |||
186 | if (_is_placeholder($a)) |
||
187 | return _curry_two(function($_a, $c) use($fn, &$b) { |
||
188 | return $fn($_a, $b, $c); |
||
189 | }); |
||
190 | return _curry_one(function($c) use($fn, &$a, &$b) { |
||
191 | return $fn($a, $b, $c); |
||
192 | }); |
||
193 | } |
||
194 | |||
195 | $a = &$args[0]; $b = &$args[1]; $c = &$args[2]; |
||
196 | |||
197 | View Code Duplication | if (_is_placeholder($a) && _is_placeholder($b)) |
|
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. ![]() |
|||
198 | return _curry_two(function($_a, $_b) use($fn, &$c) { |
||
199 | return $fn($_a, $_b, $c); |
||
200 | }); |
||
201 | View Code Duplication | if (_is_placeholder($a)) |
|
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. ![]() |
|||
202 | return _curry_one(function($_a) use($fn, &$b, &$c) { |
||
203 | return $fn($_a, $b, $c); |
||
204 | }); |
||
205 | View Code Duplication | if (_is_placeholder($b)) |
|
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. ![]() |
|||
206 | return _curry_one(function($_b) use($fn, &$a, &$c) { |
||
207 | return $fn($a, $_b, $c); |
||
208 | }); |
||
209 | |||
210 | return $fn($a, $b, $c); |
||
211 | }; |
||
212 | } |
||
213 | |||
214 | /** |
||
215 | * Curry a function with `$n` arguments. |
||
216 | * |
||
217 | * ```php |
||
218 | * $polynomial = F\_curry_n(function($a, $b, $c, $x) { |
||
219 | * return $a * $x * $x + $b * $x + $c; |
||
220 | * }, 4); |
||
221 | * |
||
222 | * $linear = $polynomial(0); |
||
223 | * $linear(2, 1, 5); //=> 11 |
||
224 | * ``` |
||
225 | * |
||
226 | * @signature (*... -> *) -> Number -> (* -> ... -> *) |
||
227 | * @param callable $fn |
||
228 | * @param int $n |
||
229 | * @param array $given |
||
230 | * @return callable |
||
231 | */ |
||
232 | function _curry_n($fn, $n, $given = []) { |
||
233 | return function() use($fn, $n, $given) { |
||
234 | $args = func_get_args(); |
||
235 | $merged = _merge_args($given, $args, $n); |
||
236 | $args = $merged->args; |
||
237 | switch ($merged->placeholders) { |
||
238 | case 0: return _apply($fn, $args); |
||
0 ignored issues
–
show
The case body in a switch statement must start on the line following the statement.
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement. switch ($expr) {
case "A":
doSomething(); //right
break;
case "B":
doSomethingElse(); //wrong
break;
} To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() Terminating statement must be on a line by itself
As per the PSR-2 coding standard, the switch ($expr) {
case "A":
doSomething();
break; //wrong
case "B":
doSomething();
break; //right
case "C:":
doSomething();
return true; //right
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig. ![]() |
|||
239 | case 1: |
||
240 | return _curry_one(function($a) use($fn, &$args) { |
||
241 | return _apply($fn, _fill_placeholders($args, [$a])); |
||
242 | }); |
||
243 | case 2: |
||
244 | return _curry_two(function($a, $b) use($fn, &$args) { |
||
245 | return _apply($fn, _fill_placeholders($args, [$a, $b])); |
||
246 | }); |
||
247 | case 3: |
||
248 | return _curry_three(function($a, $b, $c) use($fn, &$args) { |
||
249 | return _apply($fn, _fill_placeholders($args, [$a, $b, $c])); |
||
250 | }); |
||
251 | } |
||
252 | return _curry_n($fn, $n, $args); |
||
253 | }; |
||
254 | } |
||
255 | |||
256 | /** |
||
257 | * Merges already given with new arguments, filling placeholders in the process. |
||
258 | * Returns an object holding the resulting args and the number of placeholders left. |
||
259 | * |
||
260 | * ```php |
||
261 | * $given = [F\__(), 2]; |
||
262 | * $args = [1, 3]; |
||
263 | * $newArgs = F\_merge_args($given, $args, 4); |
||
264 | * $newArgs; //=> (object) ['args' => [1, 2, 3, F\__()], 'placeholders' => 1] |
||
265 | * ``` |
||
266 | * |
||
267 | * @param array &$given |
||
268 | * @param array &$args |
||
269 | * @param int $n |
||
270 | * @return object |
||
271 | */ |
||
272 | function _merge_args(&$given, &$args, $n) { |
||
273 | $merged = (object) [ |
||
274 | 'args' => [], |
||
275 | 'placeholders' => 0 |
||
276 | ]; |
||
277 | $givenIndex = 0; $argsIndex = 0; $mergedIndex = 0; |
||
278 | $givenCount = count($given); $argsCount = count($args); |
||
279 | while ($mergedIndex < $n && ($givenIndex < $givenCount || $argsIndex < $argsCount)) { |
||
280 | if ($givenIndex < $givenCount && !_is_placeholder($given[$givenIndex])) { |
||
281 | $merged->args[$mergedIndex] = $given[$givenIndex]; |
||
282 | } else if ($argsIndex < $argsCount) { |
||
283 | $merged->args[$mergedIndex] = $args[$argsIndex]; |
||
284 | $argsIndex ++; |
||
285 | } else { |
||
286 | $merged->args[$mergedIndex] = $given[$givenIndex]; |
||
287 | } |
||
288 | |||
289 | if (_is_placeholder($merged->args[$mergedIndex])) |
||
290 | $merged->placeholders ++; |
||
291 | |||
292 | $givenIndex ++; |
||
293 | $mergedIndex ++; |
||
294 | } |
||
295 | while ($mergedIndex < $n) { |
||
296 | $merged->args[$mergedIndex] = Placeholder::get(); |
||
297 | $mergedIndex ++; |
||
298 | $merged->placeholders ++; |
||
299 | } |
||
300 | return $merged; |
||
301 | } |
||
302 | |||
303 | function _fill_placeholders($args, $fillers) { |
||
304 | $argsIndex = 0; $fillersIndex = 0; |
||
305 | $argsCount = count($args); |
||
0 ignored issues
–
show
$argsCount is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
306 | $fillersCount = count($fillers); |
||
307 | while ($fillersIndex < $fillersCount) { |
||
308 | while (!_is_placeholder($args[$argsIndex])) |
||
309 | $argsIndex ++; |
||
310 | $args[$argsIndex] = $fillers[$fillersIndex]; |
||
311 | $fillersIndex ++; |
||
312 | } |
||
313 | return $args; |
||
314 | } |
||
315 |
According to the PSR-2, the body of a case statement must start on the line immediately following the case statement.
}
To learn more about the PSR-2 coding standard, please refer to the PHP-Fig.