]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/plugin/_WikiTranslation.php
more translations
[SourceForge/phpwiki.git] / lib / plugin / _WikiTranslation.php
1 <?php // -*-php-*-
2 rcs_id('$Id: _WikiTranslation.php,v 1.5 2004-03-17 15:38:03 rurban Exp $');
3 /*
4  Copyright 2004 $ThePhpWikiProgrammingTeam
5
6  This file is part of PhpWiki.
7
8  PhpWiki is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  PhpWiki is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with PhpWiki; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 /**
24  * _WikiTranslation:  Display pagenames and other strings in various languages.
25  * Can be used to let a favorite translation service translate a whole page. 
26  * Current favorite: translate.google.com if from_lang = en or fr
27  *
28  * Examples:
29  *  <?plugin _WikiTranslation page=HomePage languages=fr ?>
30  *     Translation service for HomePage into french (redirect to translate.google.com)
31  *  <?plugin _WikiTranslation what=pages ?>
32  *     Translation matrix of all pages with proper translations (all in pgsrc)
33  *  <?plugin _WikiTranslation what=wikiwords match="W*" limit=20 ?>
34  *     Translation matrix of the first 20 wikiwords matching "W*"
35  *  <?plugin _WikiTranslation string=HomePage languages=fr,de,sv ?>
36  *     Translation matrix for all given languages
37  *  <?plugin _WikiTranslation string=HomePage ?>
38  *     Translation matrix for all supported languages
39  *  <?plugin _WikiTranslation string=HomePage languages=fr ?>
40  *     Just return the translated string for this language.
41  *
42  * @author:  Reini Urban
43  */
44
45 /* Container for untranslated pagenames. Needed to show up in locale/po/phpwiki.pot */
46 $pgsrc_container = 
47     _("AddCommentPlugin")  .','.
48     _("AddingPages")  .','.
49     _("AuthorHistoryPlugin") .','.
50     _("BackLinks") .','.
51     _("CalendarListPlugin") .','.
52     _("CalendarPlugin") .','.
53     _("CategoryCategory")  .','.
54     _("CategoryHomePages")  .','.
55     _("CommentPlugin")  .','.
56     _("CreateTocPlugin")  .','.
57     _("DebugInfo") .','.
58     _("EditMetaDataPlugin") .','.
59     _("ExternalSearchPlugin") .','.
60     _("FindPage") .','.
61     _("FrameIncludePlugin") .','.
62     _("FullRecentChanges") .','.
63     _("HelloWorldPlugin") .','.
64     _("HomePageAlias") .','.
65     _("IncludePagePlugin") .','.
66     _("InterWiki") .','.
67     _("LinkIcons") .','.
68     _("MagicPhpWikiURLs") .','.
69     _("MoreAboutMechanics") .','.
70     _("NewMarkupTestPage") .','.
71     _("OldMarkupTestPage") .','.
72     _("OldStyleTablePlugin") .','.
73     _("PageDump") .','.
74     _("PageGroupTest") .','.
75     _("PageGroupTestFour") .','.
76     _("PageGroupTestOne") .','.
77     _("PageGroupTestThree") .','.
78     _("PageGroupTestTwo") .','.
79     _("PgsrcTranslation") .','.
80     _("PhotoAlbumPlugin") .','.
81     _("PhpHighlightPlugin") .','.
82     _("PhpWeatherPlugin") .','.
83     _("PhpWiki") .','.
84     _("PhpWikiAdministration/Chmod") .','.
85     _("PhpWikiAdministration/Remove") .','.
86     _("PhpWikiAdministration/Rename") .','.
87     _("PhpWikiAdministration/Replace") .','.
88     _("PhpWikiDocumentation") .','.
89     _("PhpWikiPoll") .','.
90     _("RawHtmlPlugin") .','.
91     _("RecentVisitors") .','.
92     _("RedirectToPlugin") .','.
93     _("ReleaseNotes") .','.
94     _("RichTablePlugin") .','.
95     _("SteveWainstead") .','.
96     _("SystemInfoPlugin") .','.
97     _("TranscludePlugin") .','.
98     _("TranslateText") .','.
99     _("UnfoldSubpagesPlugin") .','.
100     _("UpLoad") .','.
101     _("WabiSabi") .','.
102     _("WikiBlogPlugin") .','.
103     _("WikiPlugin") .','.
104     _("WikiWikiWeb");
105  
106 require_once('lib/PageList.php');
107
108 class WikiPlugin__WikiTranslation
109 extends WikiPlugin
110 {
111
112     function getName() {
113         return _("_WikiTranslation");
114     }
115
116     function getDescription() {
117         return _("Show translations of various words or pages");
118     }
119
120     function getVersion() {
121         return preg_replace("/[Revision: $]/", '',
122                             "\$Revision: 1.5 $");
123     }
124
125     function getDefaultArguments() {
126         return 
127             array( 'languages'  => '',  // comma delimited string of de,en,sv,...
128                    'string'     => '',  
129                    'page'       => '',  // use a translation service
130                    'what'       => 'pages', // or 'buttons', 'plugins' or 'wikiwords'
131
132                    'match'         => '*',
133                    'from_lang'     => false,
134                    'include_empty' => false,
135                    'exclude'       => '',
136                    'sortby'        => '',
137                    'limit'         => 0,
138                    'debug'         => false
139                  );
140     }
141
142     function init_locale($lang) {
143         if ($lang != $this->lang)
144             update_locale($lang);
145         // gettext module loaded: must load the LC_MESSAGES php hash
146         if (function_exists ('bindtextdomain')) {
147             include (FindLocalizedFile("LC_MESSAGES/phpwiki.php", 0,'reinit'));
148         } elseif ($lang == 'en') {
149             //hack alert! we need hash for stepping through it, even if it's in the wrong language
150             include (FindFile("locale/de/LC_MESSAGES/phpwiki.php", 0,'reinit'));
151             foreach ($locale as $en => $de) {
152                 $locale[$en] = $en;
153             }
154         // we already have a $locale, but maybe it's in the wrong language
155         } elseif ($lang != $this->lang or empty($GLOBALS['locale'])) {
156             include (FindFile("LC_MESSAGES/phpwiki.php", 0,'reinit'));
157         } else {
158            $locale = & $GLOBALS['locale'];
159         }
160         $this->_locales[$lang] = $locale;
161     }
162
163     // reverse translation: 
164     function translate_to_en($text,$lang=false) {
165         if (!$lang) $lang = $this->lang; // current locale
166         if ($lang == 'en') return $text;
167
168         $this->_locales = array();
169         $this->_reverse_locales = array();
170
171         if (!isset($this->_locales[$lang])) {
172             $this->init_locale($lang);
173         }
174         assert(!empty($this->_locales[$lang]));
175         if (!isset($this->_reverse_locales[$lang])) {
176             // and now do a reverse lookup in the $locale hash
177             $this->_reverse_locales[$lang] = array_flip($this->_locales[$lang]);
178         }
179         if (!empty($this->_reverse_locales[$lang][$text])) {
180             return $this->_reverse_locales[$lang][$text];
181         } else {
182             return $text;
183         }
184     }
185
186     function translate($text,$to_lang,$from_lang=false) {
187         if (!$from_lang) $from_lang = $this->lang; // current locale
188         if ($from_lang == $to_lang) return $text;
189         // speed up hash lookup. not needed for gettext module
190         if (!isset($this->_locales[$from_lang]) and !function_exists('bindtextdomain')) {
191             $this->init_locale($from_lang);
192         }
193         if ($from_lang != 'en') {
194             // get reverse gettext: translate to english
195             $en = $this->translate_to_en($text,$from_lang);
196             // and then to target
197             update_locale($to_lang);
198             $result = gettext($en);
199             update_locale($from_lang);
200         } else {
201             if ($from_lang != $to_lang) {
202                 update_locale($to_lang);
203             }
204             $result = gettext($text);
205             if ($from_lang != $to_lang) {
206                 update_locale($from_lang);
207             }
208         }
209         return $result;
210     }
211                 
212     function run($dbi, $argstr, $request, $basepage) {
213         extract($this->getArgs($argstr, $request));
214         $this->request = &$request;
215         if (!$from_lang) $from_lang = $request->getPref('lang');
216         if (!$from_lang) $from_lang = $GLOBALS['LANG'];
217         $this->lang = $from_lang;
218
219         if (empty($languages)) {
220             // from lib/plugin/UserPreferences.php
221             $available_languages = array();
222             if ($from_lang != 'en')
223                 array_push($available_languages, 'en');
224             $dir_root = 'locale/';
225             if (defined('PHPWIKI_DIR'))
226                 $dir_root = PHPWIKI_DIR . "/$dir_root";
227             $dir = dir($dir_root);
228             if ($dir) {
229                 while ($entry = $dir->read()) {
230                     if (is_dir($dir_root.$entry)
231                         && (substr($entry,0,1) != '.')
232                         && $entry != 'po'
233                         && $entry != $from_lang
234                         && $entry != 'CVS') {
235                         array_push($available_languages, $entry);
236                     }
237                 }
238                 $dir->close();
239             }
240             if (in_array($from_lang,$available_languages))
241                 $languages = $available_languages;
242             else
243                 $languages = array_merge($available_languages,array($from_lang));
244         } elseif (strstr($languages,',')) {
245             $languages = explode(',',$languages);
246         } else {
247             $languages = array($languages);
248         }
249         $to_lang = $languages[0];
250         if (!empty($string) and count($languages)==1) {
251             return $this->translate($string,$to_lang,$from_lang);
252         }
253         if (!empty($page)) {
254             $pagename = $page;
255             if ($dbi->isWikiPage($pagename)) {
256                 $url = '';
257                 // google can only translate from english and french
258                 if (in_array($from_lang,array('en','fr'))) {
259                     $url = "http://translate.google.com/translate";
260                     $url .= "?langpair=" . urlencode($from_lang."|".$to_lang);
261                     $url .= "&u=" . urlencode(WikiUrl($pagename,false,true));
262                 }
263                 // redirect or transclude?
264                 if ($url)
265                     return $request->redirect($url);
266                 return HTML(fmt("TODO: Google can only translate from english and french. Find a translation service for %s to language %s",
267                                 WikiUrl($pagename,false,true),
268                                 $to_lang));
269             } else
270                 return $this->error(fmt("%s is empty",$pagename));
271         }
272         
273         $pagelist = new PageList('', $exclude, $this->getArgs($argstr, $request));
274         $pagelist->_columns[0]->_heading = "$from_lang";
275         foreach ($languages as $lang) {
276             if ($lang == $from_lang) continue;
277             $field = "custom:$lang";
278             $column = new _PageList_Column_custom($field,$from_lang,$this);
279             $pagelist->_types["custom"] = $column;
280             $pagelist->_addColumn($field);
281         }
282         if (!empty($string)) {
283             $pagelist->addPage( $string );
284             return $pagelist;
285         }
286         switch ($what) {
287         case 'allpages':
288             $pagelist->addPages( $dbi->getAllPages($include_empty, $sortby, $limit) );
289             break;
290         case 'pages':
291             // not all pages, only the pgsrc pages
292             if (!is_array($exclude))
293                 $exclude = $pagelist->explodePageList($exclude,false,$sortby,$limit);
294             $path = FindLocalizedFile(WIKI_PGSRC);
295             $pgsrc = new fileSet($path);
296             foreach ($pgsrc->getFiles($exclude,$sortby,$limit) as $pagename) {
297                 $pagename = urldecode($pagename);
298                 if (substr($pagename,-1,1) == '~') continue;
299                 if (in_array($pagename, $exclude))
300                     continue;             // exclude page.
301                 if ($match != '*' and !glob_match($match,$pagename))
302                     continue;
303                 $page_handle = $dbi->getPage($pagename);
304                 $pagelist->addPage( $page_handle );
305             }
306             break;
307         case 'wikiwords':
308             if (!isset($this->_locales[$from_lang])) {
309                 $this->init_locale($from_lang);
310             }
311             $locale = & $this->_locales[$from_lang];
312             if (is_array($locale)) {
313                 $count = 0;
314                 foreach ($locale as $from => $to) {
315                     if ($match != '*' and !glob_match($match,$from))
316                         continue;
317                     if (isWikiWord($from)) {
318                         $count++;
319                         $pagelist->addPage( $from );
320                         if ($limit and $count > $limit) break;
321                     }
322                 }
323             }
324             break;
325         }
326         return $pagelist;
327     }
328 };
329
330 class _PageList_Column_custom extends _PageList_Column {
331     function _PageList_Column_custom($field, $from_lang, $plugin) {
332         $this->_field = $field;
333         $this->_from_lang = $from_lang;
334         $this->_plugin =& $plugin;
335         $this->_iscustom = substr($field, 0, 7) == 'custom:';
336         if ($this->_iscustom)
337             $this->_field = substr($field, 7);
338         $heading = $field;
339         $this->dbi = &$GLOBALS['request']->getDbh();
340         $this->_PageList_Column_base($field);
341     }
342     
343     function _getValue($page, &$revision_handle) {
344         if (is_object($page)) $text = $page->getName();
345         else $text = $page;
346         $trans = $this->_plugin->translate($text, $this->_field, $this->_from_lang);
347         // how to markup untranslated words and not existing pages?
348         // untranslated: (TODO) link to translation editor
349         if ($trans == $text or // untranslated
350             (($this->_from_lang != 'en') and 
351              ($this->_field != 'en') and
352              ($trans == $this->_plugin->translate($text, 'en', $this->_from_lang))
353              ))
354         {    
355             global $Theme;
356             $link = $Theme->linkUnknownWikiWord($trans);
357             if ($this->dbi->isWikiPage($trans)) {
358                 $url = WikiURL($trans, array('action' => 'TranslateText','lang' => $this->_field));
359                 $button = $Theme->makeButton('T', $url);
360                 $button->addTooltip(sprintf(_("Define the translation for %s in %s"), $trans, $this->_field));
361                 $link = HTML::span($button);
362                 $link->setAttr('class', 'wikiunknown');
363                 $text = HTML::span($Theme->maybeSplitWikiWord($trans));
364                 $text->setAttr('style', 'text-decoration:line-through');
365                 $link->pushContent($text);
366                 return $link;
367             } elseif (is_object($page))
368                 return '';
369             else                        // not existing: empty
370                 return '';
371         } elseif (is_object($page)) {
372             return WikiLink($trans,'auto');
373         } else {
374             return $trans;
375         }
376     }
377 }
378
379 // $Log: not supported by cvs2svn $
380 // Revision 1.4  2004/03/17 13:20:31  rurban
381 // Placeholder for all yet untranslated pgsrc pagenames. Add german translations of these.
382 //
383 // Revision 1.3  2004/03/16 20:22:32  rurban
384 // added link to TranslateText action
385 //
386 // Revision 1.2  2004/03/16 15:47:27  rurban
387 // added match, fixed reverse translation, added page=, what=allpages, what=wikiwords, fixed what=pages, simplified _PageList_Column_custom
388 //
389 // Revision 1.1  2004/03/14 16:45:10  rurban
390 // Just the page matrix for now.
391 // doesn't work yet, if the default langauge != en
392 //
393 //
394
395 // For emacs users
396 // Local Variables:
397 // mode: php
398 // tab-width: 8
399 // c-basic-offset: 4
400 // c-hanging-comment-ender-p: nil
401 // indent-tabs-mode: nil
402 // End:
403 ?>