Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
MessageHandle.php
Go to the documentation of this file.
1<?php
12use MediaWiki\Linker\LinkTarget;
13use MediaWiki\Logger\LoggerFactory;
14use MediaWiki\MediaWikiServices;
15
22 protected $title;
24 protected $key;
26 protected $code;
28 protected $groupIds;
29
30 public function __construct( LinkTarget $title ) {
31 $this->title = $title;
32 }
33
38 public function isMessageNamespace() {
39 global $wgTranslateMessageNamespaces;
40 $namespace = $this->title->getNamespace();
41
42 return in_array( $namespace, $wgTranslateMessageNamespaces );
43 }
44
49 public function figureMessage() {
50 if ( $this->key === null ) {
51 // Check if this is a valid message first
52 $this->key = $this->title->getDBkey();
53 $known = MessageIndex::singleton()->getGroupIds( $this ) !== [];
54
55 $pos = strrpos( $this->key, '/' );
56 if ( $known || $pos === false ) {
57 $this->code = '';
58 } else {
59 // For keys like Foo/, substr returns false instead of ''
60 $this->code = (string)( substr( $this->key, $pos + 1 ) );
61 $this->key = substr( $this->key, 0, $pos );
62 }
63 }
64
65 return [ $this->key, $this->code ];
66 }
67
72 public function getKey() {
73 $this->figureMessage();
74
75 return $this->key;
76 }
77
83 public function getCode() {
84 $this->figureMessage();
85
86 return $this->code;
87 }
88
95 public function getEffectiveLanguage() {
96 $code = $this->getCode();
97 $mwInstance = MediaWikiServices::getInstance();
98 if ( !$mwInstance->getLanguageNameUtils()->isKnownLanguageTag( $code ) ||
99 $this->isDoc()
100 ) {
101 return $mwInstance->getContentLanguage();
102 }
103
104 return $mwInstance->getLanguageFactory()->getLanguage( $code );
105 }
106
111 public function isDoc() {
112 global $wgTranslateDocumentationLanguageCode;
113
114 return $this->getCode() === $wgTranslateDocumentationLanguageCode;
115 }
116
122 public function isPageTranslation() {
123 return $this->title->inNamespace( NS_TRANSLATIONS );
124 }
125
133 public function getGroupIds() {
134 if ( $this->groupIds === null ) {
135 $this->groupIds = MessageIndex::singleton()->getGroupIds( $this );
136 }
137
138 return $this->groupIds;
139 }
140
146 public function getGroup() {
147 $ids = $this->getGroupIds();
148 if ( !isset( $ids[0] ) ) {
149 throw new BadMethodCallException( 'called before isValid' );
150 }
151
152 return MessageGroups::getGroup( $ids[0] );
153 }
154
160 public function isValid() {
161 if ( !$this->isMessageNamespace() ) {
162 return false;
163 }
164
165 $groups = $this->getGroupIds();
166 if ( !$groups ) {
167 return false;
168 }
169
170 // Do another check that the group actually exists
171 $group = $this->getGroup();
172 if ( !$group ) {
173 $logger = LoggerFactory::getInstance( 'Translate' );
174 $logger->warning(
175 '[MessageHandle] MessageIndex is out of date. Page {pagename} refers to ' .
176 'unknown group {messagegroup}',
177 [
178 'pagename' => $this->getTitle()->getPrefixedText(),
179 'messagegroup' => $groups[0],
180 ]
181 );
182
183 // Schedule a job in the job queue (with deduplication)
184 $job = MessageIndexRebuildJob::newJob();
185 MediaWikiServices::getInstance()->getJobQueueGroup()->push( $job );
186
187 return false;
188 }
189
190 return true;
191 }
192
197 public function getTitle() {
198 return Title::newFromLinkTarget( $this->title );
199 }
200
207 public function getTitleForLanguage( $code ) {
208 return Title::makeTitle(
209 $this->title->getNamespace(),
210 $this->getKey() . "/$code"
211 );
212 }
213
219 public function getTitleForBase() {
220 return Title::makeTitle(
221 $this->title->getNamespace(),
222 $this->getKey()
223 );
224 }
225
232 public static function hasFuzzyString( $text ) {
233 return str_contains( $text, TRANSLATE_FUZZY );
234 }
235
237 public static function makeFuzzyString( string $text ): string {
238 return self::hasFuzzyString( $text ) ? $text : TRANSLATE_FUZZY . $text;
239 }
240
245 public function isFuzzy() {
246 $dbr = wfGetDB( DB_REPLICA );
247
248 $tables = [ 'page', 'revtag' ];
249 $field = 'rt_type';
250 $conds = [
251 'page_namespace' => $this->title->getNamespace(),
252 'page_title' => $this->title->getDBkey(),
253 'rt_type' => RevTagStore::FUZZY_TAG,
254 'page_id=rt_page',
255 'page_latest=rt_revision'
256 ];
257
258 $res = $dbr->selectField( $tables, $field, $conds, __METHOD__ );
259
260 return $res !== false;
261 }
262
270 public function getInternalKey(): string {
271 $nsInfo = MediaWikiServices::getInstance()->getNamespaceInfo();
272 $contentLanguage = MediaWikiServices::getInstance()->getContentLanguage();
273
274 $key = $this->getKey();
275 $group = $this->getGroup();
276 $groupKeys = $group->getKeys();
277
278 if ( in_array( $key, $groupKeys, true ) ) {
279 return $key;
280 }
281
282 $namespace = $this->title->getNamespace();
283 if ( $nsInfo->isCapitalized( $namespace ) ) {
284 $lowercaseKey = $contentLanguage->lcfirst( $key );
285 if ( in_array( $lowercaseKey, $groupKeys, true ) ) {
286 return $lowercaseKey;
287 }
288 }
289
290 // Brute force all the keys to find the one. This one should always find a match
291 // if there is one.
292 foreach ( $groupKeys as $haystackKey ) {
293 $normalizedHaystackKey = Title::makeTitleSafe( $namespace, $haystackKey )->getDBkey();
294 if ( $normalizedHaystackKey === $key ) {
295 return $haystackKey;
296 }
297 }
298
299 return "BUG:$key";
300 }
301}
return[ 'Translate:ConfigHelper'=> static function():ConfigHelper { return new ConfigHelper();}, 'Translate:CsvTranslationImporter'=> static function(MediaWikiServices $services):CsvTranslationImporter { return new CsvTranslationImporter( $services->getWikiPageFactory());}, 'Translate:EntitySearch'=> static function(MediaWikiServices $services):EntitySearch { return new EntitySearch($services->getMainWANObjectCache(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), MessageGroups::singleton(), $services->getNamespaceInfo(), $services->get( 'Translate:MessageIndex'), $services->getTitleParser(), $services->getTitleFormatter());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->getMainConfig(), $services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance( 'Translate.GroupSynchronization'), $services->get( 'Translate:MessageIndex'));}, 'Translate:FileFormatFactory'=> static function(MediaWikiServices $services):FileFormatFactory { return new FileFormatFactory( $services->getObjectFactory());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:HookRunner'=> static function(MediaWikiServices $services):HookRunner { return new HookRunner( $services->getHookContainer());}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore($services->get( 'Translate:RevTagStore'), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReviewStore'=> static function(MediaWikiServices $services):MessageGroupReviewStore { return new MessageGroupReviewStore($services->getDBLoadBalancer(), $services->get( 'Translate:HookRunner'));}, 'Translate:MessageGroupStatsTableFactory'=> static function(MediaWikiServices $services):MessageGroupStatsTableFactory { return new MessageGroupStatsTableFactory($services->get( 'Translate:ProgressStatsTableFactory'), $services->getDBLoadBalancer(), $services->getLinkRenderer(), $services->get( 'Translate:MessageGroupReviewStore'), $services->getMainConfig() ->get( 'TranslateWorkflowStates') !==false);}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=$services->getMainConfig() ->get( 'TranslateMessageIndex');if(is_string( $params)) { $params=(array) $params;} $class=array_shift( $params);return new $class( $params);}, 'Translate:MessagePrefixStats'=> static function(MediaWikiServices $services):MessagePrefixStats { return new MessagePrefixStats( $services->getTitleParser());}, 'Translate:ParsingPlaceholderFactory'=> static function():ParsingPlaceholderFactory { return new ParsingPlaceholderFactory();}, 'Translate:PersistentCache'=> static function(MediaWikiServices $services):PersistentCache { return new PersistentDatabaseCache($services->getDBLoadBalancer(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'));}, 'Translate:RevTagStore'=> static function(MediaWikiServices $services):RevTagStore { return new RevTagStore($services->getDBLoadBalancerFactory());}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleExporter'=> static function(MediaWikiServices $services):TranslatableBundleExporter { return new TranslatableBundleExporter($services->get( 'Translate:SubpageListBuilder'), $services->getWikiExporterFactory(), $services->getDBLoadBalancer());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, 'Translate:TranslatableBundleImporter'=> static function(MediaWikiServices $services):TranslatableBundleImporter { return new TranslatableBundleImporter($services->getWikiImporterFactory(), $services->get( 'Translate:TranslatablePageParser'), $services->getRevisionLookup());}, 'Translate:TranslatableBundleMover'=> static function(MediaWikiServices $services):TranslatableBundleMover { return new TranslatableBundleMover($services->getMovePageFactory(), $services->getJobQueueGroup(), $services->getLinkBatchFactory(), $services->get( 'Translate:TranslatableBundleFactory'), $services->get( 'Translate:SubpageListBuilder'), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatableBundleStatusStore'=> static function(MediaWikiServices $services):TranslatableBundleStatusStore { return new TranslatableBundleStatusStore($services->getDBLoadBalancer() ->getConnection(DB_PRIMARY), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), $services->getDBLoadBalancer() ->getMaintenanceConnectionRef(DB_PRIMARY));}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), $services->get( 'Translate:RevTagStore'), $services->getDBLoadBalancer(), $services->get( 'Translate:TranslatableBundleStatusStore'), $services->get( 'Translate:TranslatablePageParser'),);}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnection(DB_REPLICA);return new TranslationStashStorage( $db);}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory(), $services->getDBLoadBalancer());}, 'Translate:TranslationUnitStoreFactory'=> static function(MediaWikiServices $services):TranslationUnitStoreFactory { return new TranslationUnitStoreFactory( $services->getDBLoadBalancer());}, 'Translate:TranslatorActivity'=> static function(MediaWikiServices $services):TranslatorActivity { $query=new TranslatorActivityQuery($services->getMainConfig(), $services->getDBLoadBalancer());return new TranslatorActivity($services->getMainObjectStash(), $query, $services->getJobQueueGroup());}, 'Translate:TtmServerFactory'=> static function(MediaWikiServices $services):TtmServerFactory { $config=$services->getMainConfig();$default=$config->get( 'TranslateTranslationDefaultService');if( $default===false) { $default=null;} return new TtmServerFactory( $config->get( 'TranslateTranslationServices'), $default);}]
@phpcs-require-sorted-array
Factory class for accessing message groups individually by id or all of them as a list.
Class to manage revision tags for translatable bundles.
Class for pointing to messages, like Title class is for titles.
isFuzzy()
Check if a title is marked as fuzzy.
isPageTranslation()
Determine whether the current handle is for page translation feature.
static makeFuzzyString(string $text)
Check if a string has fuzzy string and if not, add it.
static hasFuzzyString( $text)
Check if a string contains the fuzzy string.
figureMessage()
Recommended to use getCode and getKey instead.
isDoc()
Determine whether the current handle is for message documentation.
getGroup()
Get the primary MessageGroup this message belongs to.
getTitleForLanguage( $code)
Get the original title.
isValid()
Checks if the handle corresponds to a known message.
getEffectiveLanguage()
Return the Language object for the assumed language of the content, which might be different from the...
getGroupIds()
Returns all message group ids this message belongs to.
getTitle()
Get the original title.
isMessageNamespace()
Check if this handle is in a message namespace.
getCode()
Returns the language code.
getTitleForBase()
Get the title for the page base.
getInternalKey()
This returns the key that can be used for showMessage parameter for Special:Translate for regular mes...
getKey()
Returns the identified or guessed message key.