19 private MessageLocalizer $localizer;
20 private LinkRenderer $linkRenderer;
22 public function __construct( MessageLocalizer $localizer, LinkRenderer $linkRenderer ) {
23 $this->localizer = $localizer;
24 $this->linkRenderer = $linkRenderer;
29 sort( $groupsInSync );
31 if ( !$groupsInSync ) {
32 return Html::rawElement(
34 [
'class' => $wrapperClass ],
35 $this->localizer->msg(
'translate-smg-no-groups-in-sync' )->escaped()
36 . $this->addGroupSyncHelp( $wrapperClass )
41 foreach ( $groupsInSync as $groupId ) {
42 $htmlGroupItems[] = Html::element(
'li', [], $groupId );
45 return $this->getGroupSyncInfoHtml(
47 'translate-smg-groups-in-sync',
48 'translate-smg-groups-in-sync-list',
49 Html::rawElement(
'ul', [], implode(
'', $htmlGroupItems ) ),
50 $this->addGroupSyncHelp( $wrapperClass )
54 public function getHtmlForGroupsWithError(
55 GroupSynchronizationCache $groupSynchronizationCache,
59 $groupsWithErrors = $groupSynchronizationCache->getGroupsWithErrors();
60 if ( !$groupsWithErrors ) {
65 foreach ( $groupsWithErrors as $groupId ) {
66 $groupErrorResponse = $groupSynchronizationCache->getGroupErrorInfo( $groupId );
67 $htmlGroupItems[] = $this->getHtmlForGroupErrors( $groupErrorResponse, $currentLang, $wrapperClass );
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 )
78 private function addGroupSyncHelp(
string $wrapperClass ): string {
82 'href' =>
'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:Translate/' .
83 'Group_management#Strong_synchronization',
85 'class' =>
"{$wrapperClass}__help",
87 '[' . $this->localizer->msg(
'translate-smg-strong-sync-help' )->text() .
']'
91 private function getGroupSyncInfoHtml(
93 string $summaryMsgKey,
94 string $descriptionMsgKey,
96 ?
string $preHtmlContent =
null
98 $output = Html::openElement(
'div', [
'class' => $className ] );
99 if ( $preHtmlContent ) {
100 $output .= $preHtmlContent;
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' );
113 private function getHtmlForGroupErrors(
114 GroupSynchronizationResponse $groupErrorResponse,
118 $groupId = $groupErrorResponse->getGroupId();
119 $output = Html::openElement(
121 [
'class' =>
"{$wrapperClass}__group_errors js-group-sync-group-errors" ]
124 $groupResolveAction = Html::linkButton(
125 $this->localizer->msg(
'translate-smg-group-action-resolve' )->text(),
127 'class' =>
"{$wrapperClass}__resolve-action js-group-sync-group-resolve",
129 'data-group-id' => $groupId,
133 $output .= Html::rawElement(
139 [
'class' =>
"{$wrapperClass}__sync-actions" ],
140 $this->localizer->msg(
'parentheses' )
141 ->rawParams( $groupResolveAction )->escaped()
146 $errorMessages = $groupErrorResponse->getRemainingMessages();
148 $output .= Html::openElement(
'ol' );
149 foreach ( $errorMessages as $message ) {
150 $output .= Html::rawElement(
152 [
'class' =>
"{$wrapperClass}__message-error js-group-sync-message-error" ],
153 $this->getErrorMessageHtml( $groupId, $message, $language, $wrapperClass )
156 $output .= Html::closeElement(
'ol' );
158 $output .= Html::closeElement(
'details' );
163 private function getErrorMessageHtml(
165 MessageUpdateParameter $message,
169 $messageTitle = Title::newFromText( $message->getPageName() );
171 if ( $messageTitle->exists() ) {
172 $output = $this->linkRenderer->makeLink( $messageTitle, $message->getPageName() );
173 $actions[] = $this->linkRenderer->makeLink(
175 $this->localizer->msg(
'translate-smg-group-message-action-history' )->text(),
177 [
'action' =>
'history' ]
180 $output = $this->linkRenderer->makeBrokenLink( $messageTitle, $message->getPageName() );
183 $actions[] = Html::linkButton(
184 $this->localizer->msg(
'translate-smg-group-action-resolve' )->text(),
186 'class' =>
"{$wrapperClass}__resolve-action js-group-sync-message-resolve",
188 'data-group-id' => $groupId,
189 'data-msg-title' => $message->getPageName(),
193 $output .=
' ' . Html::rawElement(
195 [
'class' =>
"{$wrapperClass}__sync-actions" ],
196 $this->localizer->msg(
'parentheses' )
197 ->rawParams( $language->pipeList( $actions ) )->escaped()
200 $output .= $this->getMessageInfoHtml( $message, $language );
205 private function getMessageInfoHtml( MessageUpdateParameter $message, Language $language ): string {
206 $output = Html::openElement(
'dl' );
209 if ( $message->isFuzzy() ) {
210 $tags[] = $this->localizer->msg(
'translate-smg-group-message-tag-outdated' )->text();
213 if ( $message->isRename() ) {
214 $tags[] = $this->localizer->msg(
'translate-smg-group-message-tag-rename' )->text();
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 )
225 $output .= $this->getMessagePropHtml(
226 $this->localizer->msg(
'translate-smg-group-message-message-content' )->text(),
227 $message->getContent()
230 if ( $message->isRename() ) {
231 $output .= $this->getMessagePropHtml(
232 $this->localizer->msg(
'translate-smg-group-message-message-target' )->text(),
233 $message->getTargetValue()
236 $output .= $this->getMessagePropHtml(
237 $this->localizer->msg(
'translate-smg-group-message-message-replacement' )->text(),
238 $message->getReplacementValue()
241 $otherLangs = $message->getOtherLangs();
243 $output .= $this->getMessagePropHtml(
244 $this->localizer->msg(
'translate-smg-group-message-message-other-langs' )->text(),
246 $this->localizer->msg(
'comma-separator' )->text(),
247 array_keys( $otherLangs )
253 $output .= Html::closeElement(
'dl' );
257 private function getMessagePropHtml(
string $label,
string $value ): string {
258 return Html::element(
'dt', [], $label ) . Html::element(
'dd', [], $value );
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