source: branches/version-2_12-multilang/data/class/helper/SC_Helper_Locale.php @ 22186

Revision 22186, 10.1 KB checked in by Seasoft, 11 years ago (diff)

#1988 (国際化テンプレート:エスケープ処理) 現状コミット。

  • ja.po は、data/Smarty/templates/admin/ownersstore/plugin.tpl に対応する部分のみ、局所的に変更しています。
    • data/Smarty/templates/admin/ownersstore/plugin.tpl にコメントを記載している「案1」及び「案2」の方向性については協議中。
  • 上記以外では、po ファイルの改修が終わるまで、HTML エスケープが過剰に行なわれます。(主に、入力必須マークの出力が正しく行なわれないといった状況が生じます。)
Line 
1<?php
2/*
3 * This file is part of EC-CUBE
4 *
5 * Copyright(c) 2000-2011 LOCKON CO.,LTD. All Rights Reserved.
6 *
7 * http://www.lockon.co.jp/
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22 */
23
24require DATA_REALDIR . 'module/Locale/streams.php';
25require DATA_REALDIR . 'module/Locale/gettext.php';
26
27/**
28 * Helper class for localization.
29 * Library of static method.
30 *
31 * @package Helper
32 * @author LOCKON CO.,LTD.
33 * @version $Id$
34 */
35class SC_Helper_Locale {
36
37    /**
38     * Store the instance of SC_Helper_Locale_Ex.
39     * @var SC_Helper_Locale
40     */
41     static $_instance = NULL;
42
43     public $_translations = array();
44
45     /**
46     * Return a string which corresponding with message alias.
47     *
48     * @param   string  $string     message alias
49     * @param   array   $options    options
50     * @return  string  a string corresponding with message alias
51     */
52     public static function get_locale($string, &$options) {
53        is_null(SC_Helper_Locale_Ex::$_instance) and SC_Helper_Locale_Ex::$_instance = new SC_Helper_Locale_Ex();
54
55        // If language code is not specified, use site default.
56        if (empty($options['lang_code'])) {
57            $lang_code = $options['lang_code'] = defined('LANG_CODE') ? LANG_CODE : 'en';
58        } else {
59            $lang_code = $options['lang_code'];
60        }
61        // If device type ID is not specified, detect the viewing device.
62        if (!isset($options['device_type_id']) || ($options['device_type_id'] !== FALSE && !strlen($options['device_type_id']))) {
63            if (method_exists('SC_Display_Ex', 'detectDevice')) {
64                $device_type_id = SC_Display_Ex::detectDevice();
65            } else {
66                $device_type_id = FALSE;
67            }
68        } else {
69            $device_type_id = $options['device_type_id'];
70        }
71
72        $return = $string;
73        // Get string list of specified language.
74        if ($lang_code != 'en') {
75            $translations = SC_Helper_Locale_Ex::$_instance->get_translations($lang_code, $device_type_id);
76            // Whether a string which corresponding with alias is exist.
77            if (isset($translations[$return])) {
78                $return = $translations[$return];
79            }
80        }
81
82        $esc_types = $options['escape'];
83        if (is_null($esc_types) && $string[0] !== '<') {
84            $esc_types = 'h';
85        }
86        foreach (explode(',', $esc_types) as $esc_type) {
87            switch ($esc_type) {
88                case 'h':
89                case 'html':
90                    $return = htmlspecialchars($return, ENT_QUOTES);
91                    break;
92
93                case 'j':
94                case 'javascript':
95                    // escape quotes and backslashes, newlines, etc.
96                    $return = strtr($return, array('\\'=>'\\\\',"'"=>"\\'",'"'=>'\\"',"\r"=>'\\r',"\n"=>'\\n','</'=>'<\/'));
97                    break;
98
99                case 'nl2br':
100                    $return = nl2br($return, true);
101                    break;
102
103                case '':
104                case 'none':
105                    break;
106
107                case 'htmlall':
108                    $return = htmlentities($return, ENT_QUOTES);
109                    break;
110
111                case 'u':
112                case 'url':
113                    $return = rawurlencode($return);
114                    break;
115
116                case 'urlpathinfo':
117                    $return = str_replace('%2F','/',rawurlencode($return));
118                    break;
119
120                case 'quotes':
121                    // escape unescaped single quotes
122                    $return = preg_replace("%(?<!\\\\)'%", "\\'", $return);
123                    break;
124
125                case 'hex':
126                    // escape every character into hex
127                    $text = '';
128                    for ($x=0; $x < strlen($return); $x++) {
129                        $text .= '%' . bin2hex($return[$x]);
130                    }
131                    $return = $text;
132                    break;
133
134                case 'hexentity':
135                    $text = '';
136                    for ($x=0; $x < strlen($return); $x++) {
137                        $text .= '&#x' . bin2hex($return[$x]) . ';';
138                    }
139                    $return = $text;
140                    break;
141
142                case 'decentity':
143                    $text = '';
144                    for ($x=0; $x < strlen($return); $x++) {
145                        $text .= '&#' . ord($return[$x]) . ';';
146                    }
147                    $return = $text;
148                    break;
149
150                case 'mail':
151                    // safe way to display e-mail address on a web page
152                    $return = str_replace(array('@', '.'),array(' [AT] ', ' [DOT] '), $return);
153                    break;
154
155                case 'nonstd':
156                   // escape non-standard chars, such as ms document quotes
157                   $_res = '';
158                   for($_i = 0, $_len = strlen($return); $_i < $_len; $_i++) {
159                       $_ord = ord(substr($return, $_i, 1));
160                       // non-standard char, escape it
161                       if($_ord >= 126){
162                           $_res .= '&#' . $_ord . ';';
163                       }
164                       else {
165                           $_res .= substr($return, $_i, 1);
166                       }
167                   }
168                   $return = $_res;
169                    break;
170
171                default:
172                    trigger_error('unknown escape type. ' . var_export(func_get_args(), true), E_USER_WARNING);
173                    break;
174            }
175        }
176
177        return $return;
178    }
179
180    /**
181     * Return a string which corresponding with message alias.
182     *
183     * @param   string  $single     message alias (single)
184     * @param   string  $plural     message alias (plural)
185     * @param   array   $options    options
186     * @return  array
187     */
188    public static function get_locale_plural($single, $plural, &$options) {
189        // Plural strings are coupled with a null character.
190        $key = $single . chr(0) . $plural;
191        // Get a string of specified language which corresponds to the message alias.
192        $translated = SC_Helper_Locale_Ex::get_locale($key, $options);
193        // Divide with a null character.
194        return explode(chr(0), $translated);
195    }
196
197    /**
198     * Get the strings of specified language from locale files.
199     *
200     * @param   string  $lang_code      language code
201     * @param   integer $device_type_id device type ID
202     * @return  array   strings
203     */
204    function get_translations($lang_code, $device_type_id = FALSE) {
205        $translations_key = "translations_" . $lang_code . "_" . $device_type_id;
206        // If the strings of specified language is not loaded
207        if (empty($this->_translations[$translations_key])) {
208            $translations = array();
209
210            // Get a list of files to load.
211            $file_list = $this->get_locale_file_list($lang_code, $device_type_id);
212
213            // Get the strings from each locale file using php_gettext.
214            foreach ($file_list as $locale_file) {
215                $stream = new FileReader($locale_file);
216                $gettext = new gettext_reader($stream);
217
218                $gettext->load_tables();
219                $translations = array_merge($translations, $gettext->cache_translations);
220            }
221
222            $this->_translations[$translations_key] = $translations;
223        }
224
225        return $this->_translations[$translations_key];
226    }
227
228    /**
229     * Get a list of locale files.
230     *
231     * @param   string  $lang_code      language code
232     * @param   integer $device_type_id device type ID
233     * @return  array   file list
234     */
235    function get_locale_file_list($lang_code, $device_type_id = FALSE) {
236        $file_list = array();
237
238        // Path to the EC-CUBE Core locale file.
239        $core_locale_path = DATA_REALDIR . "locales/{$lang_code}.mo";
240        // If a locale file of specified language is exist, add to the file list.
241        if (file_exists($core_locale_path)) {
242            $file_list[] = $core_locale_path;
243        }
244
245        // Get a list of enabled plugins.
246        if (defined(PLUGIN_UPLOAD_REALDIR)) {
247            $arrPluginDataList = SC_Plugin_Util_Ex::getEnablePlugin();
248            // Get the plugins directory.
249            $arrPluginDirectory = SC_Plugin_Util_Ex::getPluginDirectory();
250            foreach ($arrPluginDataList as $arrPluginData) {
251                // Check that the plugin filename is contained in the list of plugins directory.
252                if (array_search($arrPluginData['plugin_code'], $arrPluginDirectory) !== false) {
253                    // Path to the plugin locale file.
254                    $plugin_locale_path = PLUGIN_UPLOAD_REALDIR . $arrPluginData['plugin_code'] . "/locales/{$lang_code}.mo";
255                    // If a locale file of specified language is exist, add to the file list.
256                    if (file_exists($plugin_locale_path)) {
257                        $file_list[] = $plugin_locale_path;
258                    }
259                }
260            }
261        }
262
263        // Path to the template locale file.
264        if ($device_type_id !== FALSE) {
265            $template_locale_path = HTML_REALDIR . SC_Helper_PageLayout_Ex::getUserDir($device_type_id, true) . "locales/{$lang_code}.mo";
266            // If a locale file of specified language is exist, add to the file list.
267            if (file_exists($template_locale_path)) {
268                $file_list[] = $template_locale_path;
269            }
270        }
271
272        return $file_list;
273    }
274}
Note: See TracBrowser for help on using the repository browser.