1000 for the latter) are now hard-coded.
* $wgDebugDumpSqlLength was removed (deprecated in 1.24).
* $wgDebugDBTransactions was removed (deprecated in 1.20).
+* $wgRemoteUploadTarget (added in 1.26) removed, replaced by $wgForeignUploadTargets
=== New features in 1.27 ===
* $wgDataCenterId and $wgDataCenterRoles where added, which will serve as
$wgUseInstantCommons = false;
/**
- * Name of the remote repository to which users will be allowed to upload
- * files in their editors. Used to find a set of message names to describe
- * the legal requirements for uploading to that wiki, and suggestions for
- * when those requirements are not met.
+ * Array of foreign file repos (set in $wgForeignFileRepos above) that
+ * are allowable upload targets. These wikis must have some method of
+ * authentication (i.e. CentralAuth), and be CORS-enabled for this wiki.
*/
-$wgRemoteUploadTarget = 'default';
+$wgForeignUploadTargets = array();
/**
* File backend structure configuration.
}
public function execute() {
+ $conf = $this->getConfig();
+
$params = $this->extractRequestParams();
$props = array_flip( $params['prop'] );
$repos = array();
$repoGroup = $this->getInitialisedRepoGroup();
+ $foreignTargets = $conf->get( 'ForeignUploadTargets' );
+
+ $repoGroup->forEachForeignRepo( function ( $repo ) use ( &$repos, $props, $foreignTargets ) {
+ $repoProps = $repo->getInfo();
+ $repoProps['canUpload'] = in_array( $repoProps['name'], $foreignTargets );
- $repoGroup->forEachForeignRepo( function ( $repo ) use ( &$repos, $props ) {
- $repos[] = array_intersect_key( $repo->getInfo(), $props );
+ $repos[] = array_intersect_key( $repoProps, $props );
} );
- $repos[] = array_intersect_key( $repoGroup->getLocalRepo()->getInfo(), $props );
+ $localInfo = $repoGroup->getLocalRepo()->getInfo();
+ $localInfo['canUpload'] = $conf->get( 'EnableUploads' );
+ $repos[] = array_intersect_key( $localInfo, $props );
$result = $this->getResult();
ApiResult::setIndexedTagName( $repos, 'repo' );
$props = array_merge( $props, array_keys( $repo->getInfo() ) );
} );
- return array_values( array_unique( array_merge(
+ $propValues = array_values( array_unique( array_merge(
$props,
array_keys( $repoGroup->getLocalRepo()->getInfo() )
) ) );
+
+ $propValues[] = 'canUpload';
+
+ return $propValues;
}
protected function getExamplesMessages() {
'wgResourceLoaderStorageVersion' => $conf->get( 'ResourceLoaderStorageVersion' ),
'wgResourceLoaderStorageEnabled' => $conf->get( 'ResourceLoaderStorageEnabled' ),
'wgResourceLoaderLegacyModules' => self::getLegacyModules(),
- 'wgRemoteUploadTarget' => $conf->get( 'RemoteUploadTarget' ),
+ 'wgForeignUploadTargets' => $conf->get( 'ForeignUploadTargets' ),
);
Hooks::run( 'ResourceLoaderGetConfigVars', array( &$vars ) );
"foreign-structured-upload-form-label-own-work": "This is my own work",
"foreign-structured-upload-form-label-infoform-categories": "Categories",
"foreign-structured-upload-form-label-infoform-date": "Date",
+ "foreign-structured-upload-form-label-own-work-message-local": "I confirm that I am uploading this file following the terms of service and licensing policies on {{SITENAME}}.",
+ "foreign-structured-upload-form-label-not-own-work-message-local": "If you are not able to upload this file under the policies of {{SITENAME}}, please close this dialog and try another method.",
+ "foreign-structured-upload-form-label-not-own-work-local-local": "You may also want to try [[Special:Upload|the default upload page]].",
"foreign-structured-upload-form-label-own-work-message-default": "I understand that I am uploading this file to a shared repository. I confirm that I am doing so following the terms of service and licensing policies there.",
"foreign-structured-upload-form-label-not-own-work-message-default": "If you are not able to upload this file under the policies of the shared repository, please close this dialog and try another method.",
"foreign-structured-upload-form-label-not-own-work-local-default": "You may also want to try using [[Special:Upload|the upload page on {{SITENAME}}]], if this file can be uploaded there under their policies.",
"foreign-structured-upload-form-label-own-work": "Label for own work toggle",
"foreign-structured-upload-form-label-infoform-categories": "Label for category selector input\n{{Identical|Category}}",
"foreign-structured-upload-form-label-infoform-date": "Label for date input\n{{Identical|Date}}",
+ "foreign-structured-upload-form-label-own-work-message-local": "Message shown by local when a user affirms that they are allowed to upload a file to the local wiki.",
+ "foreign-structured-upload-form-label-not-own-work-message-local": "Message shown by local when a user cannot upload a file to the local wiki.",
+ "foreign-structured-upload-form-label-not-own-work-local-local": "Suggests uploading a file via Special:Upload instead of using whatever method they're currently using.",
"foreign-structured-upload-form-label-own-work-message-default": "Message shown by default when a user affirms that they are allowed to upload a file to a remote wiki.",
"foreign-structured-upload-form-label-not-own-work-message-default": "Message shown by default when a user cannot upload a file to a remote wiki.",
- "foreign-structured-upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki. $1 is the name of the local wiki.",
+ "foreign-structured-upload-form-label-not-own-work-local-default": "Suggests uploading a file locally instead of to a remote wiki.",
"foreign-structured-upload-form-label-own-work-message-wikimediacommons": "Legal message to show when the work is made by the uploader.",
"foreign-structured-upload-form-label-not-own-work-message-wikimediacommons": "Message to show when the work isn't owned by the uploader.",
"foreign-structured-upload-form-label-not-own-work-local-wikimediacommons": "Message suggesting the user might want to upload a file locally instead of to Wikimedia Commons. $1 is the name of the local wiki.",
*/
mw.ForeignStructuredUpload.BookletLayout.prototype.renderUploadForm = function () {
var fieldset,
- target = mw.config.get( 'wgRemoteUploadTarget' ),
+ targets = mw.config.get( 'wgForeignUploadTargets' ),
+ // Default to using local, but try to use a configured target.
+ // TODO allow finer configuration of this somehow?
+ target = ( targets && targets.length ) ? targets[ 0 ] : 'local',
$ownWorkMessage = $( '<p>' ).html(
mw.message( 'foreign-structured-upload-form-label-own-work-message-' + target ).parse()
),
-( function ( mw, OO ) {
+( function ( mw, OO, $ ) {
/**
* @class mw.ForeignUpload
* @extends mw.Upload
* instead.
*
* @constructor
- * @param {string} [targetHost="commons.wikimedia.org"] Used to set up the target
+ * @param {string} [target="local"] Used to set up the target
* wiki. If not remote, this class behaves identically to mw.Upload (unless further subclassed)
+ * Use the same names as set in $wgForeignFileRepos for this. Also,
+ * make sure there is an entry in the $wgForeignUploadTargets array
+ * set to "true" for this name.
* @param {Object} [apiconfig] Passed to the constructor of mw.ForeignApi or mw.Api, as needed.
*/
- function ForeignUpload( targetHost, apiconfig ) {
- var api;
+ function ForeignUpload( target, apiconfig ) {
+ var api, upload = this;
- if ( typeof targetHost === 'object' ) {
- // targetHost probably wasn't passed in, it must
+ if ( typeof target === 'object' ) {
+ // target probably wasn't passed in, it must
// be apiconfig
- apiconfig = targetHost;
- } else {
- // targetHost is a useful string, set it here
- this.targetHost = targetHost || this.targetHost;
+ apiconfig = target;
+ target = undefined;
}
- if ( location.host !== this.targetHost ) {
- api = new mw.ForeignApi(
- location.protocol + '//' + this.targetHost + '/w/api.php',
- apiconfig
- );
+ // Resolve defaults etc. - if target isn't passed in, we use
+ // the default.
+ this.target = target || this.target;
+
+ // Now we have several different options.
+ // If the local wiki is the target, then we can skip a bunch of steps
+ // and just return an mw.Api object, because we don't need any special
+ // configuration for that.
+ // However, if the target is a remote wiki, we must check the API
+ // to confirm that the target is one that this site is configured to
+ // support.
+ if ( this.target !== 'local' ) {
+ api = new mw.Api();
+ this.apiPromise = api.get( {
+ action: 'query',
+ meta: 'filerepoinfo',
+ friprop: [ 'name', 'scriptDirUrl', 'canUpload' ]
+ } ).then( function ( data ) {
+ var i, repo,
+ repos = data.query.repos;
+
+ for ( i in repos ) {
+ repo = repos[ i ];
+
+ if ( repo.name === upload.target ) {
+ // This is our target repo.
+ if ( !repo.canUpload ) {
+ // But it's not configured correctly.
+ return $.Deferred().reject( 'repo-cannot-upload' );
+ }
+
+ return new mw.ForeignApi(
+ repo.scriptDirUrl + '/api.php',
+ apiconfig
+ );
+ }
+ }
+ } );
} else {
- // We'll ignore the CORS and centralauth stuff if we're on Commons already
- api = new mw.Api( apiconfig );
+ // We'll ignore the CORS and centralauth stuff if the target is
+ // the local wiki.
+ this.apiPromise = $.Deferred().resolve( new mw.Api( apiconfig ) );
}
- mw.Upload.call( this, api );
+ // Build the upload object without an API - this class overrides the
+ // actual API call methods to wait for the apiPromise to resolve
+ // before continuing.
+ mw.Upload.call( this, null );
}
OO.inheritClass( ForeignUpload, mw.Upload );
* @property targetHost
* Used to specify the target repository of the upload.
*
- * You could override this to point at something that isn't Commons,
- * but be sure it has the correct templates and is CORS and CentralAuth
- * ready.
+ * If you set this to something that isn't 'local', you must be sure to
+ * add that target to $wgForeignUploadTargets in LocalSettings, and the
+ * repository must be set up to use CORS and CentralAuth.
+ */
+ ForeignUpload.prototype.target = 'local';
+
+ /**
+ * Override from mw.Upload to make sure the API info is found and allowed
+ */
+ ForeignUpload.prototype.upload = function () {
+ var upload = this;
+ return this.apiPromise.then( function ( api ) {
+ upload.api = api;
+ return mw.Upload.prototype.upload.call( upload );
+ } );
+ };
+
+ /**
+ * Override from mw.Upload to make sure the API info is found and allowed
*/
- ForeignUpload.prototype.targetHost = 'commons.wikimedia.org';
+ ForeignUpload.prototype.uploadToStash = function () {
+ var upload = this;
+ return this.apiPromise.then( function ( api ) {
+ upload.api = api;
+ return mw.Upload.prototype.uploadToStash.call( upload );
+ } );
+ };
mw.ForeignUpload = ForeignUpload;
-}( mediaWiki, OO ) );
+}( mediaWiki, OO, jQuery ) );
var upload = new mw.ForeignUpload();
assert.ok( upload, 'The ForeignUpload constructor is working.' );
- assert.strictEqual( upload.targetHost, 'commons.wikimedia.org', 'Default target host is correct' );
- assert.ok( upload.api instanceof mw.ForeignApi, 'API is correctly configured to point at a foreign wiki.' );
+ assert.strictEqual( upload.target, 'local', 'Default target host is correct' );
+ assert.ok( upload.api instanceof mw.Api, 'API is local because default target is local.' );
} );
}( mediaWiki ) );