xref: /plugin/autotranslation/helper.php (revision 01dd7da952b399244b4a96b0b4311ee4443f6cbb)
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
110*01dd7da9SAndreas Gohr    /**
111*01dd7da9SAndreas Gohr     * Return the (localized) about link
112*01dd7da9SAndreas Gohr     *
113*01dd7da9SAndreas Gohr     * @fixme why is this doing the detection stuff again?
114*01dd7da9SAndreas Gohr     */
115*01dd7da9SAndreas Gohr    function showAbout() {
116c9640767STomasz Tomasik        global $ID;
117c9640767STomasz Tomasik        global $conf;
118c9640767STomasz Tomasik        global $INFO;
119c9640767STomasz Tomasik
120c9640767STomasz Tomasik        $this->checkage();
121c9640767STomasz Tomasik
122c9640767STomasz Tomasik        $LN = confToHash(dirname(__FILE__).'/lang/langnames.txt');
123c9640767STomasz Tomasik
124c9640767STomasz Tomasik        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
125c9640767STomasz Tomasik        $idpart = preg_replace($rx,'',$ID);
126c9640767STomasz Tomasik
127c9640767STomasz Tomasik        $out = '';
128c9640767STomasz Tomasik        $out .= '<sup>';
129c9640767STomasz Tomasik        if($this->getConf('localabout')){
130c9640767STomasz Tomasik            $lc = '';
131c9640767STomasz Tomasik
132c9640767STomasz Tomasik            //try main lang namespace
133c9640767STomasz Tomasik            foreach($this->trans as $t){
134c9640767STomasz Tomasik                list($link,$name) = $this->buildTransID($t,$idpart);
135c9640767STomasz Tomasik                $link = cleanID($link);
136c9640767STomasz Tomasik                if($ID == $link){
137c9640767STomasz Tomasik                    $lc = hsc($name);
138c9640767STomasz Tomasik                }
139c9640767STomasz Tomasik                if ($lc) break;
140c9640767STomasz Tomasik            }
141c9640767STomasz Tomasik
142c9640767STomasz Tomasik            //try browser language
143c9640767STomasz Tomasik            if(!$lc) $lc = $this->getBrowserLang();
144c9640767STomasz Tomasik
145c9640767STomasz Tomasik            //try wiki language
146c9640767STomasz Tomasik            if(!$lc) $lc = $conf['lang'];
147c9640767STomasz Tomasik
148c9640767STomasz Tomasik            if(!$lc) { //can't find language
149c9640767STomasz Tomasik                $localabout = $this->getConf('about'); //http://localhost/dokuwiki/doku.php?id=translation:about
150c9640767STomasz Tomasik            } else { //i found language!
151c9640767STomasz Tomasik                        $localabout = $lc.':'.$this->getConf('about'); //http://localhost/dokuwiki/doku.php?id=en:translation:about
152c9640767STomasz Tomasik            }
153c9640767STomasz Tomasik
154c9640767STomasz Tomasik            //make link
155c9640767STomasz Tomasik            $out .= html_wikilink($localabout,'?');
156*01dd7da9SAndreas Gohr            } else {
157c9640767STomasz Tomasik            $out .= html_wikilink($this->getConf('about'),'?');
158c9640767STomasz Tomasik        }
159c9640767STomasz Tomasik        $out .= '</sup>';
160c9640767STomasz Tomasik
161c9640767STomasz Tomasik        return $out;
162c9640767STomasz Tomasik    }
163c9640767STomasz Tomasik
16484877e9bSAndreas Gohr    /**
1651469199dSAndreas Gohr     * Displays the available and configured translations. Needs to be placed in the template.
1661469199dSAndreas Gohr     */
1671469199dSAndreas Gohr    function showTranslations(){
1681469199dSAndreas Gohr        global $ID;
1691469199dSAndreas Gohr        global $conf;
1701469199dSAndreas Gohr        global $INFO;
1711469199dSAndreas Gohr
17284877e9bSAndreas Gohr        if(!$this->istranslatable($ID)) return;
17384877e9bSAndreas Gohr
17484877e9bSAndreas Gohr        $this->checkage();
1751469199dSAndreas Gohr
17639ecab8bSAndreas Gohr        $LN = confToHash(dirname(__FILE__).'/lang/langnames.txt');
17739ecab8bSAndreas Gohr
1781469199dSAndreas Gohr        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
1791469199dSAndreas Gohr        $idpart = preg_replace($rx,'',$ID);
1801469199dSAndreas Gohr
1811469199dSAndreas Gohr        $out  = '<div class="plugin_translation">';
182c9640767STomasz Tomasik
183c9640767STomasz Tomasik        //show text
184c9640767STomasz Tomasik        if ($this->getConf('description')){
1851469199dSAndreas Gohr            $out .= '<span>'.$this->getLang('translations');
186c9640767STomasz Tomasik            if ($this->getConf('showabout')) $out .= $this->showAbout();
1871469199dSAndreas Gohr            $out .= ':</span> ';
188c9640767STomasz Tomasik        }
1891469199dSAndreas Gohr
190*01dd7da9SAndreas Gohr        if($this->getConf('dropdown')){ // use dropdown fixme move to own functions
1911469199dSAndreas Gohr            if($INFO['exists']){
1921469199dSAndreas Gohr                $class = 'wikilink1';
1931469199dSAndreas Gohr            }else{
1941469199dSAndreas Gohr                $class = 'wikilink2';
1951469199dSAndreas Gohr            }
196c9640767STomasz Tomasik
197*01dd7da9SAndreas Gohr            $out2 = ""; //FIXME ugly name
1981469199dSAndreas Gohr            foreach($this->trans as $t){
1991469199dSAndreas Gohr                list($link,$name) = $this->buildTransID($t,$idpart);
2001469199dSAndreas Gohr                $link = cleanID($link);
2011469199dSAndreas Gohr                if($ID == $link){
2021469199dSAndreas Gohr                    $sel = ' selected="selected"';
203*01dd7da9SAndreas Gohr                    if($this->getConf('dropdown2')) { //FIXME ugly name
204c9640767STomasz Tomasik                        $out .= $this->makecountrylink($LN, $idpart, $t, false);
205c9640767STomasz Tomasik                        $out .= "&nbsp;";
206c9640767STomasz Tomasik                    }
2071469199dSAndreas Gohr                }else{
2081469199dSAndreas Gohr                    $sel = '';
2091469199dSAndreas Gohr                }
2101469199dSAndreas Gohr                if(page_exists($link,'',false)){
2111469199dSAndreas Gohr                    $class = 'wikilink1';
2121469199dSAndreas Gohr                }else{
2131469199dSAndreas Gohr                    $class = 'wikilink2';
2141469199dSAndreas Gohr                }
215c9640767STomasz Tomasik
216c9640767STomasz Tomasik                //linktitle
217c9640767STomasz Tomasik                $linktitle = '';
218c9640767STomasz Tomasik                if (strlen($LN[$name]) > 0){
219c9640767STomasz Tomasik                    $linktitle = $LN[$name];
220c9640767STomasz Tomasik                } else{
221c9640767STomasz Tomasik                    $linktitle = hsc($name);
2221469199dSAndreas Gohr                }
223c9640767STomasz Tomasik
224c9640767STomasz Tomasik                $out2 .= '<option value="'.$link.'"'.$sel.' class="'.$class.'" title="'.$linktitle.'">'.hsc($name).'</option>';
225c9640767STomasz Tomasik            }
226c9640767STomasz Tomasik            $out .= '<form action="'.wl().'" id="translation__dropdown">';
227c9640767STomasz Tomasik            $out .= '<select name="id" class="'.$class.'">';
228c9640767STomasz Tomasik            $out .= $out2;
2291469199dSAndreas Gohr            $out .= '</select>';
2301469199dSAndreas Gohr            $out .= '<input name="go" type="submit" value="&rarr;" />';
2311469199dSAndreas Gohr            $out .= '</form>';
232c9640767STomasz Tomasik
233c9640767STomasz Tomasik            //link to about (right)
234c9640767STomasz Tomasik            if (!$this->getConf('description') && $this->getConf('showabout')) {
235c9640767STomasz Tomasik                $out .= '&nbsp';
236c9640767STomasz Tomasik                $out .= $this->showAbout();
23739ecab8bSAndreas Gohr            }
238c9640767STomasz Tomasik        }else{ // use list
239c9640767STomasz Tomasik            $out .= '<ul>';
240c9640767STomasz Tomasik
241*01dd7da9SAndreas Gohr            // FIXME what's this?
242c9640767STomasz Tomasik            if (!$this->getConf('description') && $this->getConf('showabout')) {
243c9640767STomasz Tomasik                $out .= '&nbsp';
244c9640767STomasz Tomasik                $out .= $this->showAbout();
245c9640767STomasz Tomasik            }
246c9640767STomasz Tomasik
247c9640767STomasz Tomasik            foreach($this->trans as $t){
248c9640767STomasz Tomasik                $out .= $this->makecountrylink($LN, $idpart, $t, true);
2491469199dSAndreas Gohr            }
2501469199dSAndreas Gohr            $out .= '</ul>';
2511469199dSAndreas Gohr        }
2521469199dSAndreas Gohr
2531469199dSAndreas Gohr        $out .= '</div>';
2541469199dSAndreas Gohr
2551469199dSAndreas Gohr        return $out;
2561469199dSAndreas Gohr    }
257af1904f9SAndreas Gohr
258*01dd7da9SAndreas Gohr    /**
259*01dd7da9SAndreas Gohr     * Create the link or option for a single translation
260*01dd7da9SAndreas Gohr     *
261*01dd7da9SAndreas Gohr     * @fixme bad name - translations are not about countries
262*01dd7da9SAndreas Gohr     * @param $LN string      The language
263*01dd7da9SAndreas Gohr     * @param $idpart string  The ID of the translated page
264*01dd7da9SAndreas Gohr     * @param $t  FIXME
265*01dd7da9SAndreas Gohr     * @param $div bool  true for lists, false for dropdown FIXME
266*01dd7da9SAndreas Gohr     * @returns FIXME
267*01dd7da9SAndreas Gohr     */
268*01dd7da9SAndreas Gohr    function makecountrylink($LN, $idpart, $t, $div) {
269c9640767STomasz Tomasik        global $ID;
270c9640767STomasz Tomasik        global $conf;
271c9640767STomasz Tomasik        global $INFO;
272c9640767STomasz Tomasik
273c9640767STomasz Tomasik        require(DOKU_PLUGIN.'translation/flags/langnames.php');
274c9640767STomasz Tomasik
275c9640767STomasz Tomasik        list($link,$name) = $this->buildTransID($t,$idpart);
276c9640767STomasz Tomasik        $link = cleanID($link);
277c9640767STomasz Tomasik        if(page_exists($link,'',false)){
278c9640767STomasz Tomasik            $class = 'wikilink1';
279c9640767STomasz Tomasik        }else{
280c9640767STomasz Tomasik            $class = 'wikilink2';
281c9640767STomasz Tomasik        }
282c9640767STomasz Tomasik
283c9640767STomasz Tomasik        //linktitle
284c9640767STomasz Tomasik        $linktitle = '';
285c9640767STomasz Tomasik        if (strlen($LN[$name]) > 0){
286c9640767STomasz Tomasik            $linktitle = $LN[$name];
287c9640767STomasz Tomasik        } else{
288c9640767STomasz Tomasik            $linktitle = hsc($name);
289c9640767STomasz Tomasik        }
290c9640767STomasz Tomasik
291c9640767STomasz Tomasik        //if (show flag AND ((flag exist) OR (flag not exist AND show blank flag))
292c9640767STomasz Tomasik        if (($langflag[hsc($name)] != NULL && strlen($langflag[hsc($name)]) > 0 && $this->getConf('flags')) || $this->getConf('flags') && $this->getConf('blankflag')) {
293c9640767STomasz Tomasik
294c9640767STomasz Tomasik            resolve_pageid(getNS($ID),$link,$exists);
295*01dd7da9SAndreas Gohr            if ($div) {
296c9640767STomasz Tomasik                if ($exists){ //solid box
297c9640767STomasz Tomasik                    $out .= '  <li><div class="li">';
298c9640767STomasz Tomasik                } else{ //50% transparent box (50% transparent flag)
299c9640767STomasz Tomasik                    $out .= '  <li><div class="flag_not_exists">';
300c9640767STomasz Tomasik                }
301c9640767STomasz Tomasik            }
302c9640767STomasz Tomasik
303c9640767STomasz Tomasik            //html_wikilink works very slow for images
304c9640767STomasz Tomasik            //$flag['title'] = $langname[$name];
305c9640767STomasz Tomasik            //$flag['src'] = DOKU_URL.'lib/plugins/translation/flags/'.$langflag[$name];
306c9640767STomasz Tomasik            //$out .= html_wikilink($link,$flag);
307c9640767STomasz Tomasik
308c9640767STomasz Tomasik            $out .= '<a href="'.wl($link).'"';
309c9640767STomasz Tomasik            $out .= 'title="'.$linktitle.'"';
310c9640767STomasz Tomasik            //class for image
311*01dd7da9SAndreas Gohr            $out .= 'class="wikilink3"'; //FIXME WTF?
312c9640767STomasz Tomasik            $out .= '>';
313c9640767STomasz Tomasik
314c9640767STomasz Tomasik            //show flag
315c9640767STomasz Tomasik            if ($langflag[hsc($name)] != NULL && strlen($langflag[hsc($name)]) > 0){
316c9640767STomasz Tomasik                $out .= '<img src="'.DOKU_URL.'lib/plugins/translation/flags/'.$langflag[hsc($name)].'" alt='.$linktitle.'" border="0">';
317c9640767STomasz Tomasik            } else{ //show blank flag
318c9640767STomasz Tomasik                //$out .= '<img src="'.DOKU_BASE.'lib/images/blank.gif'.'" width=15 height=11 alt="'.$linktitle.'" border="0">';
319c9640767STomasz Tomasik                $out .= '<img src="'.DOKU_BASE.'lib/plugins/translation/flags/blankflag.gif'.'" width=15 height=11 alt="'.$linktitle.'" border="0">';
320c9640767STomasz Tomasik            }
321c9640767STomasz Tomasik            $out .= '</a>';
322c9640767STomasz Tomasik
323*01dd7da9SAndreas Gohr        } else{ //show text (also if flag not exist and blankflag=false)
324*01dd7da9SAndreas Gohr            if ($div) {
325c9640767STomasz Tomasik                $out .= '  <li><div class="li">';
326c9640767STomasz Tomasik            }
327c9640767STomasz Tomasik            $out .= html_wikilink($link,hsc($name));
328c9640767STomasz Tomasik        }
329*01dd7da9SAndreas Gohr        if ($div) {
330c9640767STomasz Tomasik            $out .= '</div></li>';
331c9640767STomasz Tomasik        }
332c9640767STomasz Tomasik
333c9640767STomasz Tomasik        return $out;
334c9640767STomasz Tomasik    }
335c9640767STomasz Tomasik
33684877e9bSAndreas Gohr    /**
33784877e9bSAndreas Gohr     * Checks if the current page is a translation of a page
33884877e9bSAndreas Gohr     * in the default language. Displays a notice when it is
33984877e9bSAndreas Gohr     * older than the original page. Tries to lin to a diff
34084877e9bSAndreas Gohr     * with changes on the original since the translation
34184877e9bSAndreas Gohr     */
34284877e9bSAndreas Gohr    function checkage(){
34384877e9bSAndreas Gohr        global $ID;
34484877e9bSAndreas Gohr        global $INFO;
34584877e9bSAndreas Gohr        if(!$this->getConf('checkage')) return;
34684877e9bSAndreas Gohr        if(!$INFO['exists']) return;
34784877e9bSAndreas Gohr        $lng = $this->getLangPart($ID);
34884877e9bSAndreas Gohr        if($lng == $this->defaultlang) return;
349af1904f9SAndreas Gohr
35084877e9bSAndreas Gohr        $rx = '/^'.$this->tns.'(('.join('|',$this->trans).'):)?/';
35184877e9bSAndreas Gohr        $idpart = preg_replace($rx,'',$ID);
35284877e9bSAndreas Gohr
35384877e9bSAndreas Gohr        // compare modification times
35484877e9bSAndreas Gohr        list($orig,$name) = $this->buildTransID($this->defaultlang,$idpart);
35584877e9bSAndreas Gohr        $origfn = wikiFN($orig);
35684877e9bSAndreas Gohr        if($INFO['lastmod'] >= @filemtime($origfn) ) return;
35784877e9bSAndreas Gohr
35884877e9bSAndreas Gohr        // get revision from before translation
35984877e9bSAndreas Gohr        $orev = 0;
36084877e9bSAndreas Gohr        $revs = getRevisions($orig,0,100);
36184877e9bSAndreas Gohr        foreach($revs as $rev){
36284877e9bSAndreas Gohr            if($rev < $INFO['lastmod']){
36384877e9bSAndreas Gohr                $orev = $rev;
36484877e9bSAndreas Gohr                break;
36584877e9bSAndreas Gohr            }
36684877e9bSAndreas Gohr        }
36784877e9bSAndreas Gohr
36844552920SAndreas Gohr        // see if the found revision still exists
36944552920SAndreas Gohr        if($orev && !page_exists($orig,$orev)) $orev=0;
37044552920SAndreas Gohr
37184877e9bSAndreas Gohr        // build the message and display it
372dc3fbdb9SOleksiy Zagorskyi        $orig = cleanID($orig);
37384877e9bSAndreas Gohr        $msg = sprintf($this->getLang('outdated'),wl($orig));
37484877e9bSAndreas Gohr        if($orev){
37584877e9bSAndreas Gohr            $msg .= sprintf(' '.$this->getLang('diff'),
37684877e9bSAndreas Gohr                    wl($orig,array('do'=>'diff','rev'=>$orev)));
37784877e9bSAndreas Gohr        }
37800431e1eSAndreas Gohr
37900431e1eSAndreas Gohr        echo '<div class="notify">'.$msg.'</div>';
38084877e9bSAndreas Gohr    }
381af1904f9SAndreas Gohr}
382