2 // +----------------------------------------------------------------------+
4 // +----------------------------------------------------------------------+
5 // | This source file is subject to version 3.0 of the PHP license, |
6 // | that is available at http://www.php.net/license/3_0.txt |
7 // | If you did not receive a copy of the PHP license and are unable |
8 // | to obtain it through the world-wide-web, please send a note to |
9 // | license@php.net so we can mail you a copy immediately. |
10 // +----------------------------------------------------------------------+
11 // | Copyright (c) 2004 Michael Wallner <mike@iworks.at> |
12 // +----------------------------------------------------------------------+
14 // $Id: I18Nv2.php,v 1.36 2006/03/08 13:07:18 mike Exp $
20 * @category Internationalization
23 define('I18Nv2_WIN', defined('OS_WINDOWS') ? OS_WINDOWS : (strToUpper(substr(PHP_OS, 0,3)) === 'WIN'));
26 * I18Nv2 - Internationalization v2
28 * @author Michael Wallner <mike@php.net>
29 * @version $Revision: 1.36 $
41 * I18Nv2::setLocale('en_GB');
46 * @return mixed &type.string; used locale or false on failure
47 * @param string $locale a valid locale like en_US or de_DE
48 * @param int $cat the locale category - usually LC_ALL
50 static function setLocale($locale = null, $cat = LC_ALL)
52 if (!strlen($locale)) {
53 return setLocale($cat, null);
56 $locales = I18Nv2::getStaticProperty('locales');
58 // get complete standard locale code (en => en_US)
59 if (isset($locales[$locale])) {
60 $locale = $locales[$locale];
63 // get Win32 locale code (en_US => enu)
65 $windows = I18Nv2::getStaticProperty('windows');
66 $setlocale = isset($windows[$locale]) ? $windows[$locale] : $locale;
71 $syslocale = setLocale($cat, $setlocale);
73 // if the locale is not recognized by the system, check if there
74 // is a fallback locale and try that, otherwise return false
76 $fallbacks = &I18Nv2::getStaticProperty('fallbacks');
77 if (isset($fallbacks[$locale])) {
78 // avoid endless recursion with circular fallbacks
79 $trylocale = $fallbacks[$locale];
80 unset($fallbacks[$locale]);
81 if ($retlocale = I18Nv2::setLocale($trylocale, $cat)) {
82 $fallbacks[$locale] = $trylocale;
89 $language = substr($locale, 0,2);
92 @putEnv('LANG=' . $language);
93 @putEnv('LANGUAGE=' . $language);
95 @putEnv('LANG=' . $locale);
96 @putEnv('LANGUAGE=' . $locale);
99 // unshift locale stack
100 $last = &I18Nv2::getStaticProperty('last');
107 'language' => $language,
108 'syslocale' => $syslocale,
112 // fetch locale specific information
113 $info = &I18Nv2::getStaticProperty('info');
114 $info = localeConv();
120 * Get current/prior Locale
124 * @return mixed last locale as string or array
125 * @param int $prior if 0, the current otherwise n prior to current
126 * @param bool $part true|all|0=locale|1=language|2=syslocale
128 function lastLocale($prior = 0, $part = 0)
130 $last = I18Nv2::getStaticProperty('last');
132 return I18Nv2::setLocale();
134 if (!isset($last[$prior])) {
137 if ($part === true || $part == 'all') {
138 return $last[$prior];
140 return $last[$prior][$part];
144 * Get several locale specific information
146 * @see http://www.php.net/localeconv
149 * $locale = I18Nv2::setLocale('en_US');
150 * $dollar = I18Nv2::getInfo('currency_symbol');
151 * $point = I18Nv2::getInfo('decimal_point');
157 * @param string $part
159 function getInfo($part = null)
161 $info = &I18Nv2::getStaticProperty('info');
162 return isset($part, $info[$part]) ? $info[$part] : $info;
166 * Create a Locale object
170 * @return object I18Nv2_Locale
171 * @param string $locale The locale to use.
172 * @param bool $paranoid Whether to operate in paranoid mode.
174 function &createLocale($locale = null, $paranoid = false)
176 require_once 'I18Nv2/Locale.php';
177 $obj = new I18Nv2_Locale($locale, $paranoid);
182 * Create a Negotiator object
186 * @return object I18Nv2_Negotiator
187 * @param string $defLang default language
188 * @param string $defEnc default encoding
189 * @param string $defCtry default country
191 function &createNegotiator($defLang = 'en', $defEnc = 'iso-8859-1', $defCtry = '')
193 require_once 'I18Nv2/Negotiator.php';
194 $obj = new I18Nv2_Negotiator($defLang, $defEnc, $defCtry);
199 * Automatically transform output between encodings
201 * This method utilizes ob_iconv_handler(), so you should call it at the
202 * beginning of your script (prior to output). If any output buffering has
203 * been started before, the contents will be fetched with ob_get_contents()
204 * and the buffers will be destroyed by ob_end_clean() if $refetchOB is set
208 * require_once('I18Nv2.php');
209 * I18Nv2::autoConv('CP1252');
210 * print('...'); // some iso-8859-1 stuff gets converted to Windows-1252
216 * @return mixed Returns &true; on success or
217 * <classname>PEAR_Error</classname> on failure.
218 * @param string $oe desired output encoding
219 * @param string $ie internal encoding
220 * @param bool $decodeRequest whether to decode request variables
221 * ($_GET and $_POST) from $oe to $ie
222 * @param bool $refetchOB whether contents of already active
223 * output buffers should be fetched, the
224 * output buffer handlers destroyed and
225 * the fetched data be passed through
228 function autoConv($oe = 'UTF-8', $ie = 'ISO-8859-1', $decodeRequest = true, $refetchOB = true)
230 if (!strcasecmp($oe, $ie)) {
234 if (!extension_loaded('iconv')) {
235 require_once 'PEAR.php';
236 if (!PEAR::loadExtension('iconv')) {
237 return PEAR::staticRaiseError('Error: ext/iconv is not available');
241 iconv_set_encoding('internal_encoding', $ie);
242 iconv_set_encoding('output_encoding', $oe);
243 iconv_set_encoding('input_encoding', $oe);
246 if ($refetchOB && $level = ob_get_level()) {
248 $buffer .= ob_get_contents();
253 if (!ob_start('ob_iconv_handler')) {
254 require_once 'PEAR.php';
255 return PEAR::staticRaiseError('Couldn\'t start output buffering');
259 if ($decodeRequest) {
260 I18Nv2::recursiveIconv($_GET, $oe, $ie);
261 I18Nv2::recursiveIconv($_POST, $oe, $ie);
273 * @param array $value
274 * @param string $from
277 function recursiveIconv(&$value, $from, $to)
279 foreach ($value as $key => $val) {
280 if (is_array($val)) {
281 I18Nv2::recursiveIconv($value[$key], $from, $to);
283 $value[$key] = iconv($from, $to .'//TRANSLIT', $val);
289 * Traverse locales to languages
291 * Returns en-US, de-DE from en_US and de_DE
296 * @param array $locales
298 function locales2langs($locales)
300 return array_map(array('I18Nv2','l2l'), (array) $locales);
304 * Traverse languages to locales
306 * Returns en_US, de_DE from en-US and de-DE
311 * @param array $languages
313 function langs2locales($languages)
315 return array_map(array('I18Nv2','l2l'), (array) $languages);
319 * Locale to language or language to locale
324 * @param string $localeOrLanguage
326 function l2l($localeOrLanguage)
328 return strtr($localeOrLanguage, '-_', '_-');
334 * Splits locale codes into its language and country part
339 * @param string $locale
341 function splitLocale($locale)
343 @list($l, $c) = preg_split('/[_-]/', $locale, 2, PREG_SPLIT_NO_EMPTY);
344 return array($l, $c);
348 * Get language code of locale
353 * @patram string $locale
355 function languageOf($locale)
357 return current($a = I18Nv2::splitLocale($locale));
361 * Get country code of locale
366 * @param string $locale
368 function countryOf($locale)
370 return end($a = I18Nv2::splitLocale($locale));
374 * Get access to static property
378 * @return mixed Returns a reference to a static property
379 * @param string $property the static property
381 static function &getStaticProperty($property)
384 return $properties[$property];
388 * This one gets called automatically
396 static function _main()
398 // initialize the locale stack
399 $last = &I18Nv2::getStaticProperty('last');
402 // map of "fully qualified locale" codes
403 $locales = &I18Nv2::getStaticProperty('locales');
427 // define locale fallbacks
428 $fallbacks = &I18Nv2::getStaticProperty('fallbacks');
434 // include Win32 locale codes
436 include_once 'I18Nv2/Locale/Windows.php';