These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /** |
||
3 | * Output functions |
||
4 | * Processing text for output such as pulling out URLs and extracting excerpts |
||
5 | * |
||
6 | * @package Elgg |
||
7 | * @subpackage Core |
||
8 | */ |
||
9 | |||
10 | /** |
||
11 | * Takes a string and turns any URLs into formatted links |
||
12 | * |
||
13 | * @param string $text The input string |
||
14 | * |
||
15 | * @return string The output string with formatted links |
||
16 | */ |
||
17 | function parse_urls($text) { |
||
18 | |||
19 | $linkify = new \Misd\Linkify\Linkify(); |
||
20 | |||
21 | return $linkify->processUrls($text, ['attr' => ['rel' => 'nofollow']]); |
||
22 | } |
||
23 | |||
24 | /** |
||
25 | * Takes a string and turns any email addresses into formatted links |
||
26 | * |
||
27 | * @param string $text The input string |
||
28 | * |
||
29 | * @return string The output string with formatted links |
||
30 | * |
||
31 | * @since 2.3 |
||
32 | */ |
||
33 | function elgg_parse_emails($text) { |
||
34 | $linkify = new \Misd\Linkify\Linkify(); |
||
35 | |||
36 | return $linkify->processEmails($text, ['attr' => ['rel' => 'nofollow']]); |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * Create paragraphs from text with line spacing |
||
41 | * |
||
42 | * @param string $string The string |
||
43 | * |
||
44 | * @return string |
||
45 | **/ |
||
46 | function elgg_autop($string) { |
||
47 | try { |
||
48 | return _elgg_services()->autoP->process($string); |
||
49 | } catch (\RuntimeException $e) { |
||
50 | _elgg_services()->logger->warn('ElggAutoP failed to process the string: ' . $e->getMessage()); |
||
51 | return $string; |
||
52 | } |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * Returns an excerpt. |
||
57 | * Will return up to n chars stopping at the nearest space. |
||
58 | * If no spaces are found (like in Japanese) will crop off at the |
||
59 | * n char mark. Adds ... if any text was chopped. |
||
60 | * |
||
61 | * @param string $text The full text to excerpt |
||
62 | * @param int $num_chars Return a string up to $num_chars long |
||
63 | * |
||
64 | * @return string |
||
65 | * @since 1.7.2 |
||
66 | */ |
||
67 | View Code Duplication | function elgg_get_excerpt($text, $num_chars = 250) { |
|
68 | $view = 'output/excerpt'; |
||
69 | $vars = [ |
||
70 | 'text' => $text, |
||
71 | 'num_chars' => $num_chars, |
||
72 | ]; |
||
73 | $viewtype = elgg_view_exists($view) ? '' : 'default'; |
||
74 | |||
75 | return _elgg_view_under_viewtype($view, $vars, $viewtype); |
||
76 | } |
||
77 | |||
78 | /** |
||
79 | * Format bytes to a human readable format |
||
80 | * |
||
81 | * @param int $size File size in bytes to format |
||
82 | * |
||
83 | * @param int $precision Precision to round formatting bytes to |
||
84 | * |
||
85 | * @return string |
||
86 | * @since 1.9.0 |
||
87 | */ |
||
88 | function elgg_format_bytes($size, $precision = 2) { |
||
89 | if (!$size || $size < 0) { |
||
90 | return false; |
||
91 | } |
||
92 | |||
93 | $base = log($size) / log(1024); |
||
94 | $suffixes = ['B', 'kB', 'MB', 'GB', 'TB']; |
||
95 | |||
96 | return round(pow(1024, $base - floor($base)), $precision) . ' ' . $suffixes[floor($base)]; |
||
97 | } |
||
98 | |||
99 | /** |
||
100 | * Converts an associative array into a string of well-formed HTML/XML attributes |
||
101 | * Returns a concatenated string of HTML attributes to be inserted into a tag (e.g., <tag $attrs>) |
||
102 | * |
||
103 | * @see elgg_format_element |
||
104 | * |
||
105 | * @param array $attrs Attributes |
||
106 | * An array of attribute => value pairs |
||
107 | * Attribute value can be a scalar value, an array of scalar values, or true |
||
108 | * <code> |
||
109 | * $attrs = array( |
||
110 | * 'class' => ['elgg-input', 'elgg-input-text'], // will be imploded with spaces |
||
111 | * 'style' => ['margin-left:10px;', 'color: #666;'], // will be imploded with spaces |
||
112 | * 'alt' => 'Alt text', // will be left as is |
||
113 | * 'disabled' => true, // will be converted to disabled="disabled" |
||
114 | * 'data-options' => json_encode(['foo' => 'bar']), // will be output as an escaped JSON string |
||
115 | * 'batch' => <\ElggBatch>, // will be ignored |
||
116 | * 'items' => [<\ElggObject>], // will be ignored |
||
117 | * ); |
||
118 | * </code> |
||
119 | * |
||
120 | * @return string |
||
121 | */ |
||
122 | function elgg_format_attributes(array $attrs = []) { |
||
123 | 7 | if (!is_array($attrs) || empty($attrs)) { |
|
124 | return ''; |
||
125 | } |
||
126 | |||
127 | 7 | $attributes = []; |
|
128 | |||
129 | 7 | foreach ($attrs as $attr => $val) { |
|
130 | 7 | if (0 !== strpos($attr, 'data-') && false !== strpos($attr, '_')) { |
|
131 | // this is probably a view $vars variable not meant for output |
||
132 | 1 | continue; |
|
133 | } |
||
134 | |||
135 | 7 | $attr = strtolower($attr); |
|
136 | |||
137 | 7 | if (!isset($val) || $val === false) { |
|
138 | 1 | continue; |
|
139 | } |
||
140 | |||
141 | 7 | if ($val === true) { |
|
142 | 2 | $val = $attr; //e.g. checked => true ==> checked="checked" |
|
143 | } |
||
144 | |||
145 | 7 | if (is_scalar($val)) { |
|
146 | 7 | $val = [$val]; |
|
147 | } |
||
148 | |||
149 | 7 | if (!is_array($val)) { |
|
150 | 1 | continue; |
|
151 | } |
||
152 | |||
153 | // Check if array contains non-scalar values and bail if so |
||
154 | $filtered_val = array_filter($val, function($e) { |
||
155 | 7 | return is_scalar($e); |
|
156 | 7 | }); |
|
157 | |||
158 | 7 | if (count($val) != count($filtered_val)) { |
|
159 | 1 | continue; |
|
160 | } |
||
161 | |||
162 | 7 | $val = implode(' ', $val); |
|
163 | |||
164 | 7 | $val = htmlspecialchars($val, ENT_QUOTES, 'UTF-8', false); |
|
165 | 7 | $attributes[] = "$attr=\"$val\""; |
|
166 | } |
||
167 | |||
168 | 7 | return implode(' ', $attributes); |
|
169 | } |
||
170 | |||
171 | /** |
||
172 | * Format an HTML element |
||
173 | * |
||
174 | * @param string|array $tag_name The element tagName. e.g. "div". This will not be validated. |
||
175 | * All function arguments can be given as a single array: The array will be used |
||
176 | * as $attributes, except for the keys "#tag_name", "#text", and "#options", which |
||
177 | * will be extracted as the other arguments. |
||
178 | * |
||
179 | * @param array $attributes The element attributes. This is passed to elgg_format_attributes(). |
||
180 | * |
||
181 | * @param string $text The contents of the element. Assumed to be HTML unless encode_text is true. |
||
182 | * |
||
183 | * @param array $options Options array with keys: |
||
184 | * |
||
185 | * encode_text => (bool, default false) If true, $text will be HTML-escaped. Already-escaped entities |
||
186 | * will not be double-escaped. |
||
187 | * |
||
188 | * double_encode => (bool, default false) If true, the $text HTML escaping will be allowed to double |
||
189 | * encode HTML entities: '×' will become '&times;' |
||
190 | * |
||
191 | * is_void => (bool) If given, this determines whether the function will return just the open tag. |
||
192 | * Otherwise this will be determined by the tag name according to this list: |
||
193 | * http://www.w3.org/html/wg/drafts/html/master/single-page.html#void-elements |
||
194 | * |
||
195 | * is_xml => (bool, default false) If true, void elements will be formatted like "<tag />" |
||
196 | * |
||
197 | * @return string |
||
198 | * @throws InvalidArgumentException |
||
199 | * @since 1.9.0 |
||
200 | */ |
||
201 | function elgg_format_element($tag_name, array $attributes = [], $text = '', array $options = []) { |
||
202 | 9 | if (is_array($tag_name)) { |
|
203 | 6 | $args = $tag_name; |
|
204 | |||
205 | 6 | if ($attributes !== [] || $text !== '' || $options !== []) { |
|
206 | throw new \InvalidArgumentException('If $tag_name is an array, the other arguments must not be set'); |
||
207 | } |
||
208 | |||
209 | 6 | if (isset($args['#tag_name'])) { |
|
210 | 5 | $tag_name = $args['#tag_name']; |
|
211 | } |
||
212 | 6 | if (isset($args['#text'])) { |
|
213 | 4 | $text = $args['#text']; |
|
214 | } |
||
215 | 6 | if (isset($args['#options'])) { |
|
216 | 5 | $options = $args['#options']; |
|
217 | } |
||
218 | |||
219 | 6 | unset($args['#tag_name'], $args['#text'], $args['#options']); |
|
220 | 6 | $attributes = $args; |
|
221 | } |
||
222 | |||
223 | 9 | if (!is_string($tag_name) || $tag_name === '') { |
|
224 | 1 | throw new \InvalidArgumentException('$tag_name is required'); |
|
225 | } |
||
226 | |||
227 | 8 | if (isset($options['is_void'])) { |
|
228 | 1 | $is_void = $options['is_void']; |
|
229 | } else { |
||
230 | // from http://www.w3.org/TR/html-markup/syntax.html#syntax-elements |
||
231 | 7 | $is_void = in_array(strtolower($tag_name), [ |
|
232 | 7 | 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', |
|
233 | 'meta', 'param', 'source', 'track', 'wbr' |
||
234 | ]); |
||
235 | } |
||
236 | |||
237 | 8 | if (!empty($options['encode_text'])) { |
|
238 | 2 | $double_encode = empty($options['double_encode']) ? false : true; |
|
239 | 2 | $text = htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', $double_encode); |
|
240 | } |
||
241 | |||
242 | 8 | if ($attributes) { |
|
243 | 4 | $attrs = elgg_format_attributes($attributes); |
|
244 | 4 | if ($attrs !== '') { |
|
245 | 4 | $attrs = " $attrs"; |
|
246 | } |
||
247 | } else { |
||
248 | 5 | $attrs = ''; |
|
249 | } |
||
250 | |||
251 | 8 | if ($is_void) { |
|
252 | 2 | return empty($options['is_xml']) ? "<{$tag_name}{$attrs}>" : "<{$tag_name}{$attrs} />"; |
|
253 | } else { |
||
254 | 6 | return "<{$tag_name}{$attrs}>$text</$tag_name>"; |
|
255 | } |
||
256 | } |
||
257 | |||
258 | /** |
||
259 | * Converts shorthand URLs to absolute URLs, unless the given URL is absolute, protocol-relative, |
||
260 | * or starts with a protocol/fragment/query |
||
261 | * |
||
262 | * @example |
||
263 | * elgg_normalize_url(''); // 'http://my.site.com/' |
||
264 | * elgg_normalize_url('dashboard'); // 'http://my.site.com/dashboard' |
||
265 | * elgg_normalize_url('http://google.com/'); // no change |
||
266 | * elgg_normalize_url('//google.com/'); // no change |
||
267 | * |
||
268 | * @param string $url The URL to normalize |
||
269 | * |
||
270 | * @return string The absolute URL |
||
271 | */ |
||
272 | function elgg_normalize_url($url) { |
||
273 | 231 | $url = str_replace(' ', '%20', $url); |
|
274 | |||
275 | 231 | if (_elgg_sane_validate_url($url)) { |
|
276 | 59 | return $url; |
|
277 | } |
||
278 | |||
279 | 225 | if (preg_match("#^([a-z]+)\\:#", $url, $m)) { |
|
280 | // we don't let http/https: URLs fail filter_var(), but anything else starting with a protocol |
||
281 | // is OK |
||
282 | 1 | if ($m[1] !== 'http' && $m[1] !== 'https') { |
|
283 | 1 | return $url; |
|
284 | } |
||
285 | } |
||
286 | |||
287 | 224 | if (preg_match("#^(\\#|\\?|//)#", $url)) { |
|
288 | // starts with '//' (protocol-relative link), query, or fragment |
||
289 | 3 | return $url; |
|
290 | } |
||
291 | |||
292 | 221 | if (preg_match("#^[^/]*\\.php(\\?.*)?$#", $url)) { |
|
293 | // root PHP scripts: 'install.php', 'install.php?step=step'. We don't want to confuse these |
||
294 | // for domain names. |
||
295 | 3 | return elgg_get_site_url() . $url; |
|
296 | } |
||
297 | |||
298 | 219 | if (preg_match("#^[^/?]*\\.#", $url)) { |
|
299 | // URLs starting with domain: 'example.com', 'example.com/subpage' |
||
300 | 2 | return "http://$url"; |
|
301 | } |
||
302 | |||
303 | // 'page/handler', 'mod/plugin/file.php' |
||
304 | // trim off any leading / because the site URL is stored |
||
305 | // with a trailing / |
||
306 | 217 | return elgg_get_site_url() . ltrim($url, '/'); |
|
307 | } |
||
308 | |||
309 | /** |
||
310 | * From untrusted input, get a site URL safe for forwarding. |
||
311 | * |
||
312 | * @param string $unsafe_url URL from untrusted input |
||
313 | * |
||
314 | * @return bool|string Normalized URL or false if given URL was not a path. |
||
315 | * |
||
316 | * @since 3.0.0 |
||
317 | */ |
||
318 | function elgg_normalize_site_url($unsafe_url) { |
||
319 | if (!is_string($unsafe_url)) { |
||
320 | return false; |
||
321 | } |
||
322 | |||
323 | $unsafe_url = elgg_normalize_url($unsafe_url); |
||
324 | if (0 === strpos($unsafe_url, elgg_get_site_url())) { |
||
325 | return $unsafe_url; |
||
326 | } |
||
327 | |||
328 | return false; |
||
329 | } |
||
330 | |||
331 | /** |
||
332 | * When given a title, returns a version suitable for inclusion in a URL |
||
333 | * |
||
334 | * @param string $title The title |
||
335 | * |
||
336 | * @return string The optimized title |
||
337 | * @since 1.7.2 |
||
338 | */ |
||
339 | function elgg_get_friendly_title($title) { |
||
340 | |||
341 | // return a URL friendly title to short circuit normal title formatting |
||
342 | $params = ['title' => $title]; |
||
343 | $result = elgg_trigger_plugin_hook('format', 'friendly:title', $params, null); |
||
344 | if ($result) { |
||
345 | return $result; |
||
346 | } |
||
347 | |||
348 | // titles are often stored HTML encoded |
||
349 | $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); |
||
350 | |||
351 | $title = \Elgg\Translit::urlize($title); |
||
352 | |||
353 | return $title; |
||
354 | } |
||
355 | |||
356 | /** |
||
357 | * Formats a UNIX timestamp in a friendly way (eg "less than a minute ago") |
||
358 | * |
||
359 | * @see elgg_view_friendly_time() |
||
360 | * |
||
361 | * @param int $time A UNIX epoch timestamp |
||
362 | * @param int $current_time Current UNIX epoch timestamp (optional) |
||
363 | * |
||
364 | * @return string The friendly time string |
||
365 | * @since 1.7.2 |
||
366 | */ |
||
367 | function elgg_get_friendly_time($time, $current_time = null) { |
||
368 | |||
369 | 7 | if (!$current_time) { |
|
1 ignored issue
–
show
|
|||
370 | $current_time = time(); |
||
371 | } |
||
372 | |||
373 | // return a time string to short circuit normal time formatting |
||
374 | 7 | $params = ['time' => $time, 'current_time' => $current_time]; |
|
375 | 7 | $result = elgg_trigger_plugin_hook('format', 'friendly:time', $params, null); |
|
376 | 7 | if ($result) { |
|
377 | return $result; |
||
378 | } |
||
379 | |||
380 | 7 | $diff = abs((int) $current_time - (int) $time); |
|
381 | |||
382 | 7 | $minute = 60; |
|
383 | 7 | $hour = $minute * 60; |
|
384 | 7 | $day = $hour * 24; |
|
385 | |||
386 | 7 | if ($diff < $minute) { |
|
387 | 1 | return elgg_echo("friendlytime:justnow"); |
|
388 | } |
||
389 | |||
390 | 6 | if ($diff < $hour) { |
|
391 | 3 | $granularity = ':minutes'; |
|
392 | 3 | $diff = round($diff / $minute); |
|
393 | 3 | } else if ($diff < $day) { |
|
394 | 1 | $granularity = ':hours'; |
|
395 | 1 | $diff = round($diff / $hour); |
|
396 | } else { |
||
397 | 2 | $granularity = ':days'; |
|
398 | 2 | $diff = round($diff / $day); |
|
399 | } |
||
400 | |||
401 | 6 | if ($diff == 0) { |
|
402 | $diff = 1; |
||
403 | } |
||
404 | |||
405 | 6 | $future = ((int) $current_time - (int) $time < 0) ? ':future' : ''; |
|
406 | 6 | $singular = ($diff == 1) ? ':singular' : ''; |
|
407 | |||
408 | 6 | return elgg_echo("friendlytime{$future}{$granularity}{$singular}", [$diff]); |
|
409 | } |
||
410 | |||
411 | /** |
||
412 | * Returns a human-readable message for PHP's upload error codes |
||
413 | * |
||
414 | * @param int $error_code The code as stored in $_FILES['name']['error'] |
||
415 | * @return string |
||
416 | */ |
||
417 | function elgg_get_friendly_upload_error($error_code) { |
||
418 | switch ($error_code) { |
||
419 | case UPLOAD_ERR_OK: |
||
420 | return ''; |
||
421 | |||
422 | case UPLOAD_ERR_INI_SIZE: |
||
423 | $key = 'ini_size'; |
||
424 | break; |
||
425 | |||
426 | case UPLOAD_ERR_FORM_SIZE: |
||
427 | $key = 'form_size'; |
||
428 | break; |
||
429 | |||
430 | case UPLOAD_ERR_PARTIAL: |
||
431 | $key = 'partial'; |
||
432 | break; |
||
433 | |||
434 | case UPLOAD_ERR_NO_FILE: |
||
435 | $key = 'no_file'; |
||
436 | break; |
||
437 | |||
438 | case UPLOAD_ERR_NO_TMP_DIR: |
||
439 | $key = 'no_tmp_dir'; |
||
440 | break; |
||
441 | |||
442 | case UPLOAD_ERR_CANT_WRITE: |
||
443 | $key = 'cant_write'; |
||
444 | break; |
||
445 | |||
446 | case UPLOAD_ERR_EXTENSION: |
||
447 | $key = 'extension'; |
||
448 | break; |
||
449 | |||
450 | default: |
||
451 | $key = 'unknown'; |
||
452 | break; |
||
453 | } |
||
454 | |||
455 | return elgg_echo("upload:error:$key"); |
||
456 | } |
||
457 | |||
458 | |||
459 | /** |
||
460 | * Strip tags and offer plugins the chance. |
||
461 | * Plugins register for output:strip_tags plugin hook. |
||
462 | * Original string included in $params['original_string'] |
||
463 | * |
||
464 | * @param string $string Formatted string |
||
465 | * @param string $allowable_tags Optional parameter to specify tags which should not be stripped |
||
466 | * |
||
467 | * @return string String run through strip_tags() and any plugin hooks. |
||
468 | */ |
||
469 | function elgg_strip_tags($string, $allowable_tags = null) { |
||
470 | 2 | $params['original_string'] = $string; |
|
471 | 2 | $params['allowable_tags'] = $allowable_tags; |
|
472 | |||
473 | 2 | $string = strip_tags($string, $allowable_tags); |
|
474 | 2 | $string = elgg_trigger_plugin_hook('format', 'strip_tags', $params, $string); |
|
475 | |||
476 | 2 | return $string; |
|
477 | } |
||
478 | |||
479 | /** |
||
480 | * Decode HTML markup into a raw text string |
||
481 | * |
||
482 | * This applies html_entity_decode() to a string while re-entitising HTML |
||
483 | * special char entities to prevent them from being decoded back to their |
||
484 | * unsafe original forms. |
||
485 | * |
||
486 | * This relies on html_entity_decode() not translating entities when |
||
487 | * doing so leaves behind another entity, e.g. &gt; if decoded would |
||
488 | * create > which is another entity itself. This seems to escape the |
||
489 | * usual behaviour where any two paired entities creating a HTML tag are |
||
490 | * usually decoded, i.e. a lone > is not decoded, but <foo> would |
||
491 | * be decoded to <foo> since it creates a full tag. |
||
492 | * |
||
493 | * Note: html_entity_decode() is poorly explained in the manual - which is really |
||
494 | * bad given its potential for misuse on user input already escaped elsewhere. |
||
495 | * Stackoverflow is littered with advice to use this function in the precise |
||
496 | * way that would lead to user input being capable of injecting arbitrary HTML. |
||
497 | * |
||
498 | * @param string $string Encoded HTML |
||
499 | * |
||
500 | * @return string |
||
501 | * |
||
502 | * @author Pádraic Brady |
||
503 | * @copyright Copyright (c) 2010 Pádraic Brady (http://blog.astrumfutura.com) |
||
504 | * @license Released under dual-license GPL2/MIT by explicit permission of Pádraic Brady |
||
505 | */ |
||
506 | function elgg_html_decode($string) { |
||
507 | $string = str_replace( |
||
508 | ['>', '<', '&', '"', '''], |
||
509 | ['&gt;', '&lt;', '&amp;', '&quot;', '&#039;'], |
||
510 | $string |
||
511 | ); |
||
512 | $string = html_entity_decode($string, ENT_NOQUOTES, 'UTF-8'); |
||
513 | $string = str_replace( |
||
514 | ['&gt;', '&lt;', '&amp;', '&quot;', '&#039;'], |
||
515 | ['>', '<', '&', '"', '''], |
||
516 | $string |
||
517 | ); |
||
518 | return $string; |
||
519 | } |
||
520 | |||
521 | /** |
||
522 | * Prepares query string for output to prevent CSRF attacks. |
||
523 | * |
||
524 | * @param string $string |
||
525 | * @return string |
||
526 | * |
||
527 | * @access private |
||
528 | */ |
||
529 | function _elgg_get_display_query($string) { |
||
530 | //encode <,>,&, quotes and characters above 127 |
||
531 | View Code Duplication | if (function_exists('mb_convert_encoding')) { |
|
1 ignored issue
–
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.
Loading history...
|
|||
532 | $display_query = mb_convert_encoding($string, 'HTML-ENTITIES', 'UTF-8'); |
||
533 | } else { |
||
534 | // if no mbstring extension, we just strip characters |
||
535 | $display_query = preg_replace("/[^\x01-\x7F]/", "", $string); |
||
536 | } |
||
537 | return htmlspecialchars($display_query, ENT_QUOTES, 'UTF-8', false); |
||
538 | } |
||
539 | |||
540 | /** |
||
541 | * Use a "fixed" filter_var() with FILTER_VALIDATE_URL that handles multi-byte chars. |
||
542 | * |
||
543 | * @param string $url URL to validate |
||
544 | * @return string|false |
||
545 | * @access private |
||
546 | */ |
||
547 | function _elgg_sane_validate_url($url) { |
||
548 | // based on http://php.net/manual/en/function.filter-var.php#104160 |
||
549 | 231 | $res = filter_var($url, FILTER_VALIDATE_URL); |
|
550 | 231 | if ($res) { |
|
551 | 59 | return $res; |
|
552 | } |
||
553 | |||
554 | // Check if it has unicode chars. |
||
555 | 225 | $l = elgg_strlen($url); |
|
556 | 225 | if (strlen($url) == $l) { |
|
557 | 225 | return $res; |
|
558 | } |
||
559 | |||
560 | // Replace wide chars by “X”. |
||
561 | $s = ''; |
||
562 | for ($i = 0; $i < $l; ++$i) { |
||
563 | $ch = elgg_substr($url, $i, 1); |
||
564 | $s .= (strlen($ch) > 1) ? 'X' : $ch; |
||
565 | } |
||
566 | |||
567 | // Re-check now. |
||
568 | return filter_var($s, FILTER_VALIDATE_URL) ? $url : false; |
||
569 | } |
||
570 |
In PHP, under loose comparison (like
==
, or!=
, orswitch
conditions), values of different types might be equal.For
integer
values, zero is a special case, in particular the following results might be unexpected: