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 some useful String functions. |
||
4 | * @file |
||
5 | */ |
||
6 | |||
7 | /** |
||
8 | * Some functions are not written in a clean way for efficiency; |
||
9 | * I hope code is not that much durty |
||
10 | * @ignore |
||
11 | */ |
||
12 | |||
13 | /** |
||
14 | * Curried version of `explode`. |
||
15 | * |
||
16 | * ```php |
||
17 | * $words = F\split(' '); |
||
18 | * $words('Hello World'); //=> ['Hello', 'World'] |
||
19 | * ``` |
||
20 | * |
||
21 | * @stream |
||
22 | * @signature String -> String -> [String] |
||
23 | * @param string $delimiter |
||
24 | * @param string $string |
||
25 | * @return array |
||
26 | */ |
||
27 | function split() { |
||
28 | static $split = false; |
||
29 | $split = $split ?: curry('explode'); |
||
30 | return _apply($split, func_get_args()); |
||
31 | } |
||
32 | |||
33 | /** |
||
34 | * Curried version of `implode`. |
||
35 | * |
||
36 | * ```php |
||
37 | * $sentence = F\join(' '); |
||
38 | * $sentence(['Hello', 'World']); //=> 'Hello World' |
||
39 | * ``` |
||
40 | * |
||
41 | * @stream |
||
42 | * @signature String -> [String] -> String |
||
43 | * @param string $glue |
||
44 | * @param array $pieces |
||
45 | * @return string |
||
46 | */ |
||
47 | function join() { |
||
48 | static $join = false; |
||
49 | $join = $join ?: curry(function($glue, $pieces){ |
||
50 | return implode($glue, $pieces); |
||
51 | }); |
||
52 | return _apply($join, func_get_args()); |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Curried version of `str_replace`. |
||
57 | * |
||
58 | * ```php |
||
59 | * $string = 'a b c d e f'; |
||
60 | * $noSpace = F\replace(' ', ''); |
||
61 | * $noSpace($string); //=> 'abcdef' |
||
62 | * F\replace(['a', 'b', ' '], '', $string); //=> 'cdef' |
||
63 | * F\replace(['a', 'e', ' '], ['x', 'y', ''], $string); //=> 'xbcdyf' |
||
64 | * ``` |
||
65 | * |
||
66 | * @stream |
||
67 | * @signature String|[String] -> String|[String] -> String -> String |
||
68 | * @param string $search |
||
69 | * @param string $replacement |
||
70 | * @param string $string |
||
71 | * @return string |
||
72 | */ |
||
73 | function replace() { |
||
74 | static $replace = false; |
||
75 | $replace = $replace ?: curry('str_replace'); |
||
76 | return _apply($replace, func_get_args()); |
||
77 | } |
||
78 | |||
79 | /** |
||
80 | * Curried version of `preg_replace`. |
||
81 | * |
||
82 | * ```php |
||
83 | * $string = 'A12;b_{F}|d'; |
||
84 | * $alpha = F\regReplace('/[^a-z]+/i', ''); |
||
85 | * $alpha($string); //=> 'AbFd' |
||
86 | * ``` |
||
87 | * |
||
88 | * @stream |
||
89 | * @signature String -> String -> String -> String |
||
90 | * @param string $pattern |
||
91 | * @param string $replacement |
||
92 | * @param string $string |
||
93 | * @return string |
||
94 | */ |
||
95 | function regReplace() { |
||
96 | static $regReplace = false; |
||
97 | $regReplace = $regReplace ?: curry('preg_replace'); |
||
98 | return _apply($regReplace, func_get_args()); |
||
99 | } |
||
100 | |||
101 | /** |
||
102 | * Alias of `strtoupper`. |
||
103 | * |
||
104 | * ```php |
||
105 | * F\upperCase('hello'); //=> 'HELLO' |
||
106 | * ``` |
||
107 | * |
||
108 | * @stream |
||
109 | * @signature String -> String |
||
110 | * @param string $string |
||
111 | * @return string |
||
112 | */ |
||
113 | function upperCase() { |
||
114 | static $upperCase = false; |
||
115 | $upperCase = $upperCase ?: curry('strtoupper'); |
||
116 | return _apply($upperCase, func_get_args()); |
||
117 | } |
||
118 | |||
119 | /** |
||
120 | * Alias of `strtolower`. |
||
121 | * |
||
122 | * ```php |
||
123 | * F\lowerCase('HeLLO'); //=> 'hello' |
||
124 | * ``` |
||
125 | * |
||
126 | * @stream |
||
127 | * @signature String -> String |
||
128 | * @param string $string |
||
129 | * @return string |
||
130 | */ |
||
131 | function lowerCase() { |
||
132 | static $lowerCase = false; |
||
133 | $lowerCase = $lowerCase ?: curry('strtolower'); |
||
134 | return _apply($lowerCase, func_get_args()); |
||
135 | } |
||
136 | |||
137 | /** |
||
138 | * Gets the camlCase version of a string. |
||
139 | * |
||
140 | * ```php |
||
141 | * F\camelCase('Yes, we can! 123'); //=> 'yesWeCan123' |
||
142 | * ``` |
||
143 | * |
||
144 | * @stream |
||
145 | * @signature String -> String |
||
146 | * @param string $string |
||
147 | * @return string |
||
148 | */ |
||
149 | function camelCase() { |
||
150 | static $camelCase = false; |
||
151 | $camelCase = $camelCase ?: curry(function($string) { |
||
152 | return lcfirst(str_replace(' ', '', ucwords(trim(preg_replace('/[^a-z0-9]+/i', ' ', $string))))); |
||
153 | }); |
||
154 | return _apply($camelCase, func_get_args()); |
||
155 | } |
||
156 | |||
157 | /** |
||
158 | * Gets the snake-case of the string using `$delimiter` as separator. |
||
159 | * |
||
160 | * ```php |
||
161 | * $underscoreCase = F\snakeCase('_'); |
||
162 | * $underscoreCase('IAm-Happy'); //=> 'i_am_happy' |
||
163 | * ``` |
||
164 | * |
||
165 | * @stream |
||
166 | * @signature String -> String -> String |
||
167 | * @param string $delimiter |
||
168 | * @param string $string |
||
169 | * @return string |
||
170 | */ |
||
171 | function snakeCase() { |
||
172 | static $snackCase = false; |
||
173 | $snackCase = $snackCase ?: curry(function($delimiter, $string) { |
||
174 | return str_replace(' ', $delimiter, trim(strtolower( |
||
175 | preg_replace('/[^a-z0-9]+/i', ' ', |
||
176 | preg_replace('/([0-9]+)/', ' \\1', |
||
177 | preg_replace('/([A-Z])/', ' \\1', $string)))))); |
||
178 | }); |
||
179 | return _apply($snackCase, func_get_args()); |
||
180 | } |
||
181 | |||
182 | /** |
||
183 | * Checks if `$string` starts with `$token`. |
||
184 | * |
||
185 | * ```php |
||
186 | * $http = F\startsWith('http://'); |
||
187 | * $http('http://gitbub.com'); //=> true |
||
188 | * $http('gitbub.com'); //=> false |
||
189 | * ``` |
||
190 | * |
||
191 | * @stream |
||
192 | * @signature String -> String -> Boolean |
||
193 | * @param string $token |
||
194 | * @param string $string |
||
195 | * @return bool |
||
196 | */ |
||
197 | View Code Duplication | function startsWith() { |
|
0 ignored issues
–
show
|
|||
198 | static $startsWith = false; |
||
199 | $startsWith = $startsWith ?: curry(function($token, $string) { |
||
200 | return ( |
||
201 | strlen($token) <= strlen($string) && |
||
202 | substr($string, 0, strlen($token)) === $token |
||
203 | ); |
||
204 | }); |
||
205 | return _apply($startsWith, func_get_args()); |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * Checks if `$string` ends with `$token`. |
||
210 | * |
||
211 | * ```php |
||
212 | * $dotCom = F\endsWith('.com'); |
||
213 | * $dotCom('http://gitbub.com'); //=> true |
||
214 | * $dotCom('php.net'); //=> false |
||
215 | * ``` |
||
216 | * |
||
217 | * @stream |
||
218 | * @signature String -> String -> Boolean |
||
219 | * @param string $token |
||
220 | * @param string $string |
||
221 | * @return bool |
||
222 | */ |
||
223 | View Code Duplication | function endsWith() { |
|
0 ignored issues
–
show
This function 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. ![]() |
|||
224 | static $endsWith = false; |
||
225 | $endsWith = $endsWith ?: curry(function($token, $string) { |
||
226 | return ( |
||
227 | strlen($token) <= strlen($string) && |
||
228 | substr($string, - strlen($token)) === $token |
||
229 | ); |
||
230 | }); |
||
231 | return _apply($endsWith, func_get_args()); |
||
232 | } |
||
233 | |||
234 | /** |
||
235 | * Checks if a string matches a regular expression. |
||
236 | * |
||
237 | * ```php |
||
238 | * $numeric = F\test('/^[0-9.]+$/'); |
||
239 | * $numeric('123.43'); //=> true |
||
240 | * $numeric('12a3.43'); //=> false |
||
241 | * ``` |
||
242 | * |
||
243 | * @stream |
||
244 | * @signature String -> String -> Boolean |
||
245 | * @param string $pattern |
||
246 | * @param string $string |
||
247 | * @return bool |
||
248 | */ |
||
249 | function test() { |
||
250 | static $test = false; |
||
251 | $test = $test ?: curry(function($pattern, $string) { |
||
252 | return 1 === preg_match($pattern, $string); |
||
253 | }); |
||
254 | return _apply($test, func_get_args()); |
||
255 | } |
||
256 | |||
257 | /** |
||
258 | * Performs a global regular expression match |
||
259 | * and returns array of results. |
||
260 | * |
||
261 | * ```php |
||
262 | * $numbers = F\match('/[0-9.]+/'); |
||
263 | * $numbers('Hello World'); //=> [] |
||
264 | * $numbers('12 is 4 times 3'); //=> ['12', '4', '3'] |
||
265 | * ``` |
||
266 | * |
||
267 | * @stream |
||
268 | * @signature String -> String -> [String] |
||
269 | * @param string $pattern |
||
270 | * @param string $string |
||
271 | * @return array |
||
272 | */ |
||
273 | function match() { |
||
274 | static $match = false; |
||
275 | $match = $match ?: curry(function($pattern, $string) { |
||
276 | $results = []; |
||
277 | preg_match_all($pattern, $string, $results); |
||
278 | return $results[0]; |
||
279 | }); |
||
280 | return _apply($match, func_get_args()); |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Curried version of `substr_count` with changed order of parameters, |
||
285 | * |
||
286 | * ```php |
||
287 | * $spaces = F\occurences(' '); |
||
288 | * $spaces('Hello'); //=> 0 |
||
289 | * $spaces('12 is 4 times 3'); //=> 4 |
||
290 | * ``` |
||
291 | * |
||
292 | * @stream |
||
293 | * @signature String -> String -> Number |
||
294 | * @param string $token |
||
295 | * @param string $text |
||
296 | * @return int |
||
297 | */ |
||
298 | function occurences() { |
||
299 | static $occurences = false; |
||
300 | $occurences = $occurences ?: curry(function($token, $text) { |
||
301 | return substr_count($text, $token); |
||
302 | }); |
||
303 | return _apply($occurences, func_get_args()); |
||
304 | } |
||
305 | |||
306 | /** |
||
307 | * Splits a string into chunks without spliting any group surrounded with some specified characters. |
||
308 | * |
||
309 | * `$surrounders` is a string where each pair of characters specifies |
||
310 | * the starting and ending characters of a group that should not be split. |
||
311 | * |
||
312 | * **Note that this function assumes that the given `$text` is well formatted** |
||
313 | * |
||
314 | * ```php |
||
315 | * $names = F\chunks("''()\"\"", ' '); |
||
316 | * $names('Foo "Bar Baz" (Some other name)'); //=> ['Foo', '"Bar Baz"', '(Some other name)'] |
||
317 | * $names("This 'Quote\'s Test' is working"); //=> ['This', "'Quote\'s Test'", 'is', 'working'] |
||
318 | * |
||
319 | * $groups = F\chunks('(){}', '->'); |
||
320 | * $groups('1->2->(3->4->5)->{6->(7->8)}->9'); //=> ['1', '2', '(3->4->5)', '{6->(7->8)}', '9'] |
||
321 | * ``` |
||
322 | * |
||
323 | * @stream |
||
324 | * @signature String -> String -> String -> [String] |
||
325 | * @param string $surrounders |
||
326 | * @param string $separator |
||
327 | * @param sring $text |
||
328 | * @return array |
||
329 | */ |
||
330 | function chunks() { |
||
331 | static $chunks = false; |
||
332 | // This is by far the most complicated string function |
||
333 | $chunks = $chunks ?: curry(function($surrounders, $separator, $text) { |
||
334 | // Let's assume some values to understand how this function works |
||
335 | // surrounders = '""{}()' |
||
336 | // separator = ' ' |
||
337 | // $text = 'foo ("bar baz" alpha) beta' |
||
338 | $counters = [ |
||
339 | 'values' => [], // each item of this array refers to the number |
||
340 | // of closings needed for an opening |
||
341 | 'openings' => [], // an associative array where the key is an opening |
||
342 | // and the value is the index of corresponding cell |
||
343 | // in the 'values' field |
||
344 | 'closings' => [], // associative array for closings like the previous one |
||
345 | 'total' => 0 // the total number of needed closings |
||
346 | ]; |
||
347 | foreach (str_split($surrounders) as $key => $char) { |
||
348 | $counters['values'][$key / 2] = 0; |
||
349 | if ($key % 2 == 0) |
||
350 | $counters['openings'][$char] = $key / 2; |
||
351 | else |
||
352 | $counters['closings'][$char] = $key / 2; |
||
353 | } |
||
354 | // $counters = [ |
||
355 | // 'values' => [0, 0, 0], |
||
356 | // 'openings' => ['"' => 0, '{' => 1, '(' => 2], |
||
357 | // 'openings' => ['"' => 0, '}' => 1, ')' => 2], |
||
358 | // 'total' => 0 |
||
359 | // ] |
||
360 | $result = []; |
||
361 | $length = strlen($text); |
||
362 | $separatorLength = strlen($separator); |
||
363 | $characters = str_split($text); |
||
364 | $index = 0; |
||
365 | $buffer = ''; |
||
366 | while ($index < $length) { |
||
367 | if (substr($text, $index, $separatorLength) == $separator && $counters['total'] == 0) { |
||
368 | $result[] = $buffer; |
||
369 | $buffer = ''; |
||
370 | $index += $separatorLength; |
||
371 | } else { |
||
372 | $c = $characters[$index]; |
||
373 | if ($c == '\\') { |
||
374 | $buffer .= $c; |
||
375 | $index ++; |
||
376 | if ($index < $length) { |
||
377 | $buffer .= $characters[$index]; |
||
378 | $index ++; |
||
379 | } |
||
380 | continue; |
||
381 | } |
||
382 | $isOpening = array_key_exists($c, $counters['openings']); |
||
383 | $isClosing = array_key_exists($c, $counters['closings']); |
||
384 | if ($isOpening && $isClosing) { // when $c == '"' for example |
||
385 | $value = $counters['values'][$counters['openings'][$c]]; |
||
386 | if ($value == 0) { |
||
387 | $counters['values'][$counters['openings'][$c]] = 1; |
||
388 | $counters['total'] ++; |
||
389 | } else { |
||
390 | $counters['values'][$counters['openings'][$c]] = 0; |
||
391 | $counters['total'] --; |
||
392 | } |
||
393 | } else { |
||
394 | if ($isOpening) { |
||
395 | $counters['values'][$counters['openings'][$c]] ++; |
||
396 | $counters['total'] ++; |
||
397 | } |
||
398 | if ($isClosing) { |
||
399 | $counters['values'][$counters['closings'][$c]] --; |
||
400 | $counters['total'] --; |
||
401 | } |
||
402 | } |
||
403 | $buffer .= $c; |
||
404 | $index ++; |
||
405 | } |
||
406 | } |
||
407 | if ($buffer != '') |
||
408 | $result[] = $buffer; |
||
409 | |||
410 | return $result; |
||
411 | }); |
||
412 | return _apply($chunks, func_get_args()); |
||
413 | } |
||
414 |
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.