(?:\s*[a-z\-]+\s*(=\s*(?:
"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"|\'[^\'\\\\]*(?:\\\\.[^\'\\\\]*)*\'|[^\s>]
))?)*\s*/?>~ix';
- const HTML_COMMENT_PATTERN = '~<!--(.*?)-->~';
-
- /**
- * utf8 bytes of the HORIZONTAL ELLIPSIS (U+2026)
- * @var string
- */
- const HELLIP = "\u{2026}";
-
- /**
- * utf8 bytes of the MINUS SIGN (U+2212)
- * @var string
- */
- const MINUS = "\u{2212}";
-
- /**
- * Alias to php sha1() function.
- *
- * @param string $value
- * @return string
- */
- public static function getHash($value) {
- return sha1($value);
- }
-
- /**
- * Returns a 40 character hexadecimal string generated using a CSPRNG.
- *
- * @return string
- */
- public static function getRandomID() {
- return \bin2hex(\random_bytes(20));
- }
-
- /**
- * Creates an UUID.
- *
- * @return string
- */
- public static function getUUID() {
- return sprintf(
- '%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x',
- // time_low
- \random_int(0, 0xffff), \random_int(0, 0xffff),
- // time_mid
- \random_int(0, 0xffff),
- // time_hi_and_version
- \random_int(0, 0x0fff) | 0x4000,
- // clock_seq_hi_and_res
- \random_int(0, 0x3f) | 0x80,
- // clock_seq_low
- \random_int(0, 0xff),
- // node
- \random_int(0, 0xffff), \random_int(0, 0xffff), \random_int(0, 0xffff)
- );
- }
-
- /**
- * Converts dos to unix newlines.
- *
- * @param string $string
- * @return string
- */
- public static function unifyNewlines($string) {
- return preg_replace("%(\r\n)|(\r)%", "\n", $string);
- }
-
- /**
- * Removes Unicode whitespace characters from the beginning
- * and ending of the given string.
- *
- * @param string $text
- * @return string
- */
- public static function trim($text) {
- // These regular expressions use character properties
- // to find characters defined as space in the unicode
- // specification.
- // Do not merge the expressions, they are separated for
- // performance reasons.
- $text = preg_replace('/^[\p{Zs}\s\x{202E}]+/u', '', $text);
- $text = preg_replace('/[\p{Zs}\s\x{202E}]+$/u', '', $text);
-
- return $text;
- }
-
- /**
- * Converts html special characters.
- *
- * @param string $string
- * @return string
- */
- public static function encodeHTML($string) {
- return @htmlspecialchars((string) $string, ENT_COMPAT, 'UTF-8');
- }
-
- /**
- * Converts javascript special characters.
- *
- * @param string $string
- * @return string
- */
- public static function encodeJS($string) {
- $string = self::unifyNewlines($string);
- $string = str_replace(["\\", "'", '"', "\n", "/"], ["\\\\", "\'", '\"', '\n', '\/'], $string);
-
- return $string;
- }
-
- /**
- * Encodes JSON strings. This is not the same as PHP's json_encode()!
- *
- * @param string $string
- * @return string
- */
- public static function encodeJSON($string) {
- $string = self::encodeJS($string);
-
- $string = self::encodeHTML($string);
-
- // single quotes must be encoded as HTML entity
- $string = str_replace("\'", "'", $string);
-
- return $string;
- }
-
- /**
- * Decodes html entities.
- *
- * @param string $string
- * @return string
- */
- public static function decodeHTML($string) {
- $string = str_ireplace(' ', ' ', $string); // convert non-breaking spaces to ascii 32; not ascii 160
- return @html_entity_decode($string, ENT_COMPAT, 'UTF-8');
- }
-
- /**
- * Formats a numeric.
- *
- * @param number $numeric
- * @return string
- */
- public static function formatNumeric($numeric) {
- if (is_int($numeric)) {
- return self::formatInteger($numeric);
- }
- else if (is_float($numeric)) {
- return self::formatDouble($numeric);
- }
- else {
- if (floatval($numeric) - (float) intval($numeric)) {
- return self::formatDouble($numeric);
- }
- else {
- return self::formatInteger(intval($numeric));
- }
- }
- }
-
- /**
- * Formats an integer.
- *
- * @param integer $integer
- * @return string
- */
- public static function formatInteger($integer) {
- $integer = self::addThousandsSeparator($integer);
-
- // format minus
- $integer = self::formatNegative($integer);
-
- return $integer;
- }
-
- /**
- * Formats a double.
- *
- * @param double $double
- * @param integer $maxDecimals
- * @return string
- */
- public static function formatDouble($double, $maxDecimals = 0) {
- // round
- $double = (string) round($double, ($maxDecimals > 0 ? $maxDecimals : 2));
-
- // consider as integer, if no decimal places found
- if (!$maxDecimals && preg_match('~^(-?\d+)(?:\.(?:0*|00[0-4]\d*))?$~', $double, $match)) {
- return self::formatInteger($match[1]);
- }
-
- // remove last 0
- if ($maxDecimals < 2 && substr($double, -1) == '0') $double = substr($double, 0, -1);
-
- // replace decimal point
- $double = str_replace('.', WCF::getLanguage()->get('wcf.global.decimalPoint'), $double);
-
- // add thousands separator
- $double = self::addThousandsSeparator($double);
-
- // format minus
- $double = self::formatNegative($double);
-
- return $double;
- }
-
- /**
- * Adds thousands separators to a given number.
- *
- * @param mixed $number
- * @return string
- */
- public static function addThousandsSeparator($number) {
- if ($number >= 1000 || $number <= -1000) {
- $number = preg_replace('~(?<=\d)(?=(\d{3})+(?!\d))~', WCF::getLanguage()->get('wcf.global.thousandsSeparator'), $number);
- }
-
- return $number;
- }
-
- /**
- * Replaces the MINUS-HYPHEN with the MINUS SIGN.
- *
- * @param mixed $number
- * @return string
- */
- public static function formatNegative($number) {
- return str_replace('-', self::MINUS, $number);
- }
-
- /**
- * Alias to php ucfirst() function with multibyte support.
- *
- * @param string $string
- * @return string
- */
- public static function firstCharToUpperCase($string) {
- return mb_strtoupper(mb_substr($string, 0, 1)).mb_substr($string, 1);
- }
-
- /**
- * Alias to php lcfirst() function with multibyte support.
- *
- * @param string $string
- * @return string
- */
- public static function firstCharToLowerCase($string) {
- return mb_strtolower(mb_substr($string, 0, 1)).mb_substr($string, 1);
- }
-
- /**
- * Alias to php mb_convert_case() function.
- *
- * @param string $string
- * @return string
- */
- public static function wordsToUpperCase($string) {
- return mb_convert_case($string, MB_CASE_TITLE);
- }
-
- /**
- * Alias to php str_ireplace() function with UTF-8 support.
- *
- * This function is considered to be slow, if $search contains
- * only ASCII characters, please use str_ireplace() instead.
- *
- * @param string $search
- * @param string $replace
- * @param string $subject
- * @param integer $count
- * @return string
- */
- public static function replaceIgnoreCase($search, $replace, $subject, &$count = 0) {
- $startPos = mb_strpos(mb_strtolower($subject), mb_strtolower($search));
- if ($startPos === false) return $subject;
- else {
- $endPos = $startPos + mb_strlen($search);
- $count++;
- return mb_substr($subject, 0, $startPos) . $replace . self::replaceIgnoreCase($search, $replace, mb_substr($subject, $endPos), $count);
- }
- }
-
- /**
- * Alias to php str_split() function with multibyte support.
- *
- * @param string $string
- * @param integer $length
- * @return string[]
- */
- public static function split($string, $length = 1) {
- $result = [];
- for ($i = 0, $max = mb_strlen($string); $i < $max; $i += $length) {
- $result[] = mb_substr($string, $i, $length);
- }
- return $result;
- }
-
- /**
- * Checks whether $haystack starts with $needle, or not.
- *
- * @param string $haystack The string to be checked for starting with $needle
- * @param string $needle The string to be found at the start of $haystack
- * @param boolean $ci Case insensitive or not. Default = false.
- *
- * @return boolean True, if $haystack starts with $needle, false otherwise.
- */
- public static function startsWith($haystack, $needle, $ci = false) {
- if ($ci) {
- $haystack = mb_strtolower($haystack);
- $needle = mb_strtolower($needle);
- }
- // using mb_substr and === is MUCH faster for long strings then using indexOf.
- return mb_substr($haystack, 0, mb_strlen($needle)) === $needle;
- }
-
- /**
- * Returns true if $haystack ends with $needle or if the length of $needle is 0.
- *
- * @param string $haystack
- * @param string $needle
- * @param boolean $ci case insensitive
- * @return boolean
- */
- public static function endsWith($haystack, $needle, $ci = false) {
- if ($ci) {
- $haystack = mb_strtolower($haystack);
- $needle = mb_strtolower($needle);
- }
- $length = mb_strlen($needle);
- if ($length === 0) return true;
- return (mb_substr($haystack, $length * -1) === $needle);
- }
-
- /**
- * Alias to php str_pad function with multibyte support.
- *
- * @param string $input
- * @param integer $padLength
- * @param string $padString
- * @param integer $padType
- * @return string
- */
- public static function pad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIGHT) {
- $additionalPadding = strlen($input) - mb_strlen($input);
- return str_pad($input, $padLength + $additionalPadding, $padString, $padType);
- }
-
- /**
- * Unescapes escaped characters in a string.
- *
- * @param string $string
- * @param string $chars
- * @return string
- */
- public static function unescape($string, $chars = '"') {
- for ($i = 0, $j = strlen($chars); $i < $j; $i++) {
- $string = str_replace('\\'.$chars[$i], $chars[$i], $string);
- }
-
- return $string;
- }
-
- /**
- * Takes a numeric HTML entity value and returns the appropriate UTF-8 bytes.
- *
- * @param integer $dec html entity value
- * @return string utf-8 bytes
- */
- public static function getCharacter($dec) {
- if ($dec < 128) {
- $utf = chr($dec);
- }
- else if ($dec < 2048) {
- $utf = chr(192 + (($dec - ($dec % 64)) / 64));
- $utf .= chr(128 + ($dec % 64));
- }
- else {
- $utf = chr(224 + (($dec - ($dec % 4096)) / 4096));
- $utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
- $utf .= chr(128 + ($dec % 64));
- }
- return $utf;
- }
-
- /**
- * Converts UTF-8 to Unicode
- * @see http://www1.tip.nl/~t876506/utf8tbl.html
- *
- * @param string $c
- * @return integer
- */
- public static function getCharValue($c) {
- $ud = 0;
- if (ord($c[0]) >= 0 && ord($c[0]) <= 127)
- $ud = ord($c[0]);
- if (ord($c[0]) >= 192 && ord($c[0]) <= 223)
- $ud = (ord($c[0]) - 192) * 64 + (ord($c[1]) - 128);
- if (ord($c[0]) >= 224 && ord($c[0]) <= 239)
- $ud = (ord($c[0]) - 224) * 4096 + (ord($c[1]) - 128) * 64 + (ord($c[2]) - 128);
- if (ord($c[0]) >= 240 && ord($c[0]) <= 247)
- $ud = (ord($c[0]) - 240) * 262144 + (ord($c[1]) - 128) * 4096 + (ord($c[2]) - 128) * 64 + (ord($c[3]) - 128);
- if (ord($c[0]) >= 248 && ord($c[0]) <= 251)
- $ud = (ord($c[0]) - 248) * 16777216 + (ord($c[1]) - 128) * 262144 + (ord($c[2]) - 128) * 4096 + (ord($c[3]) - 128) * 64 + (ord($c[4]) - 128);
- if (ord($c[0]) >= 252 && ord($c[0]) <= 253)
- $ud = (ord($c[0]) - 252) * 1073741824 + (ord($c[1]) - 128) * 16777216 + (ord($c[2]) - 128) * 262144 + (ord($c[3]) - 128) * 4096 + (ord($c[4]) - 128) * 64 + (ord($c[5]) - 128);
- if (ord($c[0]) >= 254 && ord($c[0]) <= 255)
- $ud = false; // error
- return $ud;
- }
-
- /**
- * Returns html entities of all characters in the given string.
- *
- * @param string $string
- * @return string
- */
- public static function encodeAllChars($string) {
- $result = '';
- for ($i = 0, $j = mb_strlen($string); $i < $j; $i++) {
- $char = mb_substr($string, $i, 1);
- $result .= '&#'.self::getCharValue($char).';';
- }
-
- return $result;
- }
-
- /**
- * Returns true if the given string contains only ASCII characters.
- *
- * @param string $string
- * @return boolean
- */
- public static function isASCII($string) {
- return preg_match('/^[\x00-\x7F]*$/', $string);
- }
-
- /**
- * Returns true if the given string is utf-8 encoded.
- * @see http://www.w3.org/International/questions/qa-forms-utf-8
- *
- * @param string $string
- * @return boolean
- */
- public static function isUTF8($string) {
- return preg_match('/^(
+
+ const HTML_COMMENT_PATTERN = '~<!--(.*?)-->~';
+
+ /**
+ * utf8 bytes of the HORIZONTAL ELLIPSIS (U+2026)
+ * @var string
+ */
+ const HELLIP = "\u{2026}";
+
+ /**
+ * utf8 bytes of the MINUS SIGN (U+2212)
+ * @var string
+ */
+ const MINUS = "\u{2212}";
+
+ /**
+ * Alias to php sha1() function.
+ *
+ * @param string $value
+ * @return string
+ */
+ public static function getHash($value)
+ {
+ return \sha1($value);
+ }
+
+ /**
+ * Returns a 40 character hexadecimal string generated using a CSPRNG.
+ *
+ * @return string
+ */
+ public static function getRandomID()
+ {
+ return Hex::encode(\random_bytes(20));
+ }
+
+ /**
+ * Creates an UUID.
+ *
+ * @return string
+ */
+ public static function getUUID()
+ {
+ return \sprintf(
+ '%04x%04x-%04x-%04x-%02x%02x-%04x%04x%04x',
+ // time_low
+ \random_int(0, 0xffff),
+ \random_int(0, 0xffff),
+ // time_mid
+ \random_int(0, 0xffff),
+ // time_hi_and_version
+ \random_int(0, 0x0fff) | 0x4000,
+ // clock_seq_hi_and_res
+ \random_int(0, 0x3f) | 0x80,
+ // clock_seq_low
+ \random_int(0, 0xff),
+ // node
+ \random_int(0, 0xffff),
+ \random_int(0, 0xffff),
+ \random_int(0, 0xffff)
+ );
+ }
+
+ /**
+ * Converts dos to unix newlines.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function unifyNewlines($string)
+ {
+ return \preg_replace("%(\r\n)|(\r)%", "\n", $string);
+ }
+
+ /**
+ * Removes Unicode whitespace characters from the beginning
+ * and ending of the given string.
+ *
+ * @param string $text
+ * @return string
+ */
+ public static function trim($text)
+ {
+ // These regular expressions use character properties
+ // to find characters defined as space in the unicode
+ // specification.
+ // Do not merge the expressions, they are separated for
+ // performance reasons.
+ $text = \preg_replace('/^[\p{Zs}\s\x{202E}\x{200B}]+/u', '', $text);
+
+ return \preg_replace('/[\p{Zs}\s\x{202E}\x{200B}]+$/u', '', $text);
+ }
+
+ /**
+ * Converts html special characters.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function encodeHTML($string)
+ {
+ return @\htmlspecialchars((string)$string, \ENT_COMPAT, 'UTF-8');
+ }
+
+ /**
+ * Converts javascript special characters.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function encodeJS($string)
+ {
+ $string = self::unifyNewlines($string);
+
- return \str_replace(["\\", "'", "\n", "/"], ["\\\\", "\\'", '\n', '\/'], $string);
++ return \str_replace(["\\", "'", '"', "\n", "/"], ["\\\\", "\\'", '\\"', '\n', '\/'], $string);
+ }
+
+ /**
+ * Encodes JSON strings. This is not the same as PHP's json_encode()!
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function encodeJSON($string)
+ {
+ $string = self::encodeJS($string);
+
+ $string = self::encodeHTML($string);
+
+ // single quotes must be encoded as HTML entity
+ return \str_replace("\\'", "'", $string);
+ }
+
+ /**
+ * Decodes html entities.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function decodeHTML($string)
+ {
+ $string = \str_ireplace(' ', ' ', $string); // convert non-breaking spaces to ascii 32; not ascii 160
+
+ return @\html_entity_decode($string, \ENT_COMPAT, 'UTF-8');
+ }
+
+ /**
+ * Formats a numeric.
+ *
+ * @param number $numeric
+ * @return string
+ */
+ public static function formatNumeric($numeric)
+ {
+ if (\is_int($numeric)) {
+ return self::formatInteger($numeric);
+ } elseif (\is_float($numeric)) {
+ return self::formatDouble($numeric);
+ } else {
+ if (\floatval($numeric) - (float)\intval($numeric)) {
+ return self::formatDouble($numeric);
+ } else {
+ return self::formatInteger(\intval($numeric));
+ }
+ }
+ }
+
+ /**
+ * Formats an integer.
+ *
+ * @param int $integer
+ * @return string
+ */
+ public static function formatInteger($integer)
+ {
+ $integer = self::addThousandsSeparator($integer);
+
+ // format minus
+ return self::formatNegative($integer);
+ }
+
+ /**
+ * Formats a double.
+ *
+ * @param double $double
+ * @param int $maxDecimals
+ * @return string
+ */
+ public static function formatDouble($double, $maxDecimals = 0)
+ {
+ // round
+ $double = (string)\round($double, ($maxDecimals > 0 ? $maxDecimals : 2));
+
+ // consider as integer, if no decimal places found
+ if (!$maxDecimals && \preg_match('~^(-?\d+)(?:\.(?:0*|00[0-4]\d*))?$~', $double, $match)) {
+ return self::formatInteger($match[1]);
+ }
+
+ // remove last 0
+ if ($maxDecimals < 2 && \substr($double, -1) == '0') {
+ $double = \substr($double, 0, -1);
+ }
+
+ // replace decimal point
+ $double = \str_replace('.', WCF::getLanguage()->get('wcf.global.decimalPoint'), $double);
+
+ // add thousands separator
+ $double = self::addThousandsSeparator($double);
+
+ // format minus
+ return self::formatNegative($double);
+ }
+
+ /**
+ * Adds thousands separators to a given number.
+ *
+ * @param mixed $number
+ * @return string
+ */
+ public static function addThousandsSeparator($number)
+ {
+ if ($number >= 1000 || $number <= -1000) {
+ $number = \preg_replace(
+ '~(?<=\d)(?=(\d{3})+(?!\d))~',
+ WCF::getLanguage()->get('wcf.global.thousandsSeparator'),
+ $number
+ );
+ }
+
+ return $number;
+ }
+
+ /**
+ * Replaces the MINUS-HYPHEN with the MINUS SIGN.
+ *
+ * @param mixed $number
+ * @return string
+ */
+ public static function formatNegative($number)
+ {
+ return \str_replace('-', self::MINUS, $number);
+ }
+
+ /**
+ * Alias to php ucfirst() function with multibyte support.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function firstCharToUpperCase($string)
+ {
+ return \mb_strtoupper(\mb_substr($string, 0, 1)) . \mb_substr($string, 1);
+ }
+
+ /**
+ * Alias to php lcfirst() function with multibyte support.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function firstCharToLowerCase($string)
+ {
+ return \mb_strtolower(\mb_substr($string, 0, 1)) . \mb_substr($string, 1);
+ }
+
+ /**
+ * Alias to php mb_convert_case() function.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function wordsToUpperCase($string)
+ {
+ return \mb_convert_case($string, \MB_CASE_TITLE);
+ }
+
+ /**
+ * Alias to php str_ireplace() function with UTF-8 support.
+ *
+ * This function is considered to be slow, if $search contains
+ * only ASCII characters, please use str_ireplace() instead.
+ *
+ * @param string $search
+ * @param string $replace
+ * @param string $subject
+ * @param int $count
+ * @return string
+ */
+ public static function replaceIgnoreCase($search, $replace, $subject, &$count = 0)
+ {
+ $startPos = \mb_strpos(\mb_strtolower($subject), \mb_strtolower($search));
+ if ($startPos === false) {
+ return $subject;
+ } else {
+ $endPos = $startPos + \mb_strlen($search);
+ $count++;
+
+ return \mb_substr($subject, 0, $startPos) . $replace . self::replaceIgnoreCase(
+ $search,
+ $replace,
+ \mb_substr($subject, $endPos),
+ $count
+ );
+ }
+ }
+
+ /**
+ * Alias to php str_split() function with multibyte support.
+ *
+ * @param string $string
+ * @param int $length
+ * @return string[]
+ */
+ public static function split($string, $length = 1)
+ {
+ $result = [];
+ for ($i = 0, $max = \mb_strlen($string); $i < $max; $i += $length) {
+ $result[] = \mb_substr($string, $i, $length);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Checks whether $haystack starts with $needle, or not.
+ *
+ * @param string $haystack The string to be checked for starting with $needle
+ * @param string $needle The string to be found at the start of $haystack
+ * @param bool $ci Case insensitive or not. Default = false.
+ *
+ * @return bool True, if $haystack starts with $needle, false otherwise.
+ */
+ public static function startsWith($haystack, $needle, $ci = false)
+ {
+ if ($ci) {
+ $haystack = \mb_strtolower($haystack);
+ $needle = \mb_strtolower($needle);
+ }
+ // using mb_substr and === is MUCH faster for long strings then using indexOf.
+ return \mb_substr($haystack, 0, \mb_strlen($needle)) === $needle;
+ }
+
+ /**
+ * Returns true if $haystack ends with $needle or if the length of $needle is 0.
+ *
+ * @param string $haystack
+ * @param string $needle
+ * @param bool $ci case insensitive
+ * @return bool
+ */
+ public static function endsWith($haystack, $needle, $ci = false)
+ {
+ if ($ci) {
+ $haystack = \mb_strtolower($haystack);
+ $needle = \mb_strtolower($needle);
+ }
+ $length = \mb_strlen($needle);
+ if ($length === 0) {
+ return true;
+ }
+
+ return \mb_substr($haystack, $length * -1) === $needle;
+ }
+
+ /**
+ * Alias to php str_pad function with multibyte support.
+ *
+ * @param string $input
+ * @param int $padLength
+ * @param string $padString
+ * @param int $padType
+ * @return string
+ */
+ public static function pad($input, $padLength, $padString = ' ', $padType = \STR_PAD_RIGHT)
+ {
+ $additionalPadding = \strlen($input) - \mb_strlen($input);
+
+ return \str_pad($input, $padLength + $additionalPadding, $padString, $padType);
+ }
+
+ /**
+ * Unescapes escaped characters in a string.
+ *
+ * @param string $string
+ * @param string $chars
+ * @return string
+ */
+ public static function unescape($string, $chars = '"')
+ {
+ for ($i = 0, $j = \strlen($chars); $i < $j; $i++) {
+ $string = \str_replace('\\' . $chars[$i], $chars[$i], $string);
+ }
+
+ return $string;
+ }
+
+ /**
+ * Takes a numeric HTML entity value and returns the appropriate UTF-8 bytes.
+ *
+ * @param int $dec html entity value
+ * @return string utf-8 bytes
+ */
+ public static function getCharacter($dec)
+ {
+ if ($dec < 128) {
+ $utf = \chr($dec);
+ } elseif ($dec < 2048) {
+ $utf = \chr(192 + (($dec - ($dec % 64)) / 64));
+ $utf .= \chr(128 + ($dec % 64));
+ } else {
+ $utf = \chr(224 + (($dec - ($dec % 4096)) / 4096));
+ $utf .= \chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
+ $utf .= \chr(128 + ($dec % 64));
+ }
+
+ return $utf;
+ }
+
+ /**
+ * Converts UTF-8 to Unicode
+ * @see http://www1.tip.nl/~t876506/utf8tbl.html
+ *
+ * @param string $c
+ * @return int
+ */
+ public static function getCharValue($c)
+ {
+ $ud = 0;
+ if (\ord($c[0]) >= 0 && \ord($c[0]) <= 127) {
+ $ud = \ord($c[0]);
+ }
+ if (\ord($c[0]) >= 192 && \ord($c[0]) <= 223) {
+ $ud = (\ord($c[0]) - 192) * 64 + (\ord($c[1]) - 128);
+ }
+ if (\ord($c[0]) >= 224 && \ord($c[0]) <= 239) {
+ $ud = (\ord($c[0]) - 224) * 4096 + (\ord($c[1]) - 128) * 64 + (\ord($c[2]) - 128);
+ }
+ if (\ord($c[0]) >= 240 && \ord($c[0]) <= 247) {
+ $ud = (\ord($c[0]) - 240) * 262144 + (\ord($c[1]) - 128) * 4096 + (\ord($c[2]) - 128) * 64 + (\ord($c[3]) - 128);
+ }
+ if (\ord($c[0]) >= 248 && \ord($c[0]) <= 251) {
+ $ud = (\ord($c[0]) - 248) * 16777216 + (\ord($c[1]) - 128) * 262144 + (\ord($c[2]) - 128) * 4096 + (\ord($c[3]) - 128) * 64 + (\ord($c[4]) - 128);
+ }
+ if (\ord($c[0]) >= 252 && \ord($c[0]) <= 253) {
+ $ud = (\ord($c[0]) - 252) * 1073741824 + (\ord($c[1]) - 128) * 16777216 + (\ord($c[2]) - 128) * 262144 + (\ord($c[3]) - 128) * 4096 + (\ord($c[4]) - 128) * 64 + (\ord($c[5]) - 128);
+ }
+ if (\ord($c[0]) >= 254 && \ord($c[0]) <= 255) {
+ $ud = false; // error
+ }
+
+ return $ud;
+ }
+
+ /**
+ * Returns html entities of all characters in the given string.
+ *
+ * @param string $string
+ * @return string
+ */
+ public static function encodeAllChars($string)
+ {
+ $result = '';
+ for ($i = 0, $j = \mb_strlen($string); $i < $j; $i++) {
+ $char = \mb_substr($string, $i, 1);
+ $result .= '&#' . self::getCharValue($char) . ';';
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns true if the given string contains only ASCII characters.
+ *
+ * @param string $string
+ * @return bool
+ */
+ public static function isASCII($string)
+ {
+ return \preg_match('/^[\x00-\x7F]*$/', $string);
+ }
+
+ /**
+ * Returns true if the given string is utf-8 encoded.
+ * @see http://www.w3.org/International/questions/qa-forms-utf-8
+ *
+ * @param string $string
+ * @return bool
+ */
+ public static function isUTF8($string)
+ {
+ return \preg_match('/^(
[\x09\x0A\x0D\x20-\x7E]* # ASCII
| [\xC2-\xDF][\x80-\xBF] # non-overlong 2-byte
| \xE0[\xA0-\xBF][\x80-\xBF] # excluding overlongs