Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
Utilities.php
1<?php
2declare( strict_types = 1 );
3
5
6use MediaWiki\Config\ConfigException;
7use MediaWiki\Content\Content;
8use MediaWiki\Content\TextContent;
9use MediaWiki\Context\RequestContext;
14use MediaWiki\Html\Html;
15use MediaWiki\Language\LanguageCode;
16use MediaWiki\Language\LanguageNameUtils;
17use MediaWiki\MediaWikiServices;
18use MediaWiki\Revision\RevisionRecord;
19use MediaWiki\Revision\SlotRecord;
20use MediaWiki\Title\Title;
21use MessageGroup;
22use UnexpectedValueException;
23use Wikimedia\Rdbms\IReadableDatabase;
24
30class Utilities {
39 public static function title( string $message, string $code, int $ns = NS_MEDIAWIKI ): string {
40 // Cache some amount of titles for speed.
41 static $cache = [];
42 $key = $ns . ':' . $message;
43
44 if ( !isset( $cache[$key] ) ) {
45 $cache[$key] = Title::capitalize( $message, $ns );
46 }
47
48 if ( $code ) {
49 return $cache[$key] . '/' . $code;
50 } else {
51 return $cache[$key];
52 }
53 }
54
61 public static function figureMessage( string $text ): array {
62 $pos = strrpos( $text, '/' );
63 $code = substr( $text, $pos + 1 );
64 $key = substr( $text, 0, $pos );
65
66 return [ $key, $code ];
67 }
68
76 public static function getMessageContent( string $key, string $language, int $namespace = NS_MEDIAWIKI ): ?string {
77 $title = self::title( $key, $language, $namespace );
78 $data = self::getContents( [ $title ], $namespace );
79
80 return $data[$title][0] ?? null;
81 }
82
92 private static function fetchLatestRevisionsByTitles( array $titles, int $namespace ): array {
93 $mwServices = MediaWikiServices::getInstance();
94 $dbr = $mwServices->getConnectionProvider()->getReplicaDatabase();
95 $revStore = $mwServices->getRevisionStore();
96
97 $rows = $revStore->newSelectQueryBuilder( $dbr )
98 ->joinPage()
99 ->joinComment()
100 ->where( [ 'page_namespace' => $namespace, 'page_title' => $titles, 'page_latest=rev_id' ] )
101 ->caller( __METHOD__ )
102 ->fetchResultSet();
103
104 $revisions = $revStore->newRevisionsFromBatch( $rows, [
105 'slots' => true,
106 'content' => true
107 ] )->getValue();
108
109 $result = [];
110 foreach ( $rows as $row ) {
111 $revision = $revisions[$row->rev_id] ?? null;
112 if ( $revision !== null ) {
113 $content = $revision->getContent( SlotRecord::MAIN );
114 if ( $content instanceof TextContent ) {
115 $result[$row->page_title] = $revision;
116 }
117 }
118 }
119
120 $rows->free();
121
122 return $result;
123 }
124
133 public static function getContents( $titles, int $namespace ): array {
134 $titleContents = [];
135 foreach ( self::fetchLatestRevisionsByTitles( (array)$titles, $namespace ) as $pageTitle => $revision ) {
136 $user = $revision->getUser( RevisionRecord::FOR_PUBLIC );
137 $titleContents[$pageTitle] = [
138 self::getTextFromTextContent( $revision->getContent( SlotRecord::MAIN ) ),
139 $user ? $user->getName() : '',
140 ];
141 }
142
143 return $titleContents;
144 }
145
152 public static function getContentForTitle( Title $title, bool $addFuzzy = false ): ?string {
153 $revision = MediaWikiServices::getInstance()->getRevisionStore()->getRevisionByTitle( $title );
154 $wiki = self::getTextFromContentOrNull( $revision?->getContent( SlotRecord::MAIN ) );
155 if ( $wiki === null ) {
156 return null;
157 }
158
159 if ( $addFuzzy ) {
160 $handle = new MessageHandle( $title );
161 if ( $handle->isFuzzy() ) {
162 $wiki = TRANSLATE_FUZZY . str_replace( TRANSLATE_FUZZY, '', $wiki );
163 }
164 }
165
166 return $wiki;
167 }
168
169 /* Some other helpers for output */
170
177 public static function getLanguageName( string $code, ?string $language = 'en' ): string {
178 $languages = self::getLanguageNames( $language );
179 return $languages[$code] ?? $code;
180 }
181
189 public static function getLanguageNames( ?string $code ): array {
190 $mwServices = MediaWikiServices::getInstance();
191 $languageNames = array_diff_key(
192 $mwServices->getLanguageNameUtils()->getLanguageNames( $code ),
193 LanguageCode::getDeprecatedCodeMapping()
194 );
195 Services::getInstance()->getHookRunner()->onTranslateSupportedLanguages( $languageNames, $code );
196
197 return $languageNames;
198 }
199
207 public static function fieldset( string $legend, string $contents, array $attributes = [] ): string {
208 return Html::rawElement(
209 'fieldset',
210 $attributes,
211 Html::rawElement( 'legend', [], $legend ) . $contents
212 );
213 }
214
226 public static function convertWhiteSpaceToHTML( string $message ): string {
227 $msg = htmlspecialchars( $message );
228 $msg = preg_replace( '/^ /m', '&#160;', $msg );
229 $msg = preg_replace( '/ $/m', '&#160;', $msg );
230 $msg = preg_replace( '/ /', '&#160; ', $msg );
231 $msg = str_replace( "\n", '<br />', $msg );
232
233 return $msg;
234 }
235
241 public static function cacheFile( string $filename ): string {
242 global $wgTranslateCacheDirectory, $wgCacheDirectory;
243
244 if ( $wgTranslateCacheDirectory !== false ) {
245 $dir = $wgTranslateCacheDirectory;
246 } elseif ( $wgCacheDirectory !== false ) {
247 $dir = $wgCacheDirectory;
248 } else {
249 throw new ConfigException( "\$wgCacheDirectory must be configured" );
250 }
251
252 return "$dir/$filename";
253 }
254
256 public static function getPlaceholder(): string {
257 static $i = 0;
258
259 return "\x7fUNIQ" . dechex( mt_rand( 0, 0x7fffffff ) ) .
260 dechex( mt_rand( 0, 0x7fffffff ) ) . '-' . $i++;
261 }
262
269 public static function getIcon( MessageGroup $g, int $size ): ?array {
270 $icon = $g->getIcon();
271 if ( !$icon || substr( $icon, 0, 7 ) !== 'wiki://' ) {
272 return null;
273 }
274
275 $formats = [];
276
277 $filename = substr( $icon, 7 );
278 $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $filename );
279 if ( !$file ) {
280 wfWarn( "Unknown message group icon file $icon" );
281
282 return null;
283 }
284
285 if ( $file->isVectorized() ) {
286 $formats['vector'] = $file->getFullUrl();
287 }
288
289 $formats['raster'] = $file->createThumb( $size, $size );
290
291 return $formats;
292 }
293
300 public static function getSafeReadDB(): IReadableDatabase {
301 $icp = MediaWikiServices::getInstance()->getConnectionProvider();
302 if ( self::shouldReadFromPrimary() ) {
303 return $icp->getPrimaryDatabase();
304 }
305 return $icp->getReplicaDatabase();
306 }
307
309 public static function shouldReadFromPrimary(): bool {
310 $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
311 // Parsing APIs need POST for payloads but are read-only, so avoid spamming
312 // the primary then. No good way to check this at the moment...
313 if ( PageTranslationHooks::$renderingContext ) {
314 return false;
315 }
316
317 return PHP_SAPI === 'cli' ||
318 RequestContext::getMain()->getRequest()->wasPosted() ||
319 $lb->hasOrMadeRecentPrimaryChanges();
320 }
321
330 public static function getEditorUrl(
331 MessageHandle $handle,
332 string $action_source = '',
333 bool $includeLanguageParam = true
334 ): string {
335 if ( !$handle->isValid() ) {
336 return $handle->getTitle()->getLocalURL( [ 'action' => 'edit' ] );
337 }
338
339 $title = MediaWikiServices::getInstance()
340 ->getSpecialPageFactory()->getPage( 'Translate' )->getPageTitle();
341 $urlParameters = [
342 'showMessage' => $handle->getInternalKey(),
343 'group' => $handle->getGroup()->getId(),
344 'language' => $includeLanguageParam ? $handle->getCode() : null,
345 ];
346
347 if ( $action_source !== '' ) {
348 $urlParameters[ 'action_source' ] = $action_source;
349 }
350
351 return $title->getFullURL( $urlParameters );
352 }
353
358 public static function serialize( $value ): string {
359 return serialize( $value );
360 }
361
366 public static function deserialize( string $str, array $opts = [ 'allowed_classes' => false ] ) {
367 return unserialize( $str, $opts );
368 }
369
370 public static function getVersion(): string {
371 // Avoid parsing JSON multiple time per request
372 static $version = null;
373 $version ??= json_decode( file_get_contents( __DIR__ . '../../../extension.json' ) )->version;
374 return $version;
375 }
376
384 public static function allowsSubpages( Title $title ): bool {
385 $mwInstance = MediaWikiServices::getInstance();
386 $namespaceInfo = $mwInstance->getNamespaceInfo();
387 return $namespaceInfo->hasSubpages( $title->getNamespace() );
388 }
389
396 public static function isSupportedLanguageCode( string $code ): bool {
397 $all = self::getLanguageNames( LanguageNameUtils::AUTONYMS );
398 return isset( $all[ $code ] );
399 }
400
406 public static function getTextFromContentOrNull( ?Content $content ): ?string {
407 return $content instanceof TextContent ? $content->getText() : null;
408 }
409
415 public static function getTextFromTextContent( ?Content $content ): string {
416 if ( !$content ) {
417 throw new UnexpectedValueException( 'Expected $content to be TextContent, got null instead.' );
418 }
419
420 if ( $content instanceof TextContent ) {
421 return $content->getText();
422 }
423
424 throw new UnexpectedValueException( 'Expected $content to be TextContent, but got ' . get_class( $content ) );
425 }
426
433 public static function getTranslations( MessageHandle $handle ): array {
434 $titleContents = [];
435 foreach ( self::getTranslationRevisions( $handle ) as $pageTitle => $revision ) {
436 $user = $revision->getUser( RevisionRecord::FOR_PUBLIC );
437 $titleContents[$pageTitle] = [
438 self::getTextFromTextContent( $revision->getContent( SlotRecord::MAIN ) ),
439 $user ? $user->getName() : '',
440 ];
441 }
442
443 return $titleContents;
444 }
445
459 public static function getTranslationRevisions( MessageHandle $handle ): array {
460 $namespace = $handle->getTitle()->getNamespace();
461 $base = $handle->getKey();
462
463 $dbr = MediaWikiServices::getInstance()->getConnectionProvider()->getReplicaDatabase();
464
465 $titles = $dbr->newSelectQueryBuilder()
466 ->select( 'page_title' )
467 ->from( 'page' )
468 ->where( [
469 'page_namespace' => $namespace,
470 'page_title ' . $dbr->buildLike( "$base/", $dbr->anyString() ),
471 ] )
472 ->caller( __METHOD__ )
473 ->orderBy( 'page_title' )
474 ->fetchFieldValues();
475
476 if ( $titles === [] ) {
477 return [];
478 }
479
480 // fetchLatestRevisionsByTitles may return results in a different order
481 // (by rev_id or row insertion), so re-index in the original page_title order.
482 $revisionsByTitle = self::fetchLatestRevisionsByTitles( $titles, $namespace );
483 $ordered = [];
484 foreach ( $titles as $title ) {
485 if ( isset( $revisionsByTitle[$title] ) ) {
486 $ordered[$title] = $revisionsByTitle[$title];
487 }
488 }
489 return $ordered;
490 }
491
492 public static function isTranslationPage( MessageHandle $handle ): bool {
493 // FIXME: A lot of this code is similar to TranslatablePage::isTranslationPage.
494 // See if they can be merged
495 // The major difference is that this method does not run a database query to check if
496 // the page is marked.
497 $key = $handle->getKey();
498 $languageCode = $handle->getCode();
499 if ( $key === '' || $languageCode === '' ) {
500 return false;
501 }
502
503 $baseTitle = Title::makeTitle( $handle->getTitle()->getNamespace(), $key );
504 if ( !TranslatablePage::isSourcePage( $baseTitle ) ) {
505 return false;
506 }
507
508 static $codes = null;
509 $codes ??= self::getLanguageNames( LanguageNameUtils::AUTONYMS );
510
511 return !$handle->isDoc() && isset( $codes[ $languageCode ] );
512 }
513
521 public static function isValidRegex( string $pattern, ?string &$error = null ): bool {
522 set_error_handler( static function ( $severity, $message ) use ( &$error ) {
523 $error = $message;
524 return true;
525 } );
526
527 try {
528 // @phan-suppress-next-line PhanParamSuspiciousOrder
529 $result = preg_match( $pattern, '' );
530 return $result !== false;
531 } finally {
532 restore_error_handler();
533 }
534 }
535}
536
537class_alias( Utilities::class, 'TranslateUtils' );
return[ 'Translate:AggregateGroupManager'=> static function(MediaWikiServices $services):AggregateGroupManager { return new AggregateGroupManager($services->getTitleFactory(), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:AggregateGroupMessageGroupFactory'=> static function(MediaWikiServices $services):AggregateGroupMessageGroupFactory { return new AggregateGroupMessageGroupFactory($services->get( 'Translate:MessageGroupMetadata'));}, '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:ExternalMessageSourceStateComparator'=> static function(MediaWikiServices $services):ExternalMessageSourceStateComparator { return new ExternalMessageSourceStateComparator(new SimpleStringComparator(), $services->getRevisionLookup(), $services->getPageStore());}, 'Translate:ExternalMessageSourceStateImporter'=> static function(MediaWikiServices $services):ExternalMessageSourceStateImporter { return new ExternalMessageSourceStateImporter($services->get( 'Translate:GroupSynchronizationCache'), $services->getJobQueueGroup(), LoggerFactory::getInstance(LogNames::GROUP_SYNCHRONIZATION), $services->get( 'Translate:MessageIndex'), $services->getTitleFactory(), $services->get( 'Translate:MessageGroupSubscription'), new ServiceOptions(ExternalMessageSourceStateImporter::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:FileBasedMessageGroupFactory'=> static function(MediaWikiServices $services):FileBasedMessageGroupFactory { return new FileBasedMessageGroupFactory(new MessageGroupConfigurationParser(), $services->getContentLanguageCode() ->toString(), new ServiceOptions(FileBasedMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, '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:HookDefinedMessageGroupFactory'=> static function(MediaWikiServices $services):HookDefinedMessageGroupFactory { return new HookDefinedMessageGroupFactory( $services->get( 'Translate:HookRunner'));}, 'Translate:HookRunner'=> static function(MediaWikiServices $services):HookRunner { return new HookRunner( $services->getHookContainer());}, 'Translate:MessageBundleDependencyPurger'=> static function(MediaWikiServices $services):MessageBundleDependencyPurger { return new MessageBundleDependencyPurger( $services->get( 'Translate:TranslatableBundleFactory'));}, 'Translate:MessageBundleMessageGroupFactory'=> static function(MediaWikiServices $services):MessageBundleMessageGroupFactory { return new MessageBundleMessageGroupFactory($services->get( 'Translate:MessageGroupMetadata'), new ServiceOptions(MessageBundleMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore($services->get( 'Translate:RevTagStore'), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:MessageBundleTranslationLoader'=> static function(MediaWikiServices $services):MessageBundleTranslationLoader { return new MessageBundleTranslationLoader( $services->getLanguageFallback());}, 'Translate:MessageGroupMetadata'=> static function(MediaWikiServices $services):MessageGroupMetadata { return new MessageGroupMetadata( $services->getConnectionProvider());}, 'Translate:MessageGroupReviewStore'=> static function(MediaWikiServices $services):MessageGroupReviewStore { return new MessageGroupReviewStore($services->getConnectionProvider(), $services->get( 'Translate:HookRunner'));}, 'Translate:MessageGroupStatsTableFactory'=> static function(MediaWikiServices $services):MessageGroupStatsTableFactory { return new MessageGroupStatsTableFactory($services->get( 'Translate:ProgressStatsTableFactory'), $services->getLinkRenderer(), $services->get( 'Translate:MessageGroupReviewStore'), $services->get( 'Translate:MessageGroupMetadata'), $services->getMainConfig() ->get( 'TranslateWorkflowStates') !==false);}, 'Translate:MessageGroupSubscription'=> static function(MediaWikiServices $services):MessageGroupSubscription { return new MessageGroupSubscription($services->get( 'Translate:MessageGroupSubscriptionStore'), $services->getJobQueueGroup(), $services->getUserIdentityLookup(), LoggerFactory::getInstance(LogNames::GROUP_SUBSCRIPTION), new ServiceOptions(MessageGroupSubscription::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:MessageGroupSubscriptionHookHandler'=> static function(MediaWikiServices $services):?MessageGroupSubscriptionHookHandler { if(! $services->getExtensionRegistry() ->isLoaded( 'Echo')) { return null;} return new MessageGroupSubscriptionHookHandler($services->get( 'Translate:MessageGroupSubscription'), $services->getUserFactory());}, 'Translate:MessageGroupSubscriptionStore'=> static function(MediaWikiServices $services):MessageGroupSubscriptionStore { return new MessageGroupSubscriptionStore( $services->getConnectionProvider());}, 'Translate:MessageIndex'=> static function(MediaWikiServices $services):MessageIndex { $params=(array) $services->getMainConfig() ->get( 'TranslateMessageIndex');$class=array_shift( $params);$implementationMap=['HashMessageIndex'=> HashMessageIndex::class, 'CDBMessageIndex'=> CDBMessageIndex::class, 'DatabaseMessageIndex'=> DatabaseMessageIndex::class, 'hash'=> HashMessageIndex::class, 'cdb'=> CDBMessageIndex::class, 'database'=> DatabaseMessageIndex::class,];$messageIndexStoreClass=$implementationMap[$class] ?? $implementationMap['database'];return new MessageIndex(new $messageIndexStoreClass, $services->getMainWANObjectCache(), $services->getJobQueueGroup(), $services->get( 'Translate:HookRunner'), LoggerFactory::getInstance(LogNames::MAIN), $services->getMainObjectStash(), $services->getConnectionProvider(), new ServiceOptions(MessageIndex::SERVICE_OPTIONS, $services->getMainConfig()),);}, '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->getConnectionProvider(), $services->getJsonCodec());}, 'Translate:ProgressStatsTableFactory'=> static function(MediaWikiServices $services):ProgressStatsTableFactory { return new ProgressStatsTableFactory($services->getLinkRenderer(), $services->get( 'Translate:ConfigHelper'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:RevTagStore'=> static function(MediaWikiServices $services):RevTagStore { return new RevTagStore( $services->getConnectionProvider());}, 'Translate:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleDeleter'=> static function(MediaWikiServices $services):TranslatableBundleDeleter { return new TranslatableBundleDeleter($services->getMainObjectStash(), $services->getJobQueueGroup(), $services->get( 'Translate:SubpageListBuilder'), $services->get( 'Translate:TranslatableBundleFactory'));}, 'Translate:TranslatableBundleExporter'=> static function(MediaWikiServices $services):TranslatableBundleExporter { return new TranslatableBundleExporter($services->get( 'Translate:SubpageListBuilder'), $services->getWikiExporterFactory(), $services->getConnectionProvider());}, '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(), $services->getNamespaceInfo(), $services->getTitleFactory(), $services->getFormatterFactory());}, '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->getConnectionProvider(), $services->getObjectCacheFactory(), $services->getMainConfig() ->get( 'TranslatePageMoveLimit'));}, 'Translate:TranslatableBundleStatusStore'=> static function(MediaWikiServices $services):TranslatableBundleStatusStore { return new TranslatableBundleStatusStore($services->getConnectionProvider() ->getPrimaryDatabase(), $services->getCollationFactory() ->makeCollation( 'uca-default-u-kn'), $services->getDBLoadBalancer() ->getMaintenanceConnectionRef(DB_PRIMARY));}, 'Translate:TranslatablePageMarker'=> static function(MediaWikiServices $services):TranslatablePageMarker { return new TranslatablePageMarker($services->getConnectionProvider(), $services->getJobQueueGroup(), $services->getLinkRenderer(), MessageGroups::singleton(), $services->get( 'Translate:MessageIndex'), $services->getTitleFormatter(), $services->getTitleParser(), $services->get( 'Translate:TranslatablePageParser'), $services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:TranslatablePageStateStore'), $services->get( 'Translate:TranslationUnitStoreFactory'), $services->get( 'Translate:MessageGroupMetadata'), $services->getWikiPageFactory(), $services->get( 'Translate:TranslatablePageView'), $services->get( 'Translate:MessageGroupSubscription'), $services->getFormatterFactory(), $services->get( 'Translate:HookRunner'),);}, 'Translate:TranslatablePageMessageGroupFactory'=> static function(MediaWikiServices $services):TranslatablePageMessageGroupFactory { return new TranslatablePageMessageGroupFactory(new ServiceOptions(TranslatablePageMessageGroupFactory::SERVICE_OPTIONS, $services->getMainConfig()),);}, 'Translate:TranslatablePageParser'=> static function(MediaWikiServices $services):TranslatablePageParser { return new TranslatablePageParser($services->get( 'Translate:ParsingPlaceholderFactory'));}, 'Translate:TranslatablePageStateStore'=> static function(MediaWikiServices $services):TranslatablePageStateStore { return new TranslatablePageStateStore($services->get( 'Translate:PersistentCache'), $services->getPageStore());}, 'Translate:TranslatablePageStore'=> static function(MediaWikiServices $services):TranslatablePageStore { return new TranslatablePageStore($services->get( 'Translate:MessageIndex'), $services->getJobQueueGroup(), $services->get( 'Translate:RevTagStore'), $services->getConnectionProvider(), $services->get( 'Translate:TranslatableBundleStatusStore'), $services->get( 'Translate:TranslatablePageParser'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:TranslatablePageView'=> static function(MediaWikiServices $services):TranslatablePageView { return new TranslatablePageView($services->getConnectionProvider(), $services->get( 'Translate:TranslatablePageStateStore'), new ServiceOptions(TranslatablePageView::SERVICE_OPTIONS, $services->getMainConfig()));}, 'Translate:TranslateSandbox'=> static function(MediaWikiServices $services):TranslateSandbox { return new TranslateSandbox($services->getUserFactory(), $services->getConnectionProvider(), $services->getPermissionManager(), $services->getAuthManager(), $services->getUserGroupManager(), $services->getActorStore(), $services->getUserOptionsManager(), $services->getJobQueueGroup(), $services->get( 'Translate:HookRunner'), new ServiceOptions(TranslateSandbox::CONSTRUCTOR_OPTIONS, $services->getMainConfig()));}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { return new TranslationStashStorage( $services->getConnectionProvider() ->getPrimaryDatabase());}, 'Translate:TranslationStatsDataProvider'=> static function(MediaWikiServices $services):TranslationStatsDataProvider { return new TranslationStatsDataProvider(new ServiceOptions(TranslationStatsDataProvider::CONSTRUCTOR_OPTIONS, $services->getMainConfig()), $services->getObjectFactory(), $services->getConnectionProvider());}, '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->getConnectionProvider());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);}, 'Translate:WorkflowStatesMessageGroupLoader'=> static function(MediaWikiServices $services):WorkflowStatesMessageGroupLoader { return new WorkflowStatesMessageGroupLoader(new ServiceOptions(WorkflowStatesMessageGroupLoader::CONSTRUCTOR_OPTIONS, $services->getMainConfig()),);},]
@phpcs-require-sorted-array
Class for pointing to messages, like Title class is for titles.
getKey()
Returns the identified or guessed message key.
Mixed bag of methods related to translatable pages.
Minimal service container.
Definition Services.php:60
Essentially random collection of helper functions, similar to GlobalFunctions.php.
Definition Utilities.php:30
static getPlaceholder()
Returns a random string that can be used as placeholder in strings.
static allowsSubpages(Title $title)
Checks if the namespace that the title belongs to allows subpages.
static getIcon(MessageGroup $g, int $size)
Get URLs for icons if available.
static getMessageContent(string $key, string $language, int $namespace=NS_MEDIAWIKI)
Loads page content without side effects.
Definition Utilities.php:76
static getTranslationRevisions(MessageHandle $handle)
Returns the latest RevisionRecord for each existing translation of a message.
static getLanguageName(string $code, ?string $language='en')
Returns a localised language name.
static fieldset(string $legend, string $contents, array $attributes=[])
Constructs a fieldset with contents.
static isSupportedLanguageCode(string $code)
Checks whether a language code is supported for translation at the wiki level.
static getTranslations(MessageHandle $handle)
Returns all translations of a given message.
static getContentForTitle(Title $title, bool $addFuzzy=false)
Returns the content for a given title and adds the fuzzy tag if requested.
static getSafeReadDB()
Get a DB handle suitable for read and read-for-write cases.
static getEditorUrl(MessageHandle $handle, string $action_source='', bool $includeLanguageParam=true)
Get a URL that points to an editor for this message handle.
static getContents( $titles, int $namespace)
Fetches contents for page names in given namespace.
static shouldReadFromPrimary()
Check whether primary should be used for reads to avoid reading stale data.
static getTextFromTextContent(?Content $content)
Strict extraction of text from content.
static isValidRegex(string $pattern, ?string &$error=null)
Validate a regular exception.
static serialize( $value)
Serialize the given value.
static cacheFile(string $filename)
Gets the path for cache files.
static convertWhiteSpaceToHTML(string $message)
Escapes the message, and does some mangling to whitespace, so that it is preserved when outputted as-...
static deserialize(string $str, array $opts=[ 'allowed_classes'=> false])
Deserialize the given string.
static title(string $message, string $code, int $ns=NS_MEDIAWIKI)
Does quick normalisation of message name so that in can be looked from the database.
Definition Utilities.php:39
static getTextFromContentOrNull(?Content $content)
Best-effort extraction of text from content.
static figureMessage(string $text)
Splits page name into message key and language code.
Definition Utilities.php:61
static getLanguageNames(?string $code)
Get translated language names for the languages generally supported for translation in the current wi...
Interface for message groups.