123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- <?php
- /* vim: set expandtab sw=4 ts=4 sts=4: */
- /**
- * Hold the PhpMyAdmin\Encoding class
- *
- * @package PhpMyAdmin
- */
- namespace PhpMyAdmin;
- use PhpMyAdmin\Config\ConfigFile;
- use PhpMyAdmin\Core;
- use PhpMyAdmin\Template;
- /**
- * Encoding conversion helper class
- *
- * @package PhpMyAdmin
- */
- class Encoding
- {
- /**
- * None encoding conversion engine
- *
- * @var int
- */
- const ENGINE_NONE = 0;
- /**
- * iconv encoding conversion engine
- *
- * @var int
- */
- const ENGINE_ICONV = 1;
- /**
- * recode encoding conversion engine
- *
- * @var int
- */
- const ENGINE_RECODE = 2;
- /**
- * mbstring encoding conversion engine
- *
- * @var int
- */
- 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 = array(
- 'iconv' => array('iconv', self::ENGINE_ICONV, 'iconv'),
- 'recode' => array('recode_string', self::ENGINE_RECODE, 'recode'),
- 'mb' => array('mb_convert_encoding', self::ENGINE_MB, 'mbstring'),
- 'none' => array('isset', self::ENGINE_NONE, ''),
- );
- /**
- * Order of automatic detection of engines
- *
- * @var array
- */
- private static $_engineorder = array(
- 'iconv', 'mb', 'recode',
- );
- /**
- * Kanji encodings list
- *
- * @var string
- */
- private static $_kanji_encodings = 'ASCII,SJIS,EUC-JP,JIS';
- /**
- * Initializes encoding engine detecting available backends.
- *
- * @return void
- */
- public static function initEngine()
- {
- $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;
- } else {
- 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 enconding
- *
- * @return void
- */
- public static function setEngine($engine)
- {
- self::$_engine = $engine;
- }
- /**
- * Checks whether there is any charset conversion supported
- *
- * @return bool
- */
- public static function isSupported()
- {
- if (is_null(self::$_engine)) {
- 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($src_charset, $dest_charset, $what)
- {
- if ($src_charset == $dest_charset) {
- return $what;
- }
- if (is_null(self::$_engine)) {
- 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 .
- (isset($GLOBALS['cfg']['IconvExtraParams']) ? $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
- *
- * @return bool
- */
- public static function canConvertKanji()
- {
- return $GLOBALS['lang'] == 'ja';
- }
- /**
- * Setter for Kanji encodings. Use with caution, mostly useful for testing.
- *
- * @return string
- */
- public static function getKanjiEncodings()
- {
- return self::$_kanji_encodings;
- }
- /**
- * Setter for Kanji encodings. Use with caution, mostly useful for testing.
- *
- * @param string $value Kanji encodings list
- *
- * @return void
- */
- public static function setKanjiEncodings($value)
- {
- self::$_kanji_encodings = $value;
- }
- /**
- * Reverses SJIS & EUC-JP position in the encoding codes list
- *
- * @return void
- */
- public static function kanjiChangeOrder()
- {
- $parts = explode(',', self::$_kanji_encodings);
- if ($parts[1] == 'EUC-JP') {
- self::$_kanji_encodings = 'ASCII,SJIS,EUC-JP,JIS';
- } else {
- self::$_kanji_encodings = '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($str, $enc, $kana)
- {
- if ($enc == '' && $kana == '') {
- return $str;
- }
- $string_encoding = mb_detect_encoding($str, self::$_kanji_encodings);
- 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($file, $enc, $kana)
- {
- if ($enc == '' && $kana == '') {
- return $file;
- }
- $tmpfname = 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);
- fputs($fpd, $dist);
- } // end while
- self::kanjiChangeOrder();
- fclose($fps);
- fclose($fpd);
- unlink($file);
- return $tmpfname;
- }
- /**
- * Defines radio form fields to switch between encoding modes
- *
- * @return string xhtml code for the radio controls
- */
- public static function kanjiEncodingForm()
- {
- return Template::get('encoding/kanji_encoding_form')->render();
- }
- /**
- * Lists available encodings.
- *
- * @return array
- */
- public static function listEncodings()
- {
- if (is_null(self::$_engine)) {
- 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']
- );
- }
- }
|