diff options
Diffstat (limited to 'Translate/src/TranslatorSandbox/TranslationStashSpecialPage.php')
-rw-r--r-- | Translate/src/TranslatorSandbox/TranslationStashSpecialPage.php | 223 |
1 files changed, 223 insertions, 0 deletions
diff --git a/Translate/src/TranslatorSandbox/TranslationStashSpecialPage.php b/Translate/src/TranslatorSandbox/TranslationStashSpecialPage.php new file mode 100644 index 00000000..712beb39 --- /dev/null +++ b/Translate/src/TranslatorSandbox/TranslationStashSpecialPage.php @@ -0,0 +1,223 @@ +<?php +declare( strict_types = 1 ); + +namespace MediaWiki\Extension\Translate\TranslatorSandbox; + +use FormatJson; +use Html; +use Language; +use MediaWiki\Config\ServiceOptions; +use MediaWiki\Languages\LanguageFactory; +use MediaWiki\Languages\LanguageNameUtils; +use MediaWiki\User\UserOptionsLookup; +use SpecialPage; +use Title; +use TranslateSandbox; +use TranslateUtils; + +/** + * Special page for new users to translate example messages. + * + * @author Santhosh Thottingal + * @license GPL-2.0-or-later + * @ingroup SpecialPage TranslateSpecialPage + */ +class TranslationStashSpecialPage extends SpecialPage { + /** @var TranslationStashReader */ + private $stash; + /** @var ServiceOptions */ + private $options; + /** @var LanguageNameUtils */ + private $languageNameUtils; + /** @var UserOptionsLookup */ + private $userOptionsLookup; + /** @var LanguageFactory */ + private $languageFactory; + + public const CONSTRUCTOR_OPTIONS = [ + 'TranslateSandboxLimit', + ]; + + public function __construct( + LanguageNameUtils $languageNameUtils, + TranslationStashReader $stash, + UserOptionsLookup $userOptionsLookup, + LanguageFactory $languageFactory, + ServiceOptions $options + ) { + parent::__construct( 'TranslationStash' ); + $this->languageNameUtils = $languageNameUtils; + $this->stash = $stash; + $this->userOptionsLookup = $userOptionsLookup; + $this->languageFactory = $languageFactory; + $this->options = $options; + } + + public function doesWrites() { + return true; + } + + protected function getGroupName() { + return 'translation'; + } + + public function execute( $params ) { + $limit = $this->options->get( 'TranslateSandboxLimit' ); + + $this->setHeaders(); + $out = $this->getOutput(); + + if ( !$this->hasPermissionToUse() ) { + $out->redirect( Title::newMainPage()->getLocalURL() ); + + return; + } + + $out->addJsConfigVars( 'wgTranslateSandboxLimit', $limit ); + $out->addModules( 'ext.translate.specialTranslationStash' ); + $out->addModuleStyles( 'mediawiki.ui.button' ); + $this->showPage(); + } + + /** Checks that the user is in the sandbox. */ + private function hasPermissionToUse(): bool { + return TranslateSandbox::isSandboxed( $this->getUser() ); + } + + /** Generates the whole page html and appends it to output */ + private function showPage(): void { + $out = $this->getOutput(); + $user = $this->getUser(); + + $count = count( $this->stash->getTranslations( $user ) ); + if ( $count === 0 ) { + $progress = $this->msg( 'translate-translationstash-initialtranslation' )->parse(); + } else { + $progress = $this->msg( 'translate-translationstash-translations' ) + ->numParams( $count ) + ->parse(); + } + + $out->addHTML( + <<<HTML +<div class="grid"> + <div class="row translate-welcome-header"> + <h1> + {$this->msg( 'translate-translationstash-welcome', $user->getName() )->parse()} + </h1> + <p> + {$this->msg( 'translate-translationstash-welcome-note' )->parse()} + </p> + </div> + <div class="row translate-stash-control"> + <div class="six columns stash-stats"> + {$progress} + </div> + <div class="six columns ext-translate-language-selector"> + {$this->tuxLanguageSelector()} + </div> + </div> + {$this->getMessageTable()} + <div class="row limit-reached hide"></div> +</div> +HTML + ); + } + + private function getMessageTable(): string { + $sourceLang = $this->getSourceLanguage(); + $targetLang = $this->getTargetLanguage(); + + return Html::element( + 'div', + [ + 'class' => 'row tux-messagelist', + 'data-sourcelangcode' => $sourceLang->getCode(), + 'data-sourcelangdir' => $sourceLang->getDir(), + 'data-targetlangcode' => $targetLang->getCode(), + 'data-targetlangdir' => $targetLang->getDir(), + ] + ); + } + + private function tuxLanguageSelector(): string { + // The name will be displayed in the UI language, + // so use for lang and dir + $language = $this->getTargetLanguage(); + $targetLangName = $this->languageNameUtils->getLanguageName( $language->getCode() ); + + $label = Html::element( 'span', [], $this->msg( 'tux-languageselector' )->text() ); + + $languageIcon = Html::element( + 'span', + [ 'class' => 'ext-translate-language-icon' ] + ); + + $targetLanguageName = Html::element( + 'span', + [ + 'class' => 'ext-translate-target-language', + 'dir' => $language->getDir(), + 'lang' => $language->getHtmlCode() + ], + $targetLangName + ); + + $expandIcon = Html::element( + 'span', + [ 'class' => 'ext-translate-language-selector-expand' ] + ); + + $value = Html::rawElement( + 'span', + [ + 'class' => 'uls mw-ui-button', + 'tabindex' => 0, + 'title' => $this->msg( 'tux-select-target-language' )->text() + ], + $languageIcon . $targetLanguageName . $expandIcon + ); + + return Html::rawElement( + 'div', + [ 'class' => 'columns ext-translate-language-selector' ], + "$label $value" + ); + } + + /** Returns the source language for messages. */ + protected function getSourceLanguage(): Language { + // Bad + return $this->languageFactory->getLanguage( 'en' ); + } + + /** Returns the default target language for messages. */ + private function getTargetLanguage(): Language { + $ui = $this->getLanguage(); + $source = $this->getSourceLanguage(); + if ( !$ui->equals( $source ) ) { + return $ui; + } + + $options = FormatJson::decode( + $this->userOptionsLookup->getOption( $this->getUser(), 'translate-sandbox' ), + true + ); + $supported = TranslateUtils::getLanguageNames( 'en' ); + + if ( isset( $options['languages'] ) ) { + foreach ( $options['languages'] as $code ) { + if ( !isset( $supported[$code] ) ) { + continue; + } + + if ( $code !== $source->getCode() ) { + return $this->languageFactory->getLanguage( $code ); + } + } + } + + // User has not chosen any valid language. Pick the source. + return $this->languageFactory->getLanguage( $source->getCode() ); + } +} |