xref: /plugin/autotranslation/helper.php (revision a4491bec02cd71268b14f2002c535b1cd1b14fae)
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 = '';
1649a71a89SAndreas Gohr    var $LN = array(); // hold native names
1704971eeaSAndreas Gohr    var $opts = array(); // display options
18af1904f9SAndreas Gohr
19af1904f9SAndreas Gohr    /**
20af1904f9SAndreas Gohr     * Initialize
21af1904f9SAndreas Gohr     */
22af1904f9SAndreas Gohr    function helper_plugin_translation() {
237c54a0a6SAndreas Gohr        global $conf;
24af1904f9SAndreas Gohr        require_once(DOKU_INC . 'inc/pageutils.php');
25af1904f9SAndreas Gohr        require_once(DOKU_INC . 'inc/utf8.php');
26af1904f9SAndreas Gohr
27af1904f9SAndreas Gohr        // load wanted translation into array
28af1904f9SAndreas Gohr        $this->trans = strtolower(str_replace(',', ' ', $this->getConf('translations')));
29af1904f9SAndreas Gohr        $this->trans = array_unique(array_filter(explode(' ', $this->trans)));
30af1904f9SAndreas Gohr        sort($this->trans);
317c54a0a6SAndreas Gohr
3249a71a89SAndreas Gohr        // load language names
3349a71a89SAndreas Gohr        $this->LN = confToHash(dirname(__FILE__) . '/lang/langnames.txt');
3449a71a89SAndreas Gohr
3504971eeaSAndreas Gohr        // display options
3604971eeaSAndreas Gohr        $this->opts = $this->getConf('display');
3704971eeaSAndreas Gohr        $this->opts = explode(',', $this->opts);
3804971eeaSAndreas Gohr        $this->opts = array_map('trim', $this->opts);
3904971eeaSAndreas Gohr        $this->opts = array_fill_keys($this->opts, true);
4004971eeaSAndreas Gohr
417c54a0a6SAndreas Gohr        // get default translation
427c54a0a6SAndreas Gohr        if(!$conf['lang_before_translation']) {
437c54a0a6SAndreas Gohr            $dfl = $conf['lang'];
447c54a0a6SAndreas Gohr        } else {
457c54a0a6SAndreas Gohr            $dfl = $conf['lang_before_translation'];
467c54a0a6SAndreas Gohr        }
477c54a0a6SAndreas Gohr        if(in_array($dfl, $this->trans)) {
487c54a0a6SAndreas Gohr            $this->defaultlang = $dfl;
497c54a0a6SAndreas Gohr        } else {
507c54a0a6SAndreas Gohr            $this->defaultlang = '';
51af1904f9SAndreas Gohr            array_unshift($this->trans, '');
527c54a0a6SAndreas Gohr        }
537c54a0a6SAndreas Gohr
54*a4491becSGerry Weißbach        $this->tns = $this->setupTNS();
55af1904f9SAndreas Gohr        if($this->tns) $this->tns .= ':';
56*a4491becSGerry Weißbach        $JSINFO['conf']['lang'] = $dfl;
57*a4491becSGerry Weißbach    }
58*a4491becSGerry Weißbach
59*a4491becSGerry Weißbach    /**
60*a4491becSGerry Weißbach     * Find the current translation namespace
61*a4491becSGerry Weißbach     * This may be detected automatically or defined by the config option
62*a4491becSGerry Weißbach     **/
63*a4491becSGerry Weißbach	function setupTNS($ID="") {
64*a4491becSGerry Weißbach	    global $conf;
65*a4491becSGerry Weißbach
66*a4491becSGerry Weißbach		if ( !empty( $this->tns) ) { return $this->tns; }
67*a4491becSGerry Weißbach		if ( empty($ID) ) { $ID = getID(); }
68*a4491becSGerry Weißbach
69*a4491becSGerry Weißbach		// autodetect?
70*a4491becSGerry Weißbach		// this will only work for namespaces other than the root and default language
71*a4491becSGerry Weißbach		if ( $this->getConf('autodetectnamespace') )
72*a4491becSGerry Weißbach		{
73*a4491becSGerry Weißbach    		$lang = explode(':', $ID);
74*a4491becSGerry Weißbach    		foreach( array_reverse($lang) as $tns )
75*a4491becSGerry Weißbach    		{
76*a4491becSGerry Weißbach                array_pop($lang);
77*a4491becSGerry Weißbach                if ( in_array($tns, $this->trans) )
78*a4491becSGerry Weißbach                {
79*a4491becSGerry Weißbach                    // Found
80*a4491becSGerry Weißbach                    $tns = implode(":", $lang) . ':';
81*a4491becSGerry Weißbach        			if($tns == ':' ) { $tns = ''; }
82*a4491becSGerry Weißbach        			return $tns;
83*a4491becSGerry Weißbach                }
84*a4491becSGerry Weißbach            }
85*a4491becSGerry Weißbach        }
86*a4491becSGerry Weißbach
87*a4491becSGerry Weißbach		// Array of translations can be givven
88*a4491becSGerry Weißbach		$tnsA = explode(' ', $this->getConf('translationns'));
89*a4491becSGerry Weißbach		if ( empty($tnsA) ) return ''; // there is just this one - and translation is active.
90*a4491becSGerry Weißbach
91*a4491becSGerry Weißbach		usort($tnsA,array($this, 'lensort') );
92*a4491becSGerry Weißbach		foreach ( $tnsA as $tns ) {
93*a4491becSGerry Weißbach			$tns = cleanID(trim($tns));
94*a4491becSGerry Weißbach        	if($tns && substr($tns, -1) != ':') { $tns .= ':'; }
95*a4491becSGerry Weißbach			if($tns && strpos($ID,$tns) === false) continue;
96*a4491becSGerry Weißbach			if($tns == ':' ) { $tns = ''; }
97*a4491becSGerry Weißbach
98*a4491becSGerry Weißbach			return $tns;
99*a4491becSGerry Weißbach		}
100*a4491becSGerry Weißbach
101*a4491becSGerry Weißbach		return false;
102*a4491becSGerry Weißbach	}
103*a4491becSGerry Weißbach
104*a4491becSGerry Weißbach	// Inner function for sorting
105*a4491becSGerry Weißbach	private function lensort($a,$b){
106*a4491becSGerry Weißbach    	return strlen($b)-strlen($a);
107af1904f9SAndreas Gohr	}
108af1904f9SAndreas Gohr
109af1904f9SAndreas Gohr    /**
110af1904f9SAndreas Gohr     * Check if the given ID is a translation and return the language code.
111af1904f9SAndreas Gohr     */
112af1904f9SAndreas Gohr    function getLangPart($id) {
11326522e09SAndreas Gohr        list($lng) = $this->getTransParts($id);
11426522e09SAndreas Gohr        return $lng;
115af1904f9SAndreas Gohr    }
11626522e09SAndreas Gohr
11726522e09SAndreas Gohr    /**
118*a4491becSGerry Weißbach     * Check if the given ID is a translation and return the ID up the translation root.
119*a4491becSGerry Weißbach     */
120*a4491becSGerry Weißbach    function getIDPart($id) {
121*a4491becSGerry Weißbach        list($lng, $idpart) = $this->getTransParts($id);
122*a4491becSGerry Weißbach        return $idpart;
123*a4491becSGerry Weißbach    }
124*a4491becSGerry Weißbach
125*a4491becSGerry Weißbach    /**
12626522e09SAndreas Gohr     * Check if the given ID is a translation and return the language code and
12726522e09SAndreas Gohr     * the id part.
12826522e09SAndreas Gohr     */
12926522e09SAndreas Gohr    function getTransParts($id) {
13026522e09SAndreas Gohr        $rx = '/^' . $this->tns . '(' . join('|', $this->trans) . '):(.*)/';
13126522e09SAndreas Gohr        if(preg_match($rx, $id, $match)) {
13226522e09SAndreas Gohr            return array($match[1], $match[2]);
13326522e09SAndreas Gohr        }
13426522e09SAndreas Gohr        return array('', $id);
135af1904f9SAndreas Gohr    }
136af1904f9SAndreas Gohr
137af1904f9SAndreas Gohr    /**
1387053cd66SAndreas Gohr     * Returns the browser language if it matches with one of the configured
1397053cd66SAndreas Gohr     * languages
1407053cd66SAndreas Gohr     */
1417053cd66SAndreas Gohr    function getBrowserLang() {
1427053cd66SAndreas Gohr        $rx = '/(^|,|:|;|-)(' . join('|', $this->trans) . ')($|,|:|;|-)/i';
1437053cd66SAndreas Gohr        if(preg_match($rx, $_SERVER['HTTP_ACCEPT_LANGUAGE'], $match)) {
1447053cd66SAndreas Gohr            return strtolower($match[2]);
1457053cd66SAndreas Gohr        }
1467053cd66SAndreas Gohr        return false;
1477053cd66SAndreas Gohr    }
1487053cd66SAndreas Gohr
1497053cd66SAndreas Gohr    /**
1507c54a0a6SAndreas Gohr     * Returns the ID and name to the wanted translation, empty
1517c54a0a6SAndreas Gohr     * $lng is default lang
152af1904f9SAndreas Gohr     */
153af1904f9SAndreas Gohr    function buildTransID($lng, $idpart) {
154af1904f9SAndreas Gohr        global $conf;
155af1904f9SAndreas Gohr        if($lng) {
156af1904f9SAndreas Gohr            $link = ':' . $this->tns . $lng . ':' . $idpart;
157af1904f9SAndreas Gohr            $name = $lng;
158af1904f9SAndreas Gohr        } else {
159af1904f9SAndreas Gohr            $link = ':' . $this->tns . $idpart;
16004971eeaSAndreas Gohr            $name = $this->realLC('');
161af1904f9SAndreas Gohr        }
162af1904f9SAndreas Gohr        return array($link, $name);
163af1904f9SAndreas Gohr    }
164af1904f9SAndreas Gohr
1651469199dSAndreas Gohr    /**
16604971eeaSAndreas Gohr     * Returns the real language code, even when an empty one is given
16704971eeaSAndreas Gohr     * (eg. resolves th default language)
16804971eeaSAndreas Gohr     */
16904971eeaSAndreas Gohr    function realLC($lc) {
17004971eeaSAndreas Gohr        global $conf;
17104971eeaSAndreas Gohr        if($lc) {
17204971eeaSAndreas Gohr            return $lc;
17304971eeaSAndreas Gohr        } elseif(!$conf['lang_before_translation']) {
17404971eeaSAndreas Gohr            return $conf['lang'];
17504971eeaSAndreas Gohr        } else {
17604971eeaSAndreas Gohr            return $conf['lang_before_translation'];
17704971eeaSAndreas Gohr        }
17804971eeaSAndreas Gohr    }
17904971eeaSAndreas Gohr
18004971eeaSAndreas Gohr    /**
18184877e9bSAndreas Gohr     * Check if current ID should be translated and any GUI
18284877e9bSAndreas Gohr     * should be shown
18384877e9bSAndreas Gohr     */
18484877e9bSAndreas Gohr    function istranslatable($id, $checkact = true) {
18584877e9bSAndreas Gohr        global $ACT;
18684877e9bSAndreas Gohr
18784877e9bSAndreas Gohr        if($checkact && $ACT != 'show') return false;
18884877e9bSAndreas Gohr        if($this->tns && strpos($id, $this->tns) !== 0) return false;
18984877e9bSAndreas Gohr        $skiptrans = trim($this->getConf('skiptrans'));
19084877e9bSAndreas Gohr        if($skiptrans && preg_match('/' . $skiptrans . '/ui', ':' . $id)) return false;
19184877e9bSAndreas Gohr        $meta = p_get_metadata($id);
19284877e9bSAndreas Gohr        if($meta['plugin']['translation']['notrans']) return false;
19384877e9bSAndreas Gohr
19484877e9bSAndreas Gohr        return true;
19584877e9bSAndreas Gohr    }
19684877e9bSAndreas Gohr
19701dd7da9SAndreas Gohr    /**
19801dd7da9SAndreas Gohr     * Return the (localized) about link
19901dd7da9SAndreas Gohr     */
20001dd7da9SAndreas Gohr    function showAbout() {
201c9640767STomasz Tomasik        global $ID;
202c9640767STomasz Tomasik        global $conf;
203c9640767STomasz Tomasik        global $INFO;
204c9640767STomasz Tomasik
2055ad1c278SAndreas Gohr        $curlc = $this->getLangPart($ID);
206f34c9eb2SAndreas Gohr
207d0bdb959SAndreas Gohr        $about = $this->getConf('about');
208d0bdb959SAndreas Gohr        if($this->getConf('localabout')) {
209d0bdb959SAndreas Gohr            list($lc, $idpart) = $this->getTransParts($about);
210f34c9eb2SAndreas Gohr            list($about, $name) = $this->buildTransID($curlc, $idpart);
211d0bdb959SAndreas Gohr            $about = cleanID($about);
212d0bdb959SAndreas Gohr        }
213c9640767STomasz Tomasik
214c9640767STomasz Tomasik        $out = '';
215c9640767STomasz Tomasik        $out .= '<sup>';
216d0bdb959SAndreas Gohr        $out .= html_wikilink($about, '?');
217c9640767STomasz Tomasik        $out .= '</sup>';
218c9640767STomasz Tomasik
219c9640767STomasz Tomasik        return $out;
220c9640767STomasz Tomasik    }
221c9640767STomasz Tomasik
22284877e9bSAndreas Gohr    /**
223bbe70520SAndreas Gohr     * Returns a list of (lc => link) for all existing translations of a page
224bbe70520SAndreas Gohr     *
225bbe70520SAndreas Gohr     * @param $id
226bbe70520SAndreas Gohr     * @return array
227bbe70520SAndreas Gohr     */
228bbe70520SAndreas Gohr    function getAvailableTranslations($id) {
229bbe70520SAndreas Gohr        $result = array();
230bbe70520SAndreas Gohr
231bbe70520SAndreas Gohr        list($lc, $idpart) = $this->getTransParts($id);
232bbe70520SAndreas Gohr        $lang = $this->realLC($lc);
233bbe70520SAndreas Gohr
234bbe70520SAndreas Gohr        foreach($this->trans as $t) {
235bbe70520SAndreas Gohr            if($t == $lc) continue; //skip self
236bbe70520SAndreas Gohr            list($link, $name) = $this->buildTransID($t, $idpart);
237bbe70520SAndreas Gohr            if(page_exists($link)) {
238bbe70520SAndreas Gohr                $result[$name] = $link;
239bbe70520SAndreas Gohr            }
240bbe70520SAndreas Gohr        }
241bbe70520SAndreas Gohr
242bbe70520SAndreas Gohr        return $result;
243bbe70520SAndreas Gohr    }
244bbe70520SAndreas Gohr
245bbe70520SAndreas Gohr    /**
246649de279SAndreas Gohr     * Creates an UI for linking to the available and configured translations
247649de279SAndreas Gohr     *
248649de279SAndreas Gohr     * Can be called from the template or via the ~~TRANS~~ syntax component.
2491469199dSAndreas Gohr     */
250649de279SAndreas Gohr    public function showTranslations() {
2511469199dSAndreas Gohr        global $conf;
2521469199dSAndreas Gohr        global $INFO;
2531469199dSAndreas Gohr
254649de279SAndreas Gohr        if(!$this->istranslatable($INFO['id'])) return '';
25584877e9bSAndreas Gohr        $this->checkage();
2561469199dSAndreas Gohr
257649de279SAndreas Gohr        list($lc, $idpart) = $this->getTransParts($INFO['id']);
25804971eeaSAndreas Gohr        $lang = $this->realLC($lc);
25939ecab8bSAndreas Gohr
2601469199dSAndreas Gohr        $out = '<div class="plugin_translation">';
261c9640767STomasz Tomasik
26204971eeaSAndreas Gohr        //show title and about
263c730e7ddSAndreas Gohr        if(isset($this->opts['title'])) {
2641469199dSAndreas Gohr            $out .= '<span>' . $this->getLang('translations');
2658bd452a3SAndreas Gohr            if($this->getConf('about')) $out .= $this->showAbout();
2661469199dSAndreas Gohr            $out .= ':</span> ';
267c730e7ddSAndreas Gohr            if(isset($this->opts['twolines'])) $out .= '<br />';
268c9640767STomasz Tomasik        }
2691469199dSAndreas Gohr
27004971eeaSAndreas Gohr        // open wrapper
27104971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
27204971eeaSAndreas Gohr            // select needs its own styling
2731469199dSAndreas Gohr            if($INFO['exists']) {
2741469199dSAndreas Gohr                $class = 'wikilink1';
2751469199dSAndreas Gohr            } else {
2761469199dSAndreas Gohr                $class = 'wikilink2';
2771469199dSAndreas Gohr            }
27804971eeaSAndreas Gohr            if(isset($this->opts['flag'])) {
27904971eeaSAndreas Gohr                $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
280649de279SAndreas Gohr            }else{
281649de279SAndreas Gohr                $flag = '';
282c9640767STomasz Tomasik            }
283649de279SAndreas Gohr
284fbc6382cSAndreas Gohr            if($conf['userewrite']) {
285fbc6382cSAndreas Gohr                $action = wl();
286fbc6382cSAndreas Gohr            } else {
287fbc6382cSAndreas Gohr                $action = script();
288fbc6382cSAndreas Gohr            }
289fbc6382cSAndreas Gohr
290fbc6382cSAndreas Gohr            $out .= '<form action="' . $action . '" id="translation__dropdown">';
29104971eeaSAndreas Gohr            if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" class="' . $class . '" /> ';
292c9640767STomasz Tomasik            $out .= '<select name="id" class="' . $class . '">';
29304971eeaSAndreas Gohr        } else {
29404971eeaSAndreas Gohr            $out .= '<ul>';
29504971eeaSAndreas Gohr        }
29604971eeaSAndreas Gohr
29704971eeaSAndreas Gohr        // insert items
29804971eeaSAndreas Gohr        foreach($this->trans as $t) {
29904971eeaSAndreas Gohr            $out .= $this->getTransItem($t, $idpart);
30004971eeaSAndreas Gohr        }
30104971eeaSAndreas Gohr
30204971eeaSAndreas Gohr        // close wrapper
30304971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
3041469199dSAndreas Gohr            $out .= '</select>';
3051469199dSAndreas Gohr            $out .= '<input name="go" type="submit" value="&rarr;" />';
3061469199dSAndreas Gohr            $out .= '</form>';
30704971eeaSAndreas Gohr        } else {
3081469199dSAndreas Gohr            $out .= '</ul>';
3091469199dSAndreas Gohr        }
3101469199dSAndreas Gohr
31104971eeaSAndreas Gohr        // show about if not already shown
312c730e7ddSAndreas Gohr        if(!isset($this->opts['title']) && $this->getConf('about')) {
31304971eeaSAndreas Gohr            $out .= '&nbsp';
31404971eeaSAndreas Gohr            $out .= $this->showAbout();
31504971eeaSAndreas Gohr        }
31604971eeaSAndreas Gohr
3171469199dSAndreas Gohr        $out .= '</div>';
3181469199dSAndreas Gohr
3191469199dSAndreas Gohr        return $out;
3201469199dSAndreas Gohr    }
321af1904f9SAndreas Gohr
32201dd7da9SAndreas Gohr    /**
323bbe70520SAndreas Gohr     * Return the local name
324bbe70520SAndreas Gohr     *
325bbe70520SAndreas Gohr     * @param $lang
326bbe70520SAndreas Gohr     * @return string
327bbe70520SAndreas Gohr     */
328bbe70520SAndreas Gohr    function getLocalName($lang) {
329bbe70520SAndreas Gohr        if($this->LN[$lang]) {
330bbe70520SAndreas Gohr            return $this->LN[$lang];
331bbe70520SAndreas Gohr        }
332bbe70520SAndreas Gohr        return $lang;
333bbe70520SAndreas Gohr    }
334bbe70520SAndreas Gohr
335bbe70520SAndreas Gohr    /**
33601dd7da9SAndreas Gohr     * Create the link or option for a single translation
33701dd7da9SAndreas Gohr     *
33804971eeaSAndreas Gohr     * @param $lc string      The language code
33901dd7da9SAndreas Gohr     * @param $idpart string  The ID of the translated page
34004971eeaSAndreas Gohr     * @returns string        The item
34101dd7da9SAndreas Gohr     */
34204971eeaSAndreas Gohr    function getTransItem($lc, $idpart) {
343c9640767STomasz Tomasik        global $ID;
344c9640767STomasz Tomasik        global $conf;
345c9640767STomasz Tomasik
34604971eeaSAndreas Gohr        list($link, $lang) = $this->buildTransID($lc, $idpart);
347c9640767STomasz Tomasik        $link = cleanID($link);
34804971eeaSAndreas Gohr
34904971eeaSAndreas Gohr        // class
350c9640767STomasz Tomasik        if(page_exists($link, '', false)) {
351c9640767STomasz Tomasik            $class = 'wikilink1';
352c9640767STomasz Tomasik        } else {
353c9640767STomasz Tomasik            $class = 'wikilink2';
354c9640767STomasz Tomasik        }
355c9640767STomasz Tomasik
35604971eeaSAndreas Gohr        // local language name
357bbe70520SAndreas Gohr        $localname = $this->getLocalName($lang);
358c9640767STomasz Tomasik
35904971eeaSAndreas Gohr        // current?
36004971eeaSAndreas Gohr        if($ID == $link) {
36104971eeaSAndreas Gohr            $sel = ' selected="selected"';
36204971eeaSAndreas Gohr            $class .= ' cur';
36304971eeaSAndreas Gohr        } else {
36404971eeaSAndreas Gohr            $sel = '';
36504971eeaSAndreas Gohr        }
366c9640767STomasz Tomasik
36704971eeaSAndreas Gohr        // flag
36804971eeaSAndreas Gohr        if(isset($this->opts['flag'])) {
36904971eeaSAndreas Gohr            $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
37004971eeaSAndreas Gohr            $style = ' style="background-image: url(\'' . $flag . '\')"';
37104971eeaSAndreas Gohr            $class .= ' flag';
37204971eeaSAndreas Gohr        }
37304971eeaSAndreas Gohr
37404971eeaSAndreas Gohr        // what to display as name
37504971eeaSAndreas Gohr        if(isset($this->opts['name'])) {
37604971eeaSAndreas Gohr            $display = hsc($localname);
377c730e7ddSAndreas Gohr            if(isset($this->opts['langcode'])) $display .= ' (' . hsc($lang) . ')';
378c730e7ddSAndreas Gohr        } elseif(isset($this->opts['langcode'])) {
37904971eeaSAndreas Gohr            $display = hsc($lang);
38004971eeaSAndreas Gohr        } else {
38104971eeaSAndreas Gohr            $display = '&nbsp;';
38204971eeaSAndreas Gohr        }
38304971eeaSAndreas Gohr
38404971eeaSAndreas Gohr        // prepare output
38504971eeaSAndreas Gohr        $out = '';
38604971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
3872546b043SAndreas Gohr            if($conf['useslash']) $link = str_replace(':', '/', $link);
3882546b043SAndreas Gohr
38904971eeaSAndreas Gohr            $out .= '<option class="' . $class . '" title="' . hsc($localname) . '" value="' . $link . '"' . $sel . $style . '>';
39004971eeaSAndreas Gohr            $out .= $display;
39104971eeaSAndreas Gohr            $out .= '</option>';
39204971eeaSAndreas Gohr        } else {
393c9640767STomasz Tomasik            $out .= '<li><div class="li">';
394*a4491becSGerry Weißbach            $out .= '<a href="' . wl($link, 'tns') . '" class="' . $class . '" title="' . hsc($localname) . '">';
39504971eeaSAndreas Gohr            if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" />';
39604971eeaSAndreas Gohr            $out .= $display;
397c9640767STomasz Tomasik            $out .= '</a>';
398c9640767STomasz Tomasik            $out .= '</div></li>';
399c9640767STomasz Tomasik        }
400c9640767STomasz Tomasik
401c9640767STomasz Tomasik        return $out;
402c9640767STomasz Tomasik    }
403c9640767STomasz Tomasik
40484877e9bSAndreas Gohr    /**
40584877e9bSAndreas Gohr     * Checks if the current page is a translation of a page
40684877e9bSAndreas Gohr     * in the default language. Displays a notice when it is
40784877e9bSAndreas Gohr     * older than the original page. Tries to lin to a diff
40884877e9bSAndreas Gohr     * with changes on the original since the translation
40984877e9bSAndreas Gohr     */
41084877e9bSAndreas Gohr    function checkage() {
41184877e9bSAndreas Gohr        global $ID;
41284877e9bSAndreas Gohr        global $INFO;
41384877e9bSAndreas Gohr        if(!$this->getConf('checkage')) return;
41484877e9bSAndreas Gohr        if(!$INFO['exists']) return;
41584877e9bSAndreas Gohr        $lng = $this->getLangPart($ID);
41684877e9bSAndreas Gohr        if($lng == $this->defaultlang) return;
417af1904f9SAndreas Gohr
41884877e9bSAndreas Gohr        $rx = '/^' . $this->tns . '((' . join('|', $this->trans) . '):)?/';
41984877e9bSAndreas Gohr        $idpart = preg_replace($rx, '', $ID);
42084877e9bSAndreas Gohr
42184877e9bSAndreas Gohr        // compare modification times
42284877e9bSAndreas Gohr        list($orig, $name) = $this->buildTransID($this->defaultlang, $idpart);
42384877e9bSAndreas Gohr        $origfn = wikiFN($orig);
42484877e9bSAndreas Gohr        if($INFO['lastmod'] >= @filemtime($origfn)) return;
42584877e9bSAndreas Gohr
42684877e9bSAndreas Gohr        // get revision from before translation
42784877e9bSAndreas Gohr        $orev = 0;
42884877e9bSAndreas Gohr        $revs = getRevisions($orig, 0, 100);
42984877e9bSAndreas Gohr        foreach($revs as $rev) {
43084877e9bSAndreas Gohr            if($rev < $INFO['lastmod']) {
43184877e9bSAndreas Gohr                $orev = $rev;
43284877e9bSAndreas Gohr                break;
43384877e9bSAndreas Gohr            }
43484877e9bSAndreas Gohr        }
43584877e9bSAndreas Gohr
43644552920SAndreas Gohr        // see if the found revision still exists
43744552920SAndreas Gohr        if($orev && !page_exists($orig, $orev)) $orev = 0;
43844552920SAndreas Gohr
43984877e9bSAndreas Gohr        // build the message and display it
440dc3fbdb9SOleksiy Zagorskyi        $orig = cleanID($orig);
44184877e9bSAndreas Gohr        $msg = sprintf($this->getLang('outdated'), wl($orig));
44284877e9bSAndreas Gohr        if($orev) {
4435fd0d0d1SAndreas Gohr            $msg .= sprintf(
4445fd0d0d1SAndreas Gohr                ' ' . $this->getLang('diff'),
4455fd0d0d1SAndreas Gohr                wl($orig, array('do' => 'diff', 'rev' => $orev))
4465fd0d0d1SAndreas Gohr            );
44784877e9bSAndreas Gohr        }
44800431e1eSAndreas Gohr
44900431e1eSAndreas Gohr        echo '<div class="notify">' . $msg . '</div>';
45084877e9bSAndreas Gohr    }
451*a4491becSGerry Weißbach
452*a4491becSGerry Weißbach    /**
453*a4491becSGerry Weißbach     * Checks if the current ID has a translated page
454*a4491becSGerry Weißbach     */
455*a4491becSGerry Weißbach	function hasTranslation($inputID = null) {
456*a4491becSGerry Weißbach		global $ID, $INFO, $conf;
457*a4491becSGerry Weißbach
458*a4491becSGerry Weißbach        if ( empty($inputID) )
459*a4491becSGerry Weißbach        {
460*a4491becSGerry Weißbach            $inputID = $ID;
461*a4491becSGerry Weißbach        }
462*a4491becSGerry Weißbach
463*a4491becSGerry Weißbach        if ( !$this->istranslatable($id) ) return false;
464*a4491becSGerry Weißbach
465*a4491becSGerry Weißbach		$idpart = $this->getIDPart($inputID);
466*a4491becSGerry Weißbach
467*a4491becSGerry Weißbach		foreach($this->trans as $t)
468*a4491becSGerry Weißbach		{
469*a4491becSGerry Weißbach			list($link,$name) = $this->buildTransID($t,$idpart,false);
470*a4491becSGerry Weißbach			$link = cleanID($link);
471*a4491becSGerry Weißbach
472*a4491becSGerry Weißbach			if( $inputID != $link && page_exists($link,'',false) ){
473*a4491becSGerry Weißbach				return true;
474*a4491becSGerry Weißbach			}
475*a4491becSGerry Weißbach		}
476*a4491becSGerry Weißbach
477*a4491becSGerry Weißbach		return false;
478*a4491becSGerry Weißbach	}
479af1904f9SAndreas Gohr}
480