summaryrefslogtreecommitdiff
path: root/www/wiki/extensions/Translate/specials/SpecialExportTranslations.php
diff options
context:
space:
mode:
Diffstat (limited to 'www/wiki/extensions/Translate/specials/SpecialExportTranslations.php')
-rw-r--r--www/wiki/extensions/Translate/specials/SpecialExportTranslations.php265
1 files changed, 265 insertions, 0 deletions
diff --git a/www/wiki/extensions/Translate/specials/SpecialExportTranslations.php b/www/wiki/extensions/Translate/specials/SpecialExportTranslations.php
new file mode 100644
index 00000000..8c7b3d2e
--- /dev/null
+++ b/www/wiki/extensions/Translate/specials/SpecialExportTranslations.php
@@ -0,0 +1,265 @@
+<?php
+/**
+ * @license GPL-2.0-or-later
+ * @ingroup SpecialPage TranslateSpecialPage
+ */
+class SpecialExportTranslations extends SpecialPage {
+ /** @var string */
+ protected $language;
+
+ /** @var string */
+ protected $format;
+
+ /** @var string */
+ protected $groupId;
+
+ /** @var string[] */
+ public static $validFormats = [ 'export-as-po', 'export-to-file' ];
+
+ public function __construct() {
+ parent::__construct( 'ExportTranslations' );
+ }
+
+ /**
+ * @param null|string $par
+ */
+ public function execute( $par ) {
+ $out = $this->getOutput();
+ $request = $this->getRequest();
+ $lang = $this->getLanguage();
+
+ $this->setHeaders();
+
+ $this->groupId = $request->getText( 'group', $par );
+ $this->language = $request->getVal( 'language', $lang->getCode() );
+ $this->format = $request->getText( 'format' );
+
+ $this->outputForm();
+
+ if ( $this->groupId ) {
+ $status = $this->checkInput();
+ if ( !$status->isGood() ) {
+ TranslateUtils::wrapWikiTextAsInterface(
+ $out, 'error',
+ $status->getWikiText( false, false, $lang )
+ );
+ return;
+ }
+
+ $this->doExport();
+ }
+ }
+
+ protected function outputForm() {
+ $fields = [
+ 'group' => [
+ 'type' => 'select',
+ 'name' => 'group',
+ 'id' => 'group',
+ 'label-message' => 'translate-page-group',
+ 'options' => $this->getGroupOptions(),
+ 'default' => $this->groupId,
+ ],
+ 'language' => [
+ // @todo Apply ULS to this field
+ 'type' => 'select',
+ 'name' => 'language',
+ 'id' => 'language',
+ 'label-message' => 'translate-page-language',
+ 'options' => $this->getLanguageOptions(),
+ 'default' => $this->language,
+ ],
+ 'format' => [
+ 'type' => 'radio',
+ 'name' => 'format',
+ 'id' => 'format',
+ 'label-message' => 'translate-export-form-format',
+ 'flatlist' => true,
+ 'options' => $this->getFormatOptions(),
+ 'default' => $this->format,
+ ],
+ ];
+ $form = HTMLForm::factory( 'ooui', $fields, $this->getContext() );
+ $form
+ ->setMethod( 'get' )
+ ->setWrapperLegendMsg( 'translate-page-settings-legend' )
+ ->setSubmitTextMsg( 'translate-submit' )
+ ->prepareForm()
+ ->displayForm( false );
+ }
+
+ /**
+ * @return array
+ */
+ protected function getGroupOptions() {
+ $selected = $this->groupId;
+ $groups = MessageGroups::getAllGroups();
+ uasort( $groups, [ 'MessageGroups', 'groupLabelSort' ] );
+
+ $options = [];
+ foreach ( $groups as $id => $group ) {
+ if ( !$group->exists()
+ || ( MessageGroups::getPriority( $group ) === 'discouraged' && $id !== $selected )
+ ) {
+ continue;
+ }
+
+ $options[$group->getLabel()] = $id;
+ }
+
+ return $options;
+ }
+
+ /**
+ * @return array
+ */
+ protected function getLanguageOptions() {
+ $languages = TranslateUtils::getLanguageNames( 'en' );
+ $options = [];
+ foreach ( $languages as $code => $name ) {
+ $options["$code - $name"] = $code;
+ }
+
+ return $options;
+ }
+
+ /**
+ * @return array
+ */
+ protected function getFormatOptions() {
+ $options = [];
+ foreach ( self::$validFormats as $format ) {
+ // translate-taskui-export-to-file, translate-taskui-export-as-po
+ $options[ $this->msg( "translate-taskui-$format" )->escaped() ] = $format;
+ }
+ return $options;
+ }
+
+ /**
+ * @return Status
+ */
+ protected function checkInput() {
+ $status = Status::newGood();
+
+ $msgGroup = MessageGroups::getGroup( $this->groupId );
+ if ( $msgGroup === null ) {
+ $status->fatal( 'translate-page-no-such-group' );
+ } elseif ( MessageGroups::isDynamic( $msgGroup ) ) {
+ $status->fatal( 'translate-export-not-supported' );
+ }
+
+ $langNames = TranslateUtils::getLanguageNames( 'en' );
+ if ( !isset( $langNames[$this->language] ) ) {
+ $status->fatal( 'translate-page-no-such-language' );
+ }
+
+ // Do not show this error if no/invalid format is specified for translatable
+ // page groups as we can show a textarea box containing the translation page text
+ // (however it's not currently supported for other groups).
+ if ( !$msgGroup instanceof WikiPageMessageGroup
+ && !in_array( $this->format, self::$validFormats )
+ ) {
+ $status->fatal( 'translate-export-invalid-format' );
+ }
+
+ if ( $this->format === 'export-to-file'
+ && !$msgGroup instanceof FileBasedMessageGroup
+ ) {
+ $status->fatal( 'translate-export-format-notsupported' );
+ }
+
+ return $status;
+ }
+
+ protected function doExport() {
+ $out = $this->getOutput();
+ $group = MessageGroups::getGroup( $this->groupId );
+ $collection = $this->setupCollection( $group );
+
+ switch ( $this->format ) {
+ case 'export-as-po':
+ $out->disable();
+
+ $ffs = null;
+ if ( $group instanceof FileBasedMessageGroup ) {
+ $ffs = $group->getFFS();
+ }
+
+ if ( !$ffs instanceof GettextFFS ) {
+ $group = FileBasedMessageGroup::newFromMessageGroup( $group );
+ $ffs = new GettextFFS( $group );
+ }
+
+ $ffs->setOfflineMode( true );
+
+ $filename = "{$group->getId()}_{$this->language}.po";
+ $this->sendExportHeaders( $filename );
+
+ echo $ffs->writeIntoVariable( $collection );
+ break;
+
+ case 'export-to-file':
+ $out->disable();
+
+ $filename = basename( $group->getSourceFilePath( $collection->getLanguage() ) );
+ $this->sendExportHeaders( $filename );
+
+ echo $group->getFFS()->writeIntoVariable( $collection );
+ break;
+
+ default:
+ // @todo Add web viewing for groups other than WikiPageMessageGroup
+ $pageTranslation = $this->getConfig()->get( 'EnablePageTranslation' );
+ if ( $pageTranslation && $group instanceof WikiPageMessageGroup ) {
+ $collection->loadTranslations();
+ $page = TranslatablePage::newFromTitle( $group->getTitle() );
+ $text = $page->getParse()->getTranslationPageText( $collection );
+ $displayTitle = $page->getPageDisplayTitle( $this->language );
+ if ( $displayTitle ) {
+ $text = "{{DISPLAYTITLE:$displayTitle}}$text";
+ }
+ $box = Html::element(
+ 'textarea',
+ [ 'id' => 'wpTextbox', 'rows' => 40, ],
+ $text
+ );
+ $out->addHTML( $box );
+ return;
+ }
+
+ // This should have been prevented at validation. See checkInput().
+ throw new Exception( 'Unexpected export format.' );
+ }
+ }
+
+ private function setupCollection( MessageGroup $group ) {
+ $collection = $group->initCollection( $this->language );
+
+ // Don't export ignored, unless it is the source language or message documentation
+ $translateDocCode = $this->getConfig()->get( 'TranslateDocumentationLanguageCode' );
+ if ( $this->language !== $translateDocCode
+ && $this->language !== $group->getSourceLanguage()
+ ) {
+ $collection->filter( 'ignored' );
+ }
+
+ $collection->loadTranslations();
+
+ return $collection;
+ }
+
+ /**
+ * Send the appropriate response headers for the export
+ *
+ * @param string $fileName
+ */
+ protected function sendExportHeaders( $fileName ) {
+ $response = $this->getRequest()->response();
+ $response->header( 'Content-Type: text/plain; charset=UTF-8' );
+ $response->header( "Content-Disposition: attachment; filename=\"$fileName\"" );
+ }
+
+ protected function getGroupName() {
+ return 'wiki';
+ }
+}