+
+/**
+ * @ingroup MaintenanceLanguage
+ */
+class CheckExtensionsCLI extends CheckLanguageCLI {
+ private $extensions;
+
+ /**
+ * Constructor.
+ * @param $options array Options for script.
+ * @param $extension string The extension name (or names).
+ */
+ public function __construct( Array $options, $extension ) {
+ if ( isset( $options['help'] ) ) {
+ echo $this->help();
+ exit(1);
+ }
+
+ if ( isset( $options['lang'] ) ) {
+ $this->code = $options['lang'];
+ } else {
+ global $wgLanguageCode;
+ $this->code = $wgLanguageCode;
+ }
+
+ if ( isset( $options['level'] ) ) {
+ $this->level = $options['level'];
+ }
+
+ $this->doLinks = isset( $options['links'] );
+
+ if ( isset( $options['wikilang'] ) ) {
+ $this->wikiCode = $options['wikilang'];
+ }
+
+ if ( isset( $options['whitelist'] ) ) {
+ $this->checks = explode( ',', $options['whitelist'] );
+ } elseif ( isset( $options['blacklist'] ) ) {
+ $this->checks = array_diff(
+ isset( $options['easy'] ) ? $this->easyChecks() : $this->defaultChecks(),
+ explode( ',', $options['blacklist'] )
+ );
+ } elseif ( isset( $options['easy'] ) ) {
+ $this->checks = $this->easyChecks();
+ } else {
+ $this->checks = $this->defaultChecks();
+ }
+
+ if ( isset( $options['output'] ) ) {
+ $this->output = $options['output'];
+ }
+
+ # Some additional checks not enabled by default
+ if ( isset( $options['duplicate'] ) ) {
+ $this->checks[] = 'duplicate';
+ }
+
+ $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() ) {
+ $this->extensions[] = new extensionLanguages( $group );
+ }
+ }
+ } elseif ( $extension == 'wikimedia' ) {
+ $wikimedia = MessageGroups::getGroup( 'ext-0-wikimedia' );
+ 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 ) {
+ $group = MessageGroups::getGroup( 'ext-' . $extension );
+ if ( $group ) {
+ $extension = new extensionLanguages( $group );
+ $this->extensions[] = $extension;
+ } else {
+ print "No such extension $extension.\n";
+ }
+ }
+ }
+ }
+
+ /**
+ * Get the default checks.
+ * @return array 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 array 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 arrayA list of the easy checks.
+ */
+ protected function easyChecks() {
+ return array(
+ 'duplicate', 'obsolete', 'empty', 'whitespace', 'xhtml', 'chars',
+ );
+ }
+
+ /**
+ * Get help.
+ * @return string 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, "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 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).
+ * 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, or with variables which should not be used.
+ * empty: Empty messages.
+ * 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 ]}.
+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.
+ * 2: Show only the headers and the message keys, without the message values.
+ * 3: Show both the headers and the complete messages, with both keys and values.
+
+ENDS;
+ }
+
+ /**
+ * Execute the script.
+ */
+ public function execute() {
+ $this->doChecks();
+ }
+
+ /**
+ * Check a language and show the results.
+ * @param $code string The language code.
+ */
+ protected function checkLanguage( $code ) {
+ foreach( $this->extensions as $extension ) {
+ $this->L = $extension;
+ $this->results = array();
+ $this->results[$code] = parent::checkLanguage( $code );
+
+ if( !$this->isEmpty() ) {
+ echo $extension->name() . ":\n";
+
+ if( $this->level > 0 ) {
+ switch( $this->output ) {
+ case 'plain':
+ $this->outputText();
+ break;
+ case 'wiki':
+ $this->outputWiki();
+ break;
+ default:
+ throw new MWException( "Invalid output type $this->output" );
+ }
+ }
+
+ echo "\n";
+ }
+ }
+ }
+}
+
+# Blacklist some checks for some languages
+$checkBlacklist = array(
+#'code' => array( 'check1', 'check2' ... )
+'az' => array( 'plural' ),
+'bo' => array( 'plural' ),
+'dz' => array( 'plural' ),
+'id' => array( 'plural' ),
+'fa' => array( 'plural' ),
+'gan' => array( 'plural' ),
+'gan-hans' => array( 'plural' ),
+'gan-hant' => array( 'plural' ),
+'gn' => array( 'plural' ),
+'hak' => array( 'plural' ),
+'hu' => array( 'plural' ),
+'ja' => array( 'plural' ), // Does not use plural
+'jv' => array( 'plural' ),
+'ka' => array( 'plural' ),
+'kk-arab' => array( 'plural' ),
+'kk-cyrl' => array( 'plural' ),
+'kk-latn' => array( 'plural' ),
+'km' => array( 'plural' ),
+'kn' => array( 'plural' ),
+'ko' => array( 'plural' ),
+'lzh' => array( 'plural' ),
+'mn' => array( 'plural' ),
+'ms' => array( 'plural' ),
+'my' => array( 'plural', 'chars' ), // Uses a lot zwnj
+'sah' => array( 'plural' ),
+'sq' => array( 'plural' ),
+'tet' => array( 'plural' ),
+'th' => array( 'plural' ),
+'to' => array( 'plural' ),
+'tr' => array( 'plural' ),
+'vi' => array( 'plural' ),
+'wuu' => array( 'plural' ),
+'xmf' => array( 'plural' ),
+'yo' => array( 'plural' ),
+'yue' => array( 'plural' ),
+'zh' => array( 'plural' ),
+'zh-classical' => array( 'plural' ),
+'zh-cn' => array( 'plural' ),
+'zh-hans' => array( 'plural' ),
+'zh-hant' => array( 'plural' ),
+'zh-hk' => array( 'plural' ),
+'zh-sg' => array( 'plural' ),
+'zh-tw' => array( 'plural' ),
+'zh-yue' => array( 'plural' ),
+);