MediaWiki  REL1_19
languages.inc
Go to the documentation of this file.
00001 <?php
00027 class languages {
00028         protected $mLanguages; # List of languages
00029 
00030         protected $mRawMessages; # Raw list of the messages in each language
00031         protected $mMessages; # Messages in each language (except for English), divided to groups
00032         protected $mFallback; # Fallback language in each language
00033         protected $mGeneralMessages; # General messages in English, divided to groups
00034         protected $mIgnoredMessages; # All the messages which should be exist only in the English file
00035         protected $mOptionalMessages; # All the messages which may be translated or not, depending on the language
00036 
00037         protected $mNamespaceNames; # Namespace names
00038         protected $mNamespaceAliases; # Namespace aliases
00039         protected $mMagicWords; # Magic words
00040         protected $mSpecialPageAliases; # Special page aliases
00041 
00048         function __construct( $exif = true ) {
00049                 require( dirname(__FILE__) . '/messageTypes.inc' );
00050                 $this->mIgnoredMessages = $wgIgnoredMessages;
00051                 if ( $exif ) {
00052                         $this->mOptionalMessages = array_merge( $wgOptionalMessages );
00053                 } else {
00054                         $this->mOptionalMessages = array_merge( $wgOptionalMessages, $wgEXIFMessages );
00055                 }
00056 
00057                 $this->mLanguages = array_keys( Language::getLanguageNames( true ) );
00058                 sort( $this->mLanguages );
00059         }
00060 
00066         public function getLanguages() {
00067                 return $this->mLanguages;
00068         }
00069 
00075         public function getIgnoredMessages() {
00076                 return $this->mIgnoredMessages;
00077         }
00078 
00084         public function getOptionalMessages() {
00085                 return $this->mOptionalMessages;
00086         }
00087 
00093         protected function loadFile( $code ) {
00094                 if ( isset( $this->mRawMessages[$code] ) &&
00095                         isset( $this->mFallback[$code] ) &&
00096                         isset( $this->mNamespaceNames[$code] ) &&
00097                         isset( $this->mNamespaceAliases[$code] ) &&
00098                         isset( $this->mMagicWords[$code] ) &&
00099                         isset( $this->mSpecialPageAliases[$code] ) ) {
00100                         return;
00101                 }
00102                 $this->mRawMessages[$code] = array();
00103                 $this->mFallback[$code] = '';
00104                 $this->mNamespaceNames[$code] = array();
00105                 $this->mNamespaceAliases[$code] = array();
00106                 $this->mMagicWords[$code] = array();
00107                 $this->mSpecialPageAliases[$code] = array();
00108                 $filename = Language::getMessagesFileName( $code );
00109                 if ( file_exists( $filename ) ) {
00110                         require( $filename );
00111                         if ( isset( $messages ) ) {
00112                                 $this->mRawMessages[$code] = $messages;
00113                         }
00114                         if ( isset( $fallback ) ) {
00115                                 $this->mFallback[$code] = $fallback;
00116                         }
00117                         if ( isset( $namespaceNames ) ) {
00118                                 $this->mNamespaceNames[$code] = $namespaceNames;
00119                         }
00120                         if ( isset( $namespaceAliases ) ) {
00121                                 $this->mNamespaceAliases[$code] = $namespaceAliases;
00122                         }
00123                         if ( isset( $magicWords ) ) {
00124                                 $this->mMagicWords[$code] = $magicWords;
00125                         }
00126                         if ( isset( $specialPageAliases ) ) {
00127                                 $this->mSpecialPageAliases[$code] = $specialPageAliases;
00128                         }
00129                 }
00130         }
00131 
00142         private function loadMessages( $code ) {
00143                 if ( isset( $this->mMessages[$code] ) ) {
00144                         return;
00145                 }
00146                 $this->loadFile( $code );
00147                 $this->loadGeneralMessages();
00148                 $this->mMessages[$code]['all'] = $this->mRawMessages[$code];
00149                 $this->mMessages[$code]['required'] = array();
00150                 $this->mMessages[$code]['optional'] = array();
00151                 $this->mMessages[$code]['obsolete'] = array();
00152                 $this->mMessages[$code]['translated'] = array();
00153                 foreach ( $this->mMessages[$code]['all'] as $key => $value ) {
00154                         if ( isset( $this->mGeneralMessages['required'][$key] ) ) {
00155                                 $this->mMessages[$code]['required'][$key] = $value;
00156                                 $this->mMessages[$code]['translated'][$key] = $value;
00157                         } else if ( isset( $this->mGeneralMessages['optional'][$key] ) ) {
00158                                 $this->mMessages[$code]['optional'][$key] = $value;
00159                                 $this->mMessages[$code]['translated'][$key] = $value;
00160                         } else {
00161                                 $this->mMessages[$code]['obsolete'][$key] = $value;
00162                         }
00163                 }
00164         }
00165 
00174         private function loadGeneralMessages() {
00175                 if ( isset( $this->mGeneralMessages ) ) {
00176                         return;
00177                 }
00178                 $this->loadFile( 'en' );
00179                 $this->mGeneralMessages['all'] = $this->mRawMessages['en'];
00180                 $this->mGeneralMessages['required'] = array();
00181                 $this->mGeneralMessages['optional'] = array();
00182                 $this->mGeneralMessages['ignored'] = array();
00183                 $this->mGeneralMessages['translatable'] = array();
00184                 foreach ( $this->mGeneralMessages['all'] as $key => $value ) {
00185                         if ( in_array( $key, $this->mIgnoredMessages ) ) {
00186                                 $this->mGeneralMessages['ignored'][$key] = $value;
00187                         } else if ( in_array( $key, $this->mOptionalMessages ) ) {
00188                                 $this->mGeneralMessages['optional'][$key] = $value;
00189                                 $this->mGeneralMessages['translatable'][$key] = $value;
00190                         } else {
00191                                 $this->mGeneralMessages['required'][$key] = $value;
00192                                 $this->mGeneralMessages['translatable'][$key] = $value;
00193                         }
00194                 }
00195         }
00196 
00210         public function getMessages( $code ) {
00211                 $this->loadMessages( $code );
00212                 return $this->mMessages[$code];
00213         }
00214 
00225         public function getGeneralMessages() {
00226                 $this->loadGeneralMessages();
00227                 return $this->mGeneralMessages;
00228         }
00229 
00237         public function getFallback( $code ) {
00238                 $this->loadFile( $code );
00239                 return $this->mFallback[$code];
00240         }
00241 
00249         public function getNamespaceNames( $code ) {
00250                 $this->loadFile( $code );
00251                 return $this->mNamespaceNames[$code];
00252         }
00253 
00261         public function getNamespaceAliases( $code ) {
00262                 $this->loadFile( $code );
00263                 return $this->mNamespaceAliases[$code];
00264         }
00265 
00273         public function getMagicWords( $code ) {
00274                 $this->loadFile( $code );
00275                 return $this->mMagicWords[$code];
00276         }
00277 
00285         public function getSpecialPageAliases( $code ) {
00286                 $this->loadFile( $code );
00287                 return $this->mSpecialPageAliases[$code];
00288         }
00289 
00297         public function getUntranslatedMessages( $code ) {
00298                 $this->loadGeneralMessages();
00299                 $this->loadMessages( $code );
00300                 return array_diff_key( $this->mGeneralMessages['required'], $this->mMessages[$code]['required'] );
00301         }
00302 
00310         public function getDuplicateMessages( $code ) {
00311                 $this->loadGeneralMessages();
00312                 $this->loadMessages( $code );
00313                 $duplicateMessages = array();
00314                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00315                         if ( $this->mGeneralMessages['translatable'][$key] == $value ) {
00316                                 $duplicateMessages[$key] = $value;
00317                         }
00318                 }
00319                 return $duplicateMessages;
00320         }
00321 
00329         public function getObsoleteMessages( $code ) {
00330                 $this->loadGeneralMessages();
00331                 $this->loadMessages( $code );
00332                 return $this->mMessages[$code]['obsolete'];
00333         }
00334 
00342         public function getMessagesWithMismatchVariables( $code ) {
00343                 $this->loadGeneralMessages();
00344                 $this->loadMessages( $code );
00345                 $variables = array( '\$1', '\$2', '\$3', '\$4', '\$5', '\$6', '\$7', '\$8', '\$9' );
00346                 $mismatchMessages = array();
00347                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00348                         $missing = false;
00349                         foreach ( $variables as $var ) {
00350                                 if ( preg_match( "/$var/sU", $this->mGeneralMessages['translatable'][$key] ) &&
00351                                         !preg_match( "/$var/sU", $value ) ) {
00352                                         $missing = true;
00353                                 }
00354                                 if ( !preg_match( "/$var/sU", $this->mGeneralMessages['translatable'][$key] ) &&
00355                                         preg_match( "/$var/sU", $value ) ) {
00356                                         $missing = true;
00357                                 }
00358                         }
00359                         if ( $missing ) {
00360                                 $mismatchMessages[$key] = $value;
00361                         }
00362                 }
00363                 return $mismatchMessages;
00364         }
00365 
00373         public function getMessagesWithoutPlural( $code ) {
00374                 $this->loadGeneralMessages();
00375                 $this->loadMessages( $code );
00376                 $messagesWithoutPlural = array();
00377                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00378                         if ( stripos( $this->mGeneralMessages['translatable'][$key], '{{plural:' ) !== false && stripos( $value, '{{plural:' ) === false ) {
00379                                 $messagesWithoutPlural[$key] = $value;
00380                         }
00381                 }
00382                 return $messagesWithoutPlural;
00383         }
00384 
00392         public function getEmptyMessages( $code ) {
00393                 $this->loadGeneralMessages();
00394                 $this->loadMessages( $code );
00395                 $emptyMessages = array();
00396                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00397                         if ( $value === '' || $value === '-' ) {
00398                                 $emptyMessages[$key] = $value;
00399                         }
00400                 }
00401                 return $emptyMessages;
00402         }
00403 
00411         public function getMessagesWithWhitespace( $code ) {
00412                 $this->loadGeneralMessages();
00413                 $this->loadMessages( $code );
00414                 $messagesWithWhitespace = array();
00415                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00416                         if ( $this->mGeneralMessages['translatable'][$key] !== '' && $value !== rtrim( $value ) ) {
00417                                 $messagesWithWhitespace[$key] = $value;
00418                         }
00419                 }
00420                 return $messagesWithWhitespace;
00421         }
00422 
00430         public function getNonXHTMLMessages( $code ) {
00431                 $this->loadGeneralMessages();
00432                 $this->loadMessages( $code );
00433                 $wrongPhrases = array(
00434                         '<hr *\\?>',
00435                         '<br *\\?>',
00436                         '<hr/>',
00437                         '<br/>',
00438                         '<hr>',
00439                         '<br>',
00440                 );
00441                 $wrongPhrases = '~(' . implode( '|', $wrongPhrases ) . ')~sDu';
00442                 $nonXHTMLMessages = array();
00443                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00444                         if ( preg_match( $wrongPhrases, $value ) ) {
00445                                 $nonXHTMLMessages[$key] = $value;
00446                         }
00447                 }
00448                 return $nonXHTMLMessages;
00449         }
00450 
00458         public function getMessagesWithWrongChars( $code ) {
00459                 $this->loadGeneralMessages();
00460                 $this->loadMessages( $code );
00461                 $wrongChars = array(
00462                         '[LRM]' => "\xE2\x80\x8E",
00463                         '[RLM]' => "\xE2\x80\x8F",
00464                         '[LRE]' => "\xE2\x80\xAA",
00465                         '[RLE]' => "\xE2\x80\xAB",
00466                         '[POP]' => "\xE2\x80\xAC",
00467                         '[LRO]' => "\xE2\x80\xAD",
00468                         '[RLO]' => "\xE2\x80\xAB",
00469                         '[ZWSP]'=> "\xE2\x80\x8B",
00470                         '[NBSP]'=> "\xC2\xA0",
00471                         '[WJ]'  => "\xE2\x81\xA0",
00472                         '[BOM]' => "\xEF\xBB\xBF",
00473                         '[FFFD]'=> "\xEF\xBF\xBD",
00474                 );
00475                 $wrongRegExp = '/(' . implode( '|', array_values( $wrongChars ) ) . ')/sDu';
00476                 $wrongCharsMessages = array();
00477                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00478                         if ( preg_match( $wrongRegExp, $value ) ) {
00479                                 foreach ( $wrongChars as $viewableChar => $hiddenChar ) {
00480                                         $value = str_replace( $hiddenChar, $viewableChar, $value );
00481                                 }
00482                                 $wrongCharsMessages[$key] = $value;
00483                         }
00484                 }
00485                 return $wrongCharsMessages;
00486         }
00487 
00495         public function getMessagesWithDubiousLinks( $code ) {
00496                 $this->loadGeneralMessages();
00497                 $this->loadMessages( $code );
00498                 $tc = Title::legalChars() . '#%{}';
00499                 $messages = array();
00500                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00501                         $matches = array();
00502                         preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $value, $matches );
00503                         for ($i = 0; $i < count($matches[0]); $i++ ) {
00504                                 if ( preg_match( "/.*project.*/isDu",  $matches[1][$i] ) ) {
00505                                         $messages[$key][] = $matches[0][$i];
00506                                 }
00507                         }
00508 
00509 
00510                         if ( isset( $messages[$key] ) ) {
00511                                 $messages[$key] = implode( $messages[$key],", " );
00512                         }
00513                 }
00514                 return $messages;
00515         }
00516 
00524         public function getMessagesWithUnbalanced( $code ) {
00525                 $this->loadGeneralMessages();
00526                 $this->loadMessages( $code );
00527                 $messages = array();
00528                 foreach ( $this->mMessages[$code]['translated'] as $key => $value ) {
00529                         $a = $b = $c = $d = 0;
00530                         foreach ( preg_split( '//', $value ) as $char ) {
00531                                 switch ( $char ) {
00532                                         case '[':
00533                                                 $a++;
00534                                                 break;
00535                                         case ']':
00536                                                 $b++;
00537                                                 break;
00538                                         case '{':
00539                                                 $c++;
00540                                                 break;
00541                                         case '}':
00542                                                 $d++;
00543                                                 break;
00544                                 }
00545                         }
00546 
00547                         if ( $a !== $b || $c !== $d ) {
00548                                 $messages[$key] = "$a, $b, $c, $d";
00549                         }
00550 
00551                 }
00552                 return $messages;
00553         }
00554 
00562         public function getUntranslatedNamespaces( $code ) {
00563                 $this->loadFile( 'en' );
00564                 $this->loadFile( $code );
00565                 $namespacesDiff = array_diff_key( $this->mNamespaceNames['en'], $this->mNamespaceNames[$code] );
00566                 if ( isset( $namespacesDiff[NS_MAIN] ) ) unset( $namespacesDiff[NS_MAIN] );
00567                 return $namespacesDiff;
00568         }
00569 
00577         public function getProblematicProjectTalks( $code ) {
00578                 $this->loadFile( $code );
00579                 $namespaces = array();
00580 
00581                 # Check default namespace name
00582                 if( isset( $this->mNamespaceNames[$code][NS_PROJECT_TALK] ) ) {
00583                         $default = $this->mNamespaceNames[$code][NS_PROJECT_TALK];
00584                         if ( strpos( $default, '$1' ) === FALSE ) {
00585                                 $namespaces[$default] = 'default';
00586                         }
00587                 }
00588 
00589                 # Check namespace aliases
00590                 foreach( $this->mNamespaceAliases[$code] as $key => $value ) {
00591                         if ( $value == NS_PROJECT_TALK && strpos( $key, '$1' ) === FALSE ) {
00592                                 $namespaces[$key] = '';
00593                         }
00594                 }
00595 
00596                 return $namespaces;
00597         }
00598 
00606         public function getUntranslatedMagicWords( $code ) {
00607                 $this->loadFile( 'en' );
00608                 $this->loadFile( $code );
00609                 $magicWords = array();
00610                 foreach ( $this->mMagicWords['en'] as $key => $value ) {
00611                         if ( !isset( $this->mMagicWords[$code][$key] ) ) {
00612                                 $magicWords[$key] = $value[1];
00613                         }
00614                 }
00615                 return $magicWords;
00616         }
00617 
00625         public function getObsoleteMagicWords( $code ) {
00626                 $this->loadFile( 'en' );
00627                 $this->loadFile( $code );
00628                 $magicWords = array();
00629                 foreach ( $this->mMagicWords[$code] as $key => $value ) {
00630                         if ( !isset( $this->mMagicWords['en'][$key] ) ) {
00631                                 $magicWords[$key] = $value[1];
00632                         }
00633                 }
00634                 return $magicWords;
00635         }
00636 
00644         public function getOverridingMagicWords( $code ) {
00645                 $this->loadFile( 'en' );
00646                 $this->loadFile( $code );
00647                 $magicWords = array();
00648                 foreach ( $this->mMagicWords[$code] as $key => $local ) {
00649                         if ( !isset( $this->mMagicWords['en'][$key] ) ) {
00650                                 # Unrecognized magic word
00651                                 continue;
00652                         }
00653                         $en = $this->mMagicWords['en'][$key];
00654                         array_shift( $local );
00655                         array_shift( $en );
00656                         foreach ( $en as $word ) {
00657                                 if ( !in_array( $word, $local ) ) {
00658                                         $magicWords[$key] = $word;
00659                                         break;
00660                                 }
00661                         }
00662                 }
00663                 return $magicWords;
00664         }
00665 
00673         public function getCaseMismatchMagicWords( $code ) {
00674                 $this->loadFile( 'en' );
00675                 $this->loadFile( $code );
00676                 $magicWords = array();
00677                 foreach ( $this->mMagicWords[$code] as $key => $local ) {
00678                         if ( !isset( $this->mMagicWords['en'][$key] ) ) {
00679                                 # Unrecognized magic word
00680                                 continue;
00681                         }
00682                         if ( $local[0] != $this->mMagicWords['en'][$key][0] ) {
00683                                 $magicWords[$key] = $local[0];
00684                         }
00685                 }
00686                 return $magicWords;
00687         }
00688 
00696         public function getUntraslatedSpecialPages( $code ) {
00697                 $this->loadFile( 'en' );
00698                 $this->loadFile( $code );
00699                 $specialPageAliases = array();
00700                 foreach ( $this->mSpecialPageAliases['en'] as $key => $value ) {
00701                         if ( !isset( $this->mSpecialPageAliases[$code][$key] ) ) {
00702                                 $specialPageAliases[$key] = $value[0];
00703                         }
00704                 }
00705                 return $specialPageAliases;
00706         }
00707 
00715         public function getObsoleteSpecialPages( $code ) {
00716                 $this->loadFile( 'en' );
00717                 $this->loadFile( $code );
00718                 $specialPageAliases = array();
00719                 foreach ( $this->mSpecialPageAliases[$code] as $key => $value ) {
00720                         if ( !isset( $this->mSpecialPageAliases['en'][$key] ) ) {
00721                                 $specialPageAliases[$key] = $value[0];
00722                         }
00723                 }
00724                 return $specialPageAliases;
00725         }
00726 }
00727 
00728 class extensionLanguages extends languages {
00729 
00733         private $mMessageGroup;
00734 
00739         function __construct( MessageGroup $group ) {
00740                 $this->mMessageGroup = $group;
00741 
00742                 $bools = $this->mMessageGroup->getBools();
00743                 $this->mIgnoredMessages = $bools['ignored'];
00744                 $this->mOptionalMessages = $bools['optional'];
00745         }
00746 
00752         public function name() {
00753                 return $this->mMessageGroup->getLabel();
00754         }
00755 
00761         protected function loadFile( $code ) {
00762                 if( !isset( $this->mRawMessages[$code] ) ) {
00763                         $this->mRawMessages[$code] = $this->mMessageGroup->load( $code );
00764                         if( empty( $this->mRawMessages[$code] ) ) {
00765                                 $this->mRawMessages[$code] = array();
00766                         }
00767                 }
00768         }
00769 }