o2system /
framework
| 1 | <?php |
||||
| 2 | /** |
||||
| 3 | * This file is part of the O2System Framework package. |
||||
| 4 | * |
||||
| 5 | * For the full copyright and license information, please view the LICENSE |
||||
| 6 | * file that was distributed with this source code. |
||||
| 7 | * |
||||
| 8 | * @author Steeve Andrian Salim |
||||
| 9 | * @copyright Copyright (c) Steeve Andrian Salim |
||||
| 10 | */ |
||||
| 11 | // ------------------------------------------------------------------------ |
||||
| 12 | |||||
| 13 | if ( ! function_exists('text_split')) { |
||||
| 14 | /** |
||||
| 15 | * text_split |
||||
| 16 | * |
||||
| 17 | * Split text into array without losing any words. |
||||
| 18 | * |
||||
| 19 | * @params string $text |
||||
| 20 | * |
||||
| 21 | * @param string $text Text Source |
||||
| 22 | * @param string $splitter Split Text Marker |
||||
| 23 | * @param int $limit Split after num of limit characters |
||||
| 24 | * |
||||
| 25 | * @return string |
||||
| 26 | */ |
||||
| 27 | function text_split($text, $splitter = '<---text-split--->', $limit = 100) |
||||
| 28 | { |
||||
| 29 | $wrap_text = wordwrap($text, $limit, $splitter); |
||||
| 30 | $wrap_text = preg_split('[' . $splitter . ']', $wrap_text, -1, PREG_SPLIT_NO_EMPTY); |
||||
| 31 | |||||
| 32 | return implode('', $wrap_text); |
||||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
| 33 | } |
||||
| 34 | } |
||||
| 35 | // ------------------------------------------------------------------------ |
||||
| 36 | |||||
| 37 | if ( ! function_exists('text_columns')) { |
||||
| 38 | /** |
||||
| 39 | * text_columns |
||||
| 40 | * |
||||
| 41 | * Split a block of strings or text evenly across a number of columns. |
||||
| 42 | * |
||||
| 43 | * @param string $text Text Source |
||||
| 44 | * @param int $cols Number of columns |
||||
| 45 | * |
||||
| 46 | * @return array |
||||
| 47 | */ |
||||
| 48 | function text_columns($text, $cols) |
||||
| 49 | { |
||||
| 50 | $col_length = ceil(strlen($text) / $cols) + 3; |
||||
| 51 | $return = explode("\n", wordwrap(strrev($text), $col_length)); |
||||
|
0 ignored issues
–
show
$col_length of type double is incompatible with the type integer expected by parameter $width of wordwrap().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 52 | |||||
| 53 | if (count($return) > $cols) { |
||||
| 54 | $return[ $cols - 1 ] .= " " . $return[ $cols ]; |
||||
| 55 | unset($return[ $cols ]); |
||||
| 56 | } |
||||
| 57 | |||||
| 58 | $return = array_map("strrev", $return); |
||||
| 59 | |||||
| 60 | return array_reverse($return); |
||||
| 61 | } |
||||
| 62 | } |
||||
| 63 | // ------------------------------------------------------------------------ |
||||
| 64 | |||||
| 65 | if ( ! function_exists('text_wrap')) { |
||||
| 66 | /** |
||||
| 67 | * text_wrap |
||||
| 68 | * |
||||
| 69 | * Wrap the given string to a certain chars length and lines. |
||||
| 70 | * |
||||
| 71 | * @param string $text Text Source |
||||
| 72 | * @param int $chars 10 means wrap at 40 chars |
||||
| 73 | * @param int|bool $lines True or false $lines = false or $lines = 3, means truncate after 3 lines |
||||
| 74 | * |
||||
| 75 | * @return string |
||||
| 76 | */ |
||||
| 77 | function text_wrap($text, $chars = 10, $lines = false) |
||||
| 78 | { |
||||
| 79 | # the simple case - return wrapped words |
||||
| 80 | if ( ! $lines) { |
||||
| 81 | return wordwrap($text, $chars, "\n"); |
||||
| 82 | } |
||||
| 83 | # truncate to maximum possible number of characters |
||||
| 84 | $return = substr($text, 0, $chars * $lines); |
||||
| 85 | # apply wrapping and return first $lines lines |
||||
| 86 | $return = wordwrap($return, $chars, "\n"); |
||||
| 87 | preg_match("/(.+\n?){0,$lines}/", $return, $regs); |
||||
| 88 | |||||
| 89 | return $regs[ 0 ]; |
||||
| 90 | } |
||||
| 91 | } |
||||
| 92 | // ------------------------------------------------------------------------ |
||||
| 93 | |||||
| 94 | if ( ! function_exists('text_trim')) { |
||||
| 95 | /** |
||||
| 96 | * text_trim |
||||
| 97 | * |
||||
| 98 | * Cuts the given string to a certain length without breaking a word. |
||||
| 99 | * |
||||
| 100 | * @param string $text Text source |
||||
| 101 | * @param int $limit number of maximum characters leave remaining |
||||
| 102 | * @param string $break = "." break on dot ending or keep maximum set on ' ' |
||||
| 103 | * @param string $ending = '...' to display '...' on the end of the trimmed string |
||||
| 104 | * |
||||
| 105 | * @return string |
||||
| 106 | */ |
||||
| 107 | function text_trim($text, $limit, $break = '.', $ending = '.') |
||||
| 108 | { |
||||
| 109 | // return with no change if string is shorter than $limit |
||||
| 110 | if (strlen($text) <= $limit) { |
||||
| 111 | return $text; |
||||
| 112 | } |
||||
| 113 | // is $break present between $limit and the end of the string? |
||||
| 114 | if (false !== ($breakpoint = strpos($text, $break, $limit))) { |
||||
| 115 | if ($breakpoint < strlen($text) - 1) { |
||||
| 116 | $text = substr($text, 0, $breakpoint) . $ending; |
||||
| 117 | } |
||||
| 118 | } |
||||
| 119 | |||||
| 120 | return $text; |
||||
| 121 | } |
||||
| 122 | } |
||||
| 123 | |||||
| 124 | // ------------------------------------------------------------------------ |
||||
| 125 | |||||
| 126 | if ( ! function_exists('text_word_limiter')) { |
||||
| 127 | /** |
||||
| 128 | * text_word_limiter |
||||
| 129 | * |
||||
| 130 | * Limits a string to X number of words. |
||||
| 131 | * |
||||
| 132 | * @param string |
||||
| 133 | * @param int |
||||
| 134 | * @param string the end character. Usually an ellipsis |
||||
|
0 ignored issues
–
show
The type
the was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 135 | * |
||||
| 136 | * @return string |
||||
| 137 | */ |
||||
| 138 | function text_word_limiter($str, $limit = 100, $end_char = '…') |
||||
| 139 | { |
||||
| 140 | if (trim($str) === '') { |
||||
| 141 | return $str; |
||||
| 142 | } |
||||
| 143 | |||||
| 144 | preg_match('/^\s*+(?:\S++\s*+){1,' . (int)$limit . '}/', $str, $matches); |
||||
| 145 | |||||
| 146 | if (strlen($str) === strlen($matches[ 0 ])) { |
||||
| 147 | $end_char = ''; |
||||
| 148 | } |
||||
| 149 | |||||
| 150 | return rtrim($matches[ 0 ]) . $end_char; |
||||
| 151 | } |
||||
| 152 | } |
||||
| 153 | |||||
| 154 | // ------------------------------------------------------------------------ |
||||
| 155 | |||||
| 156 | if ( ! function_exists('text_character_limiter')) { |
||||
| 157 | /** |
||||
| 158 | * text_character_limiter |
||||
| 159 | * |
||||
| 160 | * Limits the string based on the character count. Preserves complete words |
||||
| 161 | * so the character count may not be exactly as specified. |
||||
| 162 | * |
||||
| 163 | * @param string |
||||
| 164 | * @param int |
||||
| 165 | * @param string the end character. Usually an ellipsis |
||||
| 166 | * |
||||
| 167 | * @return string |
||||
| 168 | */ |
||||
| 169 | function text_character_limiter($string, $n = 500, $end_char = '…') |
||||
| 170 | { |
||||
| 171 | if (mb_strlen($string) < $n) { |
||||
| 172 | return $string; |
||||
| 173 | } |
||||
| 174 | |||||
| 175 | // a bit complicated, but faster than preg_replace with \s+ |
||||
| 176 | $string = preg_replace('/ {2,}/', ' ', str_replace(["\r", "\n", "\t", "\x0B", "\x0C"], ' ', $string)); |
||||
| 177 | |||||
| 178 | if (mb_strlen($string) <= $n) { |
||||
| 179 | return $string; |
||||
| 180 | } |
||||
| 181 | |||||
| 182 | $out = ''; |
||||
| 183 | foreach (explode(' ', trim($string)) as $val) { |
||||
| 184 | $out .= $val . ' '; |
||||
| 185 | |||||
| 186 | if (mb_strlen($out) >= $n) { |
||||
| 187 | $out = trim($out); |
||||
| 188 | |||||
| 189 | return (mb_strlen($out) === mb_strlen($string)) ? $out : $out . $end_char; |
||||
| 190 | } |
||||
| 191 | } |
||||
| 192 | } |
||||
| 193 | } |
||||
| 194 | |||||
| 195 | // ------------------------------------------------------------------------ |
||||
| 196 | |||||
| 197 | if ( ! function_exists('text_censored')) { |
||||
| 198 | /** |
||||
| 199 | * text_censored |
||||
| 200 | * |
||||
| 201 | * Supply a string and an array of disallowed words and any |
||||
| 202 | * matched words will be converted to #### or to the replacement |
||||
| 203 | * word you've submitted. |
||||
| 204 | * |
||||
| 205 | * @param string the text string |
||||
| 206 | * @param string the array of censoered words |
||||
| 207 | * @param string the optional replacement value |
||||
| 208 | * |
||||
| 209 | * @return string |
||||
| 210 | */ |
||||
| 211 | function text_censored($string, $censored, $replacement = '') |
||||
| 212 | { |
||||
| 213 | if ( ! is_array($censored)) { |
||||
| 214 | return $string; |
||||
| 215 | } |
||||
| 216 | |||||
| 217 | $string = ' ' . $string . ' '; |
||||
| 218 | |||||
| 219 | // \w, \b and a few others do not match on a unicode character |
||||
| 220 | // set for performance reasons. As a result words like �ber |
||||
| 221 | // will not match on a word boundary. Instead, we'll assume that |
||||
| 222 | // a bad word will be bookeneded by any of these characters. |
||||
| 223 | $delim = '[-_\'\"`(){}<>\[\]|!?@#%&,.:;^~*+=\/ 0-9\n\r\t]'; |
||||
| 224 | |||||
| 225 | foreach ($censored as $badword) { |
||||
| 226 | if ($replacement !== '') { |
||||
| 227 | $string = preg_replace( |
||||
| 228 | "/({$delim})(" . str_replace('\*', '\w*?', preg_quote($badword, '/')) . ")({$delim})/i", |
||||
| 229 | "\\1{$replacement}\\3", |
||||
| 230 | $string |
||||
| 231 | ); |
||||
| 232 | } else { |
||||
| 233 | $string = preg_replace( |
||||
| 234 | "/({$delim})(" . str_replace('\*', '\w*?', preg_quote($badword, '/')) . ")({$delim})/ie", |
||||
| 235 | "'\\1'.str_repeat('#', strlen('\\2')).'\\3'", |
||||
| 236 | $string |
||||
| 237 | ); |
||||
| 238 | } |
||||
| 239 | } |
||||
| 240 | |||||
| 241 | return trim($string); |
||||
| 242 | } |
||||
| 243 | } |
||||
| 244 | |||||
| 245 | // ------------------------------------------------------------------------ |
||||
| 246 | |||||
| 247 | if ( ! function_exists('text_highlight_phrase')) { |
||||
| 248 | /** |
||||
| 249 | * text_highlight_phrase |
||||
| 250 | * |
||||
| 251 | * Highlights a phrase within a text string. |
||||
| 252 | * |
||||
| 253 | * @param string $string the text string |
||||
| 254 | * @param string $phrase the phrase you'd like to highlight |
||||
| 255 | * @param string $tag_open the openging tag to precede the phrase with |
||||
| 256 | * @param string $tag_close the closing tag to end the phrase with |
||||
| 257 | * |
||||
| 258 | * @return string |
||||
| 259 | */ |
||||
| 260 | function text_highlight_phrase($string, $phrase, $tag_open = '<mark>', $tag_close = '</mark>') |
||||
| 261 | { |
||||
| 262 | return ($string !== '' && $phrase !== '') |
||||
| 263 | ? preg_replace( |
||||
| 264 | '/(' . preg_quote($phrase, '/') . ')/i' . ('UTF8_ENABLED' ? 'u' : ''), |
||||
| 265 | $tag_open . '\\1' . $tag_close, |
||||
| 266 | $string |
||||
| 267 | ) |
||||
| 268 | : $string; |
||||
| 269 | } |
||||
| 270 | } |
||||
| 271 | |||||
| 272 | // ------------------------------------------------------------------------ |
||||
| 273 | |||||
| 274 | if ( ! function_exists('text_word_wrap')) { |
||||
| 275 | /** |
||||
| 276 | * text_word_wrap |
||||
| 277 | * |
||||
| 278 | * Wraps text at the specified character. Maintains the integrity of words. |
||||
| 279 | * Anything placed between {unwrap}{/unwrap} will not be word wrapped, nor |
||||
| 280 | * will URLs. |
||||
| 281 | * |
||||
| 282 | * @param string $string the text string |
||||
| 283 | * @param int $limit = 76 the number of characters to wrap at |
||||
| 284 | * |
||||
| 285 | * @return string |
||||
| 286 | */ |
||||
| 287 | function text_word_wrap($string, $limit = 76) |
||||
| 288 | { |
||||
| 289 | // Set the character limit |
||||
| 290 | is_numeric($limit) OR $limit = 76; |
||||
| 291 | |||||
| 292 | // Reduce multiple spaces |
||||
| 293 | $string = preg_replace('| +|', ' ', $string); |
||||
| 294 | |||||
| 295 | // Standardize newlines |
||||
| 296 | if (strpos($string, "\r") !== false) { |
||||
| 297 | $string = str_replace(["\r\n", "\r"], "\n", $string); |
||||
| 298 | } |
||||
| 299 | |||||
| 300 | // If the current word is surrounded by {unwrap} tags we'll |
||||
| 301 | // strip the entire chunk and replace it with a marker. |
||||
| 302 | $unwrap = []; |
||||
| 303 | if (preg_match_all('|\{unwrap\}(.+?)\{/unwrap\}|s', $string, $matches)) { |
||||
| 304 | for ($i = 0, $c = count($matches[ 0 ]); $i < $c; $i++) { |
||||
| 305 | $unwrap[] = $matches[ 1 ][ $i ]; |
||||
| 306 | $string = str_replace($matches[ 0 ][ $i ], '{{unwrapped' . $i . '}}', $string); |
||||
| 307 | } |
||||
| 308 | } |
||||
| 309 | |||||
| 310 | // Use PHP's native function to do the initial wordwrap. |
||||
| 311 | // We set the cut flag to FALSE so that any individual words that are |
||||
| 312 | // too long get left alone. In the next step we'll deal with them. |
||||
| 313 | $string = wordwrap($string, $limit, "\n", false); |
||||
| 314 | |||||
| 315 | // Split the string into individual lines of text and cycle through them |
||||
| 316 | $output = ''; |
||||
| 317 | foreach (explode("\n", $string) as $line) { |
||||
| 318 | // Is the line within the allowed character count? |
||||
| 319 | // If so we'll join it to the output and continue |
||||
| 320 | if (mb_strlen($line) <= $limit) { |
||||
| 321 | $output .= $line . "\n"; |
||||
| 322 | continue; |
||||
| 323 | } |
||||
| 324 | |||||
| 325 | $temp = ''; |
||||
| 326 | while (mb_strlen($line) > $limit) { |
||||
| 327 | // If the over-length word is a URL we won't wrap it |
||||
| 328 | if (preg_match('!\[url.+\]|://|www\.!', $line)) { |
||||
| 329 | break; |
||||
| 330 | } |
||||
| 331 | |||||
| 332 | // Trim the word down |
||||
| 333 | $temp .= mb_substr($line, 0, $limit - 1); |
||||
| 334 | $line = mb_substr($line, $limit - 1); |
||||
| 335 | } |
||||
| 336 | |||||
| 337 | // If $temp contains data it means we had to split up an over-length |
||||
| 338 | // word into smaller chunks so we'll add it back to our current line |
||||
| 339 | if ($temp !== '') { |
||||
| 340 | $output .= $temp . "\n" . $line . "\n"; |
||||
| 341 | } else { |
||||
| 342 | $output .= $line . "\n"; |
||||
| 343 | } |
||||
| 344 | } |
||||
| 345 | |||||
| 346 | // Put our markers back |
||||
| 347 | if (count($unwrap) > 0) { |
||||
| 348 | foreach ($unwrap as $key => $val) { |
||||
| 349 | $output = str_replace('{{unwrapped' . $key . '}}', $val, $output); |
||||
| 350 | } |
||||
| 351 | } |
||||
| 352 | |||||
| 353 | return $output; |
||||
| 354 | } |
||||
| 355 | } |
||||
| 356 | |||||
| 357 | // ------------------------------------------------------------------------ |
||||
| 358 | |||||
| 359 | if ( ! function_exists('text_ellipsis')) { |
||||
| 360 | /** |
||||
| 361 | * text_ellipsis |
||||
| 362 | * |
||||
| 363 | * This function will strip tags from a string, split it at its max_length and ellipsis |
||||
| 364 | * |
||||
| 365 | * @param string string to ellipsize |
||||
| 366 | * @param int max length of string |
||||
|
0 ignored issues
–
show
The type
max was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 367 | * @param mixed int (1|0) or float, .5, .2, etc for position to split |
||||
| 368 | * @param string ellipsis ; Default '...' |
||||
|
0 ignored issues
–
show
The type
ellipsis was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths Loading history...
|
|||||
| 369 | * |
||||
| 370 | * @return string ellipsis string |
||||
| 371 | */ |
||||
| 372 | function text_ellipsis($string, $max_length, $position = 1, $ellipsis = '…') |
||||
| 373 | { |
||||
| 374 | // Strip tags |
||||
| 375 | $string = trim(strip_tags($string)); |
||||
| 376 | |||||
| 377 | // Is the string long enough to ellipsis? |
||||
| 378 | if (mb_strlen($string) <= $max_length) { |
||||
| 379 | return $string; |
||||
| 380 | } |
||||
| 381 | |||||
| 382 | $beg = mb_substr($string, 0, floor($max_length * $position)); |
||||
|
0 ignored issues
–
show
floor($max_length * $position) of type double is incompatible with the type integer expected by parameter $length of mb_substr().
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
| 383 | $position = ($position > 1) ? 1 : $position; |
||||
| 384 | |||||
| 385 | if ($position === 1) { |
||||
| 386 | $end = mb_substr($string, 0, -($max_length - mb_strlen($beg))); |
||||
| 387 | } else { |
||||
| 388 | $end = mb_substr($string, -($max_length - mb_strlen($beg))); |
||||
| 389 | } |
||||
| 390 | |||||
| 391 | return $beg . $ellipsis . $end; |
||||
| 392 | } |
||||
| 393 | } |
||||
| 394 | |||||
| 395 | // ------------------------------------------------------------------------ |
||||
| 396 | |||||
| 397 | if ( ! function_exists('text_excerpt')) { |
||||
| 398 | /** |
||||
| 399 | * text_excerpt |
||||
| 400 | * |
||||
| 401 | * Allows to extract a piece of text surrounding a word or phrase. |
||||
| 402 | * |
||||
| 403 | * @param string $string String to search the phrase |
||||
| 404 | * @param string $phrase Phrase that will be searched for. |
||||
| 405 | * @param int $radius The amount of characters returned arround the phrase. |
||||
| 406 | * @param string $ellipsis Ending that will be appended |
||||
| 407 | * |
||||
| 408 | * @return string |
||||
| 409 | * |
||||
| 410 | * If no $phrase is passed, will generate an excerpt of $radius characters |
||||
| 411 | * from the begining of $text. |
||||
| 412 | */ |
||||
| 413 | function text_excerpt($string, $phrase = null, $radius = 100, $ellipsis = '...') |
||||
| 414 | { |
||||
| 415 | if (isset($phrase)) { |
||||
| 416 | $phrase_pos = strpos(strtolower($string), strtolower($phrase)); |
||||
| 417 | $phrase_len = strlen($phrase); |
||||
| 418 | } elseif ( ! isset($phrase)) { |
||||
| 419 | $phrase_pos = $radius / 2; |
||||
| 420 | $phrase_len = 1; |
||||
| 421 | } |
||||
| 422 | $pre = explode(' ', substr($string, 0, $phrase_pos)); |
||||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
| 423 | $pos = explode(' ', substr($string, $phrase_pos + $phrase_len)); |
||||
|
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
|
|||||
| 424 | $prev = ' '; |
||||
| 425 | $post = ' '; |
||||
| 426 | $count = 0; |
||||
| 427 | foreach (array_reverse($pre) as $pr => $e) { |
||||
| 428 | if ((strlen($e) + $count + 1) < $radius) { |
||||
| 429 | $prev = ' ' . $e . $prev; |
||||
| 430 | } |
||||
| 431 | $count = ++$count + strlen($e); |
||||
| 432 | } |
||||
| 433 | $count = 0; |
||||
| 434 | foreach ($pos as $po => $s) { |
||||
| 435 | if ((strlen($s) + $count + 1) < $radius) { |
||||
| 436 | $post .= $s . ' '; |
||||
| 437 | } |
||||
| 438 | $count = ++$count + strlen($s); |
||||
| 439 | } |
||||
| 440 | $ellPre = $phrase ? $ellipsis : ''; |
||||
| 441 | |||||
| 442 | return $ellPre . $prev . $phrase . $post . $ellipsis; |
||||
| 443 | } |
||||
| 444 | } |