* (bug 7061) Format title on "from (page)" links on Special:Allpages
[mediawiki.git] / maintenance / languages.inc
blobbb2df89e74aed1e76db88da5219dd49a3cccd4e5
1 <?php
2 /**
3  * Handle messages in the language files.
4  *
5  * @package MediaWiki
6  * @subpackage Maintenance
7  */
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         );
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         }
61         /**
62          * Get the language list.
63          *
64          * @return the language list
65          */
66         public function getList() {
67                 return $this->mList;
68         }
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         }
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         }
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         }
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         }
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         }
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         }
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         }
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 = false;
216                                 foreach ( $variables as $var ) {
217                                         if ( preg_match( "/$var/sU", $this->mTranslatableMessages[$key] ) &&
218                                                 !preg_match( "/$var/sU", $value ) ) {
219                                                 $missing = true;
220                                         }
221                                 }
222                                 if ( $missing ) {
223                                         $messagesWithoutVariables[$key] = $value;
224                                 }
225                         }
226                 }
227                 return $messagesWithoutVariables;
228         }
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         }
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         }
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         }
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         }
333         /**
334          * Output a messages list.
335          *
336          * @param $messages The messages list.
337          * @param $code The language code.
338          * @param $text The text to show before the list (optional).
339          * @param $level The display level.
340          * @param $links Show links.
341          */
342         public function outputMessagesList( $messages, $code, $text = '', $level = 2, $links = false ) {
343                 if ( count( $messages ) > 0 ) {
344                         if ( $text ) {
345                                 echo "$text\n";
346                         }
347                         if ( $level == 1 ) {
348                                 echo "[messages are hidden]\n";
349                         } else {
350                                 foreach ( $messages as $key => $value ) {
351                                         if ( $links ) {
352                                                 $displayKey = ucfirst( $key );
353                                                 global $wgContLang;
354                                                 if ( $code == $wgContLang->getCode() ) {
355                                                         $displayKey = "[[MediaWiki:$displayKey|$key]]";
356                                                 } else {
357                                                         $displayKey = "[[MediaWiki:$displayKey/$code|$key]]";
358                                                 }
359                                         } else {
360                                                 $displayKey = $key;
361                                         }
362                                         if ( $level == 2 ) {
363                                                 echo "* $displayKey\n";
364                                         } else {
365                                                 echo "* $displayKey:            '$value'\n";
366                                         }
367                                 }
368                         }
369                 }
370         }