TTO has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/84194


Change subject: Allow two-tier setup of transwiki import sources
......................................................................

Allow two-tier setup of transwiki import sources

There has been some demand, particularly in the Wikimedia cluster, for the
ability to import from any wiki of a cluster. For this to occur, the
transwiki import user interface needs a bit of a rethink.

This patch replaces the existing single dropdown with a pair of dropdowns:
the first to select the wiki project, and the second to select the
subproject (e.g. a Wikipedia/Wiktionary language, or a Wikia site).
The second one is optional (to support single-wiki sites like Meta, or
for backwards compatibility with existing setups).

$wgImportSources is now treated as a mixed array/associated array (see
comment in DefaultSettings.php). Existing configurations will still work
but will receive no new functionality.

The non-JavaScript fallback is not pretty, but (a) it works, (b) I don't
see an easy way to make it nicer, and (c) wiki sysops should probably be
using a JavaScript-enabled browser for admin actions like importing...

The intention is to alter the WMF configuration to automatically populate
$wgImportSources with all public cluster wikis. I'm not exactly sure how
this will be set up, but this patch is an important first step. I expect
some non-WMF users of MediaWiki will find it helpful as well.

Change-Id: Icdb655500c1ae5374dc7a9f4d99e6738b2269b14
---
M includes/DefaultSettings.php
M includes/specials/SpecialImport.php
M languages/messages/MessagesEn.php
M maintenance/language/messages.inc
M resources/Resources.php
A resources/mediawiki.special/mediawiki.special.import.js
6 files changed, 141 insertions(+), 18 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/94/84194/1

diff --git a/includes/DefaultSettings.php b/includes/DefaultSettings.php
index 22b7f1e..5c0d3c3 100644
--- a/includes/DefaultSettings.php
+++ b/includes/DefaultSettings.php
@@ -5716,6 +5716,17 @@
  * Special:Import (for sysops). Since complete page history can be imported,
  * these should be 'trusted'.
  *
+ * This can either be a regular array, or an associative map specifying
+ * subprojects on the interwiki map of the target wiki, or a mix of the two,
+ * e.g.
+ * @code
+ *     $wgImportSources = array(
+ *         'wikipedia' => array( 'cs', 'en', 'fr', 'zh' ),
+ *         'wikispecies',
+ *         'wikia' => array( 'animanga', 'brickipedia', 'desserts' ),
+ *     );
+ * @endcode
+ *
  * If a user has the 'import' permission but not the 'importupload' permission,
  * they will only be able to run imports through this transwiki interface.
  */
