xref: /plugin/autotranslation/helper.php (revision 06f3a063496b1645751f582093e4f6dc795a9082)
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     * Check if the given ID is a translation and return the language code.
50     */
51    function getLangPart($id){
52        $rx = '/^'.$this->tns.'('.join('|',$this->trans).'):/';
53        if(preg_match($rx,$id,$match)){
54            return $match[1];
55        }
56        return '';
57    }
58
59    /**
60     * Returns the browser language if it matches with one of the configured
61     * languages
62     */
63    function getBrowserLang(){
64        $rx = '/(^|,|:|;|-)('.join('|',$this->trans).')($|,|:|;|-)/i';
65        if(preg_match($rx,$_SERVER['HTTP_ACCEPT_LANGUAGE'],$match)){
66            return strtolower($match[2]);
67        }
68        return false;
69    }
70
71
72    /**
73     * Returns the ID and name to the wanted translation, empty
74     * $lng is default lang
75     */
76    function buildTransID($lng,$idpart){
77        global $conf;
78        global $saved_conf;
79        if($lng){
80            $link = ':'.$this->tns.$lng.':'.$idpart;
81            $name = $lng;
82        }else{
83            $link = ':'.$this->tns.$idpart;
84            if(!$conf['lang_before_translation']){
85              $name = $conf['lang'];
86            } else {
87              $name = $conf['lang_before_translation'];
88            }
89        }
90        return array($link,$name);
91    }
92
93    /**
94     * Check if current ID should be translated and any GUI
95     * should be shown
96     */
97    function istranslatable($id,$checkact=true){
98        global $ACT;
99
100        if($checkact && $ACT != 'show') return false;
101        if($this->tns && strpos($id,$this->tns) !== 0) return false;
102        $skiptrans = trim($this->getConf('skiptrans'));
103        if($skiptrans &&  preg_match('/'.$skiptrans.'/ui',':'.$id)) return false;
104        $meta = p_get_metadata($id);
105        if($meta['plugin']['translation']['notrans']) return false;
106
107        return true;
108    }
109
110    /**
111     * Displays the available and configured translations. Needs to be placed in the template.
112     */
113    function showTranslations(){
114        global $ID;
115        global $conf;
116        global $INFO;
117
118        if(!$this->istranslatable($ID)) return;
119
120        $this->checkage();
121
122        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
123        $idpart = preg_replace($rx,'',$ID);
124
125        $out  = '<div class="plugin_translation">';
126        $out .= '<span>'.$this->getLang('translations');
127        if($this->getConf('about')){
128            $out .= '<sup>'.html_wikilink($this->getConf('about'),'?').'</sup>';
129        }
130        $out .= ':</span> ';
131
132        if($this->getConf('dropdown')){ // use dropdown
133            if($INFO['exists']){
134                $class = 'wikilink1';
135            }else{
136                $class = 'wikilink2';
137            }
138            $out .= '<form action="'.wl().'" id="translation__dropdown">';
139            $out .= '<select name="id" class="'.$class.'">';
140            foreach($this->trans as $t){
141                list($link,$name) = $this->buildTransID($t,$idpart);
142                $link = cleanID($link);
143                if($ID == $link){
144                    $sel = ' selected="selected"';
145                }else{
146                    $sel = '';
147                }
148                if(page_exists($link,'',false)){
149                    $class = 'wikilink1';
150                }else{
151                    $class = 'wikilink2';
152                }
153                $out .= '<option value="'.$link.'"'.$sel.' class="'.$class.'">'.hsc($name).'</option>';
154            }
155            $out .= '</select>';
156            $out .= '<input name="go" type="submit" value="&rarr;" />';
157            $out .= '</form>';
158        }else{ // use list
159            $out .= '<ul>';
160            foreach($this->trans as $t){
161                list($link,$name) = $this->buildTransID($t,$idpart);
162                $out .= '  <li><div class="li">'.html_wikilink($link,$name).'</div></li>';
163            }
164            $out .= '</ul>';
165        }
166
167        $out .= '</div>';
168
169        return $out;
170    }
171
172    /**
173     * Checks if the current page is a translation of a page
174     * in the default language. Displays a notice when it is
175     * older than the original page. Tries to lin to a diff
176     * with changes on the original since the translation
177     */
178    function checkage(){
179        global $ID;
180        global $INFO;
181        if(!$this->getConf('checkage')) return;
182        if(!$INFO['exists']) return;
183        $lng = $this->getLangPart($ID);
184        if($lng == $this->defaultlang) return;
185
186        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
187        $idpart = preg_replace($rx,'',$ID);
188
189        // compare modification times
190        list($orig,$name) = $this->buildTransID($this->defaultlang,$idpart);
191        $origfn = wikiFN($orig);
192        if($INFO['lastmod'] >= @filemtime($origfn) ) return;
193
194        // get revision from before translation
195        $orev = 0;
196        $revs = getRevisions($orig,0,100);
197        foreach($revs as $rev){
198            if($rev < $INFO['lastmod']){
199                $orev = $rev;
200                break;
201            }
202        }
203
204        // see if the found revision still exists
205        if($orev && !page_exists($orig,$orev)) $orev=0;
206
207        // build the message and display it
208        $msg = sprintf($this->getLang('outdated'),wl($orig));
209        if($orev){
210            $msg .= sprintf(' '.$this->getLang('diff'),
211                    wl($orig,array('do'=>'diff','rev'=>$orev)));
212        }
213
214        echo '<div class="notify">'.$msg.'</div>';
215    }
216}
217