xref: /plugin/autotranslation/helper.php (revision 44552920f00280791acc895cfd1eae40e0daa42b)
1<?php
2/**
3 * Translation Plugin: Simple multilanguage plugin
4 *
5 * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6 * @author     Andreas Gohr <andi@splitbrain.org>
7 */
8
9// must be run within Dokuwiki
10if(!defined('DOKU_INC')) die();
11
12class helper_plugin_translation extends DokuWiki_Plugin {
13    var $trans       = array();
14    var $tns         = '';
15    var $defaultlang = '';
16
17    /**
18     * Initialize
19     */
20    function helper_plugin_translation(){
21        global $conf;
22        require_once(DOKU_INC.'inc/pageutils.php');
23        require_once(DOKU_INC.'inc/utf8.php');
24
25        // load wanted translation into array
26        $this->trans = strtolower(str_replace(',',' ',$this->getConf('translations')));
27        $this->trans = array_unique(array_filter(explode(' ',$this->trans)));
28        sort($this->trans);
29
30        // get default translation
31        if(!$conf['lang_before_translation']){
32          $dfl = $conf['lang'];
33        } else {
34          $dfl = $conf['lang_before_translation'];
35        }
36        if(in_array($dfl,$this->trans)){
37            $this->defaultlang = $dfl;
38        }else{
39            $this->defaultlang = '';
40            array_unshift($this->trans,'');
41        }
42
43
44        $this->tns = cleanID($this->getConf('translationns'));
45        if($this->tns) $this->tns .= ':';
46    }
47
48    /**
49     * return some info
50     */
51    function getInfo(){
52        return confToHash(dirname(__FILE__).'/info.txt');
53    }
54
55    /**
56     * Check if the given ID is a translation and return the language code.
57     */
58    function getLangPart($id){
59        $rx = '/^'.$this->tns.'('.join('|',$this->trans).'):/';
60        if(preg_match($rx,$id,$match)){
61            return $match[1];
62        }
63        return '';
64    }
65
66    /**
67     * Returns the browser language if it matches with one of the configured
68     * languages
69     */
70    function getBrowserLang(){
71        $rx = '/(^|,|:|;|-)('.join('|',$this->trans).')($|,|:|;|-)/i';
72        if(preg_match($rx,$_SERVER['HTTP_ACCEPT_LANGUAGE'],$match)){
73            return strtolower($match[2]);
74        }
75        return false;
76    }
77
78
79    /**
80     * Returns the ID and name to the wanted translation, empty
81     * $lng is default lang
82     */
83    function buildTransID($lng,$idpart){
84        global $conf;
85        global $saved_conf;
86        if($lng){
87            $link = ':'.$this->tns.$lng.':'.$idpart;
88            $name = $lng;
89        }else{
90            $link = ':'.$this->tns.$idpart;
91            if(!$conf['lang_before_translation']){
92              $name = $conf['lang'];
93            } else {
94              $name = $conf['lang_before_translation'];
95            }
96        }
97        return array($link,$name);
98    }
99
100    /**
101     * Check if current ID should be translated and any GUI
102     * should be shown
103     */
104    function istranslatable($id,$checkact=true){
105        global $ACT;
106
107        if($checkact && $ACT != 'show') return false;
108        if($this->tns && strpos($id,$this->tns) !== 0) return false;
109        $skiptrans = trim($this->getConf('skiptrans'));
110        if($skiptrans &&  preg_match('/'.$skiptrans.'/ui',':'.$id)) return false;
111        $meta = p_get_metadata($id);
112        if($meta['plugin']['translation']['notrans']) return false;
113
114        return true;
115    }
116
117    /**
118     * Displays the available and configured translations. Needs to be placed in the template.
119     */
120    function showTranslations(){
121        global $ID;
122        global $conf;
123        global $INFO;
124
125        if(!$this->istranslatable($ID)) return;
126
127        $this->checkage();
128
129        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
130        $idpart = preg_replace($rx,'',$ID);
131
132        $out  = '<div class="plugin_translation">';
133        $out .= '<span>'.$this->getLang('translations');
134        if($this->getConf('about')){
135            $out .= '<sup>'.html_wikilink($this->getConf('about'),'?').'</sup>';
136        }
137        $out .= ':</span> ';
138
139        if($this->getConf('dropdown')){ // use dropdown
140            if($INFO['exists']){
141                $class = 'wikilink1';
142            }else{
143                $class = 'wikilink2';
144            }
145            $out .= '<form action="'.wl().'" id="translation__dropdown">';
146            $out .= '<select name="id" class="'.$class.'">';
147            foreach($this->trans as $t){
148                list($link,$name) = $this->buildTransID($t,$idpart);
149                $link = cleanID($link);
150                if($ID == $link){
151                    $sel = ' selected="selected"';
152                }else{
153                    $sel = '';
154                }
155                if(page_exists($link,'',false)){
156                    $class = 'wikilink1';
157                }else{
158                    $class = 'wikilink2';
159                }
160                $out .= '<option value="'.$link.'"'.$sel.' class="'.$class.'">'.hsc($name).'</option>';
161            }
162            $out .= '</select>';
163            $out .= '<input name="go" type="submit" value="&rarr;" />';
164            $out .= '</form>';
165        }else{ // use list
166            $out .= '<ul>';
167            foreach($this->trans as $t){
168                list($link,$name) = $this->buildTransID($t,$idpart);
169                $out .= '  <li><div class="li">'.html_wikilink($link,$name).'</div></li>';
170            }
171            $out .= '</ul>';
172        }
173
174        $out .= '</div>';
175
176        return $out;
177    }
178
179    /**
180     * Checks if the current page is a translation of a page
181     * in the default language. Displays a notice when it is
182     * older than the original page. Tries to lin to a diff
183     * with changes on the original since the translation
184     */
185    function checkage(){
186        global $ID;
187        global $INFO;
188        if(!$this->getConf('checkage')) return;
189        if(!$INFO['exists']) return;
190        $lng = $this->getLangPart($ID);
191        if($lng == $this->defaultlang) return;
192
193        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
194        $idpart = preg_replace($rx,'',$ID);
195
196        // compare modification times
197        list($orig,$name) = $this->buildTransID($this->defaultlang,$idpart);
198        $origfn = wikiFN($orig);
199        if($INFO['lastmod'] >= @filemtime($origfn) ) return;
200
201        // get revision from before translation
202        $orev = 0;
203        $revs = getRevisions($orig,0,100);
204        foreach($revs as $rev){
205            if($rev < $INFO['lastmod']){
206                $orev = $rev;
207                break;
208            }
209        }
210
211        // see if the found revision still exists
212        if($orev && !page_exists($orig,$orev)) $orev=0;
213
214        // build the message and display it
215        $msg = sprintf($this->getLang('outdated'),wl($orig));
216        if($orev){
217            $msg .= sprintf(' '.$this->getLang('diff'),
218                    wl($orig,array('do'=>'diff','rev'=>$orev)));
219        }
220        msg($msg,2);
221    }
222}
223