3 * Handle messages in the language files.
6 * @subpackage Maintenance
10 private $mList = array();
11 private $mMessages = array();
12 private $mTranslatableMessages = array();
13 private $mIgnoredMessages = array(
21 'exif-software-value',
27 'markaspatrolledlink',
30 'number_of_watching_users_RCview',
35 'shareddescriptionfollows',
47 * Load the list of languages: all the Messages*.php
48 * files in the languages directory.
50 function __construct() {
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 ) );
62 * Get the language list.
64 * @return the language list
66 public function getList() {
71 * Load the messages for a specific langauge from the messages file.
73 * @param $code The langauge code.
75 private function loadMessages( $code ) {
76 if ( !isset( $this->mMessages[$code] ) ) {
78 $filename = Language::getFileName( "$IP/languages/Messages", $code, '.php' );
79 if ( file_exists( $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] );
92 $this->mMessages[$code] = array();
95 $this->mMessages[$code] = array();
101 * Get all the messages for a specific langauge, without the fallback
104 * @param $code The langauge code.
106 * @return The messages in this language.
108 public function getMessagesFor( $code ) {
109 $this->loadMessages( $code );
110 return $this->mMessages[$code];
114 * Get all the messages which are translatable - not ignored messages.
116 * @param $code The langauge code.
118 * @return The messages in this language.
120 public function getTranslatableMessages() {
121 $this->loadMessages( 'en' );
122 return $this->mTranslatableMessages;
126 * Get the translated messages for a specific language.
128 * @param $code The langauge code.
130 * @return The translated messages for this language.
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;
141 return $translatedMessages;
145 * Get the untranslated messages for a specific language.
147 * @param $code The langauge code.
149 * @return The untranslated messages for this language.
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;
160 return $untranslatedMessages;
164 * Get the duplicate messages for a specific language.
166 * @param $code The langauge code.
168 * @return The duplicate messages for this language.
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;
179 return $duplicateMessages;
183 * Get the obsolete messages for a specific language.
185 * @param $code The langauge code.
187 * @return The obsolete messages for this language.
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;
198 return $obsoleteMessages;
202 * Get the messages which do not use some variables.
204 * @param $code The langauge code.
206 * @return The messages which do not use some variables in this language.
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] ) ) {
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 );
222 if ( count( $missing ) > 0 ) {
223 $messagesWithoutVariables[$key] = implode( ', ', $missing );
227 return $messagesWithoutVariables;
231 * Get the empty messages.
233 * @param $code The langauge code.
235 * @return The empty messages for this language.
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;
247 return $emptyMessages;
251 * Get the messages with trailing whitespace.
253 * @param $code The langauge code.
255 * @return The messages with trailing whitespace in this language.
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;
267 return $messagesWithWhitespace;
271 * Get the non-XHTML messages.
273 * @param $code The langauge code.
275 * @return The non-XHTML messages for this language.
277 public function getNonXHTMLMessages( $code ) {
278 $this->loadMessages( 'en' );
279 $this->loadMessages( $code );
280 $wrongPhrases = array(
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;
293 return $nonXHTMLMessages;
297 * Get the messages which include wrong characters.
299 * @param $code The langauge code.
301 * @return The messages which include wrong characters in this language.
303 public function getMessagesWithWrongChars( $code ) {
304 $this->loadMessages( 'en' );
305 $this->loadMessages( $code );
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",
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 );
327 $nonXHTMLMessages[$key] = $value;
330 return $nonXHTMLMessages;
334 * Output a messages list.
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.
340 public function outputMessagesList( $messages, $text = '', $hideMessages = false, $hidevalues = false ) {
341 if ( count( $messages ) > 0 ) {
345 if ( $hideMessages ) {
346 echo "[messages are hidden]\n";
348 foreach ( $messages as $key => $value ) {
352 echo "* '$key': '$value'\n";