bf64f517f3b62e012ec1856304c675cea17459de
[moodle.git] / filter / multilang / filter.php
1 <?php\r
2 ///////////////////////////////////////////////////////////////////////////\r
3 //                                                                       //\r
4 // This program is part of Moodle - Modular Object-Oriented Dynamic      //\r
5 // Learning Environment - http://moodle.com                              //\r
6 //                                                                       //\r
7 // $Id$ //\r
8 //                                                                       //\r
9 // Copyright (C) 2004  Gaëtan Frenoy <gaetan à frenoy.net>               //\r
10 //                                                                       //\r
11 // This program is free software; you can redistribute it and/or modify  //\r
12 // it under the terms of the GNU General Public License as published by  //\r
13 // the Free Software Foundation; either version 2 of the License, or     //\r
14 // (at your option) any later version.                                   //\r
15 //                                                                       //\r
16 // This program is distributed in the hope that it will be useful,       //\r
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //\r
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //\r
19 // GNU General Public License for more details:                          //\r
20 //                                                                       //\r
21 //          http://www.gnu.org/copyleft/gpl.html                         //\r
22 //                                                                       //\r
23 ///////////////////////////////////////////////////////////////////////////\r
24 //                                                                       //\r
25 //  To activate this filter, add a line like this to your                //\r
26 //  list of filters in your Filter configuration:                        //\r
27 //                                                                       //\r
28 //       filter/multilang/filter.php                                     //\r
29 //                                                                       //\r
30 // See README.txt for more information about this module                 //\r
31 //                                                                       //\r
32 ///////////////////////////////////////////////////////////////////////////\r
33 \r
34 /// These lines are important - the variable must match the name \r
35 /// of the actual function below\r
36 \r
37 $textfilter_function = 'multilang_filter';\r
38 \r
39 if (function_exists($textfilter_function)) {\r
40     return;\r
41 }\r
42 \r
43 \r
44 /// Given XML multilinguage text, return relevant text according to\r
45 /// current language.  i.e.=\r
46 ///   - look for lang sections in the code.\r
47 ///   - if there exists texts in the currently active language, print them.\r
48 ///   - else, if there exists texts in the current parent language, print them.\r
49 ///   - else, if there are English texts, print them\r
50 ///   - else, print everything.\r
51 ///\r
52 /// $text is raw unmodified user text\r
53 \r
54 function multilang_filter($courseid, $text) {\r
55 \r
56     global $CFG;\r
57 \r
58 /// Make sure XML is enabled in this PHP\r
59     if (!function_exists('xml_parser_create')) {\r
60         return $text;\r
61     }\r
62 \r
63 /// Do a quick check using stripos to avoid unnecessary work\r
64     if (stripos($text, '<lang') === false) {\r
65         return $text;\r
66     }\r
67 \r
68 /// Flag this text as something not to cache\r
69     $CFG->currenttextiscacheable = false;\r
70 \r
71 /// Get current language\r
72     $currentlanguage = current_language();\r
73 \r
74 /// Strip all spaces between tags\r
75     $text = eregi_replace(">"."[[:space:]]+"."<","><", $text);\r
76     $text = eregi_replace("&", "&amp;", $text);\r
77 \r
78 /// Parse XML multilingual file\r
79     $xml = new XMLParser($text);\r
80     $text = $xml->texts['en'];\r
81     foreach ($xml->texts as $lang => $lang_text) {\r
82         if ($lang == $currentlanguage) $text = $lang_text;\r
83     }\r
84 \r
85     return $text;\r
86 }\r
87 \r
88 \r
89 \r
90 /// XML Parser for Multilingual text\r
91 /// Search for "<LANG>" tags and stores inner xml into $this->texts[lang]\r
92 ///\r
93 class XMLParser { \r
94   /// Currently parsed language\r
95   var $current_lang = NULL;\r
96   /// Currently parsed format\r
97   var $current_format = NULL;\r
98   /// Currently parsed text\r
99   var $current_text = NULL;\r
100   /// List of parsed texts so far\r
101   var $texts = NULL;\r
102 \r
103 /// Constructor\r
104   function XMLParser($data) {\r
105     /// Init member variables\r
106     $this->current_lang = NULL;\r
107     $this->current_format = NULL;\r
108     $this->current_text = '';\r
109     $this->texts = array();\r
110 \r
111     /// Default text for default language is input data\r
112     $this->texts['en'] = $data;\r
113 \r
114     /// Create parser\r
115     $xml_parser = xml_parser_create(); \r
116     xml_set_object($xml_parser, &$this); \r
117     xml_set_element_handler($xml_parser, 'startElement', 'endElement'); \r
118     xml_set_character_data_handler($xml_parser, 'characterData'); \r
119     /// Parse date (embed data around dummy tag so parser will receive \r
120     /// a complete XML document\r
121     if (!xml_parse($xml_parser, '<moodle_xml_text_20040116>'.$data.'</moodle_xml_text_20040116>', true))\r
122     {\r
123       /*\r
124       die(sprintf("XML error: %s at line %d",\r
125                   xml_error_string(xml_get_error_code($xml_parser)),\r
126                   xml_get_current_line_number($xml_parser)));\r
127       */\r
128     }\r
129     /// Free resource\r
130     xml_parser_free($xml_parser); \r
131   }\r
132 \r
133 /// Callback on start of an XML element\r
134   function startElement($parser, $tag, $attributeList) {\r
135     if ($tag == 'LANG' && is_null($this->current_lang))\r
136     {\r
137       // <LANG> tag found, initialise current member vars\r
138       // default language is 'en'\r
139       $this->current_lang = array_key_exists("LANG", $attributeList)?strtolower($attributeList['LANG']):'en';\r
140       // default format is 'auto'\r
141       $this->current_format = array_key_exists('FORMAT', $attributeList)?strtolower($attributeList['FORMAT']):'auto';\r
142       // init inner xml\r
143       $this->current_text = '';\r
144     }\r
145     elseif (!is_null($this->current_lang))\r
146     {\r
147       // If a language has been found already, process tag and attributes\r
148       // and add it to inner xml for current language\r
149       $this->current_text .= "<{$tag}";\r
150       foreach ($attributeList as $key => $val) {\r
151         $this->current_text .= " {$key}=\"{$val}\"";\r
152       }\r
153       $this->current_text .= ">";\r
154     }\r
155     else {\r
156       // This code is outside any <LANG> tag, text is probably not\r
157       // a valid multilingual format\r
158     }\r
159   } \r
160   \r
161 /// Callback on end of an XML element\r
162   function endElement($parser, $tag) { \r
163     if ($tag == 'LANG' && !is_null($this->current_lang)) {\r
164       // <LANG> tag found while <LANG> tag was already open, \r
165       // store inner xml and reset context\r
166       $this->texts[$this->current_lang] = $this->current_text;\r
167       $this->current_text = '';\r
168       $this->current_lang = NULL;\r
169       $this->current_format = NULL;\r
170     }\r
171     elseif (!is_null($this->current_lang)) {\r
172       // If a language has been found already, process tag\r
173       // and add it to inner xml for current language\r
174       $this->current_text .= "</{$tag}>";\r
175     }\r
176     else {\r
177       // This code is outside any <LANG> tag, text is probably not\r
178       // a valid multilingual format\r
179     }\r
180   } \r
181   \r
182 /// Callback on character data\r
183   function characterData($parser, $data) {\r
184     // Process inner text and add it to current inner xml\r
185     $this->current_text .= $data;\r
186   } \r
187\r
188 \r
189 ?>\r