plugin updates

This commit is contained in:
Tony Volpe
2024-11-15 13:53:04 -05:00
parent 1293d604ca
commit 0238f0c4ca
2009 changed files with 163492 additions and 89543 deletions

View File

@@ -105,7 +105,7 @@ final class Idn
*/
public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
{
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
@\trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
}
$options = ['CheckHyphens' => \true, 'CheckBidi' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 !== ($options & self::IDNA_CHECK_BIDI), 'CheckJoiners' => self::INTL_IDNA_VARIANT_UTS46 === $variant && 0 !== ($options & self::IDNA_CHECK_CONTEXTJ), 'UseSTD3ASCIIRules' => 0 !== ($options & self::IDNA_USE_STD3_RULES), 'Transitional_Processing' => self::INTL_IDNA_VARIANT_2003 === $variant || 0 === ($options & self::IDNA_NONTRANSITIONAL_TO_ASCII), 'VerifyDnsLength' => \true];
@@ -140,7 +140,7 @@ final class Idn
*/
public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
{
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
@\trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
}
$info = new \WPMailSMTP\Vendor\Symfony\Polyfill\Intl\Idn\Info();
@@ -198,8 +198,6 @@ final class Idn
$data = self::lookupCodePointStatus($codePoint, $useSTD3ASCIIRules);
switch ($data['status']) {
case 'disallowed':
$info->errors |= self::ERROR_DISALLOWED;
// no break.
case 'valid':
$str .= \mb_chr($codePoint, 'utf-8');
break;
@@ -207,7 +205,7 @@ final class Idn
// Do nothing.
break;
case 'mapped':
$str .= $data['mapping'];
$str .= $transitional && 0x1e9e === $codePoint ? 'ss' : $data['mapping'];
break;
case 'deviation':
$info->transitionalDifferent = \true;
@@ -247,6 +245,16 @@ final class Idn
foreach ($labels as $i => $label) {
$validationOptions = $options;
if ('xn--' === \substr($label, 0, 4)) {
// Step 4.1. If the label contains any non-ASCII code point (i.e., a code point greater than U+007F),
// record that there was an error, and continue with the next label.
if (\preg_match('/[^\\x00-\\x7F]/', $label)) {
$info->errors |= self::ERROR_PUNYCODE;
continue;
}
// Step 4.2. Attempt to convert the rest of the label to Unicode according to Punycode [RFC3492]. If
// that conversion fails, record that there was an error, and continue
// with the next label. Otherwise replace the original label in the string by the results of the
// conversion.
try {
$label = self::punycodeDecode(\substr($label, 4));
} catch (\Exception $e) {
@@ -383,6 +391,8 @@ final class Idn
if ('-' === \substr($label, -1, 1)) {
$info->errors |= self::ERROR_TRAILING_HYPHEN;
}
} elseif ('xn--' === \substr($label, 0, 4)) {
$info->errors |= self::ERROR_PUNYCODE;
}
// Step 4. The label must not contain a U+002E (.) FULL STOP.
if (\false !== \strpos($label, '.')) {

View File

@@ -47,6 +47,11 @@ namespace WPMailSMTP\Vendor\Symfony\Polyfill\Mbstring;
* - mb_strstr - Finds first occurrence of a string within another
* - mb_strwidth - Return width of string
* - mb_substr_count - Count the number of substring occurrences
* - mb_ucfirst - Make a string's first character uppercase
* - mb_lcfirst - Make a string's first character lowercase
* - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string
* - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string
* - mb_rtrim - Strip whitespace (or other characters) from the end of a string
*
* Not implemented:
* - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more)
@@ -73,6 +78,13 @@ final class Mbstring
private static $internalEncoding = 'UTF-8';
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($s)) {
$r = [];
foreach ($s as $str) {
$r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
}
return $r;
}
if (\is_array($fromEncoding) || null !== $fromEncoding && \false !== \strpos($fromEncoding, ',')) {
$fromEncoding = self::mb_detect_encoding($s, $fromEncoding);
} else {
@@ -337,10 +349,6 @@ final class Mbstring
}
public static function mb_check_encoding($var = null, $encoding = null)
{
if (\PHP_VERSION_ID < 70200 && \is_array($var)) {
\trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
return null;
}
if (null === $encoding) {
if (null === $var) {
return \false;
@@ -656,22 +664,15 @@ final class Mbstring
}
return $code;
}
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null) : string
public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null) : string
{
if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], \true)) {
throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH');
}
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
}
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(\sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding));
} else {
self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given');
}
if (self::mb_strlen($pad_string, $encoding) <= 0) {
throw new \ValueError('mb_str_pad(): Argument #3 ($pad_string) must be a non-empty string');
@@ -691,6 +692,28 @@ final class Mbstring
return self::mb_substr(\str_repeat($pad_string, $leftPaddingLength), 0, $leftPaddingLength, $encoding) . $string . self::mb_substr(\str_repeat($pad_string, $rightPaddingLength), 0, $rightPaddingLength, $encoding);
}
}
public static function mb_ucfirst(string $string, ?string $encoding = null) : string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = \mb_substr($string, 0, 1, $encoding);
$firstChar = \mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding);
return $firstChar . \mb_substr($string, 1, null, $encoding);
}
public static function mb_lcfirst(string $string, ?string $encoding = null) : string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given');
}
$firstChar = \mb_substr($string, 0, 1, $encoding);
$firstChar = \mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding);
return $firstChar . \mb_substr($string, 1, null, $encoding);
}
private static function getSubpart($pos, $part, $haystack, $encoding)
{
if (\false === $pos) {
@@ -750,4 +773,63 @@ final class Mbstring
}
return $encoding;
}
public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null) : string
{
return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null) : string
{
return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__);
}
public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null) : string
{
return self::mb_internal_trim('{[%s]+$}D', $string, $characters, $encoding, __FUNCTION__);
}
private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function) : string
{
if (null === $encoding) {
$encoding = self::mb_internal_encoding();
} else {
self::assertEncoding($encoding, $function . '(): Argument #3 ($encoding) must be a valid encoding, "%s" given');
}
if ('' === $characters) {
return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding);
}
if ('UTF-8' === $encoding) {
$encoding = null;
if (!\preg_match('//u', $string)) {
$string = @\iconv('UTF-8', 'UTF-8//IGNORE', $string);
}
if (null !== $characters && !\preg_match('//u', $characters)) {
$characters = @\iconv('UTF-8', 'UTF-8//IGNORE', $characters);
}
} else {
$string = \iconv($encoding, 'UTF-8//IGNORE', $string);
if (null !== $characters) {
$characters = \iconv($encoding, 'UTF-8//IGNORE', $characters);
}
}
if (null === $characters) {
$characters = "\\0 \f\n\r\t\v   …";
} else {
$characters = \preg_quote($characters);
}
$string = \preg_replace(\sprintf($regex, $characters), '', $string);
if (null === $encoding) {
return $string;
}
return \iconv('UTF-8', $encoding . '//IGNORE', $string);
}
private static function assertEncoding(string $encoding, string $errorFormat) : void
{
try {
$validEncoding = @self::mb_check_encoding('', $encoding);
} catch (\ValueError $e) {
throw new \ValueError(\sprintf($errorFormat, $encoding));
}
// BC for PHP 7.3 and lower
if (!$validEncoding) {
throw new \ValueError(\sprintf($errorFormat, $encoding));
}
}
}

