xref: /plugin/autotranslation/helper.php (revision e5aa1ca221caf657870d9c49e674428906d3c0df)
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
54a4491becSGerry Weißbach        $this->tns = $this->setupTNS();
55af1904f9SAndreas Gohr        if($this->tns) $this->tns .= ':';
56a4491becSGerry Weißbach        $JSINFO['conf']['lang'] = $dfl;
57a4491becSGerry Weißbach    }
58a4491becSGerry Weißbach
59a4491becSGerry Weißbach    /**
60a4491becSGerry Weißbach     * Find the current translation namespace
61a4491becSGerry Weißbach     * This may be detected automatically or defined by the config option
62a4491becSGerry Weißbach     **/
63a4491becSGerry Weißbach	function setupTNS($ID="") {
64a4491becSGerry Weißbach	    global $conf;
65a4491becSGerry Weißbach
66a4491becSGerry Weißbach		if ( !empty( $this->tns) ) { return $this->tns; }
67a4491becSGerry Weißbach		if ( empty($ID) ) { $ID = getID(); }
68a4491becSGerry Weißbach
69a4491becSGerry Weißbach		// autodetect?
70a4491becSGerry Weißbach		// this will only work for namespaces other than the root and default language
71a4491becSGerry Weißbach		if ( $this->getConf('autodetectnamespace') )
72a4491becSGerry Weißbach		{
73a4491becSGerry Weißbach    		$lang = explode(':', $ID);
74a4491becSGerry Weißbach    		foreach( array_reverse($lang) as $tns )
75a4491becSGerry Weißbach    		{
76a4491becSGerry Weißbach                array_pop($lang);
77a4491becSGerry Weißbach                if ( in_array($tns, $this->trans) )
78a4491becSGerry Weißbach                {
79a4491becSGerry Weißbach                    // Found
80a4491becSGerry Weißbach                    $tns = implode(":", $lang) . ':';
81a4491becSGerry Weißbach        			if($tns == ':' ) { $tns = ''; }
82a4491becSGerry Weißbach        			return $tns;
83a4491becSGerry Weißbach                }
84a4491becSGerry Weißbach            }
85a4491becSGerry Weißbach        }
86a4491becSGerry Weißbach
87a4491becSGerry Weißbach		// Array of translations can be givven
88a4491becSGerry Weißbach		$tnsA = explode(' ', $this->getConf('translationns'));
89a4491becSGerry Weißbach		if ( empty($tnsA) ) return ''; // there is just this one - and translation is active.
90a4491becSGerry Weißbach
91a4491becSGerry Weißbach		usort($tnsA,array($this, 'lensort') );
92a4491becSGerry Weißbach		foreach ( $tnsA as $tns ) {
93a4491becSGerry Weißbach			$tns = cleanID(trim($tns));
94a4491becSGerry Weißbach        	if($tns && substr($tns, -1) != ':') { $tns .= ':'; }
95a4491becSGerry Weißbach			if($tns && strpos($ID,$tns) === false) continue;
96a4491becSGerry Weißbach			if($tns == ':' ) { $tns = ''; }
97a4491becSGerry Weißbach
98a4491becSGerry Weißbach			return $tns;
99a4491becSGerry Weißbach		}
100a4491becSGerry Weißbach
101a4491becSGerry Weißbach		return false;
102a4491becSGerry Weißbach	}
103a4491becSGerry Weißbach
104a4491becSGerry Weißbach	// Inner function for sorting
105a4491becSGerry Weißbach	private function lensort($a,$b){
106a4491becSGerry 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    /**
118a4491becSGerry Weißbach     * Check if the given ID is a translation and return the ID up the translation root.
119a4491becSGerry Weißbach     */
120a4491becSGerry Weißbach    function getIDPart($id) {
121a4491becSGerry Weißbach        list($lng, $idpart) = $this->getTransParts($id);
122a4491becSGerry Weißbach        return $idpart;
123a4491becSGerry Weißbach    }
124a4491becSGerry Weißbach
125a4491becSGerry 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
187*e5aa1ca2SGerry Weißbach        if(auth_isAdmin()) return true;
188*e5aa1ca2SGerry Weißbach
18984877e9bSAndreas Gohr        if($checkact && $ACT != 'show') return false;
19084877e9bSAndreas Gohr        if($this->tns && strpos($id, $this->tns) !== 0) return false;
19184877e9bSAndreas Gohr        $skiptrans = trim($this->getConf('skiptrans'));
19284877e9bSAndreas Gohr        if($skiptrans && preg_match('/' . $skiptrans . '/ui', ':' . $id)) return false;
19384877e9bSAndreas Gohr        $meta = p_get_metadata($id);
19484877e9bSAndreas Gohr        if($meta['plugin']['translation']['notrans']) return false;
19584877e9bSAndreas Gohr
19684877e9bSAndreas Gohr        return true;
19784877e9bSAndreas Gohr    }
19884877e9bSAndreas Gohr
19901dd7da9SAndreas Gohr    /**
20001dd7da9SAndreas Gohr     * Return the (localized) about link
20101dd7da9SAndreas Gohr     */
20201dd7da9SAndreas Gohr    function showAbout() {
203c9640767STomasz Tomasik        global $ID;
204c9640767STomasz Tomasik        global $conf;
205c9640767STomasz Tomasik        global $INFO;
206c9640767STomasz Tomasik
2075ad1c278SAndreas Gohr        $curlc = $this->getLangPart($ID);
208f34c9eb2SAndreas Gohr
209d0bdb959SAndreas Gohr        $about = $this->getConf('about');
210d0bdb959SAndreas Gohr        if($this->getConf('localabout')) {
211d0bdb959SAndreas Gohr            list($lc, $idpart) = $this->getTransParts($about);
212f34c9eb2SAndreas Gohr            list($about, $name) = $this->buildTransID($curlc, $idpart);
213d0bdb959SAndreas Gohr            $about = cleanID($about);
214d0bdb959SAndreas Gohr        }
215c9640767STomasz Tomasik
216c9640767STomasz Tomasik        $out = '';
217c9640767STomasz Tomasik        $out .= '<sup>';
218d0bdb959SAndreas Gohr        $out .= html_wikilink($about, '?');
219c9640767STomasz Tomasik        $out .= '</sup>';
220c9640767STomasz Tomasik
221c9640767STomasz Tomasik        return $out;
222c9640767STomasz Tomasik    }
223c9640767STomasz Tomasik
22484877e9bSAndreas Gohr    /**
225bbe70520SAndreas Gohr     * Returns a list of (lc => link) for all existing translations of a page
226bbe70520SAndreas Gohr     *
227bbe70520SAndreas Gohr     * @param $id
228bbe70520SAndreas Gohr     * @return array
229bbe70520SAndreas Gohr     */
230bbe70520SAndreas Gohr    function getAvailableTranslations($id) {
231bbe70520SAndreas Gohr        $result = array();
232bbe70520SAndreas Gohr
233bbe70520SAndreas Gohr        list($lc, $idpart) = $this->getTransParts($id);
234bbe70520SAndreas Gohr        $lang = $this->realLC($lc);
235bbe70520SAndreas Gohr
236bbe70520SAndreas Gohr        foreach($this->trans as $t) {
237bbe70520SAndreas Gohr            if($t == $lc) continue; //skip self
238bbe70520SAndreas Gohr            list($link, $name) = $this->buildTransID($t, $idpart);
239bbe70520SAndreas Gohr            if(page_exists($link)) {
240bbe70520SAndreas Gohr                $result[$name] = $link;
241bbe70520SAndreas Gohr            }
242bbe70520SAndreas Gohr        }
243bbe70520SAndreas Gohr
244bbe70520SAndreas Gohr        return $result;
245bbe70520SAndreas Gohr    }
246bbe70520SAndreas Gohr
247bbe70520SAndreas Gohr    /**
248649de279SAndreas Gohr     * Creates an UI for linking to the available and configured translations
249649de279SAndreas Gohr     *
250649de279SAndreas Gohr     * Can be called from the template or via the ~~TRANS~~ syntax component.
2511469199dSAndreas Gohr     */
252649de279SAndreas Gohr    public function showTranslations() {
2531469199dSAndreas Gohr        global $conf;
2541469199dSAndreas Gohr        global $INFO;
2551469199dSAndreas Gohr
256649de279SAndreas Gohr        if(!$this->istranslatable($INFO['id'])) return '';
25784877e9bSAndreas Gohr        $this->checkage();
2581469199dSAndreas Gohr
259649de279SAndreas Gohr        list($lc, $idpart) = $this->getTransParts($INFO['id']);
26004971eeaSAndreas Gohr        $lang = $this->realLC($lc);
26139ecab8bSAndreas Gohr
2621469199dSAndreas Gohr        $out = '<div class="plugin_translation">';
263c9640767STomasz Tomasik
26404971eeaSAndreas Gohr        //show title and about
265c730e7ddSAndreas Gohr        if(isset($this->opts['title'])) {
2661469199dSAndreas Gohr            $out .= '<span>' . $this->getLang('translations');
2678bd452a3SAndreas Gohr            if($this->getConf('about')) $out .= $this->showAbout();
2681469199dSAndreas Gohr            $out .= ':</span> ';
269c730e7ddSAndreas Gohr            if(isset($this->opts['twolines'])) $out .= '<br />';
270c9640767STomasz Tomasik        }
2711469199dSAndreas Gohr
27204971eeaSAndreas Gohr        // open wrapper
27304971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
27404971eeaSAndreas Gohr            // select needs its own styling
2751469199dSAndreas Gohr            if($INFO['exists']) {
2761469199dSAndreas Gohr                $class = 'wikilink1';
2771469199dSAndreas Gohr            } else {
2781469199dSAndreas Gohr                $class = 'wikilink2';
2791469199dSAndreas Gohr            }
28004971eeaSAndreas Gohr            if(isset($this->opts['flag'])) {
28104971eeaSAndreas Gohr                $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
282649de279SAndreas Gohr            }else{
283649de279SAndreas Gohr                $flag = '';
284c9640767STomasz Tomasik            }
285649de279SAndreas Gohr
286fbc6382cSAndreas Gohr            if($conf['userewrite']) {
287fbc6382cSAndreas Gohr                $action = wl();
288fbc6382cSAndreas Gohr            } else {
289fbc6382cSAndreas Gohr                $action = script();
290fbc6382cSAndreas Gohr            }
291fbc6382cSAndreas Gohr
292fbc6382cSAndreas Gohr            $out .= '<form action="' . $action . '" id="translation__dropdown">';
29304971eeaSAndreas Gohr            if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" class="' . $class . '" /> ';
294c9640767STomasz Tomasik            $out .= '<select name="id" class="' . $class . '">';
29504971eeaSAndreas Gohr        } else {
29604971eeaSAndreas Gohr            $out .= '<ul>';
29704971eeaSAndreas Gohr        }
29804971eeaSAndreas Gohr
29904971eeaSAndreas Gohr        // insert items
30004971eeaSAndreas Gohr        foreach($this->trans as $t) {
30104971eeaSAndreas Gohr            $out .= $this->getTransItem($t, $idpart);
30204971eeaSAndreas Gohr        }
30304971eeaSAndreas Gohr
30404971eeaSAndreas Gohr        // close wrapper
30504971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
3061469199dSAndreas Gohr            $out .= '</select>';
3071469199dSAndreas Gohr            $out .= '<input name="go" type="submit" value="&rarr;" />';
3081469199dSAndreas Gohr            $out .= '</form>';
30904971eeaSAndreas Gohr        } else {
3101469199dSAndreas Gohr            $out .= '</ul>';
3111469199dSAndreas Gohr        }
3121469199dSAndreas Gohr
31304971eeaSAndreas Gohr        // show about if not already shown
314c730e7ddSAndreas Gohr        if(!isset($this->opts['title']) && $this->getConf('about')) {
31504971eeaSAndreas Gohr            $out .= '&nbsp';
31604971eeaSAndreas Gohr            $out .= $this->showAbout();
31704971eeaSAndreas Gohr        }
31804971eeaSAndreas Gohr
3191469199dSAndreas Gohr        $out .= '</div>';
3201469199dSAndreas Gohr
3211469199dSAndreas Gohr        return $out;
3221469199dSAndreas Gohr    }
323af1904f9SAndreas Gohr
32401dd7da9SAndreas Gohr    /**
325bbe70520SAndreas Gohr     * Return the local name
326bbe70520SAndreas Gohr     *
327bbe70520SAndreas Gohr     * @param $lang
328bbe70520SAndreas Gohr     * @return string
329bbe70520SAndreas Gohr     */
330bbe70520SAndreas Gohr    function getLocalName($lang) {
331bbe70520SAndreas Gohr        if($this->LN[$lang]) {
332bbe70520SAndreas Gohr            return $this->LN[$lang];
333bbe70520SAndreas Gohr        }
334bbe70520SAndreas Gohr        return $lang;
335bbe70520SAndreas Gohr    }
336bbe70520SAndreas Gohr
337bbe70520SAndreas Gohr    /**
33801dd7da9SAndreas Gohr     * Create the link or option for a single translation
33901dd7da9SAndreas Gohr     *
34004971eeaSAndreas Gohr     * @param $lc string      The language code
34101dd7da9SAndreas Gohr     * @param $idpart string  The ID of the translated page
34204971eeaSAndreas Gohr     * @returns string        The item
34301dd7da9SAndreas Gohr     */
34404971eeaSAndreas Gohr    function getTransItem($lc, $idpart) {
345c9640767STomasz Tomasik        global $ID;
346c9640767STomasz Tomasik        global $conf;
347c9640767STomasz Tomasik
34804971eeaSAndreas Gohr        list($link, $lang) = $this->buildTransID($lc, $idpart);
349c9640767STomasz Tomasik        $link = cleanID($link);
35004971eeaSAndreas Gohr
35104971eeaSAndreas Gohr        // class
352c9640767STomasz Tomasik        if(page_exists($link, '', false)) {
353c9640767STomasz Tomasik            $class = 'wikilink1';
354c9640767STomasz Tomasik        } else {
355c9640767STomasz Tomasik            $class = 'wikilink2';
356c9640767STomasz Tomasik        }
357c9640767STomasz Tomasik
35804971eeaSAndreas Gohr        // local language name
359bbe70520SAndreas Gohr        $localname = $this->getLocalName($lang);
360c9640767STomasz Tomasik
36104971eeaSAndreas Gohr        // current?
36204971eeaSAndreas Gohr        if($ID == $link) {
36304971eeaSAndreas Gohr            $sel = ' selected="selected"';
36404971eeaSAndreas Gohr            $class .= ' cur';
36504971eeaSAndreas Gohr        } else {
36604971eeaSAndreas Gohr            $sel = '';
36704971eeaSAndreas Gohr        }
368c9640767STomasz Tomasik
36904971eeaSAndreas Gohr        // flag
37004971eeaSAndreas Gohr        if(isset($this->opts['flag'])) {
37104971eeaSAndreas Gohr            $flag = DOKU_BASE . 'lib/plugins/translation/flags/' . hsc($lang) . '.gif';
37204971eeaSAndreas Gohr            $style = ' style="background-image: url(\'' . $flag . '\')"';
37304971eeaSAndreas Gohr            $class .= ' flag';
37404971eeaSAndreas Gohr        }
37504971eeaSAndreas Gohr
37604971eeaSAndreas Gohr        // what to display as name
37704971eeaSAndreas Gohr        if(isset($this->opts['name'])) {
37804971eeaSAndreas Gohr            $display = hsc($localname);
379c730e7ddSAndreas Gohr            if(isset($this->opts['langcode'])) $display .= ' (' . hsc($lang) . ')';
380c730e7ddSAndreas Gohr        } elseif(isset($this->opts['langcode'])) {
38104971eeaSAndreas Gohr            $display = hsc($lang);
38204971eeaSAndreas Gohr        } else {
38304971eeaSAndreas Gohr            $display = '&nbsp;';
38404971eeaSAndreas Gohr        }
38504971eeaSAndreas Gohr
38604971eeaSAndreas Gohr        // prepare output
38704971eeaSAndreas Gohr        $out = '';
38804971eeaSAndreas Gohr        if($this->getConf('dropdown')) {
3892546b043SAndreas Gohr            if($conf['useslash']) $link = str_replace(':', '/', $link);
3902546b043SAndreas Gohr
39104971eeaSAndreas Gohr            $out .= '<option class="' . $class . '" title="' . hsc($localname) . '" value="' . $link . '"' . $sel . $style . '>';
39204971eeaSAndreas Gohr            $out .= $display;
39304971eeaSAndreas Gohr            $out .= '</option>';
39404971eeaSAndreas Gohr        } else {
395c9640767STomasz Tomasik            $out .= '<li><div class="li">';
396a4491becSGerry Weißbach            $out .= '<a href="' . wl($link, 'tns') . '" class="' . $class . '" title="' . hsc($localname) . '">';
39704971eeaSAndreas Gohr            if($flag) $out .= '<img src="' . $flag . '" alt="' . hsc($lang) . '" height="11" />';
39804971eeaSAndreas Gohr            $out .= $display;
399c9640767STomasz Tomasik            $out .= '</a>';
400c9640767STomasz Tomasik            $out .= '</div></li>';
401c9640767STomasz Tomasik        }
402c9640767STomasz Tomasik
403c9640767STomasz Tomasik        return $out;
404c9640767STomasz Tomasik    }
405c9640767STomasz Tomasik
40684877e9bSAndreas Gohr    /**
40784877e9bSAndreas Gohr     * Checks if the current page is a translation of a page
40884877e9bSAndreas Gohr     * in the default language. Displays a notice when it is
40984877e9bSAndreas Gohr     * older than the original page. Tries to lin to a diff
41084877e9bSAndreas Gohr     * with changes on the original since the translation
41184877e9bSAndreas Gohr     */
41284877e9bSAndreas Gohr    function checkage() {
41384877e9bSAndreas Gohr        global $ID;
41484877e9bSAndreas Gohr        global $INFO;
41584877e9bSAndreas Gohr        if(!$this->getConf('checkage')) return;
41684877e9bSAndreas Gohr        if(!$INFO['exists']) return;
41784877e9bSAndreas Gohr        $lng = $this->getLangPart($ID);
41884877e9bSAndreas Gohr        if($lng == $this->defaultlang) return;
419af1904f9SAndreas Gohr
42084877e9bSAndreas Gohr        $rx = '/^' . $this->tns . '((' . join('|', $this->trans) . '):)?/';
42184877e9bSAndreas Gohr        $idpart = preg_replace($rx, '', $ID);
42284877e9bSAndreas Gohr
42384877e9bSAndreas Gohr        // compare modification times
42484877e9bSAndreas Gohr        list($orig, $name) = $this->buildTransID($this->defaultlang, $idpart);
42584877e9bSAndreas Gohr        $origfn = wikiFN($orig);
42684877e9bSAndreas Gohr        if($INFO['lastmod'] >= @filemtime($origfn)) return;
42784877e9bSAndreas Gohr
42884877e9bSAndreas Gohr        // get revision from before translation
42984877e9bSAndreas Gohr        $orev = 0;
43084877e9bSAndreas Gohr        $revs = getRevisions($orig, 0, 100);
43184877e9bSAndreas Gohr        foreach($revs as $rev) {
43284877e9bSAndreas Gohr            if($rev < $INFO['lastmod']) {
43384877e9bSAndreas Gohr                $orev = $rev;
43484877e9bSAndreas Gohr                break;
43584877e9bSAndreas Gohr            }
43684877e9bSAndreas Gohr        }
43784877e9bSAndreas Gohr
43844552920SAndreas Gohr        // see if the found revision still exists
43944552920SAndreas Gohr        if($orev && !page_exists($orig, $orev)) $orev = 0;
44044552920SAndreas Gohr
44184877e9bSAndreas Gohr        // build the message and display it
442dc3fbdb9SOleksiy Zagorskyi        $orig = cleanID($orig);
44384877e9bSAndreas Gohr        $msg = sprintf($this->getLang('outdated'), wl($orig));
44484877e9bSAndreas Gohr        if($orev) {
4455fd0d0d1SAndreas Gohr            $msg .= sprintf(
4465fd0d0d1SAndreas Gohr                ' ' . $this->getLang('diff'),
4475fd0d0d1SAndreas Gohr                wl($orig, array('do' => 'diff', 'rev' => $orev))
4485fd0d0d1SAndreas Gohr            );
44984877e9bSAndreas Gohr        }
45000431e1eSAndreas Gohr
45100431e1eSAndreas Gohr        echo '<div class="notify">' . $msg . '</div>';
45284877e9bSAndreas Gohr    }
453a4491becSGerry Weißbach
454a4491becSGerry Weißbach    /**
455a4491becSGerry Weißbach     * Checks if the current ID has a translated page
456a4491becSGerry Weißbach     */
457a4491becSGerry Weißbach	function hasTranslation($inputID = null) {
458a4491becSGerry Weißbach		global $ID, $INFO, $conf;
459a4491becSGerry Weißbach
460a4491becSGerry Weißbach        if ( empty($inputID) )
461a4491becSGerry Weißbach        {
462a4491becSGerry Weißbach            $inputID = $ID;
463a4491becSGerry Weißbach        }
464a4491becSGerry Weißbach
465a4491becSGerry Weißbach        if ( !$this->istranslatable($id) ) return false;
466a4491becSGerry Weißbach
467a4491becSGerry Weißbach		$idpart = $this->getIDPart($inputID);
468a4491becSGerry Weißbach
469a4491becSGerry Weißbach		foreach($this->trans as $t)
470a4491becSGerry Weißbach		{
471a4491becSGerry Weißbach			list($link,$name) = $this->buildTransID($t,$idpart,false);
472a4491becSGerry Weißbach			$link = cleanID($link);
473a4491becSGerry Weißbach
474a4491becSGerry Weißbach			if( $inputID != $link && page_exists($link,'',false) ){
475a4491becSGerry Weißbach				return true;
476a4491becSGerry Weißbach			}
477a4491becSGerry Weißbach		}
478a4491becSGerry Weißbach
479a4491becSGerry Weißbach		return false;
480a4491becSGerry Weißbach	}
481af1904f9SAndreas Gohr}
482