xref: /plugin/autotranslation/helper.php (revision 39ecab8bea52cd31b538e8049b9d2c155c40f774)
1af1904f9SAndreas Gohr<?php
2af1904f9SAndreas Gohr/**
3af1904f9SAndreas Gohr * Translation Plugin: Simple multilanguage plugin
4af1904f9SAndreas Gohr *
5af1904f9SAndreas Gohr * @license    GPL 2 (http://www.gnu.org/licenses/gpl.html)
6af1904f9SAndreas Gohr * @author     Andreas Gohr <andi@splitbrain.org>
7af1904f9SAndreas Gohr */
8af1904f9SAndreas Gohr
9af1904f9SAndreas Gohr// must be run within Dokuwiki
10af1904f9SAndreas Gohrif(!defined('DOKU_INC')) die();
11af1904f9SAndreas Gohr
12af1904f9SAndreas Gohrclass helper_plugin_translation extends DokuWiki_Plugin {
13af1904f9SAndreas Gohr    var $trans       = array();
14af1904f9SAndreas Gohr    var $tns         = '';
157c54a0a6SAndreas Gohr    var $defaultlang = '';
16af1904f9SAndreas Gohr
17af1904f9SAndreas Gohr    /**
18af1904f9SAndreas Gohr     * Initialize
19af1904f9SAndreas Gohr     */
20af1904f9SAndreas Gohr    function helper_plugin_translation(){
217c54a0a6SAndreas Gohr        global $conf;
22af1904f9SAndreas Gohr        require_once(DOKU_INC.'inc/pageutils.php');
23af1904f9SAndreas Gohr        require_once(DOKU_INC.'inc/utf8.php');
24af1904f9SAndreas Gohr
25af1904f9SAndreas Gohr        // load wanted translation into array
26af1904f9SAndreas Gohr        $this->trans = strtolower(str_replace(',',' ',$this->getConf('translations')));
27af1904f9SAndreas Gohr        $this->trans = array_unique(array_filter(explode(' ',$this->trans)));
28af1904f9SAndreas Gohr        sort($this->trans);
297c54a0a6SAndreas Gohr
307c54a0a6SAndreas Gohr        // get default translation
317c54a0a6SAndreas Gohr        if(!$conf['lang_before_translation']){
327c54a0a6SAndreas Gohr          $dfl = $conf['lang'];
337c54a0a6SAndreas Gohr        } else {
347c54a0a6SAndreas Gohr          $dfl = $conf['lang_before_translation'];
357c54a0a6SAndreas Gohr        }
367c54a0a6SAndreas Gohr        if(in_array($dfl,$this->trans)){
377c54a0a6SAndreas Gohr            $this->defaultlang = $dfl;
387c54a0a6SAndreas Gohr        }else{
397c54a0a6SAndreas Gohr            $this->defaultlang = '';
40af1904f9SAndreas Gohr            array_unshift($this->trans,'');
417c54a0a6SAndreas Gohr        }
427c54a0a6SAndreas Gohr
43af1904f9SAndreas Gohr
44af1904f9SAndreas Gohr        $this->tns = cleanID($this->getConf('translationns'));
45af1904f9SAndreas Gohr        if($this->tns) $this->tns .= ':';
46af1904f9SAndreas Gohr    }
47af1904f9SAndreas Gohr
48af1904f9SAndreas Gohr    /**
49af1904f9SAndreas Gohr     * Check if the given ID is a translation and return the language code.
50af1904f9SAndreas Gohr     */
51af1904f9SAndreas Gohr    function getLangPart($id){
52af1904f9SAndreas Gohr        $rx = '/^'.$this->tns.'('.join('|',$this->trans).'):/';
53af1904f9SAndreas Gohr        if(preg_match($rx,$id,$match)){
54af1904f9SAndreas Gohr            return $match[1];
55af1904f9SAndreas Gohr        }
56af1904f9SAndreas Gohr        return '';
57af1904f9SAndreas Gohr    }
58af1904f9SAndreas Gohr
59af1904f9SAndreas Gohr    /**
607053cd66SAndreas Gohr     * Returns the browser language if it matches with one of the configured
617053cd66SAndreas Gohr     * languages
627053cd66SAndreas Gohr     */
637053cd66SAndreas Gohr    function getBrowserLang(){
647053cd66SAndreas Gohr        $rx = '/(^|,|:|;|-)('.join('|',$this->trans).')($|,|:|;|-)/i';
657053cd66SAndreas Gohr        if(preg_match($rx,$_SERVER['HTTP_ACCEPT_LANGUAGE'],$match)){
667053cd66SAndreas Gohr            return strtolower($match[2]);
677053cd66SAndreas Gohr        }
687053cd66SAndreas Gohr        return false;
697053cd66SAndreas Gohr    }
707053cd66SAndreas Gohr
717053cd66SAndreas Gohr
727053cd66SAndreas Gohr    /**
737c54a0a6SAndreas Gohr     * Returns the ID and name to the wanted translation, empty
747c54a0a6SAndreas Gohr     * $lng is default lang
75af1904f9SAndreas Gohr     */
76af1904f9SAndreas Gohr    function buildTransID($lng,$idpart){
77af1904f9SAndreas Gohr        global $conf;
78af1904f9SAndreas Gohr        global $saved_conf;
79af1904f9SAndreas Gohr        if($lng){
80af1904f9SAndreas Gohr            $link = ':'.$this->tns.$lng.':'.$idpart;
81af1904f9SAndreas Gohr            $name = $lng;
82af1904f9SAndreas Gohr        }else{
83af1904f9SAndreas Gohr            $link = ':'.$this->tns.$idpart;
84af1904f9SAndreas Gohr            if(!$conf['lang_before_translation']){
85af1904f9SAndreas Gohr              $name = $conf['lang'];
86af1904f9SAndreas Gohr            } else {
87af1904f9SAndreas Gohr              $name = $conf['lang_before_translation'];
88af1904f9SAndreas Gohr            }
89af1904f9SAndreas Gohr        }
90af1904f9SAndreas Gohr        return array($link,$name);
91af1904f9SAndreas Gohr    }
92af1904f9SAndreas Gohr
931469199dSAndreas Gohr    /**
9484877e9bSAndreas Gohr     * Check if current ID should be translated and any GUI
9584877e9bSAndreas Gohr     * should be shown
9684877e9bSAndreas Gohr     */
9784877e9bSAndreas Gohr    function istranslatable($id,$checkact=true){
9884877e9bSAndreas Gohr        global $ACT;
9984877e9bSAndreas Gohr
10084877e9bSAndreas Gohr        if($checkact && $ACT != 'show') return false;
10184877e9bSAndreas Gohr        if($this->tns && strpos($id,$this->tns) !== 0) return false;
10284877e9bSAndreas Gohr        $skiptrans = trim($this->getConf('skiptrans'));
10384877e9bSAndreas Gohr        if($skiptrans &&  preg_match('/'.$skiptrans.'/ui',':'.$id)) return false;
10484877e9bSAndreas Gohr        $meta = p_get_metadata($id);
10584877e9bSAndreas Gohr        if($meta['plugin']['translation']['notrans']) return false;
10684877e9bSAndreas Gohr
10784877e9bSAndreas Gohr        return true;
10884877e9bSAndreas Gohr    }
10984877e9bSAndreas Gohr
11084877e9bSAndreas Gohr    /**
1111469199dSAndreas Gohr     * Displays the available and configured translations. Needs to be placed in the template.
1121469199dSAndreas Gohr     */
1131469199dSAndreas Gohr    function showTranslations(){
1141469199dSAndreas Gohr        global $ID;
1151469199dSAndreas Gohr        global $conf;
1161469199dSAndreas Gohr        global $INFO;
1171469199dSAndreas Gohr
11884877e9bSAndreas Gohr        if(!$this->istranslatable($ID)) return;
11984877e9bSAndreas Gohr
12084877e9bSAndreas Gohr        $this->checkage();
1211469199dSAndreas Gohr
122*39ecab8bSAndreas Gohr        $LN = confToHash(dirname(__FILE__).'/lang/langnames.txt');
123*39ecab8bSAndreas Gohr
1241469199dSAndreas Gohr        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
1251469199dSAndreas Gohr        $idpart = preg_replace($rx,'',$ID);
1261469199dSAndreas Gohr
1271469199dSAndreas Gohr        $out  = '<div class="plugin_translation">';
1281469199dSAndreas Gohr        $out .= '<span>'.$this->getLang('translations');
1291469199dSAndreas Gohr        if($this->getConf('about')){
1301469199dSAndreas Gohr            $out .= '<sup>'.html_wikilink($this->getConf('about'),'?').'</sup>';
1311469199dSAndreas Gohr        }
1321469199dSAndreas Gohr        $out .= ':</span> ';
1331469199dSAndreas Gohr
1341469199dSAndreas Gohr        if($this->getConf('dropdown')){ // use dropdown
1351469199dSAndreas Gohr            if($INFO['exists']){
1361469199dSAndreas Gohr                $class = 'wikilink1';
1371469199dSAndreas Gohr            }else{
1381469199dSAndreas Gohr                $class = 'wikilink2';
1391469199dSAndreas Gohr            }
1401469199dSAndreas Gohr            $out .= '<form action="'.wl().'" id="translation__dropdown">';
1411469199dSAndreas Gohr            $out .= '<select name="id" class="'.$class.'">';
1421469199dSAndreas Gohr            foreach($this->trans as $t){
1431469199dSAndreas Gohr                list($link,$name) = $this->buildTransID($t,$idpart);
1441469199dSAndreas Gohr                $link = cleanID($link);
1451469199dSAndreas Gohr                if($ID == $link){
1461469199dSAndreas Gohr                    $sel = ' selected="selected"';
1471469199dSAndreas Gohr                }else{
1481469199dSAndreas Gohr                    $sel = '';
1491469199dSAndreas Gohr                }
1501469199dSAndreas Gohr                if(page_exists($link,'',false)){
1511469199dSAndreas Gohr                    $class = 'wikilink1';
1521469199dSAndreas Gohr                }else{
1531469199dSAndreas Gohr                    $class = 'wikilink2';
1541469199dSAndreas Gohr                }
155*39ecab8bSAndreas Gohr                $out .= '<option value="'.$link.'"'.$sel.' class="'.$class.'" title="'.$LN[$name].'">'.hsc($name).'</option>';
1561469199dSAndreas Gohr            }
1571469199dSAndreas Gohr            $out .= '</select>';
1581469199dSAndreas Gohr            $out .= '<input name="go" type="submit" value="&rarr;" />';
1591469199dSAndreas Gohr            $out .= '</form>';
1601469199dSAndreas Gohr        }else{ // use list
1611469199dSAndreas Gohr            $out .= '<ul>';
1621469199dSAndreas Gohr            foreach($this->trans as $t){
1631469199dSAndreas Gohr                list($link,$name) = $this->buildTransID($t,$idpart);
164*39ecab8bSAndreas Gohr                if(page_exists($link,'',false)){
165*39ecab8bSAndreas Gohr                    $class = 'wikilink1';
166*39ecab8bSAndreas Gohr                }else{
167*39ecab8bSAndreas Gohr                    $class = 'wikilink2';
168*39ecab8bSAndreas Gohr                }
169*39ecab8bSAndreas Gohr                $out .= '  <li><div class="li"><a href="'.wl($link).'" class="'.$class.'" title="'.$LN[$name].'">'.hsc($name).'</a></div></li>';
1701469199dSAndreas Gohr            }
1711469199dSAndreas Gohr            $out .= '</ul>';
1721469199dSAndreas Gohr        }
1731469199dSAndreas Gohr
1741469199dSAndreas Gohr        $out .= '</div>';
1751469199dSAndreas Gohr
1761469199dSAndreas Gohr        return $out;
1771469199dSAndreas Gohr    }
178af1904f9SAndreas Gohr
17984877e9bSAndreas Gohr    /**
18084877e9bSAndreas Gohr     * Checks if the current page is a translation of a page
18184877e9bSAndreas Gohr     * in the default language. Displays a notice when it is
18284877e9bSAndreas Gohr     * older than the original page. Tries to lin to a diff
18384877e9bSAndreas Gohr     * with changes on the original since the translation
18484877e9bSAndreas Gohr     */
18584877e9bSAndreas Gohr    function checkage(){
18684877e9bSAndreas Gohr        global $ID;
18784877e9bSAndreas Gohr        global $INFO;
18884877e9bSAndreas Gohr        if(!$this->getConf('checkage')) return;
18984877e9bSAndreas Gohr        if(!$INFO['exists']) return;
19084877e9bSAndreas Gohr        $lng = $this->getLangPart($ID);
19184877e9bSAndreas Gohr        if($lng == $this->defaultlang) return;
192af1904f9SAndreas Gohr
19384877e9bSAndreas Gohr        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
19484877e9bSAndreas Gohr        $idpart = preg_replace($rx,'',$ID);
19584877e9bSAndreas Gohr
19684877e9bSAndreas Gohr        // compare modification times
19784877e9bSAndreas Gohr        list($orig,$name) = $this->buildTransID($this->defaultlang,$idpart);
19884877e9bSAndreas Gohr        $origfn = wikiFN($orig);
19984877e9bSAndreas Gohr        if($INFO['lastmod'] >= @filemtime($origfn) ) return;
20084877e9bSAndreas Gohr
20184877e9bSAndreas Gohr        // get revision from before translation
20284877e9bSAndreas Gohr        $orev = 0;
20384877e9bSAndreas Gohr        $revs = getRevisions($orig,0,100);
20484877e9bSAndreas Gohr        foreach($revs as $rev){
20584877e9bSAndreas Gohr            if($rev < $INFO['lastmod']){
20684877e9bSAndreas Gohr                $orev = $rev;
20784877e9bSAndreas Gohr                break;
20884877e9bSAndreas Gohr            }
20984877e9bSAndreas Gohr        }
21084877e9bSAndreas Gohr
21144552920SAndreas Gohr        // see if the found revision still exists
21244552920SAndreas Gohr        if($orev && !page_exists($orig,$orev)) $orev=0;
21344552920SAndreas Gohr
21484877e9bSAndreas Gohr        // build the message and display it
21584877e9bSAndreas Gohr        $msg = sprintf($this->getLang('outdated'),wl($orig));
21684877e9bSAndreas Gohr        if($orev){
21784877e9bSAndreas Gohr            $msg .= sprintf(' '.$this->getLang('diff'),
21884877e9bSAndreas Gohr                    wl($orig,array('do'=>'diff','rev'=>$orev)));
21984877e9bSAndreas Gohr        }
22000431e1eSAndreas Gohr
22100431e1eSAndreas Gohr        echo '<div class="notify">'.$msg.'</div>';
22284877e9bSAndreas Gohr    }
223af1904f9SAndreas Gohr}
224