Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 100 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
TranslationStashSpecialPage | |
0.00% |
0 / 100 |
|
0.00% |
0 / 10 |
306 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
hasPermissionToUse | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
showPage | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
6 | |||
getMessageTable | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
tuxLanguageSelector | |
0.00% |
0 / 34 |
|
0.00% |
0 / 1 |
2 | |||
getSourceLanguage | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getTargetLanguage | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
42 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\Extension\Translate\TranslatorSandbox; |
5 | |
6 | use FormatJson; |
7 | use Language; |
8 | use MediaWiki\Config\ServiceOptions; |
9 | use MediaWiki\Extension\Translate\Utilities\Utilities; |
10 | use MediaWiki\Html\Html; |
11 | use MediaWiki\Languages\LanguageFactory; |
12 | use MediaWiki\Languages\LanguageNameUtils; |
13 | use MediaWiki\Title\Title; |
14 | use MediaWiki\User\UserOptionsLookup; |
15 | use SpecialPage; |
16 | |
17 | /** |
18 | * Special page for new users to translate example messages. |
19 | * |
20 | * @author Santhosh Thottingal |
21 | * @license GPL-2.0-or-later |
22 | * @ingroup SpecialPage TranslateSpecialPage |
23 | */ |
24 | class TranslationStashSpecialPage extends SpecialPage { |
25 | /** @var TranslationStashReader */ |
26 | private $stash; |
27 | /** @var ServiceOptions */ |
28 | private $options; |
29 | /** @var LanguageNameUtils */ |
30 | private $languageNameUtils; |
31 | /** @var UserOptionsLookup */ |
32 | private $userOptionsLookup; |
33 | /** @var LanguageFactory */ |
34 | private $languageFactory; |
35 | |
36 | public const CONSTRUCTOR_OPTIONS = [ |
37 | 'TranslateSandboxLimit', |
38 | ]; |
39 | |
40 | public function __construct( |
41 | LanguageNameUtils $languageNameUtils, |
42 | TranslationStashReader $stash, |
43 | UserOptionsLookup $userOptionsLookup, |
44 | LanguageFactory $languageFactory, |
45 | ServiceOptions $options |
46 | ) { |
47 | parent::__construct( 'TranslationStash' ); |
48 | $this->languageNameUtils = $languageNameUtils; |
49 | $this->stash = $stash; |
50 | $this->userOptionsLookup = $userOptionsLookup; |
51 | $this->languageFactory = $languageFactory; |
52 | $this->options = $options; |
53 | } |
54 | |
55 | public function doesWrites() { |
56 | return true; |
57 | } |
58 | |
59 | protected function getGroupName() { |
60 | return 'translation'; |
61 | } |
62 | |
63 | public function execute( $params ) { |
64 | $limit = $this->options->get( 'TranslateSandboxLimit' ); |
65 | |
66 | $this->setHeaders(); |
67 | $out = $this->getOutput(); |
68 | |
69 | if ( !$this->hasPermissionToUse() ) { |
70 | $out->redirect( Title::newMainPage()->getLocalURL() ); |
71 | |
72 | return; |
73 | } |
74 | |
75 | $out->addJsConfigVars( 'wgTranslateSandboxLimit', $limit ); |
76 | $out->addModules( 'ext.translate.specialTranslationStash' ); |
77 | $out->addModuleStyles( 'mediawiki.ui.button' ); |
78 | $this->showPage(); |
79 | } |
80 | |
81 | /** Checks that the user is in the sandbox. */ |
82 | private function hasPermissionToUse(): bool { |
83 | return TranslateSandbox::isSandboxed( $this->getUser() ); |
84 | } |
85 | |
86 | /** Generates the whole page html and appends it to output */ |
87 | private function showPage(): void { |
88 | $out = $this->getOutput(); |
89 | $user = $this->getUser(); |
90 | |
91 | $count = count( $this->stash->getTranslations( $user ) ); |
92 | if ( $count === 0 ) { |
93 | $progress = $this->msg( 'translate-translationstash-initialtranslation' )->parse(); |
94 | } else { |
95 | $progress = $this->msg( 'translate-translationstash-translations' ) |
96 | ->numParams( $count ) |
97 | ->parse(); |
98 | } |
99 | |
100 | $out->addHTML( |
101 | <<<HTML |
102 | <div class="grid"> |
103 | <div class="row translate-welcome-header"> |
104 | <h1> |
105 | {$this->msg( 'translate-translationstash-welcome', $user->getName() )->parse()} |
106 | </h1> |
107 | <p> |
108 | {$this->msg( 'translate-translationstash-welcome-note' )->parse()} |
109 | </p> |
110 | </div> |
111 | <div class="row translate-stash-control"> |
112 | <div class="six columns stash-stats"> |
113 | {$progress} |
114 | </div> |
115 | <div class="six columns ext-translate-language-selector"> |
116 | {$this->tuxLanguageSelector()} |
117 | </div> |
118 | </div> |
119 | {$this->getMessageTable()} |
120 | <div class="row limit-reached hide"></div> |
121 | </div> |
122 | HTML |
123 | ); |
124 | } |
125 | |
126 | private function getMessageTable(): string { |
127 | $sourceLang = $this->getSourceLanguage(); |
128 | $targetLang = $this->getTargetLanguage(); |
129 | |
130 | return Html::element( |
131 | 'div', |
132 | [ |
133 | 'class' => 'row tux-messagelist', |
134 | 'data-sourcelangcode' => $sourceLang->getCode(), |
135 | 'data-sourcelangdir' => $sourceLang->getDir(), |
136 | 'data-targetlangcode' => $targetLang->getCode(), |
137 | 'data-targetlangdir' => $targetLang->getDir(), |
138 | ] |
139 | ); |
140 | } |
141 | |
142 | private function tuxLanguageSelector(): string { |
143 | // The name will be displayed in the UI language, |
144 | // so use for lang and dir |
145 | $language = $this->getTargetLanguage(); |
146 | $targetLangName = $this->languageNameUtils->getLanguageName( $language->getCode() ); |
147 | |
148 | $label = Html::element( 'span', [], $this->msg( 'tux-languageselector' )->text() ); |
149 | |
150 | $languageIcon = Html::element( |
151 | 'span', |
152 | [ 'class' => 'ext-translate-language-icon' ] |
153 | ); |
154 | |
155 | $targetLanguageName = Html::element( |
156 | 'span', |
157 | [ |
158 | 'class' => 'ext-translate-target-language', |
159 | 'dir' => $language->getDir(), |
160 | 'lang' => $language->getHtmlCode() |
161 | ], |
162 | $targetLangName |
163 | ); |
164 | |
165 | $expandIcon = Html::element( |
166 | 'span', |
167 | [ 'class' => 'ext-translate-language-selector-expand' ] |
168 | ); |
169 | |
170 | $value = Html::rawElement( |
171 | 'span', |
172 | [ |
173 | 'class' => 'uls mw-ui-button', |
174 | 'tabindex' => 0, |
175 | 'title' => $this->msg( 'tux-select-target-language' )->text() |
176 | ], |
177 | $languageIcon . $targetLanguageName . $expandIcon |
178 | ); |
179 | |
180 | return Html::rawElement( |
181 | 'div', |
182 | [ 'class' => 'columns ext-translate-language-selector' ], |
183 | "$label $value" |
184 | ); |
185 | } |
186 | |
187 | /** Returns the source language for messages. */ |
188 | protected function getSourceLanguage(): Language { |
189 | // Bad |
190 | return $this->languageFactory->getLanguage( 'en' ); |
191 | } |
192 | |
193 | /** Returns the default target language for messages. */ |
194 | private function getTargetLanguage(): Language { |
195 | $ui = $this->getLanguage(); |
196 | $source = $this->getSourceLanguage(); |
197 | if ( !$ui->equals( $source ) ) { |
198 | return $ui; |
199 | } |
200 | |
201 | $options = FormatJson::decode( |
202 | $this->userOptionsLookup->getOption( $this->getUser(), 'translate-sandbox' ), |
203 | true |
204 | ); |
205 | $supported = Utilities::getLanguageNames( 'en' ); |
206 | |
207 | if ( isset( $options['languages'] ) ) { |
208 | foreach ( $options['languages'] as $code ) { |
209 | if ( !isset( $supported[$code] ) ) { |
210 | continue; |
211 | } |
212 | |
213 | if ( $code !== $source->getCode() ) { |
214 | return $this->languageFactory->getLanguage( $code ); |
215 | } |
216 | } |
217 | } |
218 | |
219 | // User has not chosen any valid language. Pick the source. |
220 | return $this->languageFactory->getLanguage( $source->getCode() ); |
221 | } |
222 | } |