diff options
Diffstat (limited to 'maintenance/language')
-rw-r--r-- | maintenance/language/checkLanguage.inc | 376 | ||||
-rw-r--r-- | maintenance/language/checkLanguage.php | 7 | ||||
-rw-r--r-- | maintenance/language/countMessages.php | 40 | ||||
-rw-r--r-- | maintenance/language/diffLanguage.php | 1 | ||||
-rw-r--r-- | maintenance/language/languages.inc | 336 | ||||
-rw-r--r-- | maintenance/language/messageTypes.inc | 39 | ||||
-rw-r--r-- | maintenance/language/messages.inc | 412 | ||||
-rw-r--r-- | maintenance/language/transstat.php | 4 |
8 files changed, 1002 insertions, 213 deletions
diff --git a/maintenance/language/checkLanguage.inc b/maintenance/language/checkLanguage.inc index 2cfd1b04..52281b57 100644 --- a/maintenance/language/checkLanguage.inc +++ b/maintenance/language/checkLanguage.inc @@ -13,41 +13,36 @@ class CheckLanguageCLI { protected $checks = array(); protected $L = null; - protected $defaultChecks = array( - 'untranslated', 'obsolete', 'variables', 'empty', 'plural', - 'whitespace', 'xhtml', 'chars', 'links', 'unbalanced' - ); - protected $results = array(); private $includeExif = false; /** - * GLOBALS: $wgLanguageCode; + * Constructor. + * @param $options Options for script. */ public function __construct( Array $options ) { - if ( isset( $options['help'] ) ) { echo $this->help(); exit(); } - if ( isset($options['lang']) ) { + if ( isset( $options['lang'] ) ) { $this->code = $options['lang']; } else { global $wgLanguageCode; $this->code = $wgLanguageCode; } - if ( isset($options['level']) ) { + if ( isset( $options['level'] ) ) { $this->level = $options['level']; } - $this->doLinks = isset($options['links']); - $this->includeExif = !isset($options['noexif']); - $this->checkAll = isset($options['all']); + $this->doLinks = isset( $options['links'] ); + $this->includeExif = !isset( $options['noexif'] ); + $this->checkAll = isset( $options['all'] ); - if ( isset($options['wikilang']) ) { + if ( isset( $options['wikilang'] ) ) { $this->wikiCode = $options['wikilang']; } @@ -55,57 +50,136 @@ class CheckLanguageCLI { $this->checks = explode( ',', $options['whitelist'] ); } elseif ( isset( $options['blacklist'] ) ) { $this->checks = array_diff( - $this->defaultChecks, + isset( $options['easy'] ) ? $this->easyChecks() : $this->defaultChecks(), explode( ',', $options['blacklist'] ) ); + } elseif ( isset( $options['easy'] ) ) { + $this->checks = $this->easyChecks(); } else { - $this->checks = $this->defaultChecks; + $this->checks = $this->defaultChecks(); } - if ( isset($options['output']) ) { + if ( isset( $options['output'] ) ) { $this->output = $options['output']; } - # Some additional checks not enabled by default - if ( isset( $options['duplicate'] ) ) { - $this->checks[] = 'duplicate'; - } - $this->L = new languages( $this->includeExif ); } + /** + * Get the default checks. + * @return A list of the default checks. + */ + protected function defaultChecks() { + return array( + 'untranslated', 'duplicate', 'obsolete', 'variables', 'empty', 'plural', + 'whitespace', 'xhtml', 'chars', 'links', 'unbalanced', 'namespace', + 'projecttalk', 'magic', 'magic-old', 'magic-over', 'magic-case', + 'special', 'special-old', + ); + } + + /** + * Get the checks which check other things than messages. + * @return A list of the non-message checks. + */ + protected function nonMessageChecks() { + return array( + 'namespace', 'projecttalk', 'magic', 'magic-old', 'magic-over', + 'magic-case', 'special', 'special-old', + ); + } + + /** + * Get the checks that can easily be treated by non-speakers of the language. + * @return A list of the easy checks. + */ + protected function easyChecks() { + return array( + 'duplicate', 'obsolete', 'empty', 'whitespace', 'xhtml', 'chars', 'magic-old', + 'magic-over', 'magic-case', 'special-old', + ); + } + + /** + * Get all checks. + * @return An array of all check names mapped to their function names. + */ protected function getChecks() { - $checks = array(); - $checks['untranslated'] = 'getUntranslatedMessages'; - $checks['duplicate'] = 'getDuplicateMessages'; - $checks['obsolete'] = 'getObsoleteMessages'; - $checks['variables'] = 'getMessagesWithoutVariables'; - $checks['plural'] = 'getMessagesWithoutPlural'; - $checks['empty'] = 'getEmptyMessages'; - $checks['whitespace'] = 'getMessagesWithWhitespace'; - $checks['xhtml'] = 'getNonXHTMLMessages'; - $checks['chars'] = 'getMessagesWithWrongChars'; - $checks['links'] = 'getMessagesWithDubiousLinks'; - $checks['unbalanced'] = 'getMessagesWithUnbalanced'; - return $checks; + return array( + 'untranslated' => 'getUntranslatedMessages', + 'duplicate' => 'getDuplicateMessages', + 'obsolete' => 'getObsoleteMessages', + 'variables' => 'getMessagesWithMismatchVariables', + 'plural' => 'getMessagesWithoutPlural', + 'empty' => 'getEmptyMessages', + 'whitespace' => 'getMessagesWithWhitespace', + 'xhtml' => 'getNonXHTMLMessages', + 'chars' => 'getMessagesWithWrongChars', + 'links' => 'getMessagesWithDubiousLinks', + 'unbalanced' => 'getMessagesWithUnbalanced', + 'namespace' => 'getUntranslatedNamespaces', + 'projecttalk' => 'getProblematicProjectTalks', + 'magic' => 'getUntranslatedMagicWords', + 'magic-old' => 'getObsoleteMagicWords', + 'magic-over' => 'getOverridingMagicWords', + 'magic-case' => 'getCaseMismatchMagicWords', + 'special' => 'getUntraslatedSpecialPages', + 'special-old' => 'getObsoleteSpecialPages', + ); + } + + /** + * Get total count for each check non-messages check. + * @return An array of all check names mapped to a two-element array: + * function name to get the total count and language code or null + * for checked code. + */ + protected function getTotalCount() { + return array( + 'namespace' => array( 'getNamespaceNames', 'en' ), + 'projecttalk' => null, + 'magic' => array( 'getMagicWords', 'en' ), + 'magic-old' => array( 'getMagicWords', null ), + 'magic-over' => array( 'getMagicWords', null ), + 'magic-case' => array( 'getMagicWords', null ), + 'special' => array( 'getSpecialPageAliases', 'en' ), + 'special-old' => array( 'getSpecialPageAliases', null ), + ); } + /** + * Get all check descriptions. + * @return An array of all check names mapped to their descriptions. + */ protected function getDescriptions() { - $descriptions = array(); - $descriptions['untranslated'] = '$1 message(s) of $2 are not translated to $3, but exist in en:'; - $descriptions['duplicate'] = '$1 message(s) of $2 are translated the same in en and $3:'; - $descriptions['obsolete'] = '$1 message(s) of $2 do not exist in en or are in the ignore list, but are in $3'; - $descriptions['variables'] = '$1 message(s) of $2 in $3 don\'t use some variables that en uses:'; - $descriptions['plural'] = '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:'; - $descriptions['empty'] = '$1 message(s) of $2 in $3 are empty or -:'; - $descriptions['whitespace'] = '$1 message(s) of $2 in $3 have trailing whitespace:'; - $descriptions['xhtml'] = '$1 message(s) of $2 in $3 contain illegal XHTML:'; - $descriptions['chars'] = '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:'; - $descriptions['links'] = '$1 message(s) of $2 in $3 have problematic link(s):'; - $descriptions['unbalanced'] = '$1 message(s) of $2 in $3 have unbalanced {[]}:'; - return $descriptions; + return array( + 'untranslated' => '$1 message(s) of $2 are not translated to $3, but exist in en:', + 'duplicate' => '$1 message(s) of $2 are translated the same in en and $3:', + 'obsolete' => '$1 message(s) of $2 do not exist in en or are in the ignore list, but exist in $3:', + 'variables' => '$1 message(s) of $2 in $3 don\'t match the variables used in en:', + 'plural' => '$1 message(s) of $2 in $3 don\'t use {{plural}} while en uses:', + 'empty' => '$1 message(s) of $2 in $3 are empty or -:', + 'whitespace' => '$1 message(s) of $2 in $3 have trailing whitespace:', + 'xhtml' => '$1 message(s) of $2 in $3 contain illegal XHTML:', + 'chars' => '$1 message(s) of $2 in $3 include hidden chars which should not be used in the messages:', + 'links' => '$1 message(s) of $2 in $3 have problematic link(s):', + 'unbalanced' => '$1 message(s) of $2 in $3 have unbalanced {[]}:', + 'namespace' => '$1 namespace name(s) of $2 are not translated to $3, but exist in en:', + 'projecttalk' => '$1 namespace name(s) and alias(es) in $3 are project talk namespaces without the parameter:', + 'magic' => '$1 magic word(s) of $2 are not translated to $3, but exist in en:', + 'magic-old' => '$1 magic word(s) of $2 do not exist in en, but exist in $3:', + 'magic-over' => '$1 magic word(s) of $2 in $3 do not contain the original en word(s):', + 'magic-case' => '$1 magic word(s) of $2 in $3 change the case-sensitivity of the original en word:', + 'special' => '$1 special page alias(es) of $2 are not translated to $3, but exist in en:', + 'special-old' => '$1 special page alias(es) of $2 do not exist in en, but exist in $3:', + ); } + /** + * Get help. + * @return The help string. + */ protected function help() { return <<<ENDS Run this script to check a specific language file, or all of them. @@ -114,24 +188,32 @@ Parameters: * lang: Language code (default: the installation default language). * all: Check all customized languages. * help: Show this help. - * level: Show the following level (default: 2). + * level: Show the following display level (default: 2). * links: Link the message values (default off). * wikilang: For the links, what is the content language of the wiki to display the output in (default en). * whitelist: Do only the following checks (form: code,code). * blacklist: Don't do the following checks (form: code,code). - * duplicate: Additionally check for messages which are translated the same to English (default off). + * easy: Do only the easy checks, which can be treated by non-speakers of the language. * noexif: Don't check for EXIF messages (a bit hard and boring to translate), if you know that they are currently not translated and want to focus on other problems (default off). -Check codes (ideally, all of them should result 0; all the checks are executed by default (except duplicate and language specific check blacklists in checkLanguage.inc): +Check codes (ideally, all of them should result 0; all the checks are executed by default (except language-specific check blacklists in checkLanguage.inc): * untranslated: Messages which are required to translate, but are not translated. * duplicate: Messages which translation equal to fallback - * obsolete: Messages which are untranslatable, but translated. - * variables: Messages without variables which should be used. - * empty: Empty messages. + * obsolete: Messages which are untranslatable or do not exist, but are translated. + * variables: Messages without variables which should be used, or with variables which shouldn't be used. + * empty: Empty messages and messages that contain only -. * whitespace: Messages which have trailing whitespace. * xhtml: Messages which are not well-formed XHTML (checks only few common errors). * chars: Messages with hidden characters. * links: Messages which contains broken links to pages (does not find all). * unbalanced: Messages which contains unequal numbers of opening {[ and closing ]}. + * namespace: Namespace names that were not translated. + * projecttalk: Namespace names and aliases where the project talk does not contain $1. + * magic: Magic words that were not translated. + * magic-old: Magic words which do not exist. + * magic-over: Magic words that override the original English word. + * magic-case: Magic words whose translation changes the case-sensitivity of the original English word. + * special: Special page names that were not translated. + * special-old: Special page names which do not exist. Display levels (default: 2): * 0: Skip the checks (useful for checking syntax). * 1: Show only the stub headers and number of wrong messages, without list of messages. @@ -141,10 +223,13 @@ Display levels (default: 2): ENDS; } + /** + * Execute the script. + */ public function execute() { $this->doChecks(); if ( $this->level > 0 ) { - switch ($this->output) { + switch ( $this->output ) { case 'plain': $this->outputText(); break; @@ -152,11 +237,14 @@ ENDS; $this->outputWiki(); break; default: - throw new MWException( "Invalid output type $this->output"); + throw new MWException( "Invalid output type $this->output" ); } } } + /** + * Execute the checks. + */ protected function doChecks() { $ignoredCodes = array( 'en', 'enRTL' ); @@ -164,24 +252,33 @@ ENDS; # Check the language if ( $this->checkAll ) { foreach ( $this->L->getLanguages() as $language ) { - if ( !in_array($language, $ignoredCodes) ) { + if ( !in_array( $language, $ignoredCodes ) ) { $this->results[$language] = $this->checkLanguage( $language ); } } } else { - if ( in_array($this->code, $ignoredCodes) ) { - throw new MWException("Cannot check code $this->code."); + if ( in_array( $this->code, $ignoredCodes ) ) { + throw new MWException( "Cannot check code $this->code." ); } else { $this->results[$this->code] = $this->checkLanguage( $this->code ); } } } + /** + * Get the check blacklist. + * @return The list of checks which should not be executed. + */ protected function getCheckBlacklist() { global $checkBlacklist; return $checkBlacklist; } + /** + * Check a language. + * @param $code The language code. + * @return The results. + */ protected function checkLanguage( $code ) { # Syntax check only if ( $this->level === 0 ) { @@ -193,22 +290,28 @@ ENDS; $checkFunctions = $this->getChecks(); $checkBlacklist = $this->getCheckBlacklist(); foreach ( $this->checks as $check ) { - if ( isset($checkBlacklist[$code]) && - in_array($check, $checkBlacklist[$code]) ) { + if ( isset( $checkBlacklist[$code] ) && + in_array( $check, $checkBlacklist[$code] ) ) { $result[$check] = array(); continue; } $callback = array( $this->L, $checkFunctions[$check] ); - if ( !is_callable($callback ) ) { + if ( !is_callable( $callback ) ) { throw new MWException( "Unkown check $check." ); } - $results[$check] = call_user_func( $callback , $code ); + $results[$check] = call_user_func( $callback, $code ); } return $results; } + /** + * Format a message key. + * @param $key The message key. + * @param $code The language code. + * @return The formatted message key. + */ protected function formatKey( $key, $code ) { if ( $this->doLinks ) { $displayKey = ucfirst( $key ); @@ -222,28 +325,44 @@ ENDS; } } + /** + * Output the checks results as plain text. + * @return The checks results as plain text. + */ protected function outputText() { foreach ( $this->results as $code => $results ) { $translated = $this->L->getMessages( $code ); $translated = count( $translated['translated'] ); - $translatable = $this->L->getGeneralMessages(); - $translatable = count( $translatable['translatable'] ); foreach ( $results as $check => $messages ) { $count = count( $messages ); if ( $count ) { + if ( $check == 'untranslated' ) { + $translatable = $this->L->getGeneralMessages(); + $total = count( $translatable['translatable'] ); + } elseif ( in_array( $check, $this->nonMessageChecks() ) ) { + $totalCount = $this->getTotalCount(); + $totalCount = $totalCount[$check]; + $callback = array( $this->L, $totalCount[0] ); + $callCode = $totalCount[1] ? $totalCount[1] : $code; + $total = count( call_user_func( $callback, $callCode ) ); + } else { + $total = $translated; + } $search = array( '$1', '$2', '$3' ); - $replace = array( $count, $check == 'untranslated' ? $translatable: $translated, $code ); + $replace = array( $count, $total, $code ); $descriptions = $this->getDescriptions(); echo "\n" . str_replace( $search, $replace, $descriptions[$check] ) . "\n"; if ( $this->level == 1 ) { echo "[messages are hidden]\n"; } else { foreach ( $messages as $key => $value ) { - $displayKey = $this->formatKey( $key, $code ); - if ( $this->level == 2 ) { - echo "* $displayKey\n"; + if( !in_array( $check, $this->nonMessageChecks() ) ) { + $key = $this->formatKey( $key, $code ); + } + if ( $this->level == 2 || empty( $value ) ) { + echo "* $key\n"; } else { - echo "* $displayKey: '$value'\n"; + echo "* $key: '$value'\n"; } } } @@ -253,7 +372,8 @@ ENDS; } /** - * Globals: $wgContLang, $IP + * Output the checks results as wiki text. + * @return The checks results as wiki text. */ function outputWiki() { global $wgContLang, $IP; @@ -265,6 +385,9 @@ ENDS; $problems = 0; $detailTextForLangChecks = array(); foreach ( $results as $check => $messages ) { + if( in_array( $check, $this->nonMessageChecks() ) ) { + continue; + } $count = count( $messages ); if ( $count ) { $problems += $count; @@ -273,7 +396,7 @@ ENDS; $displayKey = $this->formatKey( $key, $code ); $messageDetails[] = $displayKey; } - $detailTextForLangChecks[] = "===$code-$check===\n* " . implode( ', ', $messageDetails ); + $detailTextForLangChecks[] = "=== $code-$check ===\n* " . implode( ', ', $messageDetails ); $numbers[] = "'''[[#$code-$check|$count]]'''"; } else { $numbers[] = $count; @@ -285,7 +408,10 @@ ENDS; $detailText .= $detailTextForLang . implode( "\n", $detailTextForLangChecks ) . "\n"; } - if ( !$problems ) { continue; } // Don't list languages without problems + if ( !$problems ) { + # Don't list languages without problems + continue; + } $language = $wgContLang->getLanguageName( $code ); $rows[] = "| $language || $code || $problems || " . implode( ' || ', $numbers ); } @@ -297,7 +423,7 @@ ENDS; '''Check results are for:''' <code>$version</code> -{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear:both;" +{| class="sortable wikitable" border="2" cellpadding="4" cellspacing="0" style="background-color: #F9F9F9; border: 1px #AAAAAA solid; border-collapse: collapse; clear: both;" $tableRows |} @@ -306,46 +432,50 @@ $detailText EOL; } + /** + * Check if there are any results for the checks, in any language. + * @return True if there are any results, false if not. + */ protected function isEmpty() { - $empty = true; foreach( $this->results as $code => $results ) { foreach( $results as $check => $messages ) { if( !empty( $messages ) ) { - $empty = false; - break; + return false; } } - if( !$empty ) { - break; - } } - return $empty; + return true; } } class CheckExtensionsCLI extends CheckLanguageCLI { private $extensions; + /** + * Constructor. + * @param $options Options for script. + * @param $extension The extension name (or names). + */ public function __construct( Array $options, $extension ) { if ( isset( $options['help'] ) ) { echo $this->help(); exit(); } - if ( isset($options['lang']) ) { + if ( isset( $options['lang'] ) ) { $this->code = $options['lang']; } else { global $wgLanguageCode; $this->code = $wgLanguageCode; } - if ( isset($options['level']) ) { + if ( isset( $options['level'] ) ) { $this->level = $options['level']; } - $this->doLinks = isset($options['links']); + $this->doLinks = isset( $options['links'] ); - if ( isset($options['wikilang']) ) { + if ( isset( $options['wikilang'] ) ) { $this->wikiCode = $options['wikilang']; } @@ -353,14 +483,16 @@ class CheckExtensionsCLI extends CheckLanguageCLI { $this->checks = explode( ',', $options['whitelist'] ); } elseif ( isset( $options['blacklist'] ) ) { $this->checks = array_diff( - $this->defaultChecks, + isset( $options['easy'] ) ? $this->easyChecks() : $this->defaultChecks(), explode( ',', $options['blacklist'] ) ); + } elseif ( isset( $options['easy'] ) ) { + $this->checks = $this->easyChecks(); } else { - $this->checks = $this->defaultChecks; + $this->checks = $this->defaultChecks(); } - if ( isset($options['output']) ) { + if ( isset( $options['output'] ) ) { $this->output = $options['output']; } @@ -372,23 +504,29 @@ class CheckExtensionsCLI extends CheckLanguageCLI { $this->extensions = array(); $extensions = new PremadeMediawikiExtensionGroups(); $extensions->addAll(); - if( $extension == 'all' ) { - foreach( MessageGroups::singleton()->getGroups() as $group ) { - if( strpos( $group->getId(), 'ext-' ) === 0 && !$group->isMeta() ) { + if ( $extension == 'all' ) { + foreach ( MessageGroups::singleton()->getGroups() as $group ) { + if ( strpos( $group->getId(), 'ext-' ) === 0 && !$group->isMeta() ) { $this->extensions[] = new extensionLanguages( $group ); } } - } elseif( $extension == 'wikimedia' ) { + } elseif ( $extension == 'wikimedia' ) { $wikimedia = MessageGroups::getGroup( 'ext-0-wikimedia' ); - foreach( $wikimedia->wmfextensions() as $extension ) { + foreach ( $wikimedia->wmfextensions() as $extension ) { $group = MessageGroups::getGroup( $extension ); $this->extensions[] = new extensionLanguages( $group ); } + } elseif ( $extension == 'flaggedrevs' ) { + foreach ( MessageGroups::singleton()->getGroups() as $group ) { + if ( strpos( $group->getId(), 'ext-flaggedrevs-' ) === 0 && !$group->isMeta() ) { + $this->extensions[] = new extensionLanguages( $group ); + } + } } else { $extensions = explode( ',', $extension ); - foreach( $extensions as $extension ) { + foreach ( $extensions as $extension ) { $group = MessageGroups::getGroup( 'ext-' . $extension ); - if( $group ) { + if ( $group ) { $extension = new extensionLanguages( $group ); $this->extensions[] = $extension; } else { @@ -398,25 +536,58 @@ class CheckExtensionsCLI extends CheckLanguageCLI { } } + /** + * Get the default checks. + * @return A list of the default checks. + */ + protected function defaultChecks() { + return array( + 'untranslated', 'duplicate', 'obsolete', 'variables', 'empty', 'plural', + 'whitespace', 'xhtml', 'chars', 'links', 'unbalanced', + ); + } + + /** + * Get the checks which check other things than messages. + * @return A list of the non-message checks. + */ + protected function nonMessageChecks() { + return array(); + } + + /** + * Get the checks that can easily be treated by non-speakers of the language. + * @return A list of the easy checks. + */ + protected function easyChecks() { + return array( + 'duplicate', 'obsolete', 'empty', 'whitespace', 'xhtml', 'chars', + ); + } + + /** + * Get help. + * @return The help string. + */ protected function help() { return <<<ENDS Run this script to check the status of a specific language in extensions, or all of them. Command line settings are in form --parameter[=value], except for the first one. Parameters: - * First parameter (mandatory): Extension name, multiple extension names (separated by commas), "all" for all the extensions or "wikimedia" for extensions used by Wikimedia. + * First parameter (mandatory): Extension name, multiple extension names (separated by commas), "all" for all the extensions, "wikimedia" for extensions used by Wikimedia or "flaggedrevs" for all FLaggedRevs extension messages. * lang: Language code (default: the installation default language). * help: Show this help. - * level: Show the following level (default: 2). + * level: Show the following display level (default: 2). * links: Link the message values (default off). * wikilang: For the links, what is the content language of the wiki to display the output in (default en). * whitelist: Do only the following checks (form: code,code). * blacklist: Do not perform the following checks (form: code,code). - * duplicate: Additionally check for messages which are translated the same to English (default off). -Check codes (ideally, all of them should result 0; all the checks are executed by default (except duplicate and language specific check blacklists in checkLanguage.inc): + * easy: Do only the easy checks, which can be treated by non-speakers of the language. +Check codes (ideally, all of them should result 0; all the checks are executed by default (except language-specific check blacklists in checkLanguage.inc): * untranslated: Messages which are required to translate, but are not translated. * duplicate: Messages which translation equal to fallback * obsolete: Messages which are untranslatable, but translated. - * variables: Messages without variables which should be used. + * variables: Messages without variables which should be used, or with variables which shouldn't be used. * empty: Empty messages. * whitespace: Messages which have trailing whitespace. * xhtml: Messages which are not well-formed XHTML (checks only few common errors). @@ -432,10 +603,17 @@ Display levels (default: 2): ENDS; } + /** + * Execute the script. + */ public function execute() { $this->doChecks(); } + /** + * Check a language and show the results. + * @param $code The language code. + */ protected function checkLanguage( $code ) { foreach( $this->extensions as $extension ) { $this->L = $extension; diff --git a/maintenance/language/checkLanguage.php b/maintenance/language/checkLanguage.php index f8553a1e..7a4d3dd2 100644 --- a/maintenance/language/checkLanguage.php +++ b/maintenance/language/checkLanguage.php @@ -11,4 +11,9 @@ require_once( 'checkLanguage.inc' ); require_once( 'languages.inc' ); $cli = new CheckLanguageCLI( $options ); -$cli->execute(); + +try { + $cli->execute(); +} catch( MWException $e ) { + print 'Error: ' . $e->getMessage() . "\n"; +} diff --git a/maintenance/language/countMessages.php b/maintenance/language/countMessages.php new file mode 100644 index 00000000..7d16915a --- /dev/null +++ b/maintenance/language/countMessages.php @@ -0,0 +1,40 @@ +<?php + +require_once( dirname(__FILE__).'/../commandLine.inc' ); + +global $IP; + +if ( !isset( $args[0] ) ) { + $dir = "$IP/languages/messages"; +} else { + $dir = $args[0]; +} + +$total = 0; +$nonZero = 0; +foreach ( glob( "$dir/*.php" ) as $file ) { + $baseName = basename( $file ); + if( !preg_match( '/Messages([A-Z][a-z_]+)\.php$/', $baseName, $m ) ) { + continue; + } + $code = str_replace( '_', '-', strtolower( $m[1] ) ); + $numMessages = wfGetNumMessages( $file ); + //print "$code: $numMessages\n"; + $total += $numMessages; + if ( $numMessages > 0 ) { + $nonZero ++; + } +} +print "\nTotal: $total\n"; +print "Languages: $nonZero\n"; + +function wfGetNumMessages( $file ) { + // Separate function to limit scope + require( $file ); + if ( isset( $messages ) ) { + return count( $messages ); + } else { + return 0; + } +} + diff --git a/maintenance/language/diffLanguage.php b/maintenance/language/diffLanguage.php index 389b01d5..9d395b3c 100644 --- a/maintenance/language/diffLanguage.php +++ b/maintenance/language/diffLanguage.php @@ -84,7 +84,6 @@ function getMediawikiMessages($languageCode = 'En') { $langFile = $IP.'/languages/classes/Language'.$languageCode.'.php'; if (file_exists( $langFile ) ) { print "Including $langFile\n"; - global $wgNamespaceNamesEn; // potentially unused global declaration? include($langFile); } else wfDie("ERROR: The file $langFile does not exist !\n"); } diff --git a/maintenance/language/languages.inc b/maintenance/language/languages.inc index 6d16f80c..6159e844 100644 --- a/maintenance/language/languages.inc +++ b/maintenance/language/languages.inc @@ -11,12 +11,18 @@ */ class languages { protected $mLanguages; # List of languages + protected $mRawMessages; # Raw list of the messages in each language protected $mMessages; # Messages in each language (except for English), divided to groups protected $mGeneralMessages; # General messages in English, divided to groups protected $mIgnoredMessages; # All the messages which should be exist only in the English file protected $mOptionalMessages; # All the messages which may be translated or not, depending on the language + protected $mNamespaceNames; # Namespace names + protected $mNamespaceAliases; # Namespace aliases + protected $mMagicWords; # Magic words + protected $mSpecialPageAliases; # Special page aliases + /** * Load the list of languages: all the Messages*.php * files in the languages directory. @@ -64,24 +70,41 @@ class languages { } /** - * Load the raw messages for a specific language from the messages file. + * Load the language file. * * @param $code The language code. */ - protected function loadRawMessages( $code ) { - if ( isset( $this->mRawMessages[$code] ) ) { + protected function loadFile( $code ) { + if ( isset( $this->mRawMessages[$code] ) && + isset( $this->mNamespaceNames[$code] ) && + isset( $this->mNamespaceAliases[$code] ) && + isset( $this->mMagicWords[$code] ) && + isset( $this->mSpecialPageAliases[$code] ) ) { return; } + $this->mRawMessages[$code] = array(); + $this->mNamespaceNames[$code] = array(); + $this->mNamespaceAliases[$code] = array(); + $this->mMagicWords[$code] = array(); + $this->mSpecialPageAliases[$code] = array(); $filename = Language::getMessagesFileName( $code ); if ( file_exists( $filename ) ) { require( $filename ); if ( isset( $messages ) ) { $this->mRawMessages[$code] = $messages; - } else { - $this->mRawMessages[$code] = array(); } - } else { - $this->mRawMessages[$code] = array(); + if ( isset( $namespaceNames ) ) { + $this->mNamespaceNames[$code] = $namespaceNames; + } + if ( isset( $namespaceAliases ) ) { + $this->mNamespaceAliases[$code] = $namespaceAliases; + } + if ( isset( $magicWords ) ) { + $this->mMagicWords[$code] = $magicWords; + } + if ( isset( $specialPageAliases ) ) { + $this->mSpecialPageAliases[$code] = $specialPageAliases; + } } } @@ -90,7 +113,7 @@ class languages { * all - all the messages. * required - messages which should be translated in order to get a complete translation. * optional - messages which can be translated, the fallback translation is used if not translated. - * obsolete - messages which should not be translated, either because they are not exist, or they are ignored messages. + * obsolete - messages which should not be translated, either because they do not exist, or they are ignored messages. * translated - messages which are either required or optional, but translated from English and needed. * * @param $code The language code. @@ -99,7 +122,7 @@ class languages { if ( isset( $this->mMessages[$code] ) ) { return; } - $this->loadRawMessages( $code ); + $this->loadFile( $code ); $this->loadGeneralMessages(); $this->mMessages[$code]['all'] = $this->mRawMessages[$code]; $this->mMessages[$code]['required'] = array(); @@ -131,7 +154,7 @@ class languages { if ( isset( $this->mGeneralMessages ) ) { return; } - $this->loadRawMessages( 'en' ); + $this->loadFile( 'en' ); $this->mGeneralMessages['all'] = $this->mRawMessages['en']; $this->mGeneralMessages['required'] = array(); $this->mGeneralMessages['optional'] = array(); @@ -156,7 +179,7 @@ class languages { * all - all the messages. * required - messages which should be translated in order to get a complete translation. * optional - messages which can be translated, the fallback translation is used if not translated. - * obsolete - messages which should not be translated, either because they are not exist, or they are ignored messages. + * obsolete - messages which should not be translated, either because they do not exist, or they are ignored messages. * translated - messages which are either required or optional, but translated from English and needed. * * @param $code The language code. @@ -184,6 +207,54 @@ class languages { } /** + * Get namespace names for a specific language. + * + * @param $code The language code. + * + * @return Namespace names. + */ + public function getNamespaceNames( $code ) { + $this->loadFile( $code ); + return $this->mNamespaceNames[$code]; + } + + /** + * Get namespace aliases for a specific language. + * + * @param $code The language code. + * + * @return Namespace aliases. + */ + public function getNamespaceAliases( $code ) { + $this->loadFile( $code ); + return $this->mNamespaceAliases[$code]; + } + + /** + * Get magic words for a specific language. + * + * @param $code The language code. + * + * @return Magic words. + */ + public function getMagicWords( $code ) { + $this->loadFile( $code ); + return $this->mMagicWords[$code]; + } + + /** + * Get special page aliases for a specific language. + * + * @param $code The language code. + * + * @return Special page aliases. + */ + public function getSpecialPageAliases( $code ) { + $this->loadFile( $code ); + return $this->mSpecialPageAliases[$code]; + } + + /** * Get the untranslated messages for a specific language. * * @param $code The language code. @@ -193,13 +264,7 @@ class languages { public function getUntranslatedMessages( $code ) { $this->loadGeneralMessages(); $this->loadMessages( $code ); - $requiredGeneralMessages = array_keys( $this->mGeneralMessages['required'] ); - $requiredMessages = array_keys( $this->mMessages[$code]['required'] ); - $untranslatedMessages = array(); - foreach ( array_diff( $requiredGeneralMessages, $requiredMessages ) as $key ) { - $untranslatedMessages[$key] = $this->mGeneralMessages['required'][$key]; - } - return $untranslatedMessages; + return array_diff_key( $this->mGeneralMessages['required'], $this->mMessages[$code]['required'] ); } /** @@ -221,6 +286,13 @@ class languages { return $duplicateMessages; } + /** + * Get the obsolete messages for a specific language. + * + * @param $code The language code. + * + * @return The obsolete messages for this language. + */ public function getObsoleteMessages( $code ) { $this->loadGeneralMessages(); $this->loadMessages( $code ); @@ -228,17 +300,17 @@ class languages { } /** - * Get the messages which do not use some variables. + * Get the messages whose variables do not match the original ones. * * @param $code The language code. * - * @return The messages which do not use some variables in this language. + * @return The messages whose variables do not match the original ones. */ - public function getMessagesWithoutVariables( $code ) { + public function getMessagesWithMismatchVariables( $code ) { $this->loadGeneralMessages(); $this->loadMessages( $code ); $variables = array( '\$1', '\$2', '\$3', '\$4', '\$5', '\$6', '\$7', '\$8', '\$9' ); - $messagesWithoutVariables = array(); + $mismatchMessages = array(); foreach ( $this->mMessages[$code]['translated'] as $key => $value ) { $missing = false; foreach ( $variables as $var ) { @@ -246,12 +318,16 @@ class languages { !preg_match( "/$var/sU", $value ) ) { $missing = true; } + if ( !preg_match( "/$var/sU", $this->mGeneralMessages['translatable'][$key] ) && + preg_match( "/$var/sU", $value ) ) { + $missing = true; + } } if ( $missing ) { - $messagesWithoutVariables[$key] = $value; + $mismatchMessages[$key] = $value; } } - return $messagesWithoutVariables; + return $mismatchMessages; } /** @@ -376,6 +452,13 @@ class languages { return $wrongCharsMessages; } + /** + * Get the messages which include dubious links. + * + * @param $code The language code. + * + * @return The messages which include dubious links in this language. + */ public function getMessagesWithDubiousLinks( $code ) { $this->loadGeneralMessages(); $this->loadMessages( $code ); @@ -383,9 +466,9 @@ class languages { $messages = array(); foreach ( $this->mMessages[$code]['translated'] as $key => $value ) { $matches = array(); - preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $value, $matches); + preg_match_all( "/\[\[([{$tc}]+)(?:\\|(.+?))?]]/sDu", $value, $matches ); for ($i = 0; $i < count($matches[0]); $i++ ) { - if ( preg_match( "/.*project.*/isDu", $matches[1][$i]) ) { + if ( preg_match( "/.*project.*/isDu", $matches[1][$i] ) ) { $messages[$key][] = $matches[0][$i]; } } @@ -398,19 +481,33 @@ class languages { return $messages; } + /** + * Get the messages which include unbalanced brackets. + * + * @param $code The language code. + * + * @return The messages which include unbalanced brackets in this language. + */ public function getMessagesWithUnbalanced( $code ) { $this->loadGeneralMessages(); $this->loadMessages( $code ); $messages = array(); foreach ( $this->mMessages[$code]['translated'] as $key => $value ) { - $a = $b = $c = $d = 0; - foreach ( preg_split('//', $value) as $char ) { - switch ($char) { - case '[': $a++; break; - case ']': $b++; break; - case '{': $c++; break; - case '}': $d++; break; + foreach ( preg_split( '//', $value ) as $char ) { + switch ( $char ) { + case '[': + $a++; + break; + case ']': + $b++; + break; + case '{': + $c++; + break; + case '}': + $d++; + break; } } @@ -422,6 +519,175 @@ class languages { return $messages; } + /** + * Get the untranslated namespace names. + * + * @param $code The language code. + * + * @return The untranslated namespace names in this language. + */ + public function getUntranslatedNamespaces( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + return array_flip( array_diff_key( $this->mNamespaceNames['en'], $this->mNamespaceNames[$code] ) ); + } + + /** + * Get the project talk namespace names with no $1. + * + * @param $code The language code. + * + * @return The problematic project talk namespaces in this language. + */ + public function getProblematicProjectTalks( $code ) { + $this->loadFile( $code ); + $namespaces = array(); + + # Check default namespace name + if( isset( $this->mNamespaceNames[$code][NS_PROJECT_TALK] ) ) { + $default = $this->mNamespaceNames[$code][NS_PROJECT_TALK]; + if ( strpos( $default, '$1' ) === FALSE ) { + $namespaces[$default] = 'default'; + } + } + + # Check namespace aliases + foreach( $this->mNamespaceAliases[$code] as $key => $value ) { + if ( $value == NS_PROJECT_TALK && strpos( $key, '$1' ) === FALSE ) { + $namespaces[$key] = ''; + } + } + + return $namespaces; + } + + /** + * Get the untranslated magic words. + * + * @param $code The language code. + * + * @return The untranslated magic words in this language. + */ + public function getUntranslatedMagicWords( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $magicWords = array(); + foreach ( $this->mMagicWords['en'] as $key => $value ) { + if ( !isset( $this->mMagicWords[$code][$key] ) ) { + $magicWords[$key] = $value[1]; + } + } + return $magicWords; + } + + /** + * Get the obsolete magic words. + * + * @param $code The language code. + * + * @return The obsolete magic words in this language. + */ + public function getObsoleteMagicWords( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $magicWords = array(); + foreach ( $this->mMagicWords[$code] as $key => $value ) { + if ( !isset( $this->mMagicWords['en'][$key] ) ) { + $magicWords[$key] = $value[1]; + } + } + return $magicWords; + } + + /** + * Get the magic words that override the original English magic word. + * + * @param $code The language code. + * + * @return The overriding magic words in this language. + */ + public function getOverridingMagicWords( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $magicWords = array(); + foreach ( $this->mMagicWords[$code] as $key => $local ) { + if ( !isset( $this->mMagicWords['en'][$key] ) ) { + # Unrecognized magic word + continue; + } + $en = $this->mMagicWords['en'][$key]; + array_shift( $local ); + array_shift( $en ); + foreach ( $en as $word ) { + if ( !in_array( $word, $local ) ) { + $magicWords[$key] = $word; + break; + } + } + } + return $magicWords; + } + + /** + * Get the magic words which do not match the case-sensitivity of the original words. + * + * @param $code The language code. + * + * @return The magic words whose case does not match in this language. + */ + public function getCaseMismatchMagicWords( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $magicWords = array(); + foreach ( $this->mMagicWords[$code] as $key => $local ) { + if ( !isset( $this->mMagicWords['en'][$key] ) ) { + # Unrecognized magic word + continue; + } + if ( $local[0] != $this->mMagicWords['en'][$key][0] ) { + $magicWords[$key] = $local[0]; + } + } + return $magicWords; + } + + /** + * Get the untranslated special page names. + * + * @param $code The language code. + * + * @return The untranslated special page names in this language. + */ + public function getUntraslatedSpecialPages( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $specialPageAliases = array(); + foreach ( $this->mSpecialPageAliases['en'] as $key => $value ) { + if ( !isset( $this->mSpecialPageAliases[$code][$key] ) ) { + $specialPageAliases[$key] = $value[0]; + } + } + return $specialPageAliases; + } + + /** + * Get the obsolete special page names. + * + * @param $code The language code. + * + * @return The obsolete special page names in this language. + */ + public function getObsoleteSpecialPages( $code ) { + $this->loadFile( 'en' ); + $this->loadFile( $code ); + $specialPageAliases = array(); + foreach ( $this->mSpecialPageAliases[$code] as $key => $value ) { + if ( !isset( $this->mSpecialPageAliases['en'][$key] ) ) { + $specialPageAliases[$key] = $value[0]; + } + } + return $specialPageAliases; + } } class extensionLanguages extends languages { @@ -449,11 +715,11 @@ class extensionLanguages extends languages { } /** - * Load the raw messages for a specific language. + * Load the language file. * * @param $code The language code. */ - protected function loadRawMessages( $code ) { + protected function loadFile( $code ) { if( !isset( $this->mRawMessages[$code] ) ) { $this->mRawMessages[$code] = $this->mMessageGroup->load( $code ); if( empty( $this->mRawMessages[$code] ) ) { diff --git a/maintenance/language/messageTypes.inc b/maintenance/language/messageTypes.inc index 67caaddd..1b95fe98 100644 --- a/maintenance/language/messageTypes.inc +++ b/maintenance/language/messageTypes.inc @@ -65,11 +65,13 @@ $wgIgnoredMessages = array( 'accesskey-preview', 'accesskey-diff', 'accesskey-compareselectedversions', + 'accesskey-visualcomparison', 'accesskey-watch', 'accesskey-upload', 'addsection', 'anonnotice', 'autoblock_whitelist', + 'searchmenu-help', 'googlesearch', 'opensearch-desc', 'exif-make-value', @@ -83,7 +85,7 @@ $wgIgnoredMessages = array( 'markaspatrolledlink', 'newarticletextanon', 'newsectionheaderdefaultlevel', - 'newtalkseperator', + 'newtalkseparator', 'noarticletextanon', 'number_of_watching_users_RCview', 'pagecategorieslink', @@ -103,6 +105,7 @@ $wgIgnoredMessages = array( 'sitetitle', 'sp-contributions-footer', 'sp-contributions-footer-anon', + 'statistics-summary', 'statistics-footer', 'talkpagetext', 'trackback', @@ -127,6 +130,7 @@ $wgIgnoredMessages = array( 'uncategorizedtemplates-summary', 'popularpages-summary', 'wantedcategories-summary', + 'wantedfiles-summary', 'wantedpages-summary', 'mostlinked-summary', 'mostlinkedcategories-summary', @@ -148,8 +152,11 @@ $wgIgnoredMessages = array( 'lonelypages-summary', 'unusedtemplates-summary', 'fewestrevisions-summary', - 'missingfiles-summary', 'upload-summary', + 'pagetitle-view-mainpage', + 'newuserlogentry', + 'restrictlogpage', + 'wantedtemplates-summary', ); /** Optional messages, which may be translated only if changed in the target language. */ @@ -162,6 +169,7 @@ $wgOptionalMessages = array( 'unit-pixel', 'userrights-irreversible-marker', 'tog-nolangconversion', + 'tog-noconvertlink', 'yourvariant', 'variantname-zh-hans', 'variantname-zh-hant', @@ -192,6 +200,14 @@ $wgOptionalMessages = array( 'resetpass_text', 'image_sample', 'media_sample', + 'skinname-standard', + 'skinname-nostalgia', + 'skinname-cologneblue', + 'skinname-monobook', + 'skinname-myskin', + 'skinname-chick', + 'skinname-simple', + 'skinname-modern', 'common.css', 'standard.css', 'nostalgia.css', @@ -201,6 +217,8 @@ $wgOptionalMessages = array( 'chick.css', 'simple.css', 'modern.css', + 'print.css', + 'handheld.css', 'common.js', 'standard.js', 'nostalgia.js', @@ -307,10 +325,15 @@ $wgOptionalMessages = array( 'semicolon-separator', 'comma-separator', 'colon-separator', + 'pipe-separator', + 'word-separator', + 'ellipsis', 'autocomment-prefix', 'listgrouprights-right-display', 'timezone-utc', - 'whatlinkshere-barrow', + 'whatlinkshere-backlink', + 'recentchangeslinked-backlink', + 'diff-with-additional', ); /** EXIF messages, which may be set as optional in several checks, but are generally mandatory */ @@ -481,6 +504,16 @@ $wgEXIFMessages = array( 'exif-lightsource-19', 'exif-lightsource-24', 'exif-lightsource-255', + 'exif-flash-fired-0' , + 'exif-flash-fired-1' , + 'exif-flash-return-0' , + 'exif-flash-return-2' , + 'exif-flash-return-3' , + 'exif-flash-mode-1' , + 'exif-flash-mode-2' , + 'exif-flash-mode-3' , + 'exif-flash-function-1' , + 'exif-flash-redeye-1' , 'exif-focalplaneresolutionunit-2', 'exif-sensingmethod-1', 'exif-sensingmethod-2', diff --git a/maintenance/language/messages.inc b/maintenance/language/messages.inc index d99f2e45..d7475428 100644 --- a/maintenance/language/messages.inc +++ b/maintenance/language/messages.inc @@ -48,19 +48,20 @@ $wgMessageStructure = array( 'tog-watchlisthideown', 'tog-watchlisthidebots', 'tog-watchlisthideminor', + 'tog-watchlisthideliu', + 'tog-watchlisthideanons', 'tog-nolangconversion', 'tog-ccmeonemails', 'tog-diffonly', 'tog-showhiddencats', + 'tog-noconvertlink', + 'tog-norollbackdiff', ), 'underline' => array( 'underline-always', 'underline-never', 'underline-default', ), - 'skinpreview' => array( - 'skinpreview', - ), 'dates' => array( 'sunday', 'monday', @@ -217,8 +218,6 @@ $wgMessageStructure = array( 'links' => array( 'aboutsite', 'aboutpage', - 'bugreports', - 'bugreportspage', 'copyright', 'copyrightpagename', 'copyrightpage', @@ -243,8 +242,6 @@ $wgMessageStructure = array( 'badaccess' => array( 'badaccess', 'badaccess-group0', - 'badaccess-group1', - 'badaccess-group2', 'badaccess-groups', ), 'versionrequired' => array( @@ -255,17 +252,20 @@ $wgMessageStructure = array( 'ok', 'sitetitle', 'pagetitle', + 'pagetitle-view-mainpage', 'sitesubtitle', 'retrievedfrom', 'youhavenewmessages', 'newmessageslink', 'newmessagesdifflink', 'youhavenewmessagesmulti', - 'newtalkseperator', + 'newtalkseparator', 'editsection', 'editsection-brackets', 'editold', 'viewsourceold', + 'editlink', + 'viewsourcelink', 'editsectionhint', 'toc', 'showtoc', @@ -335,7 +335,6 @@ $wgMessageStructure = array( 'cannotdelete', 'badtitle', 'badtitletext', - 'perfdisabled', 'perfcached', 'perfcachedts', 'querypage-no-updates', @@ -371,7 +370,6 @@ $wgMessageStructure = array( 'remembermypassword', 'yourdomainname', 'externaldberror', - 'loginproblem', 'login', 'nav-login-createaccount', 'loginprompt', @@ -435,6 +433,7 @@ $wgMessageStructure = array( 'accountcreatedtext', 'createaccount-title', 'createaccount-text', + 'login-throttled', 'loginlanguagelabel', 'loginlanguagelinks', ), @@ -443,11 +442,17 @@ $wgMessageStructure = array( 'resetpass_announce', 'resetpass_text', 'resetpass_header', + 'oldpassword', + 'newpassword', + 'retypenew', 'resetpass_submit', 'resetpass_success', 'resetpass_bad_temporary', 'resetpass_forbidden', - 'resetpass_missing', + 'resetpass-no-info', + 'resetpass-submit-loggedin', + 'resetpass-wrong-oldpass', + 'resetpass-temp-password', ), 'toolbar' => array( 'bold_sample', @@ -495,10 +500,6 @@ $wgMessageStructure = array( 'blockededitsource', 'whitelistedittitle', 'whitelistedittext', - 'whitelistreadtitle', - 'whitelistreadtext', - 'whitelistacctitle', - 'whitelistacctext', 'confirmedittitle', 'confirmedittext', 'nosuchsectiontitle', @@ -561,6 +562,13 @@ $wgMessageStructure = array( 'permissionserrorstext', 'permissionserrorstext-withaction', 'recreate-deleted-warn', + 'deleted-notice', + 'deletelog-fulllog', + 'edit-hook-aborted', + 'edit-gone-missing', + 'edit-conflict', + 'edit-no-change', + 'edit-already-exists', ), 'parserwarnings' => array( 'expensive-parserfunction-warning', @@ -569,6 +577,8 @@ $wgMessageStructure = array( 'post-expand-template-inclusion-category', 'post-expand-template-argument-warning', 'post-expand-template-argument-category', + 'parser-template-loop-warning', + 'parser-template-recursion-depth-warning', ), 'undo' => array( 'undo-success', @@ -584,9 +594,8 @@ $wgMessageStructure = array( 'history' => array( 'viewpagelogs', 'nohistory', - 'revnotfound', - 'revnotfoundtext', 'currentrev', + 'currentrev-asof', 'revisionasof', 'revision-info', 'revision-info-current', @@ -600,6 +609,7 @@ $wgMessageStructure = array( 'page_first', 'page_last', 'histlegend', + 'history-fieldset-title', 'history_copyright', 'deletedrev', 'histfirst', @@ -679,6 +689,7 @@ $wgMessageStructure = array( 'mergehistory-invalid-destination', 'mergehistory-autocomment', 'mergehistory-comment', + 'mergehistory-same-destination', ), 'mergelog' => array( 'mergelog', @@ -691,11 +702,68 @@ $wgMessageStructure = array( 'difference', 'lineno', 'compareselectedversions', + 'visualcomparison', + 'wikicodecomparison', 'editundo', 'diff-multi', + 'diff-movedto', + 'diff-styleadded', + 'diff-added', + 'diff-changedto', + 'diff-movedoutof', + 'diff-styleremoved', + 'diff-removed', + 'diff-changedfrom', + 'diff-src', + 'diff-withdestination', + 'diff-with', + 'diff-with-additional', + 'diff-with-final', + 'diff-width', + 'diff-height', + 'diff-p', + 'diff-blockquote', + 'diff-h1', + 'diff-h2', + 'diff-h3', + 'diff-h4', + 'diff-h5', + 'diff-pre', + 'diff-div', + 'diff-ul', + 'diff-ol', + 'diff-li', + 'diff-table', + 'diff-tbody', + 'diff-tr', + 'diff-td', + 'diff-th', + 'diff-br', + 'diff-hr', + 'diff-code', + 'diff-dl', + 'diff-dt', + 'diff-dd', + 'diff-input', + 'diff-form', + 'diff-img', + 'diff-span', + 'diff-a', + 'diff-i', + 'diff-b', + 'diff-strong', + 'diff-em', + 'diff-font', + 'diff-big', + 'diff-del', + 'diff-tt', + 'diff-sub', + 'diff-sup', + 'diff-strike', ), 'search' => array( 'searchresults', + 'searchresults-title', 'searchresulttext', 'searchsubtitle', 'searchsubtitleinvalid', @@ -709,6 +777,25 @@ $wgMessageStructure = array( 'prevn', 'nextn', 'viewprevnext', + 'searchmenu-legend', + 'searchmenu-exists', + 'searchmenu-new', + 'searchhelp-url', + 'searchmenu-prefix', + 'searchmenu-help', + 'searchprofile-articles', + 'searchprofile-articles-and-proj', + 'searchprofile-project', + 'searchprofile-images', + 'searchprofile-everything', + 'searchprofile-advanced', + 'searchprofile-articles-tooltip', + 'searchprofile-project-tooltip', + 'searchprofile-images-tooltip', + 'searchprofile-everything-tooltip', + 'searchprofile-advanced-tooltip', + 'prefs-search-nsdefault', + 'prefs-search-nscustom', 'search-result-size', 'search-result-score', 'search-redirect', @@ -719,15 +806,16 @@ $wgMessageStructure = array( 'search-interwiki-custom', 'search-interwiki-more', 'search-mwsuggest-enabled', - 'search-mwsuggest-disabled', + 'search-mwsuggest-disabled', 'search-relatedarticle', 'mwsuggest-disable', - 'searchrelated', + 'searchrelated', 'searchall', 'showingresults', 'showingresultsnum', 'showingresultstotal', 'nonefound', + 'search-nonefound', 'powersearch', 'powersearch-legend', 'powersearch-ns', @@ -756,6 +844,7 @@ $wgMessageStructure = array( 'qbsettings-floatingright', 'changepassword', 'skin', + 'skin-preview', 'math', 'dateformat', 'datedefault', @@ -773,14 +862,15 @@ $wgMessageStructure = array( 'prefs-rc', 'prefs-watchlist', 'prefs-watchlist-days', + 'prefs-watchlist-days-max', 'prefs-watchlist-edits', + 'prefs-watchlist-edits-max', 'prefs-misc', + 'prefs-resetpass', 'saveprefs', 'resetprefs', - 'oldpassword', - 'newpassword', - 'retypenew', 'textboxsize', + 'prefs-edit-boxsize', 'rows', 'columns', 'searchresultshead', @@ -789,11 +879,15 @@ $wgMessageStructure = array( 'contextchars', 'stub-threshold', 'recentchangesdays', + 'recentchangesdays-max', 'recentchangescount', 'savedprefs', 'timezonelegend', 'timezonetext', 'localtime', + 'timezoneselect', + 'timezoneuseserverdefault', + 'timezoneuseoffset', 'timezoneoffset', 'servertime', 'guesstimezone', @@ -802,6 +896,7 @@ $wgMessageStructure = array( 'prefs-namespaces', 'defaultns', 'default', + 'defaultns', 'files', ), 'userrights' => array( @@ -859,6 +954,8 @@ $wgMessageStructure = array( 'right-minoredit', 'right-move', 'right-move-subpages', + 'right-move-rootuserpages', + 'right-movefile', 'right-suppressredirect', 'right-upload', 'right-reupload', @@ -909,10 +1006,47 @@ $wgMessageStructure = array( 'rightslogentry', 'rightsnone', ), + 'action' => array( + 'action-read', + 'action-edit', + 'action-createpage', + 'action-createtalk', + 'action-createaccount', + 'action-minoredit', + 'action-move', + 'action-move-subpages', + 'action-move-rootuserpages', + 'action-movefile', + 'action-upload', + 'action-reupload', + 'action-reupload-shared', + 'action-upload_by_url', + 'action-writeapi', + 'action-delete', + 'action-deleterevision', + 'action-deletedhistory', + 'action-browsearchive', + 'action-undelete', + 'action-suppressrevision', + 'action-suppressionlog', + 'action-block', + 'action-protect', + 'action-import', + 'action-importupload', + 'action-patrol', + 'action-autopatrol', + 'action-unwatchedpages', + 'action-trackback', + 'action-mergehistory', + 'action-userrights', + 'action-userrights-interwiki', + 'action-siteadmin', + ), 'recentchanges' => array( 'nchanges', 'recentchanges', 'recentchanges-url', + 'recentchanges-legend', 'recentchangestext', 'recentchanges-feed-description', 'rcnote', @@ -939,10 +1073,13 @@ $wgMessageStructure = array( 'rc_categories_any', 'rc-change-size', 'newsectionsummary', + 'rc-enhanced-expand', + 'rc-enhanced-hide', ), 'recentchangeslinked' => array( 'recentchangeslinked', 'recentchangeslinked-title', + 'recentchangeslinked-backlink', 'recentchangeslinked-noresult', 'recentchangeslinked-summary', 'recentchangeslinked-page', @@ -995,6 +1132,7 @@ $wgMessageStructure = array( 'fileexists-forbidden', 'fileexists-shared-forbidden', 'file-exists-duplicate', + 'file-deleted-duplicate', 'successfulupload', 'uploadwarning', 'savefile', @@ -1036,18 +1174,19 @@ $wgMessageStructure = array( 'upload_source_url', 'upload_source_file', ), - 'imagelist' => array( - 'imagelist-summary', - 'imagelist_search_for', + 'filelist' => array( + 'listfiles-summary', + 'listfiles_search_for', 'imgfile', - 'imagelist', - 'imagelist_date', - 'imagelist_name', - 'imagelist_user', - 'imagelist_size', - 'imagelist_description', - ), - 'imagedesciption' => array( + 'listfiles', + 'listfiles_date', + 'listfiles_name', + 'listfiles_user', + 'listfiles_size', + 'listfiles_description', + 'listfiles_count', + ), + 'filedescription' => array( 'filehist', 'filehist-help', 'filehist-deleteall', @@ -1055,12 +1194,16 @@ $wgMessageStructure = array( 'filehist-revert', 'filehist-current', 'filehist-datetime', + 'filehist-thumb', + 'filehist-thumbtext', + 'filehist-nothumb', 'filehist-user', 'filehist-dimensions', 'filehist-filesize', 'filehist-comment', 'imagelinks', 'linkstoimage', + 'linkstoimage-more', 'nolinkstoimage', 'morelinkstoimage', 'redirectstofile', @@ -1102,7 +1245,6 @@ $wgMessageStructure = array( 'filedelete-success-old', 'filedelete-nofile', 'filedelete-nofile-old', - 'filedelete-iscurrent', 'filedelete-otherreason', 'filedelete-reason-otherlist', 'filedelete-reason-dropdown', @@ -1139,10 +1281,23 @@ $wgMessageStructure = array( ), 'statistics' => array( 'statistics', - 'sitestats', - 'userstats', - 'sitestatstext', - 'userstatstext', + 'statistics-summary', + 'statistics-header-pages', + 'statistics-header-edits', + 'statistics-header-views', + 'statistics-header-users', + 'statistics-articles', + 'statistics-pages', + 'statistics-pages-desc', + 'statistics-files', + 'statistics-edits', + 'statistics-edits-average', + 'statistics-views-total', + 'statistics-views-peredit', + 'statistics-jobqueue', + 'statistics-users', + 'statistics-users-active', + 'statistics-users-active-desc', 'statistics-mostpopular', 'statistics-footer', ), @@ -1204,8 +1359,10 @@ $wgMessageStructure = array( 'wantedcategories-summary', 'wantedpages', 'wantedpages-summary', - 'missingfiles', - 'missingfiles-summary', + 'wantedfiles', + 'wantedfiles-summary', + 'wantedtemplates', + 'wantedtemplates-summary', 'mostlinked', 'mostlinked-summary', 'mostlinkedcategories', @@ -1230,6 +1387,7 @@ $wgMessageStructure = array( 'protectedpages', 'protectedpages-indef', 'protectedpages-summary', + 'protectedpages-cascade', 'protectedpagestext', 'protectedpagesempty', 'protectedtitles', @@ -1238,6 +1396,8 @@ $wgMessageStructure = array( 'protectedtitlesempty', 'listusers', 'listusers-summary', + 'listusers-editsonly', + 'usereditcount', 'newpages', 'newpages-summary', 'newpages-username', @@ -1262,6 +1422,7 @@ $wgMessageStructure = array( 'booksources-isbn', 'booksources-go', 'booksources-text', + 'booksources-invalid-isbn', ), 'magicwords' => array( 'rfcurl', @@ -1272,8 +1433,6 @@ $wgMessageStructure = array( 'speciallogtitlelabel', 'log', 'all-logs-page', - 'log-search-legend', - 'log-search-submit', 'alllogstext', 'logempty', 'log-title-wildcard', @@ -1285,6 +1444,7 @@ $wgMessageStructure = array( 'nextpage', 'prevpage', 'allpagesfrom', + 'allpagesto', 'allarticles', 'allinnamespace', 'allnotinnamespace', @@ -1303,11 +1463,32 @@ $wgMessageStructure = array( 'special-categories-sort-count', 'special-categories-sort-abc', ), + 'deletedcontribs' => array( + 'deletedcontributions', + ), + 'linksearch' => array( + 'linksearch', + 'linksearch-pat', + 'linksearch-ns', + 'linksearch-ok', + 'linksearch-text', + 'linksearch-line', + 'linksearch-error', + ), 'listusers' => array( 'listusersfrom', 'listusers-submit', 'listusers-noresult', ), + 'newuserlog' => array( + 'newuserlogpage', + 'newuserlogpagetext', + 'newuserlogentry', + 'newuserlog-byemail', + 'newuserlog-create-entry', + 'newuserlog-create2-entry', + 'newuserlog-autocreate-entry', + ), 'listgrouprights' => array( 'listgrouprights', 'listgrouprights-summary', @@ -1316,6 +1497,10 @@ $wgMessageStructure = array( 'listgrouprights-helppage', 'listgrouprights-members', 'listgrouprights-right-display', + 'listgrouprights-addgroup', + 'listgrouprights-removegroup', + 'listgrouprights-addgroup-all', + 'listgrouprights-removegroup-all', ), 'emailuser' => array( 'mailnologin', @@ -1327,6 +1512,9 @@ $wgMessageStructure = array( 'defemailsubject', 'noemailtitle', 'noemailtext', + 'nowikiemailtitle', + 'nowikiemailtext', + 'email-legend', 'emailfrom', 'emailto', 'emailsubject', @@ -1366,12 +1554,7 @@ $wgMessageStructure = array( 'iteminvalidname', 'wlnote', 'wlshowlast', - 'watchlist-show-bots', - 'watchlist-hide-bots', - 'watchlist-show-own', - 'watchlist-hide-own', - 'watchlist-show-minor', - 'watchlist-hide-minor', + 'watchlist-options', ), 'watching' => array( 'watching', @@ -1390,7 +1573,7 @@ $wgMessageStructure = array( 'enotif_anon_editor', 'enotif_body', ), - 'deleteprotectrev' => array( + 'delete' => array( 'deletepage', 'confirm', 'excontent', @@ -1417,6 +1600,8 @@ $wgMessageStructure = array( 'delete-edit-reasonlist', 'delete-toobig', 'delete-warning-toobig', + ), + 'rollback' => array( 'rollback', 'rollback_short', 'rollbacklink', @@ -1427,15 +1612,18 @@ $wgMessageStructure = array( 'revertpage', 'rollback-success', 'sessionfailure', + ), + 'protect' => array( 'protectlogpage', 'protectlogtext', 'protectedarticle', 'modifiedarticleprotection', 'unprotectedarticle', + 'movedarticleprotection', 'protect-title', + 'prot_1movedto2', 'protect-backlink', 'protect-legend', - 'confirmprotect', 'protectcomment', 'protectexpiry', 'protect_expiry_invalid', @@ -1452,8 +1640,17 @@ $wgMessageStructure = array( 'protect-level-sysop', 'protect-summary-cascade', 'protect-expiring', + 'protect-expiry-indefinite', 'protect-cascade', 'protect-cantedit', + 'protect-othertime', + 'protect-othertime-op', + 'protect-existing-expiry', + 'protect-otherreason', + 'protect-otherreason-op', + 'protect-dropdown', + 'protect-edit-reasonlist', + 'protect-expiry-options', 'restriction-type', 'restriction-level', 'minimum-size', @@ -1489,6 +1686,7 @@ $wgMessageStructure = array( 'undeletebtn', 'undeletelink', 'undeletereset', + 'undeleteinvert', 'undeletecomment', 'undeletedarticle', 'undeletedrevisions', @@ -1517,6 +1715,7 @@ $wgMessageStructure = array( ), 'contributions' => array( 'contributions', + 'contributions-title', 'mycontris', 'contribsub2', 'nocontribs', @@ -1527,6 +1726,7 @@ $wgMessageStructure = array( 'sp-contributions' => array( 'sp-contributions-newbies', 'sp-contributions-newbies-sub', + 'sp-contributions-newbies-title', 'sp-contributions-blocklog', 'sp-contributions-search', 'sp-contributions-username', @@ -1540,8 +1740,7 @@ $wgMessageStructure = array( 'whatlinkshere-title', 'whatlinkshere-summary', 'whatlinkshere-page', - 'whatlinkshere-barrow', - 'linklistsub', + 'whatlinkshere-backlink', 'linkshere', 'nolinkshere', 'nolinkshere-ns', @@ -1578,6 +1777,8 @@ $wgMessageStructure = array( 'ipbotherreason', 'ipbhidename', 'ipbwatchuser', + 'ipballowusertalk', + 'ipb-change-block', 'badipaddress', 'blockipsuccesssub', 'blockipsuccesstext', @@ -1586,6 +1787,7 @@ $wgMessageStructure = array( 'ipb-unblock', 'ipb-blocklist-addr', 'ipb-blocklist', + 'ipb-blocklist-contribs', 'unblockip', 'unblockiptext', 'ipusubmit', @@ -1594,6 +1796,9 @@ $wgMessageStructure = array( 'ipblocklist', 'ipblocklist-legend', 'ipblocklist-username', + 'ipblocklist-sh-userblocks', + 'ipblocklist-sh-tempblocks', + 'ipblocklist-sh-addressblocks', 'ipblocklist-summary', 'ipblocklist-submit', 'blocklistline', @@ -1603,25 +1808,31 @@ $wgMessageStructure = array( 'noautoblockblock', 'createaccountblock', 'emailblock', + 'blocklist-nousertalk', 'ipblocklist-empty', 'ipblocklist-no-results', 'blocklink', 'unblocklink', + 'change-blocklink', 'contribslink', 'autoblocker', 'blocklogpage', + 'blocklog-fulllog', 'blocklogentry', + 'reblock-logentry', 'blocklogtext', 'unblocklogentry', 'block-log-flags-anononly', 'block-log-flags-nocreate', 'block-log-flags-noautoblock', 'block-log-flags-noemail', + 'block-log-flags-nousertalk', 'block-log-flags-angry-autoblock', 'range_block_disabled', 'ipb_expiry_invalid', 'ipb_expiry_temp', 'ipb_already_blocked', + 'ipb-needreblock', 'ipb_cant_unblock', 'ipb_blocked_as_range', 'ip_range_invalid', @@ -1633,6 +1844,7 @@ $wgMessageStructure = array( 'sorbs', 'sorbsreason', 'sorbs_create_account_reason', + 'cant-block-while-blocked', ), 'developertools' => array( 'lockdb', @@ -1661,11 +1873,16 @@ $wgMessageStructure = array( 'movenologin', 'movenologintext', 'movenotallowed', + 'movenotallowedfile', + 'cant-move-user-page', + 'cant-move-to-user-page', 'newtitle', 'move-watch', 'movepagebtn', 'pagemovedsub', 'movepage-moved', + 'movepage-moved-redirect', + 'movepage-moved-noredirect', 'articleexists', 'cantmove-titleprotected', 'talkexists', @@ -1679,6 +1896,7 @@ $wgMessageStructure = array( 'movepage-max-pages', '1movedto2', '1movedto2_redir', + 'move-redirect-suppressed', 'movelogpage', 'movelogpagetext', 'movereason', @@ -1688,11 +1906,17 @@ $wgMessageStructure = array( 'delete_and_move_confirm', 'delete_and_move_reason', 'selfmove', + 'immobile-source-namespace', + 'immobile-target-namespace', + 'immobile-target-namespace-iw', + 'immobile-source-page', + 'immobile-target-page', 'immobile_namespace', 'imagenocrossnamespace', 'imagetypemismatch', 'imageinvalidfilename', 'fix-double-redirects', + 'move-leave-redirect', ), 'export' => array( 'export', @@ -1728,9 +1952,12 @@ $wgMessageStructure = array( 'import', 'importinterwiki', 'import-interwiki-text', + 'import-interwiki-source', 'import-interwiki-history', 'import-interwiki-submit', 'import-interwiki-namespace', + 'import-upload-filename', + 'import-comment', 'importtext', 'importstart', 'import-revision-count', @@ -1821,6 +2048,7 @@ $wgMessageStructure = array( 'accesskey-preview', 'accesskey-diff', 'accesskey-compareselectedversions', + 'accesskey-visualcomparison', 'accesskey-watch', 'accesskey-upload', ), @@ -1885,6 +2113,8 @@ $wgMessageStructure = array( 'tooltip-watch', 'tooltip-recreate', 'tooltip-upload', + 'tooltip-rollback', + 'tooltip-undo', ), 'stylesheets' => array( 'common.css', @@ -1896,6 +2126,8 @@ $wgMessageStructure = array( 'chick.css', 'simple.css', 'modern.css', + 'print.css', + 'handheld.css', ), 'scripts' => array( 'common.js', @@ -1939,6 +2171,16 @@ $wgMessageStructure = array( 'numauthors', 'numtalkauthors', ), + 'skin' => array( + 'skinname-standard', + 'skinname-nostalgia', + 'skinname-cologneblue', + 'skinname-monobook', + 'skinname-myskin', + 'skinname-chick', + 'skinname-simple', + 'skinname-modern', + ), 'math' => array( 'mw_math_png', 'mw_math_simple', @@ -1965,6 +2207,7 @@ $wgMessageStructure = array( 'patrol-log-line', 'patrol-log-auto', 'patrol-log-diff', + 'log-show-hide-patrol', ), 'imagedeletion' => array( 'deletedrevision', @@ -1979,6 +2222,9 @@ $wgMessageStructure = array( 'previousdiff', 'nextdiff', ), + 'visual-comparison' => array( + 'visual-comparison', + ), 'media-info' => array( 'mediawarning', 'imagemaxsize', @@ -1992,10 +2238,12 @@ $wgMessageStructure = array( 'show-big-image', 'show-big-image-thumb', ), - 'newimages' => array( + 'newfiles' => array( 'newimages', 'imagelisttext', 'newimages-summary', + 'newimages-legend', + 'newimages-label', 'showhidebots', 'noimages', 'ilsubmit', @@ -2269,6 +2517,18 @@ $wgMessageStructure = array( 'exif-lightsource-24', 'exif-lightsource-255', ), + 'exif-flash' => array( + 'exif-flash-fired-0' , + 'exif-flash-fired-1' , + 'exif-flash-return-0' , + 'exif-flash-return-2' , + 'exif-flash-return-3' , + 'exif-flash-mode-1' , + 'exif-flash-mode-2' , + 'exif-flash-mode-3' , + 'exif-flash-function-1' , + 'exif-flash-redeye-1' , + ), 'exif-focalplaneresolutionunit' => array( 'exif-focalplaneresolutionunit-2', ), @@ -2410,19 +2670,10 @@ $wgMessageStructure = array( 'unit-pixel' => array( 'unit-pixel', ), - 'htmldump' => array( - 'redirectingto', - ), 'purge' => array( - 'confirm_purge', 'confirm_purge_button', - ), - 'search2' => array( - 'searchcontaining', - 'searchnamed', - 'articletitles', - 'hideresults', - 'useajaxsearch', + 'confirm-purge-top', + 'confirm-purge-bottom', ), 'separators' => array( 'catseparator', @@ -2430,6 +2681,9 @@ $wgMessageStructure = array( 'comma-separator', 'colon-separator', 'autocomment-prefix', + 'pipe-separator', + 'word-separator', + 'ellipsis', ), 'imgmulti' => array( 'imgmultipageprev', @@ -2560,6 +2814,7 @@ $wgMessageStructure = array( ), 'CoreParserFunctions' => array( 'unknown_extension_tag', + 'duplicate-defaultsort', ), 'version' => array( 'version', @@ -2619,6 +2874,9 @@ $wgMessageStructure = array( 'blankpage', 'intentionallyblankpage', ), + 'external_images' => array( + 'external_image_whitelist', + ), ); /** Comments for each block */ @@ -2631,7 +2889,6 @@ XHTML id it should only appear once and include characters that are legal XHTML id names.", 'toggles' => 'User preference toggles', 'underline' => '', - 'skinpreview' => '', 'dates' => 'Dates', 'categorypages' => 'Categories related messages', 'mainpage' => '', @@ -2668,6 +2925,7 @@ XHTML id names.", 'group-member' => '', 'grouppage' => '', 'right' => 'Rights', + 'action' => 'Associated actions - in the sentence "You do not have permission to X"', 'rightslog' => 'User rights log', 'recentchanges' => 'Recent changes', 'recentchangeslinked' => 'Recent changes linked', @@ -2675,8 +2933,8 @@ XHTML id names.", 'upload-errors' => '', 'upload-curl-errors' => 'Some likely curl errors. More could be added from <http://curl.haxx.se/libcurl/c/libcurl-errors.html>', 'licenses' => '', - 'imagelist' => 'Special:ImageList', - 'imagedesciption' => 'Image description page', + 'filelist' => 'Special:ListFiles', + 'filedescription' => 'File description page', 'filerevert' => 'File reversion', 'filedelete' => 'File deletion', 'mimesearch' => 'MIME search', @@ -2697,13 +2955,18 @@ XHTML id names.", 'logpages' => 'Special:Log', 'allpages' => 'Special:AllPages', 'categories' => 'Special:Categories', + 'deletedcontribs' => 'Special:DeletedContributions', + 'linksearch' => 'Special:LinkSearch', 'listusers' => 'Special:ListUsers', + 'newuserlog' => 'Special:Log/newusers', 'listgrouprights' => 'Special:ListGroupRights', 'emailuser' => 'E-mail user', 'watchlist' => 'Watchlist', 'watching' => 'Displayed when you click the "watch" button and it is in the process of watching', 'enotif' => '', - 'deleteprotectrev' => 'Delete/protect/revert', + 'delete' => 'Delete', + 'rollback' => 'Rollback', + 'protect' => 'Protect', 'restrictions' => 'Restrictions (nouns)', 'restriction-levels' => 'Restriction levels', 'undelete' => 'Undelete', @@ -2727,12 +2990,13 @@ XHTML id names.", 'attribution' => 'Attribution', 'spamprotection' => 'Spam protection', 'info' => 'Info page', + 'skin' => 'Skin names', 'math' => 'Math options', 'patrolling' => 'Patrolling', 'patrol-log' => 'Patrol log', 'imagedeletion' => 'Image deletion', 'browsediffs' => 'Browsing diffs', - 'newimages' => 'Special:NewImages', + 'newfiles' => 'Special:NewFiles', 'video-info' => 'Video information, used by Language::formatTimePeriod() to format lengths in the above messages', 'badimagelist' => 'Bad image list', 'variantname-zh' => "Short names for language variants used for language conversion links. @@ -2743,6 +3007,7 @@ Variants for Chinese language", 'variantname-kk' => 'Variants for Kazakh language', 'variantname-ku' => 'Variants for Kurdish language', 'variantname-tg' => 'Variants for Tajiki language', + 'visual-comparison' => 'Visual comparison', 'media-info' => 'Media information', 'metadata' => 'Metadata', 'exif' => 'EXIF tags', @@ -2759,6 +3024,7 @@ Variants for Chinese language", 'exif-subjectdistance-value' => '', 'exif-meteringmode' => '', 'exif-lightsource' => '', + 'exif-flash' => 'Flash modes', 'exif-focalplaneresolutionunit' => '', 'exif-sensingmethod' => '', 'exif-filesource' => '', @@ -2785,9 +3051,7 @@ Variants for Chinese language", 'trackbacks' => 'Trackbacks', 'deleteconflict' => 'Delete conflict', 'unit-pixel' => '', - 'htmldump' => 'HTML dump', 'purge' => 'action=purge', - 'search2' => 'AJAX search', 'separators' => 'Separators for various lists, etc.', 'imgmulti' => 'Multipage image navigation', 'tablepager' => 'Table pager', @@ -2808,6 +3072,7 @@ Variants for Chinese language", 'fileduplicatesearch' => 'Special:FileDuplicateSearch', 'special-specialpages' => 'Special:SpecialPages', 'special-blank' => 'Special:BlankPage', + 'external_images' => 'External image whitelist', ); /** Short comments for standalone messages */ @@ -2817,7 +3082,7 @@ $wgMessageComments = array( 'sitenotice' => 'the equivalent to wgSiteNotice', 'history-feed-item-nocomment' => 'user at time', 'editcomment' => 'only shown if there is an edit comment', - 'revertpage' => 'Additional available: $3: revid of the revision reverted to, $4: timestamp of the revision reverted to, $5: revid of the revision reverted from, $6: timestamp of the revision reverted from', + 'revertpage' => 'Additionally available: $3: revid of the revision reverted to, $4: timestamp of the revision reverted to, $5: revid of the revision reverted from, $6: timestamp of the revision reverted from', 'lastmodifiedatby' => '$1 date, $2 time, $3 user', 'exif-orientation-1' => '0th row: top; 0th column: left', 'exif-orientation-2' => '0th row: top; 0th column: right', @@ -2829,7 +3094,10 @@ $wgMessageComments = array( 'exif-orientation-8' => '0th row: left; 0th column: bottom', 'movepage-moved' => 'The two titles are passed in plain text as $3 and $4 to allow additional goodies in the message.', 'ipboptions' => 'display1:time1,display2:time2,...', + 'protect-expiry-options' => 'display1:time1,display2:time2,...', 'metadata-fields' => 'Do not translate list items', 'version' => 'Not used as normal message but as header for the special page itself', 'userrights' => 'Not used as normal message but as header for the special page itself', + 'revision-info' => 'Additionally available: $3: revision id', + 'revision-info-current' => 'Available parameters: $1: timestamp; $2: userlinks; $3: revision id', ); diff --git a/maintenance/language/transstat.php b/maintenance/language/transstat.php index ee2b844c..b433abb4 100644 --- a/maintenance/language/transstat.php +++ b/maintenance/language/transstat.php @@ -96,12 +96,12 @@ foreach ( $wgLanguages->getLanguages() as $code ) { $requiredMessagesPercent = $wgOut->formatPercent( $requiredMessagesNumber, $wgRequiredMessagesNumber ); $obsoleteMessagesNumber = count( $messages['obsolete'] ); $obsoleteMessagesPercent = $wgOut->formatPercent( $obsoleteMessagesNumber, $messagesNumber, true ); - $messagesWithoutVariables = $wgLanguages->getMessagesWithoutVariables( $code ); + $messagesWithMismatchVariables = $wgLanguages->getMessagesWithMismatchVariables( $code ); $emptyMessages = $wgLanguages->getEmptyMessages( $code ); $messagesWithWhitespace = $wgLanguages->getMessagesWithWhitespace( $code ); $nonXHTMLMessages = $wgLanguages->getNonXHTMLMessages( $code ); $messagesWithWrongChars = $wgLanguages->getMessagesWithWrongChars( $code ); - $problematicMessagesNumber = count( array_unique( array_merge( $messagesWithoutVariables, $emptyMessages, $messagesWithWhitespace, $nonXHTMLMessages, $messagesWithWrongChars ) ) ); + $problematicMessagesNumber = count( array_unique( array_merge( $messagesWithMismatchVariables, $emptyMessages, $messagesWithWhitespace, $nonXHTMLMessages, $messagesWithWrongChars ) ) ); $problematicMessagesPercent = $wgOut->formatPercent( $problematicMessagesNumber, $messagesNumber, true ); # Output them |