Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
createCheckIndex.php
Go to the documentation of this file.
1<?php
12// Standard boilerplate to define $IP
13
15use Mediawiki\Languages\LanguageNameUtils;
16use MediaWiki\MediaWikiServices;
17
18if ( getenv( 'MW_INSTALL_PATH' ) !== false ) {
19 $IP = getenv( 'MW_INSTALL_PATH' );
20} else {
21 $dir = __DIR__;
22 $IP = "$dir/../../..";
23}
24require_once "$IP/maintenance/Maintenance.php";
25
26class CreateCheckIndex extends Maintenance {
27 public function __construct() {
28 parent::__construct();
29 $this->addDescription( 'Creates serialised database of messages that need ' .
30 'checking for problems.' );
31 $this->addOption(
32 'group',
33 'Comma separated list of group IDs to process (can use * as wildcard).',
34 true, /*required*/
35 true /*has arg*/
36 );
37
38 $this->addOption(
39 'verbose',
40 '(optional) Enable verbose logging. Default: off',
41 false, /*required*/
42 false /*has arg*/
43 );
44 $this->requireExtension( 'Translate' );
45 }
46
47 public function execute() {
48 $codes = MediaWikiServices::getInstance()
49 ->getLanguageNameUtils()
50 ->getLanguageNames( null, LanguageNameUtils::ALL );
51
52 // Exclude the documentation language code
53 global $wgTranslateDocumentationLanguageCode;
54 if ( $wgTranslateDocumentationLanguageCode ) {
55 unset( $codes[$wgTranslateDocumentationLanguageCode] );
56 }
57
58 $reqGroupsPattern = $this->getOption( 'group' );
59 $reqGroups = explode( ',', $reqGroupsPattern );
60 $reqGroups = array_map( 'trim', $reqGroups );
61 $reqGroups = MessageGroups::expandWildcards( $reqGroups );
62
63 $verbose = $this->hasOption( 'verbose' );
64
65 if ( !$reqGroups ) {
66 $this->fatalError( "Pattern '$reqGroupsPattern' did not match any groups" );
67 }
68
69 $groups = MessageGroups::singleton()->getGroups();
70 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
71
73 foreach ( $reqGroups as $id ) {
74 $g = MessageGroups::getGroup( $id );
75 // Aliases may have changed the id
76 $id = $g->getId();
77 $sourceLanguage = $g->getSourceLanguage();
78
79 $validator = $g->getValidator();
80 if ( !$validator ) {
81 unset( $g );
82 $this->output( "Skipping group $id due to lack of validators" );
83 continue;
84 }
85
86 // Initialise messages, using unique definitions if appropriate
87 // @phan-suppress-next-line PhanParamTooMany MessageGroupOld takes two args
88 $collection = $g->initCollection( $sourceLanguage, true );
89 if ( !count( $collection ) ) {
90 continue;
91 }
92
93 $this->output( "Processing group $id: ", $id );
94
95 // Skip source language code
96 $langCodes = $codes;
97 unset( $langCodes[$sourceLanguage] );
98
99 $langCodes = array_keys( $langCodes );
100 sort( $langCodes );
101
102 foreach ( $langCodes as $code ) {
103 $this->output( "$code ", $id );
104
105 $problematic = [];
106
107 $collection->resetForNewLanguage( $code );
108 $collection->loadTranslations();
109 $collection->filter( 'ignored' );
110 $collection->filter( 'fuzzy' );
111 $collection->filter( 'translated', false );
112
113 foreach ( $collection as $key => $message ) {
114 $result = $validator->quickValidate( $message, $code );
115 if ( $result->hasIssues() ) {
116 if ( $verbose ) {
117 // Print it
118 $nsText = $contLang->getNsText( $g->getNamespace() );
119 $this->output( "# [[$nsText:$key/$code]]\n" );
120 }
121
122 // Add it to the array
123 $problematic[] = [ $g->getNamespace(), "$key/$code" ];
124 }
125 }
126
127 self::tagFuzzy( $problematic );
128 }
129 }
130 }
131
132 public static function tagFuzzy( array $problematic ): void {
133 if ( $problematic === [] ) {
134 return;
135 }
136
137 $titleConditions = [];
138 $dbw = wfGetDB( DB_PRIMARY );
139
140 foreach ( $problematic as $p ) {
141 // Normalize page key
142 $title = Title::makeTitleSafe( $p[0], $p[1] );
143 $titleText = $title->getDBkey();
144 $titleConditions[] = $dbw->makeList(
145 [
146 'page_namespace' => $p[0],
147 'page_title' => $titleText
148 ],
149 LIST_AND
150 );
151 }
152
153 $conds = $dbw->makeList( $titleConditions, LIST_OR );
154
155 $res = $dbw->select( 'page', [ 'page_id', 'page_latest' ], $conds, __METHOD__ );
156 $inserts = [];
157 foreach ( $res as $row ) {
158 $inserts[] = [
159 'rt_page' => $row->page_id,
160 'rt_revision' => $row->page_latest,
161 'rt_type' => RevTagStore::FUZZY_TAG
162 ];
163 }
164 $dbw->replace( 'revtag', [ [ 'rt_type', 'rt_page', 'rt_revision' ] ], $inserts, __METHOD__ );
165 }
166}
167
168$maintClass = CreateCheckIndex::class;
169require_once RUN_MAINTENANCE_IF_MAIN;
Class to manage revision tags for translatable bundles.