diff --git a/includes/specials/SpecialImport.php 
b/includes/specials/SpecialImport.php
index 0d54bb3..d926345 100644
--- a/includes/specials/SpecialImport.php
+++ b/includes/specials/SpecialImport.php
@@ -31,6 +31,7 @@
  */
 class SpecialImport extends SpecialPage {
        private $interwiki = false;
+       private $subproject;
        private $namespace;
        private $rootpage = '';
        private $frompage = '';
@@ -54,6 +55,8 @@
        function execute( $par ) {
                $this->setHeaders();
                $this->outputHeader();
+
+               $this->getOutput()->addModules( 'mediawiki.special.import' );
 
                $user = $this->getUser();
                if ( !$user->isAllowedAny( 'import', 'importupload' ) ) {
@@ -117,18 +120,27 @@
                                throw new PermissionsError( 'import' );
                        }
                        $this->interwiki = $request->getVal( 'interwiki' );
-                       if ( !in_array( $this->interwiki, $wgImportSources ) ) {
+                       // does this interwiki have subprojects?
+                       $hasSubprojects = array_key_exists( $this->interwiki, 
$wgImportSources );
+                       if ( !$hasSubprojects && !in_array( $this->interwiki, 
$wgImportSources ) ) {
                                $source = Status::newFatal( 
"import-invalid-interwiki" );
                        } else {
-                               $this->history = $request->getCheck( 
'interwikiHistory' );
-                               $this->frompage = $request->getText( "frompage" 
);
-                               $this->includeTemplates = $request->getCheck( 
'interwikiTemplates' );
-                               $source = ImportStreamSource::newFromInterwiki(
-                                       $this->interwiki,
-                                       $this->frompage,
-                                       $this->history,
-                                       $this->includeTemplates,
-                                       $this->pageLinkDepth );
+                               if ( $hasSubprojects ) {
+                                       $this->subproject = $request->getVal( 
'subproject' );
+                               }
+                               if ( $hasSubprojects && !in_array( 
$this->subproject, $wgImportSources[$this->interwiki] ) ) {
+                                       $source = Status::newFatal( 
"import-invalid-interwiki" );
+                               } else {
+                                       $this->history = $request->getCheck( 
'interwikiHistory' );
+                                       $this->frompage = $request->getText( 
"frompage" );
+                                       $this->includeTemplates = 
$request->getCheck( 'interwikiTemplates' );
+                                       $source = 
ImportStreamSource::newFromInterwiki(
+                                               $this->interwiki . ( 
$this->subproject ? ( ':' . $this->subproject ) : '' ),
+                                               $this->frompage,
+                                               $this->history,
+                                               $this->includeTemplates,
+                                               $this->pageLinkDepth );
+                               }
                        }
                } else {
                        $source = Status::newFatal( "importunknownsource" );
@@ -166,7 +178,7 @@
                        $reporter = new ImportReporter(
                                $importer,
                                $isUpload,
-                               $this->interwiki,
+                               $this->interwiki . ( $this->subproject ? ( ':' 
. $this->subproject ) : '' ),
                                $this->logcomment
                        );
                        $reporter->setContext( $this->getContext() );
@@ -297,7 +309,7 @@
                                        Xml::openElement( 'table', array( 'id' 
=> 'mw-import-table-interwiki' ) ) .
                                        "<tr>
                                        <td class='mw-label'>" .
-                                       Xml::label( $this->msg( 
'import-interwiki-source' )->text(), 'interwiki' ) .
+                                       Xml::label( $this->msg( 
'import-interwiki-sourcewiki' )->text(), 'interwiki' ) .
                                        "</td>
                                        <td class='mw-input'>" .
                                        Xml::openElement(
@@ -306,13 +318,63 @@
                                        )
                        );
 
-                       foreach ( $wgImportSources as $prefix ) {
-                               $selected = ( $this->interwiki === $prefix ) ? 
' selected="selected"' : '';
-                               $out->addHTML( Xml::option( $prefix, $prefix, 
$selected ) );
+                       $needSubprojectField = false;
+                       foreach ( $wgImportSources as $key => $value ) {
+                               if ( is_int( $key ) ) {
+                                       $key = $value;
+                               } else if ( $value !== $key ) {
+                                       $needSubprojectField = true;
+                               }
+
+                               $attribs = array( 
+                                       'value' => $key,
+                               );
+                               if ( is_array( $value ) ) {
+                                       $attribs['data-subprojects'] = implode( 
' ', $value );
+                               }
+                               if ( $this->interwiki === $key ) {
+                                       $attribs['selected'] = 'selected';
+                               }
+                               $out->addHTML( Html::element( 'option', 
$attribs, $key ) );
                        }
 
                        $out->addHTML(
-                               Xml::closeElement( 'select' ) .
+                               Xml::closeElement( 'select' )
+                       );
+
+                       if ( $needSubprojectField ) {
+                               $out->addHTML(
+                                       Xml::openElement(
+                                               'select',
+                                               array( 'name' => 'subproject', 
'id' => 'subproject' )
+                                       )
+                               );
+
+                               $subprojectsToAdd = array();
+                               foreach ( $wgImportSources as $key => $value ) {
+                                       if ( is_array( $value ) ) {
+                                               $subprojectsToAdd = 
array_merge( $subprojectsToAdd, $value );
+                                       }
+                               }
+                               $subprojectsToAdd = array_unique( 
$subprojectsToAdd );
+                               sort( $subprojectsToAdd );
+                               foreach ( $subprojectsToAdd as $subproject ) {
+                                       $out->addHTML( Xml::option( 
$subproject, $subproject, $this->subproject === $subproject ) );
+                               }
+
+                               $out->addHTML(
+                                       Xml::closeElement( 'select' )
+                               );
+                       }
+
+                       $out->addHTML(
+                                       "</td>
+                               </tr>
+                               <tr>
+                                       <td class='mw-label'>" .
+                                       Xml::label( $this->msg( 
'import-interwiki-sourcepage' )->text(), 'frompage' ) .
+                                       "</td>
+                                       <td class='mw-input'>" .
                                        Xml::input( 'frompage', 50, 
$this->frompage, array( 'id' => 'frompage' ) ) .
                                        "</td>
                                </tr>
diff --git a/languages/messages/MessagesEn.php 
b/languages/messages/MessagesEn.php
index 9e7d4c2..4e3ec98 100644
--- a/languages/messages/MessagesEn.php
+++ b/languages/messages/MessagesEn.php
@@ -3589,7 +3589,8 @@
 'import-interwiki-text'      => "Select a wiki and page title to import.
 Revision dates and editors' names will be preserved.
 All transwiki import actions are logged at the [[Special:Log/import|import 
log]].",
-'import-interwiki-source'    => 'Source wiki/page:',
+'import-interwiki-sourcewiki' => 'Source wiki:',
+'import-interwiki-sourcepage' => 'Source page:',
 'import-interwiki-history'   => 'Copy all history revisions for this page',
 'import-interwiki-templates' => 'Include all templates',
 'import-interwiki-submit'    => 'Import',
diff --git a/maintenance/language/messages.inc 
b/maintenance/language/messages.inc
index b2db694..53069a7 100644
--- a/maintenance/language/messages.inc
+++ b/maintenance/language/messages.inc
@@ -2523,7 +2523,8 @@
                'import-summary',
                'importinterwiki',
                'import-interwiki-text',
-               'import-interwiki-source',
+               'import-interwiki-sourcewiki',
+               'import-interwiki-sourcepage',
                'import-interwiki-history',
                'import-interwiki-templates',
                'import-interwiki-submit',
diff --git a/resources/Resources.php b/resources/Resources.php
index 7850d03..3faa385 100644
--- a/resources/Resources.php
+++ b/resources/Resources.php
@@ -962,6 +962,9 @@
        'mediawiki.special.changeslist.enhanced' => array(
                'styles' => 
'resources/mediawiki.special/mediawiki.special.changeslist.enhanced.css',
        ),
+       'mediawiki.special.import' => array(
+               'scripts' => 
'resources/mediawiki.special/mediawiki.special.import.js',
+       ),
        'mediawiki.special.movePage' => array(
                'scripts' => 
'resources/mediawiki.special/mediawiki.special.movePage.js',
                'dependencies' => 'jquery.byteLimit',
diff --git a/resources/mediawiki.special/mediawiki.special.import.js 
b/resources/mediawiki.special/mediawiki.special.import.js
new file mode 100644
index 0000000..0283032
--- /dev/null
+++ b/resources/mediawiki.special/mediawiki.special.import.js
@@ -0,0 +1,45 @@
+/**
+ * JavaScript for Special:Import
+ */
+( function ( $ ) {
+       function updateImportSubprojectList( ) {
+               var $projectField = $( '#mw-import-table-interwiki #interwiki' 
),
+                       $subprojectField = $projectField.parent( ).find( 
'#subproject' );
+
+               var $selected = $projectField.find( ':selected' );
+               if ( $selected.attr( 'data-subprojects' ) ) {
+                       /*$subprojectField.show( ).children( ).each( function( 
key, value ) {
+                               var $value = $( value );
+                               if ( subprojects.indexOf( $value.val( ) ) === 
-1 ) {
+                                       $value.hide( );
+                                       if ( $value.val( ) === 
$subprojectField.val( ) ) {
+                                               $subprojectField.val( 0 ); // 
reset to first value
+                                       }
+                               } else {
+                                       $value.show( );
+                               }
+                       } );*/
+                       var oldValue = $subprojectField.val( );
+                       var options = $.map( $selected.attr( 'data-subprojects' 
).split( ' ' ), function( el ) {
+                               var option = document.createElement( 'option' );
+                               option.appendChild( document.createTextNode( el 
) );
+                               option.setAttribute( 'value', el );
+                               if ( oldValue === el ) {
+                                       option.setAttribute( 'selected', 
'selected' );
+                               }
+                               return option;
+                       } );
+                       $subprojectField.show( ).empty( ).append( options );
+               } else {
+                       $subprojectField.hide( );
+               }
+       }
+
+       $( function () {
+               var $projectField = $( '#mw-import-table-interwiki #interwiki' 
);
+               if ( $projectField.length ) {
+                       $projectField.change( updateImportSubprojectList );
+                       updateImportSubprojectList( );
+               }
+       } );
+}( jQuery ) );

-- 
To view, visit https://gerrit.wikimedia.org/r/84194
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Icdb655500c1ae5374dc7a9f4d99e6738b2269b14
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: TTO <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to