2 /* vim: set expandtab sw=4 ts=4 sts=4: */
4 * Hold the PMA\libraries\Encoding class
8 namespace PMA\libraries
;
10 use PMA\libraries\config\ConfigFile
;
13 * Encoding conversion helper class
20 * None encoding conversion engine
25 const ENGINE_NONE
= 0;
27 * iconv encoding conversion engine
31 const ENGINE_ICONV
= 1;
34 * recode encoding conversion engine
38 const ENGINE_RECODE
= 2;
41 * mbstring encoding conversion engine
48 * Chosen encoding engine
52 private static $_engine = null;
55 * Map of conversion engine configurations
57 * Each entry contains:
59 * - function to detect
61 * - extension name to warn when missing
65 private static $_enginemap = array(
66 'iconv' => array('iconv', self
::ENGINE_ICONV
, 'iconv'),
67 'recode' => array('recode_string', self
::ENGINE_RECODE
, 'recode'),
68 'mb' => array('mb_convert_encoding', self
::ENGINE_MB
, 'mbstring'),
69 'none' => array('isset', self
::ENGINE_NONE
, ''),
73 * Order of automatic detection of engines
77 private static $_engineorder = array(
78 'mb', 'iconv', 'recode',
82 * Kanji encodings list
86 private static $_kanji_encodings = 'ASCII,SJIS,EUC-JP,JIS';
89 * Initializes encoding engine detecting available backends.
93 public static function initEngine()
96 if (isset($GLOBALS['cfg']['RecodingEngine'])) {
97 $engine = $GLOBALS['cfg']['RecodingEngine'];
100 /* Use user configuration */
101 if (isset(self
::$_enginemap[$engine])) {
102 if (@function_exists
(self
::$_enginemap[$engine][0])) {
103 self
::$_engine = self
::$_enginemap[$engine][1];
106 PMA_warnMissingExtension(self
::$_enginemap[$engine][2]);
111 foreach (self
::$_engineorder as $engine) {
112 if (@function_exists
(self
::$_enginemap[$engine][0])) {
113 self
::$_engine = self
::$_enginemap[$engine][1];
118 /* Fallback to none conversion */
119 self
::$_engine = self
::ENGINE_NONE
;
123 * Setter for engine. Use with caution, mostly useful for testing.
127 public static function setEngine($engine)
129 self
::$_engine = $engine;
133 * Checks whether there is any charset conversion supported
137 public static function isSupported()
139 if (is_null(self
::$_engine)) {
142 return self
::$_engine != self
::ENGINE_NONE
;
146 * Converts encoding of text according to parameters with detected
147 * conversion function.
149 * @param string $src_charset source charset
150 * @param string $dest_charset target charset
151 * @param string $what what to convert
153 * @return string converted text
157 public static function convertString($src_charset, $dest_charset, $what)
159 if ($src_charset == $dest_charset) {
162 if (is_null(self
::$_engine)) {
165 switch (self
::$_engine) {
166 case self
::ENGINE_RECODE
:
167 return recode_string(
168 $src_charset . '..' . $dest_charset,
171 case self
::ENGINE_ICONV
:
175 (isset($GLOBALS['cfg']['IconvExtraParams']) ?
$GLOBALS['cfg']['IconvExtraParams'] : ''),
178 case self
::ENGINE_MB
:
179 return mb_convert_encoding(
190 * Detects whether Kanji encoding is available
194 public static function canConvertKanji()
197 $GLOBALS['lang'] == 'ja' &&
198 function_exists('mb_convert_encoding')
203 * Setter for Kanji encodings. Use with caution, mostly useful for testing.
207 public static function getKanjiEncodings()
209 return self
::$_kanji_encodings;
213 * Setter for Kanji encodings. Use with caution, mostly useful for testing.
217 public static function setKanjiEncodings($value)
219 self
::$_kanji_encodings = $value;
223 * Reverses SJIS & EUC-JP position in the encoding codes list
227 public static function kanjiChangeOrder()
229 $parts = explode(',', self
::$_kanji_encodings);
230 if ($parts[1] == 'EUC-JP') {
231 self
::$_kanji_encodings = 'ASCII,SJIS,EUC-JP,JIS';
233 self
::$_kanji_encodings = 'ASCII,EUC-JP,SJIS,JIS';
238 * Kanji string encoding convert
240 * @param string $str the string to convert
241 * @param string $enc the destination encoding code
242 * @param string $kana set 'kana' convert to JIS-X208-kana
244 * @return string the converted string
246 public static function kanjiStrConv($str, $enc, $kana)
248 if ($enc == '' && $kana == '') {
252 $string_encoding = mb_detect_encoding($str, self
::$_kanji_encodings);
253 if ($string_encoding === false) {
254 $string_encoding = 'utf-8';
257 if ($kana == 'kana') {
258 $dist = mb_convert_kana($str, 'KV', $string_encoding);
261 if ($string_encoding != $enc && $enc != '') {
262 $dist = mb_convert_encoding($str, $enc, $string_encoding);
271 * Kanji file encoding convert
273 * @param string $file the name of the file to convert
274 * @param string $enc the destination encoding code
275 * @param string $kana set 'kana' convert to JIS-X208-kana
277 * @return string the name of the converted file
279 public static function kanjiFileConv($file, $enc, $kana)
281 if ($enc == '' && $kana == '') {
284 $tmpfname = tempnam(ConfigFile
::getDefaultTempDirectory(), $enc);
285 $fpd = fopen($tmpfname, 'wb');
286 $fps = fopen($file, 'r');
287 self
::kanjiChangeOrder();
288 while (!feof($fps)) {
289 $line = fgets($fps, 4096);
290 $dist = self
::kanjiStrConv($line, $enc, $kana);
293 self
::kanjiChangeOrder();
302 * Defines radio form fields to switch between encoding modes
304 * @return string xhtml code for the radio controls
306 public static function kanjiEncodingForm()
309 . '<input type="radio" name="knjenc" value="" checked="checked" '
311 . '<label for="kj-none">'
312 /* l10n: This is currently used only in Japanese locales */
313 . _pgettext('None encoding conversion', 'None')
315 . '<input type="radio" name="knjenc" value="EUC-JP" id="kj-euc" />'
316 . '<label for="kj-euc">EUC</label>'
317 . '<input type="radio" name="knjenc" value="SJIS" id="kj-sjis" />'
318 . '<label for="kj-sjis">SJIS</label>'
321 . '<input type="checkbox" name="xkana" value="kana" id="kj-kana" />'
322 . '<label for="kj-kana">'
323 /* l10n: This is currently used only in Japanese locales */
324 . __('Convert to Kana')
329 public static function listEncodings()
331 if (is_null(self
::$_engine)) {
334 /* Most engines do not support listing */
335 if (self
::$_engine != self
::ENGINE_MB
) {
336 return $GLOBALS['cfg']['AvailableCharsets'];
339 return array_intersect(
340 array_map('strtolower', mb_list_encodings()),
341 $GLOBALS['cfg']['AvailableCharsets']