source: extensions/AMetaData/JpegMetaData/External/php-gettext/gettext.inc @ 17554

Last change on this file since 17554 was 17554, checked in by grum, 12 years ago

feature:2701
bug:2702
bug:2720
bug:2722

  • Property svn:executable set to *
File size: 11.9 KB
Line 
1<?php
2/*
3   Copyright (c) 2005 Steven Armstrong <sa at c-area dot ch>
4   Copyright (c) 2009 Danilo Segan <danilo@kvota.net>
5
6   Drop in replacement for native gettext.
7
8   This file is part of PHP-gettext.
9
10   PHP-gettext is free software; you can redistribute it and/or modify
11   it under the terms of the GNU General Public License as published by
12   the Free Software Foundation; either version 2 of the License, or
13   (at your option) any later version.
14
15   PHP-gettext is distributed in the hope that it will be useful,
16   but WITHOUT ANY WARRANTY; without even the implied warranty of
17   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18   GNU General Public License for more details.
19
20   You should have received a copy of the GNU General Public License
21   along with PHP-gettext; if not, write to the Free Software
22   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
24*/
25/*
26LC_CTYPE        0
27LC_NUMERIC      1
28LC_TIME         2
29LC_COLLATE      3
30LC_MONETARY     4
31LC_MESSAGES     5
32LC_ALL          6
33*/
34
35
36// LC_MESSAGES is not available if php-gettext is not loaded
37// while the other constants are already available from session extension.
38if (!defined('LC_MESSAGES')) {
39  define('LC_MESSAGES', 5);
40}
41
42require('streams.php');
43require('gettext.php');
44
45
46// Variables
47
48global $text_domains, $default_domain, $LC_CATEGORIES, $EMULATEGETTEXT, $CURRENTLOCALE;
49$text_domains = array();
50$default_domain = 'messages';
51$LC_CATEGORIES = array('LC_CTYPE', 'LC_NUMERIC', 'LC_TIME', 'LC_COLLATE', 'LC_MONETARY', 'LC_MESSAGES', 'LC_ALL');
52$EMULATEGETTEXT = 0;
53$CURRENTLOCALE = '';
54
55/* Class to hold a single domain included in $text_domains. */
56class domain {
57  var $l10n;
58  var $path;
59  var $codeset;
60}
61
62// Utility functions
63
64/**
65 * Utility function to get a StreamReader for the given text domain.
66 */
67function _get_reader($domain=null, $category=5, $enable_cache=true) {
68    global $text_domains, $default_domain, $LC_CATEGORIES;
69    if (!isset($domain)) $domain = $default_domain;
70    if (!isset($text_domains[$domain]->l10n)) {
71        // get the current locale
72        $locale = _setlocale(LC_MESSAGES, 0);
73        $bound_path = isset($text_domains[$domain]->path) ?
74          $text_domains[$domain]->path : './';
75        $subpath = $LC_CATEGORIES[$category] ."/$domain.mo";
76        /* Figure out all possible locale names and start with the most
77           specific ones.  I.e. for sr_CS.UTF-8@latin, look through all of
78           sr_CS.UTF-8@latin, sr_CS@latin, sr@latin, sr_CS.UTF-8, sr_CS, sr.
79        */
80        $locale_names = array();
81        if (preg_match("/([a-z]{2,3})"            // language code
82                       ."(_([A-Z]{2}))?"          // country code
83                       ."(\.([-A-Za-z0-9_]))?"    // charset
84                       ."(@([-A-Za-z0-9_]+))?/",  // @ modifier
85                       $locale, $matches)) {
86          list(,$lang,,$country,,$charset,,$modifier) = $matches;
87          if ($modifier) {
88            $locale_names = array("${lang}_$country.$charset@$modifier",
89                                  "${lang}_$country@$modifier",
90                                  "$lang@$modifier");
91          }
92          array_push($locale_names,
93                     "${lang}_$country.$charset", "${lang}_$country", "$lang");
94        }
95        array_push($locale_names, $locale);
96
97        $input = null;
98        foreach ($locale_names as $locale) {
99          $full_path = $bound_path . $locale . "/" . $subpath;
100          if (file_exists($full_path)) {
101            $input = new FileReader($full_path);
102            break;
103          }
104        }
105
106        if (!array_key_exists($domain, $text_domains)) {
107          // Initialize an empty domain object.
108          $text_domains[$domain] = new domain();
109        }
110        $text_domains[$domain]->l10n = new gettext_reader($input,
111                                                          $enable_cache);
112    }
113    return $text_domains[$domain]->l10n;
114}
115
116/**
117 * Returns whether we are using our emulated gettext API or PHP built-in one.
118 */
119function locale_emulation() {
120    global $EMULATEGETTEXT;
121    return $EMULATEGETTEXT;
122}
123
124/**
125 * Checks if the current locale is supported on this system.
126 */
127function _check_locale() {
128    global $EMULATEGETTEXT;
129    return !$EMULATEGETTEXT;
130}
131
132/**
133 * Get the codeset for the given domain.
134 */
135function _get_codeset($domain=null) {
136    global $text_domains, $default_domain, $LC_CATEGORIES;
137    if (!isset($domain)) $domain = $default_domain;
138    return (isset($text_domains[$domain]->codeset))? $text_domains[$domain]->codeset : ini_get('mbstring.internal_encoding');
139}
140
141/**
142 * Convert the given string to the encoding set by bind_textdomain_codeset.
143 */
144function _encode($text) {
145    $source_encoding = mb_detect_encoding($text);
146    $target_encoding = _get_codeset();
147    if ($source_encoding != $target_encoding) {
148        return mb_convert_encoding($text, $target_encoding, $source_encoding);
149    }
150    else {
151        return $text;
152    }
153}
154
155
156
157
158// Custom implementation of the standard gettext related functions
159
160/**
161 * Sets a requested locale, if needed emulates it.
162 */
163function _setlocale($category, $locale) {
164    global $CURRENTLOCALE, $EMULATEGETTEXT;
165    if ($locale === 0) { // use === to differentiate between string "0"
166        if ($CURRENTLOCALE != '')
167            return $CURRENTLOCALE;
168        else
169            // obey LANG variable, maybe extend to support all of LC_* vars
170            // even if we tried to read locale without setting it first
171            return _setlocale($category, $CURRENTLOCALE);
172    } else {
173        $ret = 0;
174        if (function_exists('setlocale')) // I don't know if this ever happens ;)
175           $ret = setlocale($category, $locale);
176        if (($ret and $locale == '') or ($ret == $locale)) {
177            $EMULATEGETTEXT = 0;
178            $CURRENTLOCALE = $ret;
179        } else {
180          if ($locale == '') // emulate variable support
181             $CURRENTLOCALE = getenv('LANG');
182        else
183            $CURRENTLOCALE = $locale;
184            $EMULATEGETTEXT = 1;
185        }
186        // Allow locale to be changed on the go for one translation domain.
187        global $text_domains, $default_domain;
188        unset($text_domains[$default_domain]->l10n);
189        return $CURRENTLOCALE;
190    }
191}
192
193/**
194 * Sets the path for a domain.
195 */
196function _bindtextdomain($domain, $path) {
197    global $text_domains;
198    // ensure $path ends with a slash ('/' should work for both, but lets still play nice)
199    /*
200      --- some hoster sometimess deactivate the php_uname()
201          in all case, it's better to work with the DIRECTORY_SEPARATOR
202
203    if (substr(php_uname(), 0, 7) == "Windows") {
204      if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/')
205        $path .= '\\';
206    } else {
207      if ($path[strlen($path)-1] != '/')
208        $path .= '/';
209    }
210    */
211      if ($path[strlen($path)-1] != DIRECTORY_SEPARATOR)
212        $path .= DIRECTORY_SEPARATOR;
213
214    if (!array_key_exists($domain, $text_domains)) {
215      // Initialize an empty domain object.
216      $text_domains[$domain] = new domain();
217    }
218    $text_domains[$domain]->path = $path;
219}
220
221/**
222 * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
223 */
224function _bind_textdomain_codeset($domain, $codeset) {
225    global $text_domains;
226    $text_domains[$domain]->codeset = $codeset;
227}
228
229/**
230 * Sets the default domain.
231 */
232function _textdomain($domain) {
233    global $default_domain;
234    $default_domain = $domain;
235}
236
237/**
238 * Lookup a message in the current domain.
239 */
240function _gettext($msgid) {
241    $l10n = _get_reader();
242    //return $l10n->translate($msgid);
243    return _encode($l10n->translate($msgid));
244}
245/**
246 * Alias for gettext.
247 */
248function __($msgid) {
249    return _gettext($msgid);
250}
251/**
252 * Plural version of gettext.
253 */
254function _ngettext($single, $plural, $number) {
255    $l10n = _get_reader();
256    //return $l10n->ngettext($single, $plural, $number);
257    return _encode($l10n->ngettext($single, $plural, $number));
258}
259
260/**
261 * Override the current domain.
262 */
263function _dgettext($domain, $msgid) {
264    $l10n = _get_reader($domain);
265    //return $l10n->translate($msgid);
266    return _encode($l10n->translate($msgid));
267}
268/**
269 * Plural version of dgettext.
270 */
271function _dngettext($domain, $single, $plural, $number) {
272    $l10n = _get_reader($domain);
273    //return $l10n->ngettext($single, $plural, $number);
274    return _encode($l10n->ngettext($single, $plural, $number));
275}
276
277/**
278 * Overrides the domain and category for a single lookup.
279 */
280function _dcgettext($domain, $msgid, $category) {
281    $l10n = _get_reader($domain, $category);
282    //return $l10n->translate($msgid);
283    return _encode($l10n->translate($msgid));
284}
285/**
286 * Plural version of dcgettext.
287 */
288function _dcngettext($domain, $single, $plural, $number, $category) {
289    $l10n = _get_reader($domain, $category);
290    //return $l10n->ngettext($single, $plural, $number);
291    return _encode($l10n->ngettext($single, $plural, $number));
292}
293
294
295
296// Wrappers to use if the standard gettext functions are available, but the current locale is not supported by the system.
297// Use the standard impl if the current locale is supported, use the custom impl otherwise.
298
299function T_setlocale($category, $locale) {
300    return _setlocale($category, $locale);
301}
302
303function T_bindtextdomain($domain, $path) {
304    if (_check_locale()) return bindtextdomain($domain, $path);
305    else return _bindtextdomain($domain, $path);
306}
307function T_bind_textdomain_codeset($domain, $codeset) {
308    // bind_textdomain_codeset is available only in PHP 4.2.0+
309    if (_check_locale() and function_exists('bind_textdomain_codeset')) return bind_textdomain_codeset($domain, $codeset);
310    else return _bind_textdomain_codeset($domain, $codeset);
311}
312function T_textdomain($domain) {
313    if (_check_locale()) return textdomain($domain);
314    else return _textdomain($domain);
315}
316function T_gettext($msgid) {
317    if (_check_locale()) return gettext($msgid);
318    else return _gettext($msgid);
319}
320function T_($msgid) {
321    if (_check_locale()) return _($msgid);
322    return __($msgid);
323}
324function T_ngettext($single, $plural, $number) {
325    if (_check_locale()) return ngettext($single, $plural, $number);
326    else return _ngettext($single, $plural, $number);
327}
328function T_dgettext($domain, $msgid) {
329    if (_check_locale()) return dgettext($domain, $msgid);
330    else return _dgettext($domain, $msgid);
331}
332function T_dngettext($domain, $single, $plural, $number) {
333    if (_check_locale()) return dngettext($domain, $single, $plural, $number);
334    else return _dngettext($domain, $single, $plural, $number);
335}
336function T_dcgettext($domain, $msgid, $category) {
337    if (_check_locale()) return dcgettext($domain, $msgid, $category);
338    else return _dcgettext($domain, $msgid, $category);
339}
340function T_dcngettext($domain, $single, $plural, $number, $category) {
341    if (_check_locale()) return dcngettext($domain, $single, $plural, $number, $category);
342    else return _dcngettext($domain, $single, $plural, $number, $category);
343}
344
345
346
347// Wrappers used as a drop in replacement for the standard gettext functions
348
349if (!function_exists('gettext')) {
350    function bindtextdomain($domain, $path) {
351        return _bindtextdomain($domain, $path);
352    }
353    function bind_textdomain_codeset($domain, $codeset) {
354        return _bind_textdomain_codeset($domain, $codeset);
355    }
356    function textdomain($domain) {
357        return _textdomain($domain);
358    }
359    function gettext($msgid) {
360        return _gettext($msgid);
361    }
362    function _($msgid) {
363        return __($msgid);
364    }
365    function ngettext($single, $plural, $number) {
366        return _ngettext($single, $plural, $number);
367    }
368    function dgettext($domain, $msgid) {
369        return _dgettext($domain, $msgid);
370    }
371    function dngettext($domain, $single, $plural, $number) {
372        return _dngettext($domain, $single, $plural, $number);
373    }
374    function dcgettext($domain, $msgid, $category) {
375        return _dcgettext($domain, $msgid, $category);
376    }
377    function dcngettext($domain, $single, $plural, $number, $category) {
378        return _dcngettext($domain, $single, $plural, $number, $category);
379    }
380}
381
382?>
Note: See TracBrowser for help on using the repository browser.