26 private const GRAPH_CONTAINER_ID =
'translationStatsGraphContainer';
27 private const GRAPH_CONTAINER_CLASS =
'mw-translate-translationstats-container';
30 parent::__construct(
'TranslationStats' );
31 $this->dataProvider = $dataProvider;
47 $graphOpts->bindArray( $this->getRequest()->getValues() );
49 $pars = explode(
';', (
string)$par );
50 foreach ( $pars as $item ) {
51 if ( !str_contains( $item,
'=' ) ) {
55 [ $key, $value ] = array_map(
'trim', explode(
'=', $item, 2 ) );
56 if ( $graphOpts->hasValue( $key ) ) {
57 $graphOpts->setValue( $key, $value );
61 $graphOpts->normalize( $this->dataProvider->getGraphTypes() );
62 $opts = $graphOpts->getFormOptions();
64 if ( $this->including() ) {
65 $this->getOutput()->addHTML( $this->embed( $opts ) );
76 private function form( FormOptions $opts ): void {
77 $script = $this->getConfig()->get(
'Script' );
80 $out = $this->getOutput();
81 $out->addModules(
'ext.translate.special.translationstats' );
82 $out->addHelpLink(
'Help:Extension:Translate/Statistics_and_reporting' );
83 $out->addWikiMsg(
'translate-statsf-intro' );
85 Xml::fieldset( $this->msg(
'translate-statsf-options' )->text() ) . Html::openElement(
87 [
'action' => $script,
'id' =>
'translationStatsConfig' ]
88 ) . Html::hidden(
'title', $this->getPageTitle()->getPrefixedText() ) .
89 Html::hidden(
'preview', 1 ) .
'<table>'
91 $submit = Xml::submitButton( $this->msg(
'translate-statsf-submit' )->text() );
93 $this->eInput(
'width', $opts ) . $this->eInput(
'height', $opts ) .
94 '<tr><td colspan="2"><hr /></td></tr>' . $this->eInput(
'start', $opts, 24 ) .
95 $this->eInput(
'days', $opts ) .
96 $this->eRadio(
'scale', $opts, [
'years',
'months',
'weeks',
'days',
'hours' ] ) .
97 $this->eRadio(
'count', $opts, $this->dataProvider->getGraphTypes() ) .
98 '<tr><td colspan="2"><hr /></td></tr>' . $this->eLanguage(
'language', $opts ) .
99 $this->eGroup(
'group', $opts ) .
'<tr><td colspan="2"><hr /></td></tr>' .
100 '<tr><td colspan="2">' . $submit .
'</td></tr>'
102 $out->addHTML(
'</table></form></fieldset>' );
103 if ( !$opts[
'preview'] ) {
107 foreach ( $opts->getChangedValues() as $key => $v ) {
108 if ( $key ===
'preview' ) {
111 if ( is_array( $v ) ) {
112 $v = implode(
',', $v );
113 if ( !strlen( $v ) ) {
117 $spiParams[] = $key .
'=' . wfEscapeWikiText( $v );
120 $spiParams = $spiParams ?
'/' . implode(
';', $spiParams ) :
'';
122 $titleText = $this->getPageTitle()->getPrefixedText();
123 $out->addHTML( Html::element(
'hr' ) );
129 'id' => self::GRAPH_CONTAINER_ID,
130 'style' =>
'margin: 2em auto; display: block',
131 'class' => self::GRAPH_CONTAINER_CLASS,
139 [
'aria-label' => $this->msg(
'translate-statsf-embed' )->text() ],
140 "{{{$titleText}{$spiParams}}}"
146 private function eInput(
string $name, FormOptions $opts,
int $width = 4 ): string {
147 $value = $opts[$name];
148 return '<tr><td>' . $this->eLabel( $name ) .
'</td><td>' .
149 Xml::input( $name, $width, $value, [
'id' => $name ] ) .
'</td></tr>' .
"\n";
153 private function eLabel(
string $name ): string {
158 $label =
'translate-statsf-' . $name;
159 $label = $this->msg( $label )->escaped();
160 return Xml::tags(
'label', [
'for' => $name ], $label );
164 private function eRadio(
string $name, FormOptions $opts, array $alts ): string {
167 $label =
'translate-statsf-' . $name;
168 $label = $this->msg( $label )->escaped();
169 $s =
'<tr><td>' . $label .
'</td><td>';
171 foreach ( $alts as $alt ) {
176 $alt === $opts[$name],
179 $options[] = $radio .
' ' . $this->eLabel( $id );
181 $s .= implode(
' ', $options );
182 $s .=
'</td></tr>' .
"\n";
187 private function eLanguage(
string $name, FormOptions $opts ): string {
188 $value = implode(
',', $opts[$name] );
190 $select = $this->languageSelector();
191 $select->setTargetId(
'language' );
192 return '<tr><td>' . $this->eLabel( $name ) .
'</td><td>' . $select->getHtmlAndPrepareJS() .
193 '<br />' . Xml::input( $name, 20, $value, [
'id' => $name ] ) .
'</td></tr>' .
"\n";
197 private function languageSelector(): JsSelectToInput {
198 $languages = Utilities::getLanguageNames( $this->getLanguage()->getCode() );
200 $selector =
new XmlSelect(
'mw-language-selector',
'mw-language-selector' );
201 foreach ( $languages as $code => $name ) {
202 $selector->addOption(
"$code - $name", $code );
204 return new JsSelectToInput( $selector );
208 private function eGroup(
string $name, FormOptions $opts ): string {
209 $value = implode(
',', $opts[$name] );
211 $select = $this->groupSelector();
212 $select->setTargetId(
'group' );
213 return '<tr><td>' . $this->eLabel( $name ) .
'</td><td>' . $select->getHtmlAndPrepareJS() .
214 '<br />' . Xml::input( $name, 20, $value, [
'id' => $name ] ) .
'</td></tr>' .
"\n";
218 private function groupSelector(): JsSelectToInput {
219 $groups = MessageGroups::singleton()->getGroups();
220 foreach ( $groups as $key => $group ) {
221 if ( !$group->exists() ) {
222 unset( $groups[$key] );
226 $selector =
new XmlSelect(
'mw-group-selector',
'mw-group-selector' );
227 foreach ( $groups as $code => $name ) {
228 $selector->addOption( $name->getLabel(), $code );
230 return new JsSelectToInput( $selector );
233 private function embed( FormOptions $opts ): string {
234 $this->getOutput()->addModules(
'ext.translate.translationstats.embedded' );
235 return Html::rawElement(
238 'class' => self::GRAPH_CONTAINER_CLASS,
241 'translationStatsGraphOptions',
242 json_encode( $opts->getAllValues() )
return[ 'Translate:AggregateGroupManager'=> static function(MediaWikiServices $services):AggregateGroupManager { return new AggregateGroupManager( $services->getTitleFactory());}, '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( 'Translate.GroupSynchronization'), $services->get( 'Translate:MessageIndex'), $services->getTitleFactory(), 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: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->getDBLoadBalancer());}, '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->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( 'Translate.MessageGroupSubscription'), 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->getDBLoadBalancerFactory());}, '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( 'Translate'), $services->getMainObjectStash(), $services->getDBLoadBalancerFactory(), $services->get( 'Translate:MessageGroupSubscription'), 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->getDBLoadBalancer(), $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->getDBLoadBalancer());}, '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->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(), $services->getNamespaceInfo(), $services->getTitleFactory());}, '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->getDBLoadBalancerFactory(), $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:TranslatablePageMarker'=> static function(MediaWikiServices $services):TranslatablePageMarker { return new TranslatablePageMarker($services->getDBLoadBalancer(), $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'));}, '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->getDBLoadBalancer(), $services->get( 'Translate:TranslatableBundleStatusStore'), $services->get( 'Translate:TranslatablePageParser'), $services->get( 'Translate:MessageGroupMetadata'));}, 'Translate:TranslatablePageView'=> static function(MediaWikiServices $services):TranslatablePageView { return new TranslatablePageView($services->getDBLoadBalancerFactory(), $services->get( 'Translate:TranslatablePageStateStore'), new ServiceOptions(TranslatablePageView::SERVICE_OPTIONS, $services->getMainConfig()));}, 'Translate:TranslateSandbox'=> static function(MediaWikiServices $services):TranslateSandbox { return new TranslateSandbox($services->getUserFactory(), $services->getDBLoadBalancer(), $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 { $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