View File

@@ -136,6 +136,27 @@ if (!function_exists('mb_str_pad')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
}
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
}
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}
if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}
if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}
if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}
if (extension_loaded('mbstring')) {
return;
}

View File

@@ -93,7 +93,7 @@ if (!function_exists('mb_strstr')) {
function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
}
if (!function_exists('mb_get_info')) {
function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); }
function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); }
}
if (!function_exists('mb_http_output')) {
function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
@@ -132,6 +132,26 @@ if (!function_exists('mb_str_pad')) {
function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); }
}
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
}
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}
if (!function_exists('mb_trim')) {
function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); }
}
if (!function_exists('mb_ltrim')) {
function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); }
}
if (!function_exists('mb_rtrim')) {
function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); }
}
if (extension_loaded('mbstring')) {
return;
}

View File

@@ -1,19 +0,0 @@
Copyright (c) 2015-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,176 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace WPMailSMTP\Vendor\Symfony\Polyfill\Php72;
/**
* @author Nicolas Grekas <p@tchwork.com>
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* @internal
*/
final class Php72
{
private static $hashMask;
public static function utf8_encode($s)
{
$s .= $s;
$len = \strlen($s);
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
switch (\true) {
case $s[$i] < "<EFBFBD>":
$s[$j] = $s[$i];
break;
case $s[$i] < "<EFBFBD>":
$s[$j] = "<EFBFBD>";
$s[++$j] = $s[$i];
break;
default:
$s[$j] = "<EFBFBD>";
$s[++$j] = \chr(\ord($s[$i]) - 64);
break;
}
}
return \substr($s, 0, $j);
}
public static function utf8_decode($s)
{
$s = (string) $s;
$len = \strlen($s);
for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
switch ($s[$i] & "<EFBFBD>") {
case "<EFBFBD>":
case "<EFBFBD>":
$c = \ord($s[$i] & "\37") << 6 | \ord($s[++$i] & "?");
$s[$j] = $c < 256 ? \chr($c) : '?';
break;
case "<EFBFBD>":
++$i;
// no break
case "<EFBFBD>":
$s[$j] = '?';
$i += 2;
break;
default:
$s[$j] = $s[$i];
}
}
return \substr($s, 0, $j);
}
public static function php_os_family()
{
if ('\\' === \DIRECTORY_SEPARATOR) {
return 'Windows';
}
$map = ['Darwin' => 'Darwin', 'DragonFly' => 'BSD', 'FreeBSD' => 'BSD', 'NetBSD' => 'BSD', 'OpenBSD' => 'BSD', 'Linux' => 'Linux', 'SunOS' => 'Solaris'];
return $map[\PHP_OS] ?? 'Unknown';
}
public static function spl_object_id($object)
{
if (null === self::$hashMask) {
self::initHashMask();
}
if (null === ($hash = \spl_object_hash($object))) {
return;
}
// On 32-bit systems, PHP_INT_SIZE is 4,
return self::$hashMask ^ \hexdec(\substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function sapi_windows_vt100_support($stream, $enable = null)
{
if (!\is_resource($stream)) {
\trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, ' . \gettype($stream) . ' given', \E_USER_WARNING);
return \false;
}
$meta = \stream_get_meta_data($stream);
if ('STDIO' !== $meta['stream_type']) {
\trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING);
return \false;
}
// We cannot actually disable vt100 support if it is set
if (\false === $enable || !self::stream_isatty($stream)) {
return \false;
}
// The native function does not apply to stdin
$meta = \array_map('strtolower', $meta);
$stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];
return !$stdin && (\false !== \getenv('ANSICON') || 'ON' === \getenv('ConEmuANSI') || 'xterm' === \getenv('TERM') || 'Hyper' === \getenv('TERM_PROGRAM'));
}
public static function stream_isatty($stream)
{
if (!\is_resource($stream)) {
\trigger_error('stream_isatty() expects parameter 1 to be resource, ' . \gettype($stream) . ' given', \E_USER_WARNING);
return \false;
}
if ('\\' === \DIRECTORY_SEPARATOR) {
$stat = @\fstat($stream);
// Check if formatted mode is S_IFCHR
return $stat ? 020000 === ($stat['mode'] & 0170000) : \false;
}
return \function_exists('posix_isatty') && @\posix_isatty($stream);
}
private static function initHashMask()
{
$obj = (object) [];
self::$hashMask = -1;
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
$obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'];
foreach (\debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : \false) as $frame) {
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
$frame['line'] = 0;
break;
}
}
if (!empty($frame['line'])) {
\ob_start();
\debug_zval_dump($obj);
self::$hashMask = (int) \substr(\ob_get_clean(), 17);
}
self::$hashMask ^= \hexdec(\substr(\spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function mb_chr($code, $encoding = null)
{
if (0x80 > ($code %= 0x200000)) {
$s = \chr($code);
} elseif (0x800 > $code) {
$s = \chr(0xc0 | $code >> 6) . \chr(0x80 | $code & 0x3f);
} elseif (0x10000 > $code) {
$s = \chr(0xe0 | $code >> 12) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
} else {
$s = \chr(0xf0 | $code >> 18) . \chr(0x80 | $code >> 12 & 0x3f) . \chr(0x80 | $code >> 6 & 0x3f) . \chr(0x80 | $code & 0x3f);
}
if ('UTF-8' !== ($encoding = $encoding ?? \mb_internal_encoding())) {
$s = \mb_convert_encoding($s, $encoding, 'UTF-8');
}
return $s;
}
public static function mb_ord($s, $encoding = null)
{
if (null === $encoding) {
$s = \mb_convert_encoding($s, 'UTF-8');
} elseif ('UTF-8' !== $encoding) {
$s = \mb_convert_encoding($s, 'UTF-8', $encoding);
}
if (1 === \strlen($s)) {
return \ord($s);
}
$code = ($s = \unpack('C*', \substr($s, 0, 4))) ? $s[1] : 0;
if (0xf0 <= $code) {
return ($code - 0xf0 << 18) + ($s[2] - 0x80 << 12) + ($s[3] - 0x80 << 6) + $s[4] - 0x80;
}
if (0xe0 <= $code) {
return ($code - 0xe0 << 12) + ($s[2] - 0x80 << 6) + $s[3] - 0x80;
}
if (0xc0 <= $code) {
return ($code - 0xc0 << 6) + $s[2] - 0x80;
}
return $code;
}
}

View File

@@ -1,57 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use WPMailSMTP\Vendor\Symfony\Polyfill\Php72 as p;
if (\PHP_VERSION_ID >= 70200) {
return;
}
if (!defined('PHP_FLOAT_DIG')) {
define('PHP_FLOAT_DIG', 15);
}
if (!defined('PHP_FLOAT_EPSILON')) {
define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
}
if (!defined('PHP_FLOAT_MIN')) {
define('PHP_FLOAT_MIN', 2.2250738585072E-308);
}
if (!defined('PHP_FLOAT_MAX')) {
define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
}
if (!defined('PHP_OS_FAMILY')) {
define('PHP_OS_FAMILY', p\Php72::php_os_family());
}
if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
}
if (!function_exists('stream_isatty')) {
function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
}
if (!function_exists('utf8_encode')) {
function utf8_encode($string) { return p\Php72::utf8_encode($string); }
}
if (!function_exists('utf8_decode')) {
function utf8_decode($string) { return p\Php72::utf8_decode($string); }
}
if (!function_exists('spl_object_id')) {
function spl_object_id($object) { return p\Php72::spl_object_id($object); }
}
if (!function_exists('mb_ord')) {
function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
}
if (!function_exists('mb_chr')) {
function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
}
if (!function_exists('mb_scrub')) {
function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
}