Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslationAidDataProvider.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorInterface\Aid;
5
6use Content;
7use ContentHandler;
10use MediaWiki\MediaWikiServices;
11use MediaWiki\Revision\RevisionRecord;
12use MediaWiki\Revision\SlotRecord;
13use MessageGroup;
15use TextContent;
16use Wikimedia\Rdbms\IDatabase;
17
25 private $handle;
27 private $group;
29 private $definition;
31 private $translations;
32
33 public function __construct( MessageHandle $handle ) {
34 $this->handle = $handle;
35 $this->group = $handle->getGroup();
36 }
37
42 public function getDefinition(): string {
43 if ( $this->definition !== null ) {
44 return $this->definition;
45 }
46
47 // Optional performance optimization
48 if ( method_exists( $this->group, 'getMessageContent' ) ) {
49 // @phan-suppress-next-line PhanUndeclaredMethod
50 $this->definition = $this->group->getMessageContent( $this->handle );
51 } else {
52 $this->definition = $this->group->getMessage(
53 $this->handle->getKey(),
54 $this->group->getSourceLanguage()
55 );
56 }
57
58 if ( $this->definition === null ) {
59 throw new TranslationHelperException(
60 'Did not find message definition for ' . $this->handle->getTitle()->getPrefixedText() .
61 ' in group ' . $this->group->getId()
62 );
63 }
64 return $this->definition;
65 }
66
67 public function hasDefinition(): bool {
68 try {
69 $this->getDefinition();
70 return true;
71 } catch ( TranslationHelperException $e ) {
72 return false;
73 }
74 }
75
76 public function getDefinitionContent(): Content {
77 return ContentHandler::makeContent( $this->getDefinition(), $this->handle->getTitle() );
78 }
79
85 public function getGoodTranslations(): array {
86 if ( $this->translations !== null ) {
87 return $this->translations;
88 }
89
90 $data = self::loadTranslationData( wfGetDB( DB_REPLICA ), $this->handle );
91 $translations = [];
92 $prefixLength = strlen( $this->handle->getTitleForBase()->getDBkey() . '/' );
93 $languageNameUtils = MediaWikiServices::getInstance()->getLanguageNameUtils();
94
95 foreach ( $data as $page => $translation ) {
96 // Could use MessageHandle here, but that queries the message index.
97 // Instead, we can get away with simple string manipulation.
98 $code = substr( $page, $prefixLength );
99 if ( !$languageNameUtils->isKnownLanguageTag( $code ) ) {
100 continue;
101 }
102
103 $translations[ $code ] = $translation;
104 }
105
106 $this->translations = $translations;
107
108 return $translations;
109 }
110
111 private static function loadTranslationData( IDatabase $db, MessageHandle $handle ): array {
112 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
113 $queryInfo = $revisionStore->getQueryInfo( [ 'page' ] );
114 $tables = $queryInfo[ 'tables' ];
115 $fields = $queryInfo[ 'fields' ];
116 $conds = [];
117 $options = [];
118 $joins = $queryInfo[ 'joins' ];
119
120 // The list of pages we want to select, and their latest versions
121 $conds['page_namespace'] = $handle->getTitle()->getNamespace();
122 $base = $handle->getKey();
123 $conds[] = 'page_title ' . $db->buildLike( "$base/", $db->anyString() );
124 $conds[] = 'rev_id=page_latest';
125
126 // For fuzzy tags we also need:
127 $tables[] = 'revtag';
128 $conds[ 'rt_type' ] = null;
129 $joins[ 'revtag' ] = [
130 'LEFT JOIN',
131 [ 'page_id=rt_page', 'page_latest=rt_revision', 'rt_type' => RevTagStore::FUZZY_TAG ]
132 ];
133
134 $rows = $db->select( $tables, $fields, $conds, __METHOD__, $options, $joins );
135
136 $pages = [];
137 $revisions = $revisionStore->newRevisionsFromBatch( $rows, [ 'slots' => [ SlotRecord::MAIN ] ] )
138 ->getValue();
139 foreach ( $rows as $row ) {
141 $rev = $revisions[$row->rev_id];
142 if ( $rev && $rev->getContent( SlotRecord::MAIN ) instanceof TextContent ) {
143 $pages[$row->page_title] = $rev->getContent( SlotRecord::MAIN )->getText();
144 }
145 }
146
147 return $pages;
148 }
149}
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
Class to manage revision tags for translatable bundles.
Translation helpers can throw this exception when they cannot do anything useful with the current mes...
Class for pointing to messages, like Title class is for titles.
getGroup()
Get the primary MessageGroup this message belongs to.
getTitle()
Get the original title.
getKey()
Returns the identified or guessed message key.
Interface for message groups.