Update website
This commit is contained in:
parent
a0b0d3dae7
commit
ae7ef6ad45
3151 changed files with 566766 additions and 48 deletions
347
admin/phpMyAdmin/libraries/classes/Encoding.php
Normal file
347
admin/phpMyAdmin/libraries/classes/Encoding.php
Normal file
|
@ -0,0 +1,347 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace PhpMyAdmin;
|
||||
|
||||
use function array_intersect;
|
||||
use function array_map;
|
||||
use function explode;
|
||||
use function fclose;
|
||||
use function feof;
|
||||
use function fgets;
|
||||
use function fopen;
|
||||
use function function_exists;
|
||||
use function fwrite;
|
||||
use function recode_string;
|
||||
use function mb_convert_encoding;
|
||||
use function mb_convert_kana;
|
||||
use function mb_detect_encoding;
|
||||
use function mb_list_encodings;
|
||||
use function tempnam;
|
||||
use function unlink;
|
||||
use function iconv;
|
||||
|
||||
/**
|
||||
* Encoding conversion helper class
|
||||
*/
|
||||
class Encoding
|
||||
{
|
||||
/**
|
||||
* None encoding conversion engine
|
||||
*/
|
||||
public const ENGINE_NONE = 0;
|
||||
|
||||
/**
|
||||
* iconv encoding conversion engine
|
||||
*/
|
||||
public const ENGINE_ICONV = 1;
|
||||
|
||||
/**
|
||||
* recode encoding conversion engine
|
||||
*/
|
||||
public const ENGINE_RECODE = 2;
|
||||
|
||||
/**
|
||||
* mbstring encoding conversion engine
|
||||
*/
|
||||
public const ENGINE_MB = 3;
|
||||
|
||||
/**
|
||||
* Chosen encoding engine
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private static $engine = null;
|
||||
|
||||
/**
|
||||
* Map of conversion engine configurations
|
||||
*
|
||||
* Each entry contains:
|
||||
*
|
||||
* - function to detect
|
||||
* - engine contant
|
||||
* - extension name to warn when missing
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $enginemap = [
|
||||
'iconv' => [
|
||||
'iconv',
|
||||
self::ENGINE_ICONV,
|
||||
'iconv',
|
||||
],
|
||||
'recode' => [
|
||||
'recode_string',
|
||||
self::ENGINE_RECODE,
|
||||
'recode',
|
||||
],
|
||||
'mb' => [
|
||||
'mb_convert_encoding',
|
||||
self::ENGINE_MB,
|
||||
'mbstring',
|
||||
],
|
||||
'none' => [
|
||||
'isset',
|
||||
self::ENGINE_NONE,
|
||||
'',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
* Order of automatic detection of engines
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $engineorder = [
|
||||
'iconv',
|
||||
'mb',
|
||||
'recode',
|
||||
];
|
||||
|
||||
/**
|
||||
* Kanji encodings list
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private static $kanjiEncodings = 'ASCII,SJIS,EUC-JP,JIS';
|
||||
|
||||
/**
|
||||
* Initializes encoding engine detecting available backends.
|
||||
*/
|
||||
public static function initEngine(): void
|
||||
{
|
||||
$engine = 'auto';
|
||||
if (isset($GLOBALS['cfg']['RecodingEngine'])) {
|
||||
$engine = $GLOBALS['cfg']['RecodingEngine'];
|
||||
}
|
||||
|
||||
/* Use user configuration */
|
||||
if (isset(self::$enginemap[$engine])) {
|
||||
if (function_exists(self::$enginemap[$engine][0])) {
|
||||
self::$engine = self::$enginemap[$engine][1];
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Core::warnMissingExtension(self::$enginemap[$engine][2]);
|
||||
}
|
||||
|
||||
/* Autodetection */
|
||||
foreach (self::$engineorder as $engine) {
|
||||
if (function_exists(self::$enginemap[$engine][0])) {
|
||||
self::$engine = self::$enginemap[$engine][1];
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fallback to none conversion */
|
||||
self::$engine = self::ENGINE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for engine. Use with caution, mostly useful for testing.
|
||||
*
|
||||
* @param int $engine Engine encoding
|
||||
*/
|
||||
public static function setEngine(int $engine): void
|
||||
{
|
||||
self::$engine = $engine;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether there is any charset conversion supported
|
||||
*/
|
||||
public static function isSupported(): bool
|
||||
{
|
||||
if (self::$engine === null) {
|
||||
self::initEngine();
|
||||
}
|
||||
|
||||
return self::$engine != self::ENGINE_NONE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts encoding of text according to parameters with detected
|
||||
* conversion function.
|
||||
*
|
||||
* @param string $src_charset source charset
|
||||
* @param string $dest_charset target charset
|
||||
* @param string $what what to convert
|
||||
*
|
||||
* @return string converted text
|
||||
*
|
||||
* @access public
|
||||
*/
|
||||
public static function convertString(
|
||||
string $src_charset,
|
||||
string $dest_charset,
|
||||
string $what
|
||||
): string {
|
||||
if ($src_charset == $dest_charset) {
|
||||
return $what;
|
||||
}
|
||||
if (self::$engine === null) {
|
||||
self::initEngine();
|
||||
}
|
||||
switch (self::$engine) {
|
||||
case self::ENGINE_RECODE:
|
||||
return recode_string(
|
||||
$src_charset . '..' . $dest_charset,
|
||||
$what
|
||||
);
|
||||
case self::ENGINE_ICONV:
|
||||
return iconv(
|
||||
$src_charset,
|
||||
$dest_charset .
|
||||
($GLOBALS['cfg']['IconvExtraParams'] ?? ''),
|
||||
$what
|
||||
);
|
||||
case self::ENGINE_MB:
|
||||
return mb_convert_encoding(
|
||||
$what,
|
||||
$dest_charset,
|
||||
$src_charset
|
||||
);
|
||||
default:
|
||||
return $what;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects whether Kanji encoding is available
|
||||
*/
|
||||
public static function canConvertKanji(): bool
|
||||
{
|
||||
return $GLOBALS['lang'] === 'ja';
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for Kanji encodings. Use with caution, mostly useful for testing.
|
||||
*/
|
||||
public static function getKanjiEncodings(): string
|
||||
{
|
||||
return self::$kanjiEncodings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setter for Kanji encodings. Use with caution, mostly useful for testing.
|
||||
*
|
||||
* @param string $value Kanji encodings list
|
||||
*/
|
||||
public static function setKanjiEncodings(string $value): void
|
||||
{
|
||||
self::$kanjiEncodings = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverses SJIS & EUC-JP position in the encoding codes list
|
||||
*/
|
||||
public static function kanjiChangeOrder(): void
|
||||
{
|
||||
$parts = explode(',', self::$kanjiEncodings);
|
||||
if ($parts[1] === 'EUC-JP') {
|
||||
self::$kanjiEncodings = 'ASCII,SJIS,EUC-JP,JIS';
|
||||
} else {
|
||||
self::$kanjiEncodings = 'ASCII,EUC-JP,SJIS,JIS';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Kanji string encoding convert
|
||||
*
|
||||
* @param string $str the string to convert
|
||||
* @param string $enc the destination encoding code
|
||||
* @param string $kana set 'kana' convert to JIS-X208-kana
|
||||
*
|
||||
* @return string the converted string
|
||||
*/
|
||||
public static function kanjiStrConv(string $str, string $enc, string $kana): string
|
||||
{
|
||||
if ($enc == '' && $kana == '') {
|
||||
return $str;
|
||||
}
|
||||
|
||||
$string_encoding = mb_detect_encoding($str, self::$kanjiEncodings);
|
||||
if ($string_encoding === false) {
|
||||
$string_encoding = 'utf-8';
|
||||
}
|
||||
|
||||
if ($kana === 'kana') {
|
||||
$dist = mb_convert_kana($str, 'KV', $string_encoding);
|
||||
$str = $dist;
|
||||
}
|
||||
if ($string_encoding != $enc && $enc != '') {
|
||||
$dist = mb_convert_encoding($str, $enc, $string_encoding);
|
||||
} else {
|
||||
$dist = $str;
|
||||
}
|
||||
|
||||
return $dist;
|
||||
}
|
||||
|
||||
/**
|
||||
* Kanji file encoding convert
|
||||
*
|
||||
* @param string $file the name of the file to convert
|
||||
* @param string $enc the destination encoding code
|
||||
* @param string $kana set 'kana' convert to JIS-X208-kana
|
||||
*
|
||||
* @return string the name of the converted file
|
||||
*/
|
||||
public static function kanjiFileConv(string $file, string $enc, string $kana): string
|
||||
{
|
||||
if ($enc == '' && $kana == '') {
|
||||
return $file;
|
||||
}
|
||||
$tmpfname = (string) tempnam($GLOBALS['PMA_Config']->getUploadTempDir(), $enc);
|
||||
$fpd = fopen($tmpfname, 'wb');
|
||||
$fps = fopen($file, 'r');
|
||||
self::kanjiChangeOrder();
|
||||
while (! feof($fps)) {
|
||||
$line = fgets($fps, 4096);
|
||||
$dist = self::kanjiStrConv($line, $enc, $kana);
|
||||
fwrite($fpd, $dist);
|
||||
}
|
||||
self::kanjiChangeOrder();
|
||||
fclose($fps);
|
||||
fclose($fpd);
|
||||
unlink($file);
|
||||
|
||||
return $tmpfname;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines radio form fields to switch between encoding modes
|
||||
*
|
||||
* @return string HTML code for the radio controls
|
||||
*/
|
||||
public static function kanjiEncodingForm(): string
|
||||
{
|
||||
$template = new Template();
|
||||
|
||||
return $template->render('encoding/kanji_encoding_form');
|
||||
}
|
||||
|
||||
/**
|
||||
* Lists available encodings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function listEncodings(): array
|
||||
{
|
||||
if (self::$engine === null) {
|
||||
self::initEngine();
|
||||
}
|
||||
/* Most engines do not support listing */
|
||||
if (self::$engine != self::ENGINE_MB) {
|
||||
return $GLOBALS['cfg']['AvailableCharsets'];
|
||||
}
|
||||
|
||||
return array_intersect(
|
||||
array_map('strtolower', mb_list_encodings()),
|
||||
$GLOBALS['cfg']['AvailableCharsets']
|
||||
);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue