* Remove a redundant function: LanguageSr::getVariantname.
[lhc/web/wiklou.git] / maintenance / languages.inc
1 <?php
2 /**
3 * Handle messages in the language files.
4 *
5 * @package MediaWiki
6 * @subpackage Maintenance
7 */
8
9 class languages {
10 private $mList = array();
11 private $mMessages = array();
12 private $mTranslatableMessages = array();
13 private $mIgnoredMessages = array(
14 'sidebar',
15 'addsection',
16 'anonnotice',
17 'catseparator',
18 'googlesearch',
19 'exif-make-value',
20 'exif-model-value',
21 'exif-software-value',
22 'history_copyright',
23 'licenses',
24 'linkprefix',
25 'loginend',
26 'loginlanguagelinks',
27 'markaspatrolledlink',
28 'newarticletextanon',
29 'noarticletextanon',
30 'number_of_watching_users_RCview',
31 'pubmedurl',
32 'randompage-url',
33 'recentchanges-url',
34 'rfcurl',
35 'shareddescriptionfollows',
36 'signupend',
37 'sitenotice',
38 'sitesubtitle',
39 'sitetitle',
40 'talkpagetext',
41 'trackback',
42 'trackbackexcerpt',
43 'widthheight',
44 );
45
46 /**
47 * Load the list of languages: all the Messages*.php
48 * files in the languages directory.
49 */
50 function __construct() {
51 global $IP;
52 $dir = opendir("$IP/languages");
53 while ( $file = readdir( $dir ) ) {
54 if ( preg_match( "/Messages([^.]*?)\.php$/", $file, $matches ) ) {
55 $this->mList[] = str_replace( '_', '-', strtolower( substr( $matches[1], 0, 1 ) ) . substr( $matches[1], 1 ) );
56 }
57 }
58 sort( $this->mList );
59 }
60
61 /**
62 * Get the language list.
63 *
64 * @return the language list
65 */
66 public function getList() {
67 return $this->mList;
68 }
69
70 /**
71 * Load the messages for a specific langauge from the messages file.
72 *
73 * @param $code The langauge code.
74 */
75 private function loadMessages( $code ) {
76 if ( !isset( $this->mMessages[$code] ) ) {
77 global $IP;
78 $filename = Language::getFileName( "$IP/languages/Messages", $code, '.php' );
79 if ( file_exists( $filename ) ) {
80 require( $filename );
81 if ( isset( $messages ) ) {
82 $this->mMessages[$code] = $messages;
83 if ( $code == 'en' ) {
84 $this->mTranslatableMessages = $this->mMessages['en'];
85 foreach ( array_keys( $this->mTranslatableMessages ) as $key ) {
86 if ( in_array( $key, $this->mIgnoredMessages ) ) {
87 unset( $this->mTranslatableMessages[$key] );
88 }
89 }
90 }
91 } else {
92 $this->mMessages[$code] = array();
93 }
94 } else {
95 $this->mMessages[$code] = array();
96 }
97 }
98 }
99
100 /**
101 * Get all the messages for a specific langauge, without the fallback
102 * language messages.
103 *
104 * @param $code The langauge code.
105 *
106 * @return The messages in this language.
107 */
108 public function getMessagesFor( $code ) {
109 $this->loadMessages( $code );
110 return $this->mMessages[$code];
111 }
112
113 /**
114 * Get all the messages which are translatable - not ignored messages.
115 *
116 * @param $code The langauge code.
117 *
118 * @return The messages in this language.
119 */
120 public function getTranslatableMessages() {
121 $this->loadMessages( 'en' );
122 return $this->mTranslatableMessages;
123 }
124
125 /**
126 * Get the translated messages for a specific language.
127 *
128 * @param $code The langauge code.
129 *
130 * @return The translated messages for this language.
131 */
132 public function getTranslatedMessages( $code ) {
133 $this->loadMessages( 'en' );
134 $this->loadMessages( $code );
135 $translatedMessages = array();
136 foreach ( $this->mTranslatableMessages as $key => $value ) {
137 if ( isset( $this->mMessages[$code][$key] ) ) {
138 $translatedMessages[$key] = $value;
139 }
140 }
141 return $translatedMessages;
142 }
143
144 /**
145 * Get the untranslated messages for a specific language.
146 *
147 * @param $code The langauge code.
148 *
149 * @return The untranslated messages for this language.
150 */
151 public function getUntranslatedMessages( $code ) {
152 $this->loadMessages( 'en' );
153 $this->loadMessages( $code );
154 $untranslatedMessages = array();
155 foreach ( $this->mTranslatableMessages as $key => $value ) {
156 if ( !isset( $this->mMessages[$code][$key] ) ) {
157 $untranslatedMessages[$key] = $value;
158 }
159 }
160 return $untranslatedMessages;
161 }
162
163 /**
164 * Get the duplicate messages for a specific language.
165 *
166 * @param $code The langauge code.
167 *
168 * @return The duplicate messages for this language.
169 */
170 public function getDuplicateMessages( $code ) {
171 $this->loadMessages( 'en' );
172 $this->loadMessages( $code );
173 $duplicateMessages = array();
174 foreach ( $this->mMessages[$code] as $key => $value ) {
175 if ( @$this->mTranslatableMessages[$key] == $value ) {
176 $duplicateMessages[$key] = $value;
177 }
178 }
179 return $duplicateMessages;
180 }
181
182 /**
183 * Get the obsolete messages for a specific language.
184 *
185 * @param $code The langauge code.
186 *
187 * @return The obsolete messages for this language.
188 */
189 public function getObsoleteMessages( $code ) {
190 $this->loadMessages( 'en' );
191 $this->loadMessages( $code );
192 $obsoleteMessages = array();
193 foreach ( $this->mMessages[$code] as $key => $value ) {
194 if ( !isset( $this->mTranslatableMessages[$key] ) ) {
195 $obsoleteMessages[$key] = $value;
196 }
197 }
198 return $obsoleteMessages;
199 }
200
201 /**
202 * Get the messages which do not use some variables.
203 *
204 * @param $code The langauge code.
205 *
206 * @return The messages which do not use some variables in this language.
207 */
208 public function getMessagesWithoutVariables( $code ) {
209 $this->loadMessages( 'en' );
210 $this->loadMessages( $code );
211 $variables = array( '\$1', '\$2', '\$3', '\$4', '\$5', '\$6', '\$7', '\$8', '\$9' );
212 $messagesWithoutVariables = array();
213 foreach ( $this->mMessages[$code] as $key => $value ) {
214 if ( isset( $this->mTranslatableMessages[$key] ) ) {
215 $missing = array();
216 foreach ( $variables as $var ) {
217 if ( preg_match( "/$var/sU", $this->mTranslatableMessages[$key] ) &&
218 !preg_match( "/$var/sU", $value ) ) {
219 $missing[] = str_replace( '\$', '$', $var );
220 }
221 }
222 if ( count( $missing ) > 0 ) {
223 $messagesWithoutVariables[$key] = implode( ', ', $missing );
224 }
225 }
226 }
227 return $messagesWithoutVariables;
228 }
229
230 /**
231 * Get the empty messages.
232 *
233 * @param $code The langauge code.
234 *
235 * @return The empty messages for this language.
236 */
237 public function getEmptyMessages( $code ) {
238 $this->loadMessages( 'en' );
239 $this->loadMessages( $code );
240 $emptyMessages = array();
241 foreach ( $this->mMessages[$code] as $key => $value ) {
242 if ( isset( $this->mTranslatableMessages[$key] ) &&
243 ( $this->mMessages[$code][$key] === '' || $this->mMessages[$code][$key] === '-' ) ) {
244 $emptyMessages[$key] = $value;
245 }
246 }
247 return $emptyMessages;
248 }
249
250 /**
251 * Get the messages with trailing whitespace.
252 *
253 * @param $code The langauge code.
254 *
255 * @return The messages with trailing whitespace in this language.
256 */
257 public function getMessagesWithWhitespace( $code ) {
258 $this->loadMessages( 'en' );
259 $this->loadMessages( $code );
260 $messagesWithWhitespace = array();
261 foreach ( $this->mMessages[$code] as $key => $value ) {
262 if ( isset( $this->mTranslatableMessages[$key] ) && $this->mTranslatableMessages[$key] !== '' &&
263 $value !== rtrim( $value ) ) {
264 $messagesWithWhitespace[$key] = $value;
265 }
266 }
267 return $messagesWithWhitespace;
268 }
269
270 /**
271 * Get the non-XHTML messages.
272 *
273 * @param $code The langauge code.
274 *
275 * @return The non-XHTML messages for this language.
276 */
277 public function getNonXHTMLMessages( $code ) {
278 $this->loadMessages( 'en' );
279 $this->loadMessages( $code );
280 $wrongPhrases = array(
281 '<hr *\\?>',
282 '<br *\\?>',
283 '<hr/>',
284 '<br/>',
285 );
286 $wrongPhrases = '~(' . implode( '|', $wrongPhrases ) . ')~sDu';
287 $nonXHTMLMessages = array();
288 foreach ( $this->mMessages[$code] as $key => $value ) {
289 if ( isset( $this->mTranslatableMessages[$key] ) && preg_match( $wrongPhrases, $value ) ) {
290 $nonXHTMLMessages[$key] = $value;
291 }
292 }
293 return $nonXHTMLMessages;
294 }
295
296 /**
297 * Get the messages which include wrong characters.
298 *
299 * @param $code The langauge code.
300 *
301 * @return The messages which include wrong characters in this language.
302 */
303 public function getMessagesWithWrongChars( $code ) {
304 $this->loadMessages( 'en' );
305 $this->loadMessages( $code );
306 $wrongChars = array(
307 '[LRM]' => "\xE2\x80\x8E",
308 '[RLM]' => "\xE2\x80\x8F",
309 '[LRE]' => "\xE2\x80\xAA",
310 '[RLE]' => "\xE2\x80\xAB",
311 '[POP]' => "\xE2\x80\xAC",
312 '[LRO]' => "\xE2\x80\xAD",
313 '[RLO]' => "\xE2\x80\xAB",
314 '[ZWSP]'=> "\xE2\x80\x8B",
315 '[NBSP]'=> "\xC2\xA0",
316 '[WJ]' => "\xE2\x81\xA0",
317 '[BOM]' => "\xEF\xBB\xBF",
318 '[FFFD]'=> "\xEF\xBF\xBD",
319 );
320 $wrongRegExp = '/(' . implode( '|', array_values( $wrongChars ) ) . ')/sDu';
321 $nonXHTMLMessages = array();
322 foreach ( $this->mMessages[$code] as $key => $value ) {
323 if ( isset( $this->mTranslatableMessages[$key] ) && preg_match( $wrongRegExp, $value ) ) {
324 foreach ( $wrongChars as $viewableChar => $hiddenChar ) {
325 $value = str_replace( $hiddenChar, $viewableChar, $value );
326 }
327 $nonXHTMLMessages[$key] = $value;
328 }
329 }
330 return $nonXHTMLMessages;
331 }
332
333 /**
334 * Output a messages list.
335 *
336 * @param $messages The messages list.
337 * @param $text The text to show before the list (optional).
338 * @param $hideMessages Hide the real messages if specified.
339 */
340 public function outputMessagesList( $messages, $text = '', $hideMessages = false, $hidevalues = false ) {
341 if ( count( $messages ) > 0 ) {
342 if ( $text ) {
343 echo "$text\n";
344 }
345 if ( $hideMessages ) {
346 echo "[messages are hidden]\n";
347 } else {
348 foreach ( $messages as $key => $value ) {
349 if ( $hidevalues ) {
350 echo "* '$key'\n";
351 } else {
352 echo "* '$key': '$value'\n";
353 }
354 }
355 }
356 }
357 }
358 }
359
360 ?>