root/trunk/modules/default/classes/TranslationMgr.php

Revision 2284 (checked in by demian, 2 months ago)

cleaned up DA_Default

  • 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 // | TranslationMgr.php                                                        |
36 // +---------------------------------------------------------------------------+
37 // | Author: Demian Turner <demian@phpkitchen.com>                             |
38 // |         Werner M. Krauss <werner.krauss@hallstatt.net>                    |
39 // |         Alexander J. Tarachanowicz II <ajt@localhype.net>                 |
40 // +---------------------------------------------------------------------------+
41 // $Id: TranslationMgr. v 1.0 2005/04/17 02:15:02 demian Exp $
42
43 require_once 'Config.php';
44 require_once SGL_MOD_DIR  . '/default/classes/DA_Default.php';
45
46 /**
47  * Provides tools preform translation maintenance.
48  *
49  * @package default
50  * @author  Demian Turner <demian@phpkitchen.com>
51  * @version $Revision: 1.56 $
52  * @since   PHP 4.1
53  */
54
55 class TranslationMgr extends SGL_Manager
56 {
57     function TranslationMgr()
58     {
59         SGL::logMessage(null, PEAR_LOG_DEBUG);
60         parent::SGL_Manager();
61
62         $this->pageTitle    = 'Translation Maintenance';
63         $this->template     = 'translationMgr.html';
64         $this->redirect     = true;
65         $this->da           = & DA_Default::singleton();
66
67         $this->_aActionsMapping =  array(
68             'verify'    => array('verify', 'redirectToDefault'),
69             'edit'      => array('edit'),
70             'update'    => array('update', 'redirectToDefault'),
71             'append'    => array('append', 'redirectToDefault'),
72             'checkAllModules' => array('checkAllModules'),
73             'list'      => array('list'),
74         );
75     }
76
77     function validate($req, &$input)
78     {
79         SGL::logMessage(null, PEAR_LOG_DEBUG);
80
81         $this->validated    = true;
82         $input->pageTitle   = $this->pageTitle;
83         $input->masterTemplate = $this->masterTemplate;
84         $input->template    = $this->template;
85         $input->submit      = $req->get('submitted');
86         $input->action      = ($req->get('action'))
87             ? $req->get('action')
88             : 'list';
89         $input->aTranslation = $req->get('translation');
90
91         //  get current module, check session
92         $input->currentModule = $req->get('frmCurrentModule');
93         $sessLastModuleSelected = SGL_Session::get('lastModuleSelected');
94         if (!$input->currentModule && !$sessLastModuleSelected) {
95             $input->currentModule = 'default';
96         } elseif (!$input->currentModule) {
97             $input->currentModule = $sessLastModuleSelected;
98         } elseif ($input->action == 'checkAllModules') {
99
100             //  this one should be always ok. to avoid bad "file doesn't exist
101             //  messages from process()
102             $input->currentModule = 'default';
103         }
104
105         // get current lang, check session
106         $input->currentLang = ($req->get('frmCurrentLang'))
107             ? $req->get('frmCurrentLang')
108             : SGL_Session::get('lastLanguageSelected');
109
110         //  if both are empty get language from prefs
111         $input->currentLang = ($input->currentLang)
112             ? $input->currentLang
113             : $_SESSION['aPrefs']['language'];
114
115         //  add to session
116         SGL_Session::set('lastModuleSelected', $input->currentModule);
117         SGL_Session::set('lastLanguageSelected', $input->currentLang);
118
119         //  catch any single quotes
120         //  note: this is done by PEAR::Config automatically!
121         if (($req->get('action') !='update')
122             && ($req->get('action') !='append')) {
123             if (is_array($input->aTranslation)) {
124                 foreach ($input->aTranslation as $k => $v) {
125                     if (is_array($v)) {
126                         array_map('addslashes', $v);
127                     } else {
128                         $input->aTranslation[$k] = addslashes($v);
129                     }
130                 }
131             }
132         }
133
134         if ($input->submit) {
135             if ($req->get('action') =='' || $req->get('action') =='list') {
136                 $aErrors['noSelection'] = SGL_Output::translate('please specify an option');
137             }
138         }
139
140         //  if errors have occured
141         if (isset($aErrors) && count($aErrors)) {
142             SGL::raiseMsg('Please fill in the indicated fields');
143             $input->error = $aErrors;
144             $this->validated = false;
145         }
146         //  retrieve source translations
147         $aSourceLang = SGL_Translation::getTranslations($input->currentModule,
148             SGL_Translation::getFallbackLangID());
149         //  retrieve target translations
150         $aTargetLang = SGL_Translation::getTranslations($input->currentModule,
151             $input->currentLang);
152
153         //  if the target lang file does not exist
154         if ($this->conf['translation']['container'] == 'file') {
155             $curLang = SGL_Translation::transformLangID($input->currentLang, SGL_LANG_ID_SGL);
156             $target = SGL_MOD_DIR . '/' . $input->currentModule . '/lang/' .
157                 $GLOBALS['_SGL']['LANGUAGE'][$curLang][1] . '.php';
158
159             if (!is_file($target)) {
160                 $errMsg = SGL_String::translate('the target lang file') .
161                             ' '. $target .
162                             ' '. SGL_String::translate('does not exist.') .
163                             ' '. SGL_String::translate('Please create it.');
164                 SGL::raiseMsg($errMsg, false, SGL_ERROR_NOFILE);
165             }
166         }
167         $aTargetLang = SGL_Array::removeBlanks($aTargetLang);
168
169         if ($input->action != 'checkAllModules') {
170             //  if target has more keys than source
171             if (count($aSourceLang) && count($aTargetLang)
172                     && count($aTargetLang) > count($aSourceLang)) {
173                 $error = 'source trans has ' . count($aSourceLang) . ' keys<br />';
174                 $error .= 'target trans has ' . count($aTargetLang) . ' keys<br />';
175                 $error .= 'extra keys are:<br />';
176                 $aDiff = array_diff(array_keys($aTargetLang), array_keys($aSourceLang));
177                 foreach ($aDiff as $key => $value) {
178                     $error .= '['.$key.'] => '.$value.'<br />';
179                 }
180                 $error .= 'The translation file is probably contains more keys than the source';
181                 SGL::raiseMsg($error);
182             }
183             //  map to input for further processing
184             $input->aSourceLang = &$aSourceLang;
185             $input->aTargetLang = &$aTargetLang;
186         }
187     }
188
189     function display(&$output)
190     {
191         SGL::logMessage(null, PEAR_LOG_DEBUG);
192
193         //  get hash of all modules;
194         $output->aModules = $this->da->getModuleHash(SGL_RET_NAME_VALUE);
195
196         //  load available languages
197         $output->aLangs = ($this->conf['translation']['container'] == 'file')
198             ? SGL_Util::getLangsDescriptionMap()
199             : $this->trans->getLangs();
200         $output->isValidate = ($output->action == 'validate')? 'checked' : '';
201         $output->isEdit = ($output->action == 'edit')? 'checked' : '';
202
203         $output->currentLangName = $output->aLangs[$output->currentLang];
204     }
205
206     function _cmd_list(&$input, &$output)
207     {
208         SGL::logMessage(null, PEAR_LOG_DEBUG);
209     }
210
211     function _cmd_verify(&$input, &$output)
212     {
213         SGL::logMessage(null, PEAR_LOG_DEBUG);
214
215         if ($this->conf['translation']['container'] == 'file') {
216             $curLang = SGL_Translation::transformLangID($input->currentLang, SGL_LANG_ID_SGL);
217             $filename = SGL_MOD_DIR . '/' . $input->currentModule . '/lang/' .
218                 $GLOBALS['_SGL']['LANGUAGE'][$curLang][1] . '.php';
219
220             if (is_file($filename)) {
221                 if (!is_writeable($filename)) {
222                     $errMsg = SGL_String::translate('the target lang file') .
223                         ' '. $filename .
224                         ' '. SGL_String::translate('is not writeable.') .
225                         ' '. SGL_String::translate('Please change file permissions before editing.');
226                     SGL::raiseMsg($errMsg, false, SGL_ERROR_NOFILE);
227                     $this->redirect = true;
228                 }
229             } else {
230                 $errMsg = SGL_String::translate('the target lang file') .
231                             ' '. $filename .
232                             ' '. SGL_String::translate('does not exist.') .
233                             ' '. SGL_String::translate('Please create it.');
234                 SGL::raiseMsg($errMsg, false, SGL_ERROR_NOFILE);
235                 $this->redirect = false;
236             }
237         }
238
239         if (count($input->aSourceLang) && count($input->aTargetLang)) {
240             $aDiff = array_diff(array_keys($input->aSourceLang), array_keys($input->aTargetLang));
241
242             if (count($aDiff)) {
243                 $output->sourceElements = count($input->aSourceLang);
244                 $output->targetElements = count($input->aTargetLang);
245                 $output->template = 'langDiff.html';
246                 $output->aTargetLang = $aDiff;
247                 $output->currentModuleName = ucfirst($output->currentModule);
248
249                 //  bypass redirection
250                 $this->redirect = false;
251             } else {
252                 SGL::raiseMsg('Congratulations, the target translation' .
253                     ' appears to be up to date', true, SGL_MESSAGE_INFO);
254             }
255         }
256     }
257
258     function _cmd_edit(&$input, &$output)
259     {
260         SGL::logMessage(null, PEAR_LOG_DEBUG);
261
262         if ($this->conf['translation']['container'] == 'file') {
263             $curLang = SGL_Translation::transformLangID($input->currentLang, SGL_LANG_ID_SGL);
264             $filename = SGL_MOD_DIR . '/' . $input->currentModule . '/lang/' .
265                 $GLOBALS['_SGL']['LANGUAGE'][$curLang][1] . '.php';
266
267             if (is_file($filename)) {
268                 if (!is_writeable($filename)) {
269                     $errMsg = SGL_String::translate('the target lang file') .
270                         ' '. $filename .
271                         ' '. SGL_String::translate('is not writeable.') .
272                         ' '. SGL_String::translate('Please change file permissions before editing.');
273                     SGL::raiseMsg($errMsg, false, SGL_ERROR_NOFILE);
274                 }
275             } else {
276                 $errMsg = SGL_String::translate('the target lang file') .
277                             ' '. $filename .
278                             ' '. SGL_String::translate('does not exist.') .
279                             ' '. SGL_String::translate('Please create it.');
280                 SGL::raiseMsg($errMsg, false, SGL_ERROR_NOFILE);
281             }
282         }
283
284         $output->template = 'langEdit.html';
285         $output->currentModuleName = ucfirst($output->currentModule);
286     }
287
288     function _cmd_update(&$input, &$output)
289     {
290         SGL::logMessage(null, PEAR_LOG_DEBUG);
291
292         //  update translations
293         $curLang = $input->currentLang;
294         $ok      = SGL_Translation::updateGuiTranslations($input->currentModule,
295                         $curLang, $input->aTranslation);
296         if (!is_a($ok, 'PEAR_Error')) {
297             SGL::raiseMsg('translation successfully updated', true, SGL_MESSAGE_INFO);
298         } else {
299             SGL::raiseMsg('There was a problem updating the translation',
300                 SGL_ERROR_FILEUNWRITABLE);
301         }
302     }
303
304     function _cmd_append(&$input, &$output)
305     {
306         SGL::logMessage(null, PEAR_LOG_DEBUG);
307
308         // remove blanks and merge
309         $input->aTranslation = SGL_Array::removeBlanks($input->aTranslation);
310         $aTrans = array_merge($input->aTranslation,$input->aTargetLang);
311
312         //  update translations
313         $ok = SGL_Translation::updateGuiTranslations($input->currentModule,
314                 $input->currentLang, $aTrans);
315
316         if (!is_a($ok, 'PEAR_Error')) {
317             SGL::raiseMsg('translation successfully updated', true, SGL_MESSAGE_INFO);
318         } else {
319             SGL::raiseMsg('There was a problem updating the translation',
320                 SGL_ERROR_FILEUNWRITABLE);
321         }
322     }
323
324     function _cmd_checkAllModules(&$input, &$output)
325     {
326         SGL::logMessage(null, PEAR_LOG_DEBUG);
327         $output->template = 'langCheckAll.html';
328
329         //  get hash of all modules
330         $modules = $this->da->getModuleHash(SGL_RET_NAME_VALUE);
331
332         //  ok, now check each module
333         $status['1'] = 'ok';
334         $status['2'] = 'no file';
335         $status['3'] = 'new strings';
336         $status['4'] = 'old strings';
337
338         $fallbackLang = SGL_Translation::getFallbackLangID();
339         foreach ($modules as $name => $title) {
340             $aModules[$name]['title'] = $title;
341
342             //reset arrays
343             unset($aSourceLang);
344             unset($aTargetLang);
345             unset($words);
346             unset($defaultWords);
347
348             //get source array
349             $fbackLang = SGL_Translation::transformLangID($fallbackLang, SGL_LANG_ID_SGL);
350             $aModules[$name]['orig'] = SGL_MOD_DIR . '/' . $name . '/lang/' .
351                     $GLOBALS['_SGL']['LANGUAGE'][$fbackLang][1] . '.php';
352
353             $aSourceLang = ($words = SGL_Translation::getTranslations($name, $fallbackLang))
354                             ? $words
355                             : array();
356
357             //  hack to remove sub arrays from translations which cannot be handled by current system
358             unset($defaultWords, $words);
359
360             //  get target array
361             $curLang = SGL_Translation::transformLangID($input->currentLang, SGL_LANG_ID_SGL);
362             $aModules[$name]['src'] = SGL_MOD_DIR . '/' . $name. '/lang/' .
363                     $GLOBALS['_SGL']['LANGUAGE'][$curLang][1] . '.php';
364
365             $aTargetLang = ($words = SGL_Translation::getTranslations($name, $curLang))
366                             ? $words
367                             : array();
368
369             //  check status of target file
370             // 1: ok, all fields ok
371             // 2: targetfile doesn't exist
372             // 3: target has less entries than source
373             // 4: target has more entries than source
374
375             //  if the target lang file does not exist
376
377             if (!is_file($aModules[$name]['src'])){
378                 $aModules[$name]['status'] = $status['2'];
379             }
380
381             //  if target has less keys than source
382             elseif (array_diff(array_keys($aSourceLang),array_keys($aTargetLang))) {
383                 $aModules[$name]['status'] = $status['3'];
384                 $aModules[$name]['action'] = 'verify';
385                 $aModules[$name]['actionTitle'] = 'Validate';
386                 if ($this->conf['translation']['container'] == 'file'
387                     && !is_writeable($aModules[$name]['src'])) {
388                     $aModules[$name]['msg'] = "File not writeable";
389                 } else {
390                     $aModules[$name]['diff'] = true;
391                 }
392             }
393
394             //  if target has more keys than source
395             elseif (array_diff(array_keys($aTargetLang),array_keys($aSourceLang) )) {
396                 $aModules[$name]['status'] = $status['4'];
397                 $aModules[$name]['action']= 'edit';
398                 if ($this->conf['translation']['container'] == 'file'
399                     && !is_writeable($aModules[$name]['src'])) {
400                     $aModules[$name]['msg'] = "File not writeable";
401                 } else {
402                     $aModules[$name]['edit'] = true;
403                 }
404
405              }
406             //  so if there are no differences, everything should be ok
407             else {
408                 $aModules[$name]['status'] = $status['1'];
409                 $aModules[$name]['action']= 'edit';
410                 if ($this->conf['translation']['container'] == 'file'
411                     && !is_writeable($aModules[$name]['src'])) {
412                     $aModules[$name]['msg'] = "File not writeable";
413                 } else {
414                     $aModules[$name]['edit'] = true;
415                 }
416             }
417
418             //  remove empty array elements
419             $aTargetLang = @array_filter($aTargetLang, 'strlen');
420             $aSourceLang = @array_filter($aSourceLang, 'strlen');
421
422             $aSourceLang = array_keys($aSourceLang);
423             $aTargetLang = array_keys($aTargetLang);
424         }
425         $output->modules = $aModules;
426     }
427
428     function _cmd_redirectToDefault(&$input, &$output)
429     {
430         SGL::logMessage(null, PEAR_LOG_DEBUG);
431
432         //  if no errors have occured, redirect
433         if (!SGL_Error::count()) {
434             if (!($this->redirect)) {
435                 return;
436             } else {
437                 SGL_HTTP::redirect();
438             }
439
440         //  else display error with blank template
441         } else {
442             $output->template = 'docBlank.html';
443         }
444     }
445
446 }
447 ?>
448
Note: See TracBrowser for help on using the browser.