Translate extension for MediaWiki
 
Loading...
Searching...
No Matches
TranslationStashSpecialPage.php
1<?php
2declare( strict_types = 1 );
3
4namespace MediaWiki\Extension\Translate\TranslatorSandbox;
5
6use FormatJson;
7use Html;
8use Language;
9use MediaWiki\Config\ServiceOptions;
10use MediaWiki\Languages\LanguageNameUtils;
11use MediaWiki\User\UserOptionsLookup;
12use SpecialPage;
13use Title;
16
24class TranslationStashSpecialPage extends SpecialPage {
26 private $stash;
28 private $options;
30 private $languageNameUtils;
32 private $userOptionsLookup;
33
34 public const CONSTRUCTOR_OPTIONS = [
35 'TranslateSandboxLimit',
36 'TranslateSecondaryPermissionUrl'
37 ];
38
39 public function __construct(
40 LanguageNameUtils $languageNameUtils,
42 UserOptionsLookup $userOptionsLookup,
43 ServiceOptions $options
44 ) {
45 $this->languageNameUtils = $languageNameUtils;
46 $this->stash = $stash;
47 $this->userOptionsLookup = $userOptionsLookup;
48 $this->options = $options;
49 parent::__construct( 'TranslationStash' );
50 }
51
52 public function doesWrites() {
53 return true;
54 }
55
56 protected function getGroupName() {
57 return 'translation';
58 }
59
60 public function execute( $params ) {
61 $limit = $this->options->get( 'TranslateSandboxLimit' );
62 $secondaryPermissionUrl = $this->options->get( 'TranslateSecondaryPermissionUrl' );
63
64 $this->setHeaders();
65 $out = $this->getOutput();
66
67 $this->stash = new TranslationStashStorage( wfGetDB( DB_PRIMARY ) );
68
69 if ( !$this->hasPermissionToUse() ) {
70 if ( $secondaryPermissionUrl && $this->getUser()->isRegistered() ) {
71 $out->redirect(
72 Title::newFromText( $secondaryPermissionUrl )->getLocalURL()
73 );
74
75 return;
76 }
77
78 $out->redirect( Title::newMainPage()->getLocalURL() );
79
80 return;
81 }
82
83 $out->addJsConfigVars( 'wgTranslateSandboxLimit', $limit );
84 $out->addModules( 'ext.translate.specialTranslationStash' );
85 $out->addModuleStyles( 'mediawiki.ui.button' );
86 $this->showPage();
87 }
88
90 private function hasPermissionToUse(): bool {
91 return TranslateSandbox::isSandboxed( $this->getUser() );
92 }
93
95 private function showPage(): void {
96 $out = $this->getOutput();
97 $user = $this->getUser();
98
99 $count = count( $this->stash->getTranslations( $user ) );
100 if ( $count === 0 ) {
101 $progress = $this->msg( 'translate-translationstash-initialtranslation' )->parse();
102 } else {
103 $progress = $this->msg( 'translate-translationstash-translations' )
104 ->numParams( $count )
105 ->parse();
106 }
107
108 $out->addHTML(
109 <<<HTML
110<div class="grid">
111 <div class="row translate-welcome-header">
112 <h1>
113 {$this->msg( 'translate-translationstash-welcome', $user->getName() )->parse()}
114 </h1>
115 <p>
116 {$this->msg( 'translate-translationstash-welcome-note' )->parse()}
117 </p>
118 </div>
119 <div class="row translate-stash-control">
120 <div class="six columns stash-stats">
121 {$progress}
122 </div>
123 <div class="six columns ext-translate-language-selector">
124 {$this->tuxLanguageSelector()}
125 </div>
126 </div>
127 {$this->getMessageTable()}
128 <div class="row limit-reached hide"></div>
129</div>
130HTML
131 );
132 }
133
134 private function getMessageTable(): string {
135 $sourceLang = $this->getSourceLanguage();
136 $targetLang = $this->getTargetLanguage();
137
138 return Html::element(
139 'div',
140 [
141 'class' => 'row tux-messagelist',
142 'data-sourcelangcode' => $sourceLang->getCode(),
143 'data-sourcelangdir' => $sourceLang->getDir(),
144 'data-targetlangcode' => $targetLang->getCode(),
145 'data-targetlangdir' => $targetLang->getDir(),
146 ]
147 );
148 }
149
150 private function tuxLanguageSelector(): string {
151 // The name will be displayed in the UI language,
152 // so use for lang and dir
153 $language = $this->getTargetLanguage();
154 $targetLangName = $this->languageNameUtils->getLanguageName( $language->getCode() );
155
156 $label = Html::element( 'span', [], $this->msg( 'tux-languageselector' )->text() );
157
158 $languageIcon = Html::element(
159 'span',
160 [ 'class' => 'ext-translate-language-icon' ]
161 );
162
163 $targetLanguageName = Html::element(
164 'span',
165 [
166 'class' => 'ext-translate-target-language',
167 'dir' => $language->getDir(),
168 'lang' => $language->getHtmlCode()
169 ],
170 $targetLangName
171 );
172
173 $expandIcon = Html::element(
174 'span',
175 [ 'class' => 'ext-translate-language-selector-expand' ]
176 );
177
178 $value = Html::rawElement(
179 'span',
180 [
181 'class' => 'uls mw-ui-button',
182 'tabindex' => 0,
183 'title' => $this->msg( 'tux-select-target-language' )->text()
184 ],
185 $languageIcon . $targetLanguageName . $expandIcon
186 );
187
188 return Html::rawElement(
189 'div',
190 [ 'class' => 'columns ext-translate-language-selector' ],
191 "$label $value"
192 );
193 }
194
196 protected function getSourceLanguage(): Language {
197 // Bad
198 return Language::factory( 'en' );
199 }
200
202 private function getTargetLanguage(): Language {
203 $ui = $this->getLanguage();
204 $source = $this->getSourceLanguage();
205 if ( !$ui->equals( $source ) ) {
206 return $ui;
207 }
208
209 $options = FormatJson::decode(
210 $this->userOptionsLookup->getOption( $this->getUser(), 'translate-sandbox' ),
211 true
212 );
213 $supported = TranslateUtils::getLanguageNames( 'en' );
214
215 if ( isset( $options['languages'] ) ) {
216 foreach ( $options['languages'] as $code ) {
217 if ( !isset( $supported[$code] ) ) {
218 continue;
219 }
220
221 if ( $code !== $source->getCode() ) {
222 return Language::factory( $code );
223 }
224 }
225 }
226
227 // User has not chosen any valid language. Pick the source.
228 return Language::factory( $source->getCode() );
229 }
230}
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'), MessageIndex::singleton());}, 'Translate:GroupSynchronizationCache'=> static function(MediaWikiServices $services):GroupSynchronizationCache { return new GroupSynchronizationCache( $services->get( 'Translate:PersistentCache'));}, 'Translate:MessageBundleStore'=> static function(MediaWikiServices $services):MessageBundleStore { return new MessageBundleStore(new RevTagStore(), $services->getJobQueueGroup(), $services->getLanguageNameUtils(), $services->get( 'Translate:MessageIndex'));}, 'Translate:MessageGroupReview'=> static function(MediaWikiServices $services):MessageGroupReview { return new MessageGroupReview($services->getDBLoadBalancer(), $services->getHookContainer());}, '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: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:SubpageListBuilder'=> static function(MediaWikiServices $services):SubpageListBuilder { return new SubpageListBuilder($services->get( 'Translate:TranslatableBundleFactory'), $services->getLinkBatchFactory());}, 'Translate:TranslatableBundleFactory'=> static function(MediaWikiServices $services):TranslatableBundleFactory { return new TranslatableBundleFactory($services->get( 'Translate:TranslatablePageStore'), $services->get( 'Translate:MessageBundleStore'));}, '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: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(), new RevTagStore(), $services->getDBLoadBalancer());}, 'Translate:TranslationStashReader'=> static function(MediaWikiServices $services):TranslationStashReader { $db=$services->getDBLoadBalancer() ->getConnectionRef(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());}, '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
Utility class for the sandbox feature of Translate.
Essentially random collection of helper functions, similar to GlobalFunctions.php.