31 private $languageNameUtils;
33 private $userOptionsLookup;
35 private $languageFactory;
37 public const CONSTRUCTOR_OPTIONS = [
38 'TranslateSandboxLimit',
41 public function __construct(
42 LanguageNameUtils $languageNameUtils,
44 UserOptionsLookup $userOptionsLookup,
45 LanguageFactory $languageFactory,
46 ServiceOptions $options
48 parent::__construct(
'TranslationStash' );
49 $this->languageNameUtils = $languageNameUtils;
50 $this->stash = $stash;
51 $this->userOptionsLookup = $userOptionsLookup;
52 $this->languageFactory = $languageFactory;
53 $this->options = $options;
56 public function doesWrites() {
60 protected function getGroupName() {
64 public function execute( $params ) {
65 $limit = $this->options->get(
'TranslateSandboxLimit' );
68 $out = $this->getOutput();
70 if ( !$this->hasPermissionToUse() ) {
71 $out->redirect( Title::newMainPage()->getLocalURL() );
76 $out->addJsConfigVars(
'wgTranslateSandboxLimit', $limit );
77 $out->addModules(
'ext.translate.specialTranslationStash' );
78 $out->addModuleStyles(
'mediawiki.ui.button' );
83 private function hasPermissionToUse():
bool {
84 return TranslateSandbox::isSandboxed( $this->getUser() );
88 private function showPage():
void {
89 $out = $this->getOutput();
90 $user = $this->getUser();
92 $count = count( $this->stash->getTranslations( $user ) );
94 $progress = $this->msg(
'translate-translationstash-initialtranslation' )->parse();
96 $progress = $this->msg(
'translate-translationstash-translations' )
104 <div
class=
"row translate-welcome-header">
106 {$this->msg(
'translate-translationstash-welcome', $user->getName() )->parse()}
109 {$this->msg(
'translate-translationstash-welcome-note' )->parse()}
112 <div
class=
"row translate-stash-control">
113 <div
class=
"six columns stash-stats">
116 <div
class=
"six columns ext-translate-language-selector">
117 {$this->tuxLanguageSelector()}
120 {$this->getMessageTable()}
121 <div
class=
"row limit-reached hide"></div>
127 private function getMessageTable():
string {
128 $sourceLang = $this->getSourceLanguage();
129 $targetLang = $this->getTargetLanguage();
131 return Html::element(
134 'class' =>
'row tux-messagelist',
135 'data-sourcelangcode' => $sourceLang->getCode(),
136 'data-sourcelangdir' => $sourceLang->getDir(),
137 'data-targetlangcode' => $targetLang->getCode(),
138 'data-targetlangdir' => $targetLang->getDir(),
143 private function tuxLanguageSelector():
string {
146 $language = $this->getTargetLanguage();
147 $targetLangName = $this->languageNameUtils->getLanguageName( $language->getCode() );
149 $label = Html::element(
'span', [], $this->msg(
'tux-languageselector' )->text() );
151 $languageIcon = Html::element(
153 [
'class' =>
'ext-translate-language-icon' ]
156 $targetLanguageName = Html::element(
159 'class' =>
'ext-translate-target-language',
160 'dir' => $language->getDir(),
161 'lang' => $language->getHtmlCode()
166 $expandIcon = Html::element(
168 [
'class' =>
'ext-translate-language-selector-expand' ]
171 $value = Html::rawElement(
174 'class' =>
'uls mw-ui-button',
176 'title' => $this->msg(
'tux-select-target-language' )->text()
178 $languageIcon . $targetLanguageName . $expandIcon
181 return Html::rawElement(
183 [
'class' =>
'columns ext-translate-language-selector' ],
189 protected function getSourceLanguage(): Language {
191 return $this->languageFactory->getLanguage(
'en' );
195 private function getTargetLanguage(): Language {
196 $ui = $this->getLanguage();
197 $source = $this->getSourceLanguage();
198 if ( !$ui->equals( $source ) ) {
202 $options = FormatJson::decode(
203 $this->userOptionsLookup->getOption( $this->getUser(),
'translate-sandbox' ),
206 $supported = Utilities::getLanguageNames(
'en' );
208 if ( isset( $options[
'languages'] ) ) {
209 foreach ( $options[
'languages'] as $code ) {
210 if ( !isset( $supported[$code] ) ) {
214 if ( $code !== $source->getCode() ) {
215 return $this->languageFactory->getLanguage( $code );
221 return $this->languageFactory->getLanguage( $source->getCode() );