Merge "Import: Handle uploads with sha1 starting with 0 properly"
[mediawiki.git] / resources / src / mediawiki / mediawiki.ForeignUpload.js
blob61fb59f609c8c7d378849adbd884acaaea795070
1 ( function ( mw, OO, $ ) {
2         /**
3          * @class mw.ForeignUpload
4          * @extends mw.Upload
5          *
6          * Used to represent an upload in progress on the frontend.
7          *
8          * Subclassed to upload to a foreign API, with no other goodies. Use
9          * this for a generic foreign image repository on your wiki farm.
10          *
11          * Note you can provide the {@link #target target} or not - if the first argument is
12          * an object, we assume you want the default, and treat it as apiconfig
13          * instead.
14          *
15          * @constructor
16          * @param {string} [target] Used to set up the target
17          *     wiki. If not remote, this class behaves identically to mw.Upload (unless further subclassed)
18          *     Use the same names as set in $wgForeignFileRepos for this. Also,
19          *     make sure there is an entry in the $wgForeignUploadTargets array for this name.
20          * @param {Object} [apiconfig] Passed to the constructor of mw.ForeignApi or mw.Api, as needed.
21          */
22         function ForeignUpload( target, apiconfig ) {
23                 var api,
24                         validTargets = mw.config.get( 'wgForeignUploadTargets' ),
25                         upload = this;
27                 if ( typeof target === 'object' ) {
28                         // target probably wasn't passed in, it must
29                         // be apiconfig
30                         apiconfig = target;
31                         target = undefined;
32                 }
34                 // * Use the given `target` first;
35                 // * If not given, fall back to default (first) ForeignUploadTarget;
36                 // * If none is configured, fall back to local uploads.
37                 this.target = target || validTargets[ 0 ] || 'local';
39                 // Now we have several different options.
40                 // If the local wiki is the target, then we can skip a bunch of steps
41                 // and just return an mw.Api object, because we don't need any special
42                 // configuration for that.
43                 // However, if the target is a remote wiki, we must check the API
44                 // to confirm that the target is one that this site is configured to
45                 // support.
46                 if ( this.target === 'local' ) {
47                         // If local uploads were requested, but they are disabled, fail.
48                         if ( !mw.config.get( 'wgEnableUploads' ) ) {
49                                 throw new Error( 'Local uploads are disabled' );
50                         }
51                         // We'll ignore the CORS and centralauth stuff if the target is
52                         // the local wiki.
53                         this.apiPromise = $.Deferred().resolve( new mw.Api( apiconfig ) );
54                 } else {
55                         api = new mw.Api();
56                         this.apiPromise = api.get( {
57                                 action: 'query',
58                                 meta: 'filerepoinfo',
59                                 friprop: [ 'name', 'scriptDirUrl', 'canUpload' ]
60                         } ).then( function ( data ) {
61                                 var i, repo,
62                                         repos = data.query.repos;
64                                 // First pass - try to find the passed-in target and check
65                                 // that it's configured for uploads.
66                                 for ( i in repos ) {
67                                         repo = repos[ i ];
69                                         // Skip repos that are not our target, or if they
70                                         // are the target, cannot be uploaded to.
71                                         if ( repo.name === upload.target && repo.canUpload === '' ) {
72                                                 return new mw.ForeignApi(
73                                                         repo.scriptDirUrl + '/api.php',
74                                                         apiconfig
75                                                 );
76                                         }
77                                 }
79                                 throw new Error( 'Can not upload to requested foreign repo' );
80                         } );
81                 }
83                 // Build the upload object without an API - this class overrides the
84                 // actual API call methods to wait for the apiPromise to resolve
85                 // before continuing.
86                 mw.Upload.call( this, null );
88                 if ( this.target !== 'local' ) {
89                         // Keep these untranslated. We don't know the content language of the foreign wiki, best to
90                         // stick to English in the text.
91                         this.setComment( 'Cross-wiki upload from ' + location.host );
92                 }
93         }
95         OO.inheritClass( ForeignUpload, mw.Upload );
97         /**
98          * @property {string} target
99          * Used to specify the target repository of the upload.
100          *
101          * If you set this to something that isn't 'local', you must be sure to
102          * add that target to $wgForeignUploadTargets in LocalSettings, and the
103          * repository must be set up to use CORS and CentralAuth.
104          *
105          * Most wikis use "shared" to refer to Wikimedia Commons, we assume that
106          * in this class and in the messages linked to it.
107          *
108          * Defaults to the first available foreign upload target,
109          * or to local uploads if no foreign target is configured.
110          */
112         /**
113          * Override from mw.Upload to make sure the API info is found and allowed
114          */
115         ForeignUpload.prototype.upload = function () {
116                 var upload = this;
117                 return this.apiPromise.then( function ( api ) {
118                         upload.api = api;
119                         return mw.Upload.prototype.upload.call( upload );
120                 } );
121         };
123         /**
124          * Override from mw.Upload to make sure the API info is found and allowed
125          */
126         ForeignUpload.prototype.uploadToStash = function () {
127                 var upload = this;
128                 return this.apiPromise.then( function ( api ) {
129                         upload.api = api;
130                         return mw.Upload.prototype.uploadToStash.call( upload );
131                 } );
132         };
134         mw.ForeignUpload = ForeignUpload;
135 }( mediaWiki, OO, jQuery ) );