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 | 1 | $linkify = new \Misd\Linkify\Linkify(); |
|
20 | |||
21 | 1 | 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 | 1 | $linkify = new \Misd\Linkify\Linkify(); |
|
35 | |||
36 | 1 | 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 | 6 | return _elgg_services()->autoP->process($string); |
|
0 ignored issues
–
show
|
|||
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 | function elgg_get_excerpt($text, $num_chars = 250) { |
||
68 | 12 | $view = 'output/excerpt'; |
|
69 | $vars = [ |
||
70 | 12 | 'text' => $text, |
|
71 | 12 | 'num_chars' => $num_chars, |
|
72 | ]; |
||
73 | 12 | $viewtype = elgg_view_exists($view) ? '' : 'default'; |
|
74 | |||
75 | 12 | 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 | * @param array $attrs Attributes |
||
104 | * An array of attribute => value pairs |
||
105 | * Attribute value can be a scalar value, an array of scalar values, or true |
||
106 | * <code> |
||
107 | * $attrs = array( |
||
108 | * 'class' => ['elgg-input', 'elgg-input-text'], // will be imploded with spaces |
||
109 | * 'style' => ['margin-left:10px;', 'color: #666;'], // will be imploded with spaces |
||
110 | * 'alt' => 'Alt text', // will be left as is |
||
111 | * 'disabled' => true, // will be converted to disabled="disabled" |
||
112 | * 'data-options' => json_encode(['foo' => 'bar']), // will be output as an escaped JSON string |
||
113 | * 'batch' => <\ElggBatch>, // will be ignored |
||
114 | * 'items' => [<\ElggObject>], // will be ignored |
||
115 | * ); |
||
116 | * </code> |
||
117 | * |
||
118 | * @return string |
||
119 | * |
||
120 | * @see elgg_format_element() |
||
121 | */ |
||
122 | function elgg_format_attributes(array $attrs = []) { |
||
123 | 75 | if (!is_array($attrs) || empty($attrs)) { |
|
124 | 2 | return ''; |
|
125 | } |
||
126 | |||
127 | 75 | $attributes = []; |
|
128 | |||
129 | 75 | foreach ($attrs as $attr => $val) { |
|
130 | 75 | if (0 !== strpos($attr, 'data-') && false !== strpos($attr, '_')) { |
|
131 | // this is probably a view $vars variable not meant for output |
||
132 | 7 | continue; |
|
133 | } |
||
134 | |||
135 | 75 | $attr = strtolower($attr); |
|
136 | |||
137 | 75 | if (!isset($val) || $val === false) { |
|
138 | 19 | continue; |
|
139 | } |
||
140 | |||
141 | 75 | if ($val === true) { |
|
142 | 3 | $val = $attr; //e.g. checked => true ==> checked="checked" |
|
143 | } |
||
144 | |||
145 | 75 | if (is_scalar($val)) { |
|
146 | 71 | $val = [$val]; |
|
147 | } |
||
148 | |||
149 | 75 | if (!is_array($val)) { |
|
150 | 7 | continue; |
|
151 | } |
||
152 | |||
153 | // Check if array contains non-scalar values and bail if so |
||
154 | $filtered_val = array_filter($val, function($e) { |
||
155 | 75 | return is_scalar($e); |
|
156 | 75 | }); |
|
157 | |||
158 | 75 | if (count($val) != count($filtered_val)) { |
|
159 | 7 | continue; |
|
160 | } |
||
161 | |||
162 | 75 | $val = implode(' ', $val); |
|
163 | |||
164 | 75 | $val = htmlspecialchars($val, ENT_QUOTES, 'UTF-8', false); |
|
165 | 75 | $attributes[] = "$attr=\"$val\""; |
|
166 | } |
||
167 | |||
168 | 75 | 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 | 70 | if (is_array($tag_name)) { |
|
203 | $args = $tag_name; |
||
204 | |||
205 | if ($attributes !== [] || $text !== '' || $options !== []) { |
||
206 | throw new \InvalidArgumentException('If $tag_name is an array, the other arguments must not be set'); |
||
207 | } |
||
208 | |||
209 | if (isset($args['#tag_name'])) { |
||
210 | $tag_name = $args['#tag_name']; |
||
211 | } |
||
212 | if (isset($args['#text'])) { |
||
213 | $text = $args['#text']; |
||
214 | } |
||
215 | if (isset($args['#options'])) { |
||
216 | $options = $args['#options']; |
||
217 | } |
||
218 | |||
219 | unset($args['#tag_name'], $args['#text'], $args['#options']); |
||
220 | $attributes = $args; |
||
221 | } |
||
222 | |||
223 | 70 | if (!is_string($tag_name) || $tag_name === '') { |
|
224 | throw new \InvalidArgumentException('$tag_name is required'); |
||
225 | } |
||
226 | |||
227 | 70 | if (isset($options['is_void'])) { |
|
228 | $is_void = $options['is_void']; |
||
229 | } else { |
||
230 | // from http://www.w3.org/TR/html-markup/syntax.html#syntax-elements |
||
231 | 70 | $is_void = in_array(strtolower($tag_name), [ |
|
232 | 'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'keygen', 'link', 'menuitem', |
||
233 | 'meta', 'param', 'source', 'track', 'wbr' |
||
234 | ]); |
||
235 | } |
||
236 | |||
237 | 70 | if (!empty($options['encode_text'])) { |
|
238 | 1 | $double_encode = empty($options['double_encode']) ? false : true; |
|
239 | 1 | $text = htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8', $double_encode); |
|
240 | } |
||
241 | |||
242 | 70 | if ($attributes) { |
|
243 | 70 | $attrs = elgg_format_attributes($attributes); |
|
244 | 70 | if ($attrs !== '') { |
|
245 | 70 | $attrs = " $attrs"; |
|
246 | } |
||
247 | } else { |
||
248 | 4 | $attrs = ''; |
|
249 | } |
||
250 | |||
251 | 70 | if ($is_void) { |
|
252 | 9 | return empty($options['is_xml']) ? "<{$tag_name}{$attrs}>" : "<{$tag_name}{$attrs} />"; |
|
253 | } else { |
||
254 | 70 | 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 | 304 | $url = str_replace(' ', '%20', $url); |
|
274 | |||
275 | 304 | if (_elgg_sane_validate_url($url)) { |
|
276 | 97 | return $url; |
|
277 | } |
||
278 | |||
279 | 288 | 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 | 6 | if ($m[1] !== 'http' && $m[1] !== 'https') { |
|
283 | 6 | return $url; |
|
284 | } |
||
285 | } |
||
286 | |||
287 | 288 | if (preg_match("#^(\\#|\\?|//)#", $url)) { |
|
288 | // starts with '//' (protocol-relative link), query, or fragment |
||
289 | 3 | return $url; |
|
290 | } |
||
291 | |||
292 | 286 | 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 | 5 | return elgg_get_site_url() . $url; |
|
296 | } |
||
297 | |||
298 | 286 | 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 | 285 | 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 | 2 | if (!is_string($unsafe_url)) { |
|
320 | return false; |
||
321 | } |
||
322 | |||
323 | 2 | $unsafe_url = elgg_normalize_url($unsafe_url); |
|
324 | 2 | if (0 === strpos($unsafe_url, elgg_get_site_url())) { |
|
325 | 2 | 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 | 1 | $params = ['title' => $title]; |
|
343 | 1 | $result = elgg_trigger_plugin_hook('format', 'friendly:title', $params, null); |
|
344 | 1 | if ($result) { |
|
345 | return $result; |
||
346 | } |
||
347 | |||
348 | // titles are often stored HTML encoded |
||
349 | 1 | $title = html_entity_decode($title, ENT_QUOTES, 'UTF-8'); |
|
350 | |||
351 | 1 | $title = \Elgg\Translit::urlize($title); |
|
352 | |||
353 | 1 | 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 | 8 | if (!$current_time) { |
|
370 | 8 | $current_time = time(); |
|
371 | } |
||
372 | |||
373 | // return a time string to short circuit normal time formatting |
||
374 | 8 | $params = ['time' => $time, 'current_time' => $current_time]; |
|
375 | 8 | $result = elgg_trigger_plugin_hook('format', 'friendly:time', $params, null); |
|
376 | 8 | if ($result) { |
|
377 | return $result; |
||
378 | } |
||
379 | |||
380 | 8 | $diff = abs((int) $current_time - (int) $time); |
|
381 | |||
382 | 8 | $minute = 60; |
|
383 | 8 | $hour = $minute * 60; |
|
384 | 8 | $day = $hour * 24; |
|
385 | |||
386 | 8 | if ($diff < $minute) { |
|
387 | 8 | return elgg_echo("friendlytime:justnow"); |
|
388 | } |
||
389 | |||
390 | if ($diff < $hour) { |
||
391 | $granularity = ':minutes'; |
||
392 | $diff = round($diff / $minute); |
||
393 | } else if ($diff < $day) { |
||
394 | $granularity = ':hours'; |
||
395 | $diff = round($diff / $hour); |
||
396 | } else { |
||
397 | $granularity = ':days'; |
||
398 | $diff = round($diff / $day); |
||
399 | } |
||
400 | |||
401 | if ($diff == 0) { |
||
402 | $diff = 1; |
||
403 | } |
||
404 | |||
405 | $future = ((int) $current_time - (int) $time < 0) ? ':future' : ''; |
||
406 | $singular = ($diff == 1) ? ':singular' : ''; |
||
407 | |||
408 | 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 | 16 | $params['original_string'] = $string; |
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||
471 | 16 | $params['allowable_tags'] = $allowable_tags; |
|
472 | |||
473 | 16 | $string = strip_tags($string, $allowable_tags); |
|
474 | 16 | $string = elgg_trigger_plugin_hook('format', 'strip_tags', $params, $string); |
|
475 | |||
476 | 16 | 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 string to prepare |
||
525 | * @return string |
||
526 | * |
||
527 | * @access private |
||
528 | */ |
||
529 | function _elgg_get_display_query($string) { |
||
530 | //encode <,>,&, quotes and characters above 127 |
||
531 | 3 | if (function_exists('mb_convert_encoding')) { |
|
532 | 3 | $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 | 3 | 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 | 304 | $res = filter_var($url, FILTER_VALIDATE_URL); |
|
550 | 304 | if ($res) { |
|
551 | 98 | return $res; |
|
552 | } |
||
553 | |||
554 | // Check if it has unicode chars. |
||
555 | 288 | $l = elgg_strlen($url); |
|
556 | 288 | if (strlen($url) == $l) { |
|
557 | 288 | return $res; |
|
558 | } |
||
559 | |||
560 | // Replace wide chars by “X”. |
||
561 | 1 | $s = ''; |
|
562 | 1 | for ($i = 0; $i < $l; ++$i) { |
|
563 | 1 | $ch = elgg_substr($url, $i, 1); |
|
564 | 1 | $s .= (strlen($ch) > 1) ? 'X' : $ch; |
|
565 | } |
||
566 | |||
567 | // Re-check now. |
||
568 | 1 | return filter_var($s, FILTER_VALIDATE_URL) ? $url : false; |
|
569 | } |
||
570 |
If the returned type also contains false, it is an indicator that maybe an error condition leading to the specific return statement remains unhandled.