PluginProbe ʕ •ᴥ•ʔ
Independent Analytics – WordPress Analytics Plugin / 2.5.1
Independent Analytics – WordPress Analytics Plugin v2.5.1
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 1.19.1 1.2 1.20.0 1.21.0 1.22.0 1.22.1 1.23.0 1.23.1 1.24.0 1.24.1 1.25.0 1.25.1 1.26.0 1.27.0 1.28.0 1.28.1 1.28.2 1.28.3 1.29.0 1.3 1.30.0 1.30.1 1.4 1.5 1.6 1.7 1.8 1.9 2.0.0 2.0.1 2.1.4 2.1.5 2.1.6 2.10.0 2.10.1 2.10.2 2.10.3 2.10.4 2.11.0 2.11.1 2.11.10 2.11.2 2.11.3 2.11.4 2.11.5 2.11.6 2.11.7 2.11.8 2.11.9 2.12.0 2.12.1 2.12.2 2.13.1 2.13.2 2.13.5 2.13.6 2.14.0 2.14.1 2.14.2 2.14.4 2.14.6 2.14.7 2.14.8 2.14.9 2.2.0 2.2.1 2.3.1 2.3.2 2.4.2 2.4.3 2.5.0 2.5.1 2.6.0 2.6.1 2.6.2 2.6.3 2.6.4 2.7.0 2.7.1 2.7.2 2.7.3 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.8 2.8.9 2.9.2 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7
independent-analytics / vendor / symfony / polyfill-mbstring / Mbstring.php
independent-analytics / vendor / symfony / polyfill-mbstring Last commit date
Resources 2 years ago Mbstring.php 2 years ago bootstrap.php 2 years ago bootstrap80.php 2 years ago
Mbstring.php
755 lines
1 <?php
2
3 /*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 namespace Symfony\Polyfill\Mbstring;
12
13 /**
14 * Partial mbstring implementation in PHP, iconv based, UTF-8 centric.
15 *
16 * Implemented:
17 * - mb_chr - Returns a specific character from its Unicode code point
18 * - mb_convert_encoding - Convert character encoding
19 * - mb_convert_variables - Convert character code in variable(s)
20 * - mb_decode_mimeheader - Decode string in MIME header field
21 * - mb_encode_mimeheader - Encode string for MIME header XXX NATIVE IMPLEMENTATION IS REALLY BUGGED
22 * - mb_decode_numericentity - Decode HTML numeric string reference to character
23 * - mb_encode_numericentity - Encode character to HTML numeric string reference
24 * - mb_convert_case - Perform case folding on a string
25 * - mb_detect_encoding - Detect character encoding
26 * - mb_get_info - Get internal settings of mbstring
27 * - mb_http_input - Detect HTTP input character encoding
28 * - mb_http_output - Set/Get HTTP output character encoding
29 * - mb_internal_encoding - Set/Get internal character encoding
30 * - mb_list_encodings - Returns an array of all supported encodings
31 * - mb_ord - Returns the Unicode code point of a character
32 * - mb_output_handler - Callback function converts character encoding in output buffer
33 * - mb_scrub - Replaces ill-formed byte sequences with substitute characters
34 * - mb_strlen - Get string length
35 * - mb_strpos - Find position of first occurrence of string in a string
36 * - mb_strrpos - Find position of last occurrence of a string in a string
37 * - mb_str_split - Convert a string to an array
38 * - mb_strtolower - Make a string lowercase
39 * - mb_strtoupper - Make a string uppercase
40 * - mb_substitute_character - Set/Get substitution character
41 * - mb_substr - Get part of string
42 * - mb_stripos - Finds position of first occurrence of a string within another, case insensitive
43 * - mb_stristr - Finds first occurrence of a string within another, case insensitive
44 * - mb_strrchr - Finds the last occurrence of a character in a string within another
45 * - mb_strrichr - Finds the last occurrence of a character in a string within another, case insensitive
46 * - mb_strripos - Finds position of last occurrence of a string within another, case insensitive
47 * - mb_strstr - Finds first occurrence of a string within another
48 * - mb_strwidth - Return width of string
49 * - mb_substr_count - Count the number of substring occurrences
50 *
51 * Not implemented:
52 * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
53 * - mb_ereg_* - Regular expression with multibyte support
54 * - mb_parse_str - Parse GET/POST/COOKIE data and set global variable
55 * - mb_preferred_mime_name - Get MIME charset string
56 * - mb_regex_encoding - Returns current encoding for multibyte regex as string
57 * - mb_regex_set_options - Set/Get the default options for mbregex functions
58 * - mb_send_mail - Send encoded mail
59 * - mb_split - Split multibyte string using regular expression
60 * - mb_strcut - Get part of string
61 * - mb_strimwidth - Get truncated string with specified width
62 *
63 * @author Nicolas Grekas <p@tchwork.com>
64 *
65 * @internal
66 */
67 final class Mbstring
68 {
69 public const MB_CASE_FOLD = \PHP_INT_MAX;
70 private const SIMPLE_CASE_FOLD = [['µ', 'ſ', "�
71 ", 'ς', "ϐ", "ϑ", "ϕ", "ϖ", "ϰ", "ϱ", "ϵ", "", ""], ['μ', 's', 'ι', 'σ', 'β', 'θ', 'φ', 'π', 'κ', 'ρ', 'ε', "", 'ι']];
72 private static $encodingList = ['ASCII', 'UTF-8'];
73 private static $language = 'neutral';
74 private static $internalEncoding = 'UTF-8';
75 public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
76 {
77 if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) {
78 $fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
79 } else {
80 $fromEncoding = self::getEncoding($fromEncoding);
81 }
82 $toEncoding = self::getEncoding($toEncoding);
83 if ('BASE64' === $fromEncoding) {
84 $s = \base64_decode($s);
85 $fromEncoding = $toEncoding;
86 }
87 if ('BASE64' === $toEncoding) {
88 return \base64_encode($s);
89 }
90 if ('HTML-ENTITIES' === $toEncoding || 'HTML' === $toEncoding) {
91 if ('HTML-ENTITIES' === $fromEncoding || 'HTML' === $fromEncoding) {
92 $fromEncoding = 'Windows-1252';
93 }
94 if ('UTF-8' !== $fromEncoding) {
95 $s = \iconv($fromEncoding, 'UTF-8//IGNORE', $s);
96 }
97 return \preg_replace_callback('/[\\x80-\\xFF]+/', [__CLASS__, 'html_encoding_callback'], $s);
98 }
99 if ('HTML-ENTITIES' === $fromEncoding) {
100 $s = \html_entity_decode($s, \ENT_COMPAT, 'UTF-8');
101 $fromEncoding = 'UTF-8';
102 }
103 return \iconv($fromEncoding, $toEncoding . '//IGNORE', $s);
104 }
105 public static function mb_convert_variables($toEncoding, $fromEncoding, &...$vars)
106 {
107 $ok = \true;
108 \array_walk_recursive($vars, function (&$v) use(&$ok, $toEncoding, $fromEncoding) {
109 if (\false === ($v = self::mb_convert_encoding($v, $toEncoding, $fromEncoding))) {
110 $ok = \false;
111 }
112 });
113 return $ok ? $fromEncoding : \false;
114 }
115 public static function mb_decode_mimeheader($s)
116 {
117 return \iconv_mime_decode($s, 2, self::$internalEncoding);
118 }
119 public static function mb_encode_mimeheader($s, $charset = null, $transferEncoding = null, $linefeed = null, $indent = null)
120 {
121 \trigger_error('mb_encode_mimeheader() is bugged. Please use iconv_mime_encode() instead', \E_USER_WARNING);
122 }
123 public static function mb_decode_numericentity($s, $convmap, $encoding = null)
124 {
125 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
126 \trigger_error('mb_decode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
127 return null;
128 }
129 if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
130 return \false;
131 }
132 if (null !== $encoding && !\is_scalar($encoding)) {
133 \trigger_error('mb_decode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
134 return '';
135 // Instead of null (cf. mb_encode_numericentity).
136 }
137 $s = (string) $s;
138 if ('' === $s) {
139 return '';
140 }
141 $encoding = self::getEncoding($encoding);
142 if ('UTF-8' === $encoding) {
143 $encoding = null;
144 if (!\preg_match('//u', $s)) {
145 $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
146 }
147 } else {
148 $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
149 }
150 $cnt = \floor(\count($convmap) / 4) * 4;
151 for ($i = 0; $i < $cnt; $i += 4) {
152 // collector_decode_htmlnumericentity ignores $convmap[$i + 3]
153 $convmap[$i] += $convmap[$i + 2];
154 $convmap[$i + 1] += $convmap[$i + 2];
155 }
156 $s = \preg_replace_callback('/&#(?:0*([0-9]+)|x0*([0-9a-fA-F]+))(?!&);?/', function (array $m) use($cnt, $convmap) {
157 $c = isset($m[2]) ? (int) \hexdec($m[2]) : $m[1];
158 for ($i = 0; $i < $cnt; $i += 4) {
159 if ($c >= $convmap[$i] && $c <= $convmap[$i + 1]) {
160 return self::mb_chr($c - $convmap[$i + 2]);
161 }
162 }
163 return $m[0];
164 }, $s);
165 if (null === $encoding) {
166 return $s;
167 }
168 return \iconv('UTF-8', $encoding . '//IGNORE', $s);
169 }
170 public static function mb_encode_numericentity($s, $convmap, $encoding = null, $is_hex = \false)
171 {
172 if (null !== $s && !\is_scalar($s) && !(\is_object($s) && \method_exists($s, '__toString'))) {
173 \trigger_error('mb_encode_numericentity() expects parameter 1 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
174 return null;
175 }
176 if (!\is_array($convmap) || 80000 > \PHP_VERSION_ID && !$convmap) {
177 return \false;
178 }
179 if (null !== $encoding && !\is_scalar($encoding)) {
180 \trigger_error('mb_encode_numericentity() expects parameter 3 to be string, ' . \gettype($s) . ' given', \E_USER_WARNING);
181 return null;
182 // Instead of '' (cf. mb_decode_numericentity).
183 }
184 if (null !== $is_hex && !\is_scalar($is_hex)) {
185 \trigger_error('mb_encode_numericentity() expects parameter 4 to be boolean, ' . \gettype($s) . ' given', \E_USER_WARNING);
186 return null;
187 }
188 $s = (string) $s;
189 if ('' === $s) {
190 return '';
191 }
192 $encoding = self::getEncoding($encoding);
193 if ('UTF-8' === $encoding) {
194 $encoding = null;
195 if (!\preg_match('//u', $s)) {
196 $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
197 }
198 } else {
199 $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
200 }
201 static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
202 $cnt = \floor(\count($convmap) / 4) * 4;
203 $i = 0;
204 $len = \strlen($s);
205 $result = '';
206 while ($i < $len) {
207 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
208 $uchr = \substr($s, $i, $ulen);
209 $i += $ulen;
210 $c = self::mb_ord($uchr);
211 for ($j = 0; $j < $cnt; $j += 4) {
212 if ($c >= $convmap[$j] && $c <= $convmap[$j + 1]) {
213 $cOffset = $c + $convmap[$j + 2] & $convmap[$j + 3];
214 $result .= $is_hex ? \sprintf('&#x%X;', $cOffset) : '&#' . $cOffset . ';';
215 continue 2;
216 }
217 }
218 $result .= $uchr;
219 }
220 if (null === $encoding) {
221 return $result;
222 }
223 return \iconv('UTF-8', $encoding . '//IGNORE', $result);
224 }
225 public static function mb_convert_case($s, $mode, $encoding = null)
226 {
227 $s = (string) $s;
228 if ('' === $s) {
229 return '';
230 }
231 $encoding = self::getEncoding($encoding);
232 if ('UTF-8' === $encoding) {
233 $encoding = null;
234 if (!\preg_match('//u', $s)) {
235 $s = @\iconv('UTF-8', 'UTF-8//IGNORE', $s);
236 }
237 } else {
238 $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
239 }
240 if (\MB_CASE_TITLE == $mode) {
241 static $titleRegexp = null;
242 if (null === $titleRegexp) {
243 $titleRegexp = self::getData('titleCaseRegexp');
244 }
245 $s = \preg_replace_callback($titleRegexp, [__CLASS__, 'title_case'], $s);
246 } else {
247 if (\MB_CASE_UPPER == $mode) {
248 static $upper = null;
249 if (null === $upper) {
250 $upper = self::getData('upperCase');
251 }
252 $map = $upper;
253 } else {
254 if (self::MB_CASE_FOLD === $mode) {
255 static $caseFolding = null;
256 if (null === $caseFolding) {
257 $caseFolding = self::getData('caseFolding');
258 }
259 $s = \strtr($s, $caseFolding);
260 }
261 static $lower = null;
262 if (null === $lower) {
263 $lower = self::getData('lowerCase');
264 }
265 $map = $lower;
266 }
267 static $ulenMask = ["\xc0" => 2, "\xd0" => 2, "\xe0" => 3, "\xf0" => 4];
268 $i = 0;
269 $len = \strlen($s);
270 while ($i < $len) {
271 $ulen = $s[$i] < "\x80" ? 1 : $ulenMask[$s[$i] & "\xf0"];
272 $uchr = \substr($s, $i, $ulen);
273 $i += $ulen;
274 if (isset($map[$uchr])) {
275 $uchr = $map[$uchr];
276 $nlen = \strlen($uchr);
277 if ($nlen == $ulen) {
278 $nlen = $i;
279 do {
280 $s[--$nlen] = $uchr[--$ulen];
281 } while ($ulen);
282 } else {
283 $s = \substr_replace($s, $uchr, $i - $ulen, $ulen);
284 $len += $nlen - $ulen;
285 $i += $nlen - $ulen;
286 }
287 }
288 }
289 }
290 if (null === $encoding) {
291 return $s;
292 }
293 return \iconv('UTF-8', $encoding . '//IGNORE', $s);
294 }
295 public static function mb_internal_encoding($encoding = null)
296 {
297 if (null === $encoding) {
298 return self::$internalEncoding;
299 }
300 $normalizedEncoding = self::getEncoding($encoding);
301 if ('UTF-8' === $normalizedEncoding || \false !== @\iconv($normalizedEncoding, $normalizedEncoding, ' ')) {
302 self::$internalEncoding = $normalizedEncoding;
303 return \true;
304 }
305 if (80000 > \PHP_VERSION_ID) {
306 return \false;
307 }
308 throw new \ValueError(\sprintf('Argument #1 ($encoding) must be a valid encoding, "%s" given', $encoding));
309 }
310 public static function mb_language($lang = null)
311 {
312 if (null === $lang) {
313 return self::$language;
314 }
315 switch ($normalizedLang = \strtolower($lang)) {
316 case 'uni':
317 case 'neutral':
318 self::$language = $normalizedLang;
319 return \true;
320 }
321 if (80000 > \PHP_VERSION_ID) {
322 return \false;
323 }
324 throw new \ValueError(\sprintf('Argument #1 ($language) must be a valid language, "%s" given', $lang));
325 }
326 public static function mb_list_encodings()
327 {
328 return ['UTF-8'];
329 }
330 public static function mb_encoding_aliases($encoding)
331 {
332 switch (\strtoupper($encoding)) {
333 case 'UTF8':
334 case 'UTF-8':
335 return ['utf8'];
336 }
337 return \false;
338 }
339 public static function mb_check_encoding($var = null, $encoding = null)
340 {
341 if (\PHP_VERSION_ID < 70200 && \is_array($var)) {
342 \trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
343 return null;
344 }
345 if (null === $encoding) {
346 if (null === $var) {
347 return \false;
348 }
349 $encoding = self::$internalEncoding;
350 }
351 if (!\is_array($var)) {
352 return self::mb_detect_encoding($var, [$encoding]) || \false !== @\iconv($encoding, $encoding, $var);
353 }
354 foreach ($var as $key => $value) {
355 if (!self::mb_check_encoding($key, $encoding)) {
356 return \false;
357 }
358 if (!self::mb_check_encoding($value, $encoding)) {
359 return \false;
360 }
361 }
362 return \true;
363 }
364 public static function mb_detect_encoding($str, $encodingList = null, $strict = \false)
365 {
366 if (null === $encodingList) {
367 $encodingList = self::$encodingList;
368 } else {
369 if (!\is_array($encodingList)) {
370 $encodingList = \array_map('trim', \explode(',', $encodingList));
371 }
372 $encodingList = \array_map('strtoupper', $encodingList);
373 }
374 foreach ($encodingList as $enc) {
375 switch ($enc) {
376 case 'ASCII':
377 if (!\preg_match('/[\\x80-\\xFF]/', $str)) {
378 return $enc;
379 }
380 break;
381 case 'UTF8':
382 case 'UTF-8':
383 if (\preg_match('//u', $str)) {
384 return 'UTF-8';
385 }
386 break;
387 default:
388 if (0 === \strncmp($enc, 'ISO-8859-', 9)) {
389 return $enc;
390 }
391 }
392 }
393 return \false;
394 }
395 public static function mb_detect_order($encodingList = null)
396 {
397 if (null === $encodingList) {
398 return self::$encodingList;
399 }
400 if (!\is_array($encodingList)) {
401 $encodingList = \array_map('trim', \explode(',', $encodingList));
402 }
403 $encodingList = \array_map('strtoupper', $encodingList);
404 foreach ($encodingList as $enc) {
405 switch ($enc) {
406 default:
407 if (\strncmp($enc, 'ISO-8859-', 9)) {
408 return \false;
409 }
410 // no break
411 case 'ASCII':
412 case 'UTF8':
413 case 'UTF-8':
414 }
415 }
416 self::$encodingList = $encodingList;
417 return \true;
418 }
419 public static function mb_strlen($s, $encoding = null)
420 {
421 $encoding = self::getEncoding($encoding);
422 if ('CP850' === $encoding || 'ASCII' === $encoding) {
423 return \strlen($s);
424 }
425 return @\iconv_strlen($s, $encoding);
426 }
427 public static function mb_strpos($haystack, $needle, $offset = 0, $encoding = null)
428 {
429 $encoding = self::getEncoding($encoding);
430 if ('CP850' === $encoding || 'ASCII' === $encoding) {
431 return \strpos($haystack, $needle, $offset);
432 }
433 $needle = (string) $needle;
434 if ('' === $needle) {
435 if (80000 > \PHP_VERSION_ID) {
436 \trigger_error(__METHOD__ . ': Empty delimiter', \E_USER_WARNING);
437 return \false;
438 }
439 return 0;
440 }
441 return \iconv_strpos($haystack, $needle, $offset, $encoding);
442 }
443 public static function mb_strrpos($haystack, $needle, $offset = 0, $encoding = null)
444 {
445 $encoding = self::getEncoding($encoding);
446 if ('CP850' === $encoding || 'ASCII' === $encoding) {
447 return \strrpos($haystack, $needle, $offset);
448 }
449 if ($offset != (int) $offset) {
450 $offset = 0;
451 } elseif ($offset = (int) $offset) {
452 if ($offset < 0) {
453 if (0 > ($offset += self::mb_strlen($needle))) {
454 $haystack = self::mb_substr($haystack, 0, $offset, $encoding);
455 }
456 $offset = 0;
457 } else {
458 $haystack = self::mb_substr($haystack, $offset, 2147483647, $encoding);
459 }
460 }
461 $pos = '' !== $needle || 80000 > \PHP_VERSION_ID ? \iconv_strrpos($haystack, $needle, $encoding) : self::mb_strlen($haystack, $encoding);
462 return \false !== $pos ? $offset + $pos : \false;
463 }
464 public static function mb_str_split($string, $split_length = 1, $encoding = null)
465 {
466 if (null !== $string && !\is_scalar($string) && !(\is_object($string) && \method_exists($string, '__toString'))) {
467 \trigger_error('mb_str_split() expects parameter 1 to be string, ' . \gettype($string) . ' given', \E_USER_WARNING);
468 return null;
469 }
470 if (1 > ($split_length = (int) $split_length)) {
471 if (80000 > \PHP_VERSION_ID) {
472 \trigger_error('The length of each segment must be greater than zero', \E_USER_WARNING);
473 return \false;
474 }
475 throw new \ValueError('Argument #2 ($length) must be greater than 0');
476 }
477 if (null === $encoding) {
478 $encoding = \mb_internal_encoding();
479 }
480 if ('UTF-8' === ($encoding = self::getEncoding($encoding))) {
481 $rx = '/(';
482 while (65535 < $split_length) {
483 $rx .= '.{65535}';
484 $split_length -= 65535;
485 }
486 $rx .= '.{' . $split_length . '})/us';
487 return \preg_split($rx, $string, -1, \PREG_SPLIT_DELIM_CAPTURE | \PREG_SPLIT_NO_EMPTY);
488 }
489 $result = [];
490 $length = \mb_strlen($string, $encoding);
491 for ($i = 0; $i < $length; $i += $split_length) {
492 $result[] = \mb_substr($string, $i, $split_length, $encoding);
493 }
494 return $result;
495 }
496 public static function mb_strtolower($s, $encoding = null)
497 {
498 return self::mb_convert_case($s, \MB_CASE_LOWER, $encoding);
499 }
500 public static function mb_strtoupper($s, $encoding = null)
501 {
502 return self::mb_convert_case($s, \MB_CASE_UPPER, $encoding);
503 }
504 public static function mb_substitute_character($c = null)
505 {
506 if (null === $c) {
507 return 'none';
508 }
509 if (0 === \strcasecmp($c, 'none')) {
510 return \true;
511 }
512 if (80000 > \PHP_VERSION_ID) {
513 return \false;
514 }
515 if (\is_int($c) || 'long' === $c || 'entity' === $c) {
516 return \false;
517 }
518 throw new \ValueError('Argument #1 ($substitute_character) must be "none", "long", "entity" or a valid codepoint');
519 }
520 public static function mb_substr($s, $start, $length = null, $encoding = null)
521 {
522 $encoding = self::getEncoding($encoding);
523 if ('CP850' === $encoding || 'ASCII' === $encoding) {
524 return (string) \substr($s, $start, null === $length ? 2147483647 : $length);
525 }
526 if ($start < 0) {
527 $start = \iconv_strlen($s, $encoding) + $start;
528 if ($start < 0) {
529 $start = 0;
530 }
531 }
532 if (null === $length) {
533 $length = 2147483647;
534 } elseif ($length < 0) {
535 $length = \iconv_strlen($s, $encoding) + $length - $start;
536 if ($length < 0) {
537 return '';
538 }
539 }
540 return (string) \iconv_substr($s, $start, $length, $encoding);
541 }
542 public static function mb_stripos($haystack, $needle, $offset = 0, $encoding = null)
543 {
544 [$haystack, $needle] = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], [self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding), self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding)]);
545 return self::mb_strpos($haystack, $needle, $offset, $encoding);
546 }
547 public static function mb_stristr($haystack, $needle, $part = \false, $encoding = null)
548 {
549 $pos = self::mb_stripos($haystack, $needle, 0, $encoding);
550 return self::getSubpart($pos, $part, $haystack, $encoding);
551 }
552 public static function mb_strrchr($haystack, $needle, $part = \false, $encoding = null)
553 {
554 $encoding = self::getEncoding($encoding);
555 if ('CP850' === $encoding || 'ASCII' === $encoding) {
556 $pos = \strrpos($haystack, $needle);
557 } else {
558 $needle = self::mb_substr($needle, 0, 1, $encoding);
559 $pos = \iconv_strrpos($haystack, $needle, $encoding);
560 }
561 return self::getSubpart($pos, $part, $haystack, $encoding);
562 }
563 public static function mb_strrichr($haystack, $needle, $part = \false, $encoding = null)
564 {
565 $needle = self::mb_substr($needle, 0, 1, $encoding);
566 $pos = self::mb_strripos($haystack, $needle, $encoding);
567 return self::getSubpart($pos, $part, $haystack, $encoding);
568 }
569 public static function mb_strripos($haystack, $needle, $offset = 0, $encoding = null)
570 {
571 $haystack = self::mb_convert_case($haystack, \MB_CASE_LOWER, $encoding);
572 $needle = self::mb_convert_case($needle, \MB_CASE_LOWER, $encoding);
573 $haystack = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $haystack);
574 $needle = \str_replace(self::SIMPLE_CASE_FOLD[0], self::SIMPLE_CASE_FOLD[1], $needle);
575 return self::mb_strrpos($haystack, $needle, $offset, $encoding);
576 }
577 public static function mb_strstr($haystack, $needle, $part = \false, $encoding = null)
578 {
579 $pos = \strpos($haystack, $needle);
580 if (\false === $pos) {
581 return \false;
582 }
583 if ($part) {
584 return \substr($haystack, 0, $pos);
585 }
586 return \substr($haystack, $pos);
587 }
588 public static function mb_get_info($type = 'all')
589 {
590 $info = ['internal_encoding' => self::$internalEncoding, 'http_output' => 'pass', 'http_output_conv_mimetypes' => '^(text/|application/xhtml\\+xml)', 'func_overload' => 0, 'func_overload_list' => 'no overload', 'mail_charset' => 'UTF-8', 'mail_header_encoding' => 'BASE64', 'mail_body_encoding' => 'BASE64', 'illegal_chars' => 0, 'encoding_translation' => 'Off', 'language' => self::$language, 'detect_order' => self::$encodingList, 'substitute_character' => 'none', 'strict_detection' => 'Off'];
591 if ('all' === $type) {
592 return $info;
593 }
594 if (isset($info[$type])) {
595 return $info[$type];
596 }
597 return \false;
598 }
599 public static function mb_http_input($type = '')
600 {
601 return \false;
602 }
603 public static function mb_http_output($encoding = null)
604 {
605 return null !== $encoding ? 'pass' === $encoding : 'pass';
606 }
607 public static function mb_strwidth($s, $encoding = null)
608 {
609 $encoding = self::getEncoding($encoding);
610 if ('UTF-8' !== $encoding) {
611 $s = \iconv($encoding, 'UTF-8//IGNORE', $s);
612 }
613 $s = \preg_replace('/[\\x{1100}-\\x{115F}\\x{2329}\\x{232A}\\x{2E80}-\\x{303E}\\x{3040}-\\x{A4CF}\\x{AC00}-\\x{D7A3}\\x{F900}-\\x{FAFF}\\x{FE10}-\\x{FE19}\\x{FE30}-\\x{FE6F}\\x{FF00}-\\x{FF60}\\x{FFE0}-\\x{FFE6}\\x{20000}-\\x{2FFFD}\\x{30000}-\\x{3FFFD}]/u', '', $s, -1, $wide);
614 return ($wide << 1) + \iconv_strlen($s, 'UTF-8');
615 }
616 public static function mb_substr_count($haystack, $needle, $encoding = null)
617 {
618 return \substr_count($haystack, $needle);
619 }
620 public static function mb_output_handler($contents, $status)
621 {
622 return $contents;
623 }
624 public static function mb_chr($code, $encoding = null)
625 {
626 if (0x80 > ($code %= 0x200000)) {
627 $s = \chr($code);
628 } elseif (0x800 > $code) {
629 $s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f);
630 } elseif (0x10000 > $code) {
631 $s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
632 } else {
633 $s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
634 }
635 if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
636 $s = \mb_convert_encoding($s, $encoding, 'UTF-8');
637 }
638 return $s;
639 }
640 public static function mb_ord($s, $encoding = null)
641 {
642 if ('UTF-8' !== ($encoding = self::getEncoding($encoding))) {
643 $s = \mb_convert_encoding($s, 'UTF-8', $encoding);
644 }
645 if (1 === \strlen($s)) {
646 return \ord($s);
647 }
648 $code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0;
649 if (0xf0 <= $code) {
650 return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80;
651 }
652 if (0xe0 <= $code) {
653 return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80;
654 }
655 if (0xc0 <= $code) {
656 return ($code - 0xc0 << 6) + $s[2] - 0x80;
657 }
658 return $code;
659 }
660 public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null) : string
661 {
662 if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], \true)) {
663 throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
664 }
665 if (null === $encoding) {
666 $encoding = self::mb_internal_encoding();
667 }
668 try {
669 $validEncoding = @self::mb_check_encoding('', $encoding);
670 } catch (\ValueError $e) {
671 throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
672 }
673 // BC for PHP 7.3 and lower
674 if (!$validEncoding) {
675 throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
676 }
677 if (self::mb_strlen($pad_string, $encoding) <= 0) {
678 throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string');
679 }
680 $paddingRequired = $length - self::mb_strlen($string, $encoding);
681 if ($paddingRequired < 1) {
682 return $string;
683 }
684 switch ($pad_type) {
685 case \STR_PAD_LEFT:
686 return self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding) . $string;
687 case \STR_PAD_RIGHT:
688 return $string . self::mb_substr(\str_repeat($pad_string, $paddingRequired), 0, $paddingRequired, $encoding);
689 default:
690 $leftPaddingLength = \floor($paddingRequired / 2);
691 $rightPaddingLength = $paddingRequired - $leftPaddingLength;
692 return self::mb_substr(\str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding) . $string . self::mb_substr(\str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
693 }
694 }
695 private static function getSubpart($pos, $part, $haystack, $encoding)
696 {
697 if (\false === $pos) {
698 return \false;
699 }
700 if ($part) {
701 return self::mb_substr($haystack, 0, $pos, $encoding);
702 }
703 return self::mb_substr($haystack, $pos, null, $encoding);
704 }
705 private static function html_encoding_callback(array $m)
706 {
707 $i = 1;
708 $entities = '';
709 $m = \unpack('C*', \htmlentities($m[0], \ENT_COMPAT, 'UTF-8'));
710 while (isset($m[$i])) {
711 if (0x80 > $m[$i]) {
712 $entities .= \chr($m[$i++]);
713 continue;
714 }
715 if (0xf0 <= $m[$i]) {
716 $c = ($m[$i++] - 0xf0 << 18) + ($m[$i++] - 0x80 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
717 } elseif (0xe0 <= $m[$i]) {
718 $c = ($m[$i++] - 0xe0 << 12) + ($m[$i++] - 0x80 << 6) + $m[$i++] - 0x80;
719 } else {
720 $c = ($m[$i++] - 0xc0 << 6) + $m[$i++] - 0x80;
721 }
722 $entities .= '&#' . $c . ';';
723 }
724 return $entities;
725 }
726 private static function title_case(array $s)
727 {
728 return self::mb_convert_case($s[1], \MB_CASE_UPPER, 'UTF-8') . self::mb_convert_case($s[2], \MB_CASE_LOWER, 'UTF-8');
729 }
730 private static function getData($file)
731 {
732 if (\file_exists($file = __DIR__ . '/Resources/unidata/' . $file . '.php')) {
733 return require $file;
734 }
735 return \false;
736 }
737 private static function getEncoding($encoding)
738 {
739 if (null === $encoding) {
740 return self::$internalEncoding;
741 }
742 if ('UTF-8' === $encoding) {
743 return 'UTF-8';
744 }
745 $encoding = \strtoupper($encoding);
746 if ('8BIT' === $encoding || 'BINARY' === $encoding) {
747 return 'CP850';
748 }
749 if ('UTF8' === $encoding) {
750 return 'UTF-8';
751 }
752 return $encoding;
753 }
754 }
755