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

Last change on this file since 4686 was 4686, checked in by grum, 14 years ago

[Plugin:AMetaData] prepare the directory for a future plugin

  • Property svn:executable set to *
File size: 11.7 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    if (substr(php_uname(), 0, 7) == "Windows") {
200      if ($path[strlen($path)-1] != '\\' and $path[strlen($path)-1] != '/')
201        $path .= '\\';
202    } else {
203      if ($path[strlen($path)-1] != '/')
204        $path .= '/';
205    }
206    if (!array_key_exists($domain, $text_domains)) {
207      // Initialize an empty domain object.
208      $text_domains[$domain] = new domain();
209    }
210    $text_domains[$domain]->path = $path;
211}
212
213/**
214 * Specify the character encoding in which the messages from the DOMAIN message catalog will be returned.
215 */
216function _bind_textdomain_codeset($domain, $codeset) {
217    global $text_domains;
218    $text_domains[$domain]->codeset = $codeset;
219}
220
221/**
222 * Sets the default domain.
223 */
224function _textdomain($domain) {
225    global $default_domain;
226    $default_domain = $domain;
227}
228
229/**
230 * Lookup a message in the current domain.
231 */
232function _gettext($msgid) {
233    $l10n = _get_reader();
234    //return $l10n->translate($msgid);
235    return _encode($l10n->translate($msgid));
236}
237/**
238 * Alias for gettext.
239 */
240function __($msgid) {
241    return _gettext($msgid);
242}
243/**
244 * Plural version of gettext.
245 */
246function _ngettext($single, $plural, $number) {
247    $l10n = _get_reader();
248    //return $l10n->ngettext($single, $plural, $number);
249    return _encode($l10n->ngettext($single, $plural, $number));
250}
251
252/**
253 * Override the current domain.
254 */
255function _dgettext($domain, $msgid) {
256    $l10n = _get_reader($domain);
257    //return $l10n->translate($msgid);
258    return _encode($l10n->translate($msgid));
259}
260/**
261 * Plural version of dgettext.
262 */
263function _dngettext($domain, $single, $plural, $number) {
264    $l10n = _get_reader($domain);
265    //return $l10n->ngettext($single, $plural, $number);
266    return _encode($l10n->ngettext($single, $plural, $number));
267}
268
269/**
270 * Overrides the domain and category for a single lookup.
271 */
272function _dcgettext($domain, $msgid, $category) {
273    $l10n = _get_reader($domain, $category);
274    //return $l10n->translate($msgid);
275    return _encode($l10n->translate($msgid));
276}
277/**
278 * Plural version of dcgettext.
279 */
280function _dcngettext($domain, $single, $plural, $number, $category) {
281    $l10n = _get_reader($domain, $category);
282    //return $l10n->ngettext($single, $plural, $number);
283    return _encode($l10n->ngettext($single, $plural, $number));
284}
285
286
287
288// Wrappers to use if the standard gettext functions are available, but the current locale is not supported by the system.
289// Use the standard impl if the current locale is supported, use the custom impl otherwise.
290
291function T_setlocale($category, $locale) {
292    return _setlocale($category, $locale);
293}
294
295function T_bindtextdomain($domain, $path) {
296    if (_check_locale()) return bindtextdomain($domain, $path);
297    else return _bindtextdomain($domain, $path);
298}
299function T_bind_textdomain_codeset($domain, $codeset) {
300    // bind_textdomain_codeset is available only in PHP 4.2.0+
301    if (_check_locale() and function_exists('bind_textdomain_codeset')) return bind_textdomain_codeset($domain, $codeset);
302    else return _bind_textdomain_codeset($domain, $codeset);
303}
304function T_textdomain($domain) {
305    if (_check_locale()) return textdomain($domain);
306    else return _textdomain($domain);
307}
308function T_gettext($msgid) {
309    if (_check_locale()) return gettext($msgid);
310    else return _gettext($msgid);
311}
312function T_($msgid) {
313    if (_check_locale()) return _($msgid);
314    return __($msgid);
315}
316function T_ngettext($single, $plural, $number) {
317    if (_check_locale()) return ngettext($single, $plural, $number);
318    else return _ngettext($single, $plural, $number);
319}
320function T_dgettext($domain, $msgid) {
321    if (_check_locale()) return dgettext($domain, $msgid);
322    else return _dgettext($domain, $msgid);
323}
324function T_dngettext($domain, $single, $plural, $number) {
325    if (_check_locale()) return dngettext($domain, $single, $plural, $number);
326    else return _dngettext($domain, $single, $plural, $number);
327}
328function T_dcgettext($domain, $msgid, $category) {
329    if (_check_locale()) return dcgettext($domain, $msgid, $category);
330    else return _dcgettext($domain, $msgid, $category);
331}
332function T_dcngettext($domain, $single, $plural, $number, $category) {
333    if (_check_locale()) return dcngettext($domain, $single, $plural, $number, $category);
334    else return _dcngettext($domain, $single, $plural, $number, $category);
335}
336
337
338
339// Wrappers used as a drop in replacement for the standard gettext functions
340
341if (!function_exists('gettext')) {
342    function bindtextdomain($domain, $path) {
343        return _bindtextdomain($domain, $path);
344    }
345    function bind_textdomain_codeset($domain, $codeset) {
346        return _bind_textdomain_codeset($domain, $codeset);
347    }
348    function textdomain($domain) {
349        return _textdomain($domain);
350    }
351    function gettext($msgid) {
352        return _gettext($msgid);
353    }
354    function _($msgid) {
355        return __($msgid);
356    }
357    function ngettext($single, $plural, $number) {
358        return _ngettext($single, $plural, $number);
359    }
360    function dgettext($domain, $msgid) {
361        return _dgettext($domain, $msgid);
362    }
363    function dngettext($domain, $single, $plural, $number) {
364        return _dngettext($domain, $single, $plural, $number);
365    }
366    function dcgettext($domain, $msgid, $category) {
367        return _dcgettext($domain, $msgid, $category);
368    }
369    function dcngettext($domain, $single, $plural, $number, $category) {
370        return _dcngettext($domain, $single, $plural, $number, $category);
371    }
372}
373
374?>
Note: See TracBrowser for help on using the repository browser.