Subversion-Projekte lars-tiefland.php_share

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
 
4
/**
5
 * Contains the Translation2_Container_gettext class
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * LICENSE: Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
16
 * 3. The name of the author may not be used to endorse or promote products
17
 *    derived from this software without specific prior written permission.
18
 *
19
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
20
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22
 * IN NO EVENT SHALL THE FREEBSD PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
23
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 *
30
 * @category  Internationalization
31
 * @package   Translation2
32
 * @author    Lorenzo Alberton <l.alberton@quipo.it>
33
 * @author    Michael Wallner <mike@php.net>
34
 * @copyright 2004-2008 Lorenzo Alberton, Michael Wallner
35
 * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
36
 * @version   CVS: $Id: gettext.php 305985 2010-12-05 22:55:33Z clockwerx $
37
 * @link      http://pear.php.net/package/Translation2
38
 */
39
 
40
/**
41
 * require Translation2_Container class
42
 */
43
require_once 'Translation2/Container.php';
44
 
45
/**
46
 * require I18Nv2 for locale handling
47
 */
48
require_once 'I18Nv2.php';
49
 
50
/**
51
 * Storage driver for fetching data with gettext
52
 *
53
 * This storage driver requires the gettext extension
54
 * and the PEAR::I18Nv2 class for locale handling
55
 *
56
 * @category  Internationalization
57
 * @package   Translation2
58
 * @author    Lorenzo Alberton <l.alberton@quipo.it>
59
 * @author    Michael Wallner <mike@php.net>
60
 * @copyright 2004-2008 Lorenzo Alberton, Michael Wallner
61
 * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)
62
 * @version   CVS: $Id: gettext.php 305985 2010-12-05 22:55:33Z clockwerx $
63
 * @link      http://pear.php.net/package/Translation2
64
 * @see       /docs/gettext_readme.txt for an usage example
65
 */
66
class Translation2_Container_gettext extends Translation2_Container
67
{
68
    // {{{ class vars
69
 
70
    /**
71
     * domain bindings
72
     * @var array
73
     * @access private
74
     */
75
    var $_domains = array();
76
 
77
    /**
78
     * @var array
79
     * @access private
80
     */
81
    var $cachedDomains = array();
82
 
83
    /**
84
     * @var boolean
85
     * @access private
86
     */
87
    var $_native = false;
88
 
89
    // }}}
90
    // {{{ init
91
 
92
    /**
93
     * Initialize the container
94
     *
95
     * @param array $options gettext parameters
96
     *
97
     * @return boolean|PEAR_Error object if domains INI file doesn't exist
98
     */
99
    function init($options)
100
    {
101
        $this->_setDefaultOptions();
102
        $this->_parseOptions($options);
103
        $this->_native = (
104
            function_exists('gettext') &&
105
            (strtolower($this->options['file_type']) == 'mo') &&
106
            !$this->options['blank_on_missing']
107
        );
108
 
109
        $this->_domains = @parse_ini_file($this->options['domains_path_file']);
110
 
111
        if (!$this->_domains) {
112
            return $this->raiseError(sprintf(
113
                    'Cannot find domains INI file "%s" [%s on line %d]',
114
                    $this->options['domains_path_file'], __FILE__, __LINE__
115
                ),
116
                TRANSLATION2_ERROR_CANNOT_FIND_FILE
117
            );
118
        }
119
 
120
        if ($this->_native) {
121
            foreach ((array) $this->_domains as $domain => $path) {
122
                bindtextdomain($domain, $path);
123
            }
124
            textdomain($this->options['default_domain']);
125
        }
126
        $this->setLang($this->options['default_lang']);
127
 
128
        return true;
129
    }
130
 
131
    // }}}
132
    // {{{ _setDefaultOptions()
133
 
134
    /**
135
     * Set some default options
136
     *
137
     * @access private
138
     * @return void
139
     */
140
    function _setDefaultOptions()
141
    {
142
        $this->options['langs_avail_file']  = 'langs.ini';
143
        $this->options['domains_path_file'] = 'domains.ini';
144
        $this->options['default_domain']    = 'messages';
145
        $this->options['carriage_return']   = "\n";
146
        $this->options['file_type']         = 'mo';
147
        $this->options['default_lang']      = 'en';
148
        $this->options['default_encoding']  = 'iso-8859-1';
149
        $this->options['blank_on_missing']  = false;
150
    }
151
 
152
    // }}}
153
    // {{{ _switchLang()
154
 
155
    /**
156
     * Set the given langID
157
     *
158
     * @param string $langID new langID
159
     *
160
     * @return string previous langID
161
     * @access private
162
     */
163
    function _switchLang($langID)
164
    {
165
        $langID  = $this->_getLangID($langID);
166
        $oldLang = $this->currentLang['id'];
167
        $this->setLang($langID);
168
        return $oldLang;
169
    }
170
 
171
    // }}}
172
    // {{{ fetchLangs()
173
 
174
    /**
175
     * Fetch the available langs if they're not cached yet.
176
     *
177
     * @return void
178
     */
179
    function fetchLangs()
180
    {
181
        $this->langs = @parse_ini_file($this->options['langs_avail_file'], true);
182
        foreach ((array) $this->langs as $id => $lang) {
183
            $this->langs[$id]['id'] = $id;
184
        }
185
    }
186
 
187
    // }}}
188
    // {{{ setLang()
189
 
190
    /**
191
     * Sets the current lang
192
     *
193
     * @param string $langID language ID
194
     *
195
     * @return array language data
196
     */
197
    function setLang($langID)
198
    {
199
        if (!PEAR::isError($langData = parent::setLang($langID))) {
200
            I18Nv2::setLocale($langID);
201
        }
202
        return $langData;
203
    }
204
 
205
    // }}}
206
    // {{{ getPage()
207
 
208
    /**
209
     * Get all the strings from a domain (parsing the .mo file)
210
     *
211
     * @param string $pageID page/group ID
212
     * @param string $langID language ID
213
     *
214
     * @return array|PEAR_Error
215
     */
216
    function getPage($pageID = null, $langID = null)
217
    {
218
        $oldLang = $this->_switchLang($langID);
219
        $curLang = $this->currentLang['id'];
220
 
221
        if (empty($pageID) || $pageID == TRANSLATION2_DEFAULT_PAGEID) {
222
            $pageID = $this->options['default_domain'];
223
        }
224
 
225
        if (isset($this->cachedDomains[$curLang][$pageID])) {
226
            $this->_switchLang($oldLang);
227
            return $this->cachedDomains[$curLang][$pageID];
228
        }
229
 
230
        if (!isset($this->_domains[$pageID])) {
231
            $this->_switchLang($oldLang);
232
            return $this->raiseError(sprintf(
233
                    'The domain "%s" was not specified in the domains INI '.
234
                    'file "%s" [%s on line %d]', $pageID,
235
                    $this->options['domains_path_file'], __FILE__, __LINE__
236
                ),
237
                TRANSLATION2_ERROR_DOMAIN_NOT_SET
238
            );
239
        }
240
 
241
        include_once 'File/Gettext.php';
242
        $gtFile = &File_Gettext::factory($this->options['file_type']);
243
 
244
        $path = $this->_domains[$pageID] .'/'. $curLang .'/LC_MESSAGES/';
245
        $file = $path . $pageID .'.'. $this->options['file_type'];
246
 
247
        if (PEAR::isError($e = $gtFile->load($file))) {
248
            if (is_file($file)) {
249
                $this->_switchLang($oldLang);
250
                return $this->raiseError(sprintf(
251
                        '%s [%s on line %d]', $e->getMessage(), __FILE__, __LINE__
252
                    ),
253
                    TRANSLATION2_ERROR, PEAR_ERROR_RETURN
254
                );
255
            }
256
            $this->_switchLang($oldLang);
257
            return $this->raiseError(sprintf(
258
                    'Cannot find file "%s" [%s on line %d]',
259
                    $file, __FILE__, __LINE__
260
                ),
261
                TRANSLATION2_ERROR_CANNOT_FIND_FILE, PEAR_ERROR_RETURN
262
            );
263
        }
264
 
265
        $this->cachedDomains[$curLang][$pageID] = $gtFile->strings;
266
        $this->_switchLang($oldLang);
267
        return $gtFile->strings;
268
    }
269
 
270
    // }}}
271
    // {{{ getOne()
272
 
273
    /**
274
     * Get a single item from the container, without caching the whole page
275
     *
276
     * @param string $stringID string ID
277
     * @param string $pageID   page/group ID
278
     * @param string $langID   language ID
279
     *
280
     * @return string
281
     */
282
    function getOne($stringID, $pageID = null, $langID = null)
283
    {
284
        // native mode
285
        if ($this->_native) {
286
            $oldLang = $this->_switchLang($langID);
287
            $curLang = $this->currentLang['id'];
288
 
289
            if (empty($pageID) || $pageID == TRANSLATION2_DEFAULT_PAGEID) {
290
                $pageID = $this->options['default_domain'];
291
            }
292
 
293
            $string = dgettext($pageID, $stringID);
294
 
295
            $this->_switchLang($oldLang);
296
            return $string;
297
        }
298
 
299
        // use File_Gettext
300
        $page = $this->getPage($pageID, $langID);
301
        if (PEAR::isError($page = $this->getPage($pageID, $langID))) {
302
            if ($page->getCode() == TRANSLATION2_ERROR_CANNOT_FIND_FILE) {
303
                $page = array();
304
            } else {
305
                return $this->raiseError($page->getMessage(), $page->getCode());
306
            }
307
        }
308
 
309
        // return original string if there's no translation available
310
        if (isset($page[$stringID]) && strlen($page[$stringID])) {
311
            return $page[$stringID];
312
        } else if (false == $this->options['blank_on_missing']) {
313
            return $stringID;
314
        } else {
315
            return '';
316
        }
317
    }
318
 
319
    // }}}
320
    // {{{ getStringID()
321
 
322
    /**
323
     * Get the stringID for the given string
324
     *
325
     * @param string $string string
326
     * @param string $pageID page/group ID
327
     *
328
     * @return string|PEAR_Error
329
     */
330
    function getStringID($string, $pageID = null)
331
    {
332
        if (empty($pageID) || $pageID == TRANSLATION2_DEFAULT_PAGEID) {
333
            $pageID = $this->options['default_domain'];
334
        }
335
 
336
        if (!array_key_exists($pageID, $this->_domains)) {
337
            return $this->raiseError(sprintf(
338
                    'The domain "%s" was not specified in the domains '.
339
                    'INI file "%s" [%s on line %d]', $pageID,
340
                    $this->options['domains_path_file'], __FILE__, __LINE__
341
                ),
342
                TRANSLATION2_ERROR_DOMAIN_NOT_SET
343
            );
344
        }
345
 
346
        return array_search($string, $this->getPage($pageID));
347
    }
348
 
349
    // }}}
350
}
351
?>