root/trunk/lib/SGL/Translation.php

Revision 3125, 15.9 kB (checked in by demian, 3 weeks ago)

bugfix to trunk merge -3

  • Property svn:eol-style set to native
Line 
1 <?php
2 /* Reminder: always indent with 4 spaces (no tabs). */
3 // +---------------------------------------------------------------------------+
4 // | Copyright (c) 2006, Demian Turner                                         |
5 // | All rights reserved.                                                      |
6 // |                                                                           |
7 // | Redistribution and use in source and binary forms, with or without        |
8 // | modification, are permitted provided that the following conditions        |
9 // | are met:                                                                  |
10 // |                                                                           |
11 // | o Redistributions of source code must retain the above copyright          |
12 // |   notice, this list of conditions and the following disclaimer.           |
13 // | o 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 // | o The names of the authors may not be used to endorse or promote          |
17 // |   products derived from this software without specific prior written      |
18 // |   permission.                                                             |
19 // |                                                                           |
20 // | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
21 // | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT         |
22 // | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR     |
23 // | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT      |
24 // | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     |
25 // | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT          |
26 // | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     |
27 // | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY     |
28 // | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT       |
29 // | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE     |
30 // | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.      |
31 // |                                                                           |
32 // +---------------------------------------------------------------------------+
33 // | Seagull 0.6                                                               |
34 // +---------------------------------------------------------------------------+
35 // | Translation.php                                                           |
36 // +---------------------------------------------------------------------------+
37 // | Author:   Alexander J. Tarachanowicz II <ajt@localhype.net>               |
38 // +---------------------------------------------------------------------------+
39 // $Id: Translation.php,v 1.0 2005/05/11 00:00:00 demian Exp $
40
41 /**
42  * A wrapper to PEAR Translation2.
43  *
44  * @package SGL
45  * @author  Alexander J. Tarachanowicz II <ajt@localhype.net>
46  * @version $Revision: 1.0 $
47  */
48
49 class SGL_Translation
50 {
51     /**
52      * Generate singleton for PEAR::Tranlation2
53      *
54      * Object types:
55      *  o translation (default)
56      *  o admin - translation2_admin
57      * Storage drivers: (Set in global config under site)
58      *  o single - all translations in a single table (translations)
59      *  o multiple (default) - all translations in a seperate table
60      * (translation_en, translation_pl, translation_de)
61      *
62      * @static
63      * @access  public
64      * @param   string  $lang           language to return translations
65      * @param   string  $type           type of object: translation or admin
66      * @return  object  $translation    Translation2 object
67      *
68      *
69      */
70     function &singleton($type = 'translation')
71     {
72         static $instance;
73
74         // If the instance exists, return one
75         if (isset($instance[$type])) {
76             return $instance[$type];
77         }
78
79         $c      = &SGL_Config::singleton();
80         $conf   = $c->getAll();
81         $dbh    = SGL_DB::singleton();
82
83         //  set translation table parameters
84         $params = array(
85             'langs_avail_table' => $conf['db']['prefix'] . 'langs',
86             'lang_id_col'       => 'lang_id',
87             'lang_name_col'     => 'name',
88             'lang_meta_col'     => 'meta',
89             'lang_errmsg_col'   => 'error_text',
90             'lang_encoding_col' => 'encoding',
91             'string_id_col'      => 'translation_id',
92             'string_page_id_col' => 'page_id',
93             'string_text_col'    => '%s'  //'%s' will be replaced by the lang code
94         );
95
96         //  set translation driver
97         $driver = 'DB';
98
99         //  create translation storage tables
100         if ($conf['translation']['container'] == 'db') {
101
102             $prefix = $conf['db']['prefix'] .
103                 $conf['translation']['tablePrefix'] . '_';
104             $aLangs = explode(',', $conf['translation']['installedLanguages']);
105
106             //  set params
107             foreach ($aLangs as $lang) {
108                 $params['strings_tables'][$lang] = $prefix . $lang;
109             }
110         } else {
111             SGL::raiseError('translation table not specified check global config ',
112                 SGL_ERROR_INVALIDCONFIG, PEAR_ERROR_DIE);
113         }
114
115         //  instantiate selected translation2 object
116         switch (strtolower($type)) {
117
118         case 'admin':
119             require_once 'Translation2/Admin.php';
120             $instance[$type] = &Translation2_Admin::factory($driver, $dbh, $params);
121             break;
122
123         case 'translation':
124         default:
125             require_once 'Translation2.php';
126             $instance[$type] = &Translation2::factory($driver, $dbh, $params);
127         }
128         return $instance[$type];
129     }
130
131     /**
132      * Clear translation2 and GUI cache
133      *
134      * @static
135      * @access  public
136      *
137      * @return  boolean     true on success/false on failure
138      */
139     function clearCache()
140     {
141         $c = &SGL_Config::singleton();
142         $conf = $c->getAll();
143
144         if ('db' == $conf['translation']['container']) {
145             //   clear Translation2 cache
146             $trans = SGL_Translation::singleton('admin');
147             $trans->options['cacheOptions']['cacheDir'] = SGL_TMP_DIR .'/';
148             $trans->options['cacheOptions']['defaultGroup'] = 'translation';
149             return $trans->cleanCache();
150         } else {
151             //   clear file GUI cache
152             return SGL_Translation::clearGuiTranslationsCache();
153         }
154     }
155
156     /**
157      * Clear GUI Translations cache
158      *
159      * @static
160      * @access  public
161      *
162      * @return boolean      true on success/false on failure
163      */
164     function clearGuiTranslationsCache()
165     {
166         $c = &SGL_Config::singleton();
167
168         $aLangs = $aLangs = explode(',', $this->conf['translation']['installedLanguages']);
169
170         if (count($aLangs) > 0) {
171             $cache = & SGL_Cache::singleton();
172             $cache->setOption('cacheDir', SGL_TMP_DIR .'/');
173
174             $success = true;
175             foreach ($aLangs as $group) {
176                 $result = SGL_Cache::clear('translation_'. $group);
177                 $success = $success && $result;
178             }
179             return $success;
180         }
181     }
182
183     /**
184      * Returns a dictionary of translated strings.
185      *
186      * @static
187      * @param string $module
188      * @param string $lang
189      * @return array
190      */
191     function getGuiTranslationsFromFile($module, $lang)
192     {
193         //  fetch translations from database and cache
194         $cache = & SGL_Cache::singleton();
195         $lang = SGL_Translation::transformLangID($lang, SGL_LANG_ID_SGL);
196
197         //  returned cached translations else fetch from db and cache
198         if ($serialized = $cache->get($module, 'translation_'. $lang)) {
199             $words = unserialize($serialized);
200             SGL::logMessage('translations from cache', PEAR_LOG_DEBUG);
201             return $words;
202
203         } else {
204
205             //  fetch available languages
206             $aLanguages = $GLOBALS['_SGL']['LANGUAGE'];
207
208             //  build global lang file
209             $langID = str_replace('_', '-', $lang);
210             $language = @$aLanguages[$langID][1];
211             $globalLangFile = $language .'.php';
212             $path = SGL_MOD_DIR . '/' . $module . '/lang/';
213             if (is_readable($path . $globalLangFile)) {
214                 include $path . $globalLangFile;
215                 if ($module == 'default') {
216                     $words = &$defaultWords;
217                 }
218                 if (isset($words) && !empty($words)) {
219                     $serialized = serialize($words);
220                     $cache->save($serialized, $module, 'translation_'. $lang);
221                     SGL::logMessage('translations from file', PEAR_LOG_DEBUG);
222                     return $words;
223                 } else {
224                     return array();
225                 }
226             } elseif ($module == 'default') {
227                 SGL::raiseError('could not locate the global language file', SGL_ERROR_NOFILE);
228             } else {
229                 return array();
230             }
231         }
232     }
233
234     /**
235      * Update GUI Translations.
236      *
237      * @static
238      * @param array $aTrans hash containing tranlsations to be updated
239      * @param string $langID language id
240      * @param string $module module
241      *
242      * @return boolean true on success and PEAR Error on failure
243      */
244
245     function updateGuiTranslations($module, $langID, $aTrans)
246     {
247         switch (strtolower($this->conf['translation']['container'])) {
248         case 'db':
249             require_once SGL_CORE_DIR . '/Translation.php';
250             $trans = &SGL_Translation::singleton('admin');
251
252             $langID = SGL_Translation::transformLangID($langID, SGL_LANG_ID_TRANS2);
253
254             foreach ($aTrans as $key => $value) {
255                 $string = array($langID => $value);
256                 $result = $trans->add(stripslashes($key), $module, $string);
257
258                 if (is_a($result, 'PEAR_Error')) {
259                     return $result;
260                 }
261             }
262             return true;
263         case 'file':
264         default:
265             //  read translation data and get reference to root
266             $c = new Config();
267             foreach ($aTrans as $key => $value) {
268                 $aTransStrip[stripslashes($key)] = $value;
269             }
270             $root = & $c->parseConfig($aTransStrip, 'phparray');
271
272             $langID = SGL_Translation::transformLangID($langID, SGL_LANG_ID_SGL);
273
274             //  write translation to file
275             $filename = SGL_MOD_DIR . '/' . $module . '/lang/' .
276                 $GLOBALS['_SGL']['LANGUAGE'][$langID][1] . '.php';
277             $arrayName = ($module == 'default') ? 'defaultWords' : 'words';
278             $result = $c->writeConfig($filename, 'phparray', array('name' => $arrayName));
279             if (is_a($result, 'PEAR_Error')) {
280                 return $result;
281             }
282             return true;
283         }
284     }
285
286     /**
287      * Returns a dictionary of translated strings from the db.
288      *
289      * @static
290      * @param string $module
291      * @param string $lang
292      * @param string $fallbackLang
293      * @return array
294      */
295     function getTranslations($module, $lang, $fallbackLang = false)
296     {
297         $c = &SGL_Config::singleton();
298         $conf = $c->getAll();
299
300         if (!empty($module) && !empty($lang)) {
301             $lang = SGL_Translation::transformLangID($lang, SGL_LANG_ID_TRANS2);
302             $installedLangs = explode(',', $conf['translation']['installedLanguages']);
303
304             if ($conf['translation']['container'] == 'db'
305                 && in_array($lang, $installedLangs)) {
306                 //  instantiate translation2 object
307                 $translation = &SGL_Translation::singleton();
308
309                 //  set language
310                 $langInstalled = $translation->setLang($lang);
311
312                 //  set translation group
313                 $translation->setPageID($module);
314
315                 //  create decorator for fallback language
316                 if ($fallbackLang) {
317                     $fallbackLang = (is_string($fallbackLang))
318                         ? $fallbackLang
319                         : $conf['translation']['fallbackLang'];
320
321                     $translation = & $translation->getDecorator('Lang');
322                     $translation->setOption('fallbackLang', $fallbackLang);
323                 }
324                 //  instantiate cachelite decorator and set options
325                 if ($conf['cache']['enabled']) {
326                     $translation = &$translation->getDecorator('CacheLiteFunction');
327                     $translation->setOption('cacheDir', SGL_TMP_DIR .'/');
328                     $translation->setOption('lifeTime', $conf['cache']['lifetime']);
329                     $translation->setOption('defaultGroup', 'translation');
330                 }
331
332                 //  fetch translations
333                 $words = ($words = $translation->getPage()) ? $words : array();
334
335                 SGL::logMessage('translations from db for '. $module, PEAR_LOG_DEBUG);
336                 return $words;
337             } elseif ($conf['translation']['container'] == 'file') {
338                 return  SGL_Translation::getGuiTranslationsFromFile($module, $lang);
339             } else {
340                 return array();
341             }
342         } else {
343             return SGL::raiseError('Incorrect parameter passed to '.__CLASS__.'::'.__FUNCTION__,
344                 SGL_ERROR_INVALIDARGS);
345         }
346     }
347
348     /**
349      * Returns language ID for currently active lang.
350      *
351      * @static
352      * @return string
353      */
354     function getLangID()
355     {
356         if ($langID = str_replace('-', '_', SGL::getCurrentLang() .'_'. $GLOBALS['_SGL']['CHARSET'])) {
357             return $langID;
358         } else {
359             $c = &SGL_Config::singleton();
360             $conf = $c->getAll();
361             return $conf['translation']['fallbackLang'];
362         }
363     }
364
365     /**
366      * Returns default lang as set in installer.
367      *
368      * @static
369      * @return string
370      */
371     function getFallbackLangID()
372     {
373         $c = &SGL_Config::singleton();
374         $conf = $c->getAll();
375         return $conf['translation']['fallbackLang'];
376     }
377
378     /**
379      * Transform langID to opposite format
380      *
381      * SGL_LANG_ID_SGL - en-iso-8859-15
382      * SGL_LANG_ID_TRANS2 - en_iso_8859_15
383      *
384      * @static
385      * @param string langID language id
386      * @param int format language id format
387      * @return langID string
388      */
389      function transformLangID($langID, $format = null)
390      {
391         $c = &SGL_Config::singleton();
392         $conf = $c->getAll();
393
394         if (isset($format)) {
395             $langID = ($format == SGL_LANG_ID_SGL)
396                 ? str_replace('_', '-', $langID)
397                 : str_replace('-', '_', $langID);
398
399             return $langID;
400         } else {
401             $langID = (strstr($langID, '-'))
402                 ? str_replace('-', '_', $langID)
403                 : str_replace('_', '-', $langID);
404             return $langID;
405         }
406     }
407
408     /**
409      * Remove all translations for all languages for specified module.
410      *
411      * @static
412      * @param  string  $moduleName  module/page name
413      * @return boolean
414      */
415     function removeTranslations($moduleName)
416     {
417         $trans  = &SGL_Translation::singleton('admin');
418         $aPages = $trans->getPageNames();
419         if (PEAR::isError($aPages)) {
420             return $aPages;
421         }
422         if (!in_array($moduleName, $aPages)) {
423             return false; // no translations
424         }
425         $aLangs = $trans->getLangs('ids');
426         if (PEAR::isError($aLangs)) {
427             return $aLangs;
428         }
429         $aStrings = array();
430         foreach ($aLangs as $langId) {
431             $ret = SGL_Translation::getTranslations($moduleName, $langId);
432             $aStrings = array_merge($aStrings, array_keys($ret));
433         }
434         foreach ($aStrings as $stringId) {
435             $ret = $trans->remove($stringId, $moduleName);
436             if (PEAR::isError($ret)) {
437                 return $ret;
438             }
439         }
440         return true;
441     }
442 }
443 ?>
Note: See TracBrowser for help on using the browser.