Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
DisplayGroupSynchronizationInfo.php
1<?php
2declare( strict_types = 1 );
3
5
6use MediaWiki\Html\Html;
7use MediaWiki\Language\Language;
8use MediaWiki\Linker\LinkRenderer;
9use MediaWiki\Title\Title;
10use MessageLocalizer;
11
19 private MessageLocalizer $localizer;
20 private LinkRenderer $linkRenderer;
21
22 public function __construct( MessageLocalizer $localizer, LinkRenderer $linkRenderer ) {
23 $this->localizer = $localizer;
24 $this->linkRenderer = $linkRenderer;
25 }
26
28 public function getGroupsInSyncHtml( array $groupsInSync, string $wrapperClass ): string {
29 sort( $groupsInSync );
30
31 if ( !$groupsInSync ) {
32 return Html::rawElement(
33 'p',
34 [ 'class' => $wrapperClass ],
35 $this->localizer->msg( 'translate-smg-no-groups-in-sync' )->escaped()
36 . $this->addGroupSyncHelp( $wrapperClass )
37 );
38 }
39
40 $htmlGroupItems = [];
41 foreach ( $groupsInSync as $groupId ) {
42 $htmlGroupItems[] = Html::element( 'li', [], $groupId );
43 }
44
45 return $this->getGroupSyncInfoHtml(
46 $wrapperClass,
47 'translate-smg-groups-in-sync',
48 'translate-smg-groups-in-sync-list',
49 Html::rawElement( 'ul', [], implode( '', $htmlGroupItems ) ),
50 $this->addGroupSyncHelp( $wrapperClass )
51 );
52 }
53
54 public function getHtmlForGroupsWithError(
55 GroupSynchronizationCache $groupSynchronizationCache,
56 string $wrapperClass,
57 Language $currentLang
58 ): string {
59 $groupsWithErrors = $groupSynchronizationCache->getGroupsWithErrors();
60 if ( !$groupsWithErrors ) {
61 return '';
62 }
63
64 $htmlGroupItems = [];
65 foreach ( $groupsWithErrors as $groupId ) {
66 $groupErrorResponse = $groupSynchronizationCache->getGroupErrorInfo( $groupId );
67 $htmlGroupItems[] = $this->getHtmlForGroupErrors( $groupErrorResponse, $currentLang, $wrapperClass );
68 }
69
70 return $this->getGroupSyncInfoHtml(
71 $wrapperClass . ' js-group-sync-groups-with-error',
72 'translate-smg-groups-with-error-title',
73 'translate-smg-groups-with-error-desc',
74 implode( '', $htmlGroupItems )
75 );
76 }
77
78 private function addGroupSyncHelp( string $wrapperClass ): string {
79 return Html::element(
80 'a',
81 [
82 'href' => 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:Translate/' .
83 'Group_management#Strong_synchronization',
84 'target' => '_blank',
85 'class' => "{$wrapperClass}__help",
86 ],
87 '[' . $this->localizer->msg( 'translate-smg-strong-sync-help' )->text() . ']'
88 );
89 }
90
91 private function getGroupSyncInfoHtml(
92 string $className,
93 string $summaryMsgKey,
94 string $descriptionMsgKey,
95 string $htmlContent,
96 ?string $preHtmlContent = null
97 ): string {
98 $output = Html::openElement( 'div', [ 'class' => $className ] );
99 if ( $preHtmlContent ) {
100 $output .= $preHtmlContent;
101 }
102
103 $output .= Html::openElement( 'details' );
104 $output .= Html::element( 'summary', [], $this->localizer->msg( $summaryMsgKey )->text() );
105 $output .= Html::element( 'p', [], $this->localizer->msg( $descriptionMsgKey )->text() );
106 $output .= $htmlContent;
107 $output .= Html::closeElement( 'details' );
108 $output .= Html::closeElement( 'div' );
109
110 return $output;
111 }
112
113 private function getHtmlForGroupErrors(
114 GroupSynchronizationResponse $groupErrorResponse,
115 Language $language,
116 string $wrapperClass
117 ): string {
118 $groupId = $groupErrorResponse->getGroupId();
119 $output = Html::openElement(
120 'details',
121 [ 'class' => "{$wrapperClass}__group_errors js-group-sync-group-errors" ]
122 );
123
124 $groupResolveAction = Html::linkButton(
125 $this->localizer->msg( 'translate-smg-group-action-resolve' )->text(),
126 [
127 'class' => "{$wrapperClass}__resolve-action js-group-sync-group-resolve",
128 'href' => '#',
129 'data-group-id' => $groupId,
130 ]
131 );
132
133 $output .= Html::rawElement(
134 'summary',
135 [],
136 $groupId . ' ' .
137 Html::rawElement(
138 'span',
139 [ 'class' => "{$wrapperClass}__sync-actions" ],
140 $this->localizer->msg( 'parentheses' )
141 ->rawParams( $groupResolveAction )->escaped()
142
143 )
144 );
145
146 $errorMessages = $groupErrorResponse->getRemainingMessages();
147
148 $output .= Html::openElement( 'ol' );
149 foreach ( $errorMessages as $message ) {
150 $output .= Html::rawElement(
151 'li',
152 [ 'class' => "{$wrapperClass}__message-error js-group-sync-message-error" ],
153 $this->getErrorMessageHtml( $groupId, $message, $language, $wrapperClass )
154 );
155 }
156 $output .= Html::closeElement( 'ol' );
157
158 $output .= Html::closeElement( 'details' );
159
160 return $output;
161 }
162
163 private function getErrorMessageHtml(
164 string $groupId,
165 MessageUpdateParameter $message,
166 Language $language,
167 string $wrapperClass
168 ): string {
169 $messageTitle = Title::newFromText( $message->getPageName() );
170 $actions = [];
171 if ( $messageTitle->exists() ) {
172 $output = $this->linkRenderer->makeLink( $messageTitle, $message->getPageName() );
173 $actions[] = $this->linkRenderer->makeLink(
174 $messageTitle,
175 $this->localizer->msg( 'translate-smg-group-message-action-history' )->text(),
176 [],
177 [ 'action' => 'history' ]
178 );
179 } else {
180 $output = $this->linkRenderer->makeBrokenLink( $messageTitle, $message->getPageName() );
181 }
182
183 $actions[] = Html::linkButton(
184 $this->localizer->msg( 'translate-smg-group-action-resolve' )->text(),
185 [
186 'class' => "{$wrapperClass}__resolve-action js-group-sync-message-resolve",
187 'href' => '#',
188 'data-group-id' => $groupId,
189 'data-msg-title' => $message->getPageName(),
190 ]
191 );
192
193 $output .= ' ' . Html::rawElement(
194 'span',
195 [ 'class' => "{$wrapperClass}__sync-actions" ],
196 $this->localizer->msg( 'parentheses' )
197 ->rawParams( $language->pipeList( $actions ) )->escaped()
198 );
199
200 $output .= $this->getMessageInfoHtml( $message, $language );
201
202 return $output;
203 }
204
205 private function getMessageInfoHtml( MessageUpdateParameter $message, Language $language ): string {
206 $output = Html::openElement( 'dl' );
207
208 $tags = [];
209 if ( $message->isFuzzy() ) {
210 $tags[] = $this->localizer->msg( 'translate-smg-group-message-tag-outdated' )->text();
211 }
212
213 if ( $message->isRename() ) {
214 $tags[] = $this->localizer->msg( 'translate-smg-group-message-tag-rename' )->text();
215 }
216
217 if ( $tags ) {
218 $output .= $this->getMessagePropHtml(
219 $this->localizer->msg( 'translate-smg-group-message-tag-label' )
220 ->numParams( count( $tags ) )->text(),
221 implode( $this->localizer->msg( 'pipe-separator' )->text(), $tags )
222 );
223 }
224
225 $output .= $this->getMessagePropHtml(
226 $this->localizer->msg( 'translate-smg-group-message-message-content' )->text(),
227 $message->getContent()
228 );
229
230 if ( $message->isRename() ) {
231 $output .= $this->getMessagePropHtml(
232 $this->localizer->msg( 'translate-smg-group-message-message-target' )->text(),
233 $message->getTargetValue()
234 );
235
236 $output .= $this->getMessagePropHtml(
237 $this->localizer->msg( 'translate-smg-group-message-message-replacement' )->text(),
238 $message->getReplacementValue()
239 );
240
241 $otherLangs = $message->getOtherLangs();
242 if ( $otherLangs ) {
243 $output .= $this->getMessagePropHtml(
244 $this->localizer->msg( 'translate-smg-group-message-message-other-langs' )->text(),
245 implode(
246 $this->localizer->msg( 'comma-separator' )->text(),
247 array_keys( $otherLangs )
248 )
249 );
250 }
251 }
252
253 $output .= Html::closeElement( 'dl' );
254 return $output;
255 }
256
257 private function getMessagePropHtml( string $label, string $value ): string {
258 return Html::element( 'dt', [], $label ) . Html::element( 'dd', [], $value );
259 }
260}
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(), 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 { 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());}, '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->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
Finds external changes for file based message groups.