]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/specials/forms/UploadForm.php
MediaWiki 1.30.2
[autoinstallsdev/mediawiki.git] / includes / specials / forms / UploadForm.php
1 <?php
2 /**
3  * This program is free software; you can redistribute it and/or modify
4  * it under the terms of the GNU General Public License as published by
5  * the Free Software Foundation; either version 2 of the License, or
6  * (at your option) any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16  * http://www.gnu.org/copyleft/gpl.html
17  *
18  * @file
19  */
20
21 use MediaWiki\Linker\LinkRenderer;
22 use MediaWiki\MediaWikiServices;
23
24 /**
25  * Sub class of HTMLForm that provides the form section of SpecialUpload
26  */
27 class UploadForm extends HTMLForm {
28         protected $mWatch;
29         protected $mForReUpload;
30         protected $mSessionKey;
31         protected $mHideIgnoreWarning;
32         protected $mDestWarningAck;
33         protected $mDestFile;
34
35         protected $mComment;
36         protected $mTextTop;
37         protected $mTextAfterSummary;
38
39         protected $mSourceIds;
40
41         protected $mMaxFileSize = [];
42
43         protected $mMaxUploadSize = [];
44
45         public function __construct( array $options = [], IContextSource $context = null,
46                 LinkRenderer $linkRenderer = null
47         ) {
48                 if ( $context instanceof IContextSource ) {
49                         $this->setContext( $context );
50                 }
51
52                 if ( !$linkRenderer ) {
53                         $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
54                 }
55
56                 $this->mWatch = !empty( $options['watch'] );
57                 $this->mForReUpload = !empty( $options['forreupload'] );
58                 $this->mSessionKey = isset( $options['sessionkey'] ) ? $options['sessionkey'] : '';
59                 $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
60                 $this->mDestWarningAck = !empty( $options['destwarningack'] );
61                 $this->mDestFile = isset( $options['destfile'] ) ? $options['destfile'] : '';
62
63                 $this->mComment = isset( $options['description'] ) ?
64                         $options['description'] : '';
65
66                 $this->mTextTop = isset( $options['texttop'] )
67                         ? $options['texttop'] : '';
68
69                 $this->mTextAfterSummary = isset( $options['textaftersummary'] )
70                         ? $options['textaftersummary'] : '';
71
72                 $sourceDescriptor = $this->getSourceSection();
73                 $descriptor = $sourceDescriptor
74                         + $this->getDescriptionSection()
75                         + $this->getOptionsSection();
76
77                 Hooks::run( 'UploadFormInitDescriptor', [ &$descriptor ] );
78                 parent::__construct( $descriptor, $context, 'upload' );
79
80                 # Add a link to edit MediaWiki:Licenses
81                 if ( $this->getUser()->isAllowed( 'editinterface' ) ) {
82                         $this->getOutput()->addModuleStyles( 'mediawiki.special.upload.styles' );
83                         $licensesLink = $linkRenderer->makeKnownLink(
84                                 $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
85                                 $this->msg( 'licenses-edit' )->text(),
86                                 [],
87                                 [ 'action' => 'edit' ]
88                         );
89                         $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
90                         $this->addFooterText( $editLicenses, 'description' );
91                 }
92
93                 # Set some form properties
94                 $this->setSubmitText( $this->msg( 'uploadbtn' )->text() );
95                 $this->setSubmitName( 'wpUpload' );
96                 # Used message keys: 'accesskey-upload', 'tooltip-upload'
97                 $this->setSubmitTooltip( 'upload' );
98                 $this->setId( 'mw-upload-form' );
99
100                 # Build a list of IDs for javascript insertion
101                 $this->mSourceIds = [];
102                 foreach ( $sourceDescriptor as $field ) {
103                         if ( !empty( $field['id'] ) ) {
104                                 $this->mSourceIds[] = $field['id'];
105                         }
106                 }
107         }
108
109         /**
110          * Get the descriptor of the fieldset that contains the file source
111          * selection. The section is 'source'
112          *
113          * @return array Descriptor array
114          */
115         protected function getSourceSection() {
116                 if ( $this->mSessionKey ) {
117                         return [
118                                 'SessionKey' => [
119                                         'type' => 'hidden',
120                                         'default' => $this->mSessionKey,
121                                 ],
122                                 'SourceType' => [
123                                         'type' => 'hidden',
124                                         'default' => 'Stash',
125                                 ],
126                         ];
127                 }
128
129                 $canUploadByUrl = UploadFromUrl::isEnabled()
130                         && ( UploadFromUrl::isAllowed( $this->getUser() ) === true )
131                         && $this->getConfig()->get( 'CopyUploadsFromSpecialUpload' );
132                 $radio = $canUploadByUrl;
133                 $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
134
135                 $descriptor = [];
136                 if ( $this->mTextTop ) {
137                         $descriptor['UploadFormTextTop'] = [
138                                 'type' => 'info',
139                                 'section' => 'source',
140                                 'default' => $this->mTextTop,
141                                 'raw' => true,
142                         ];
143                 }
144
145                 $this->mMaxUploadSize['file'] = min(
146                         UploadBase::getMaxUploadSize( 'file' ),
147                         UploadBase::getMaxPhpUploadSize()
148                 );
149
150                 $help = $this->msg( 'upload-maxfilesize',
151                                 $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['file'] )
152                         )->parse();
153
154                 // If the user can also upload by URL, there are 2 different file size limits.
155                 // This extra message helps stress which limit corresponds to what.
156                 if ( $canUploadByUrl ) {
157                         $help .= $this->msg( 'word-separator' )->escaped();
158                         $help .= $this->msg( 'upload_source_file' )->parse();
159                 }
160
161                 $descriptor['UploadFile'] = [
162                         'class' => 'UploadSourceField',
163                         'section' => 'source',
164                         'type' => 'file',
165                         'id' => 'wpUploadFile',
166                         'radio-id' => 'wpSourceTypeFile',
167                         'label-message' => 'sourcefilename',
168                         'upload-type' => 'File',
169                         'radio' => &$radio,
170                         'help' => $help,
171                         'checked' => $selectedSourceType == 'file',
172                 ];
173
174                 if ( $canUploadByUrl ) {
175                         $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
176                         $descriptor['UploadFileURL'] = [
177                                 'class' => 'UploadSourceField',
178                                 'section' => 'source',
179                                 'id' => 'wpUploadFileURL',
180                                 'radio-id' => 'wpSourceTypeurl',
181                                 'label-message' => 'sourceurl',
182                                 'upload-type' => 'url',
183                                 'radio' => &$radio,
184                                 'help' => $this->msg( 'upload-maxfilesize',
185                                         $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['url'] )
186                                 )->parse() .
187                                         $this->msg( 'word-separator' )->escaped() .
188                                         $this->msg( 'upload_source_url' )->parse(),
189                                 'checked' => $selectedSourceType == 'url',
190                         ];
191                 }
192                 Hooks::run( 'UploadFormSourceDescriptors', [ &$descriptor, &$radio, $selectedSourceType ] );
193
194                 $descriptor['Extensions'] = [
195                         'type' => 'info',
196                         'section' => 'source',
197                         'default' => $this->getExtensionsMessage(),
198                         'raw' => true,
199                 ];
200
201                 return $descriptor;
202         }
203
204         /**
205          * Get the messages indicating which extensions are preferred and prohibitted.
206          *
207          * @return string HTML string containing the message
208          */
209         protected function getExtensionsMessage() {
210                 # Print a list of allowed file extensions, if so configured.  We ignore
211                 # MIME type here, it's incomprehensible to most people and too long.
212                 $config = $this->getConfig();
213
214                 if ( $config->get( 'CheckFileExtensions' ) ) {
215                         $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
216                         if ( $config->get( 'StrictFileExtensions' ) ) {
217                                 # Everything not permitted is banned
218                                 $extensionsList =
219                                         '<div id="mw-upload-permitted">' .
220                                         $this->msg( 'upload-permitted' )
221                                                 ->params( $this->getLanguage()->commaList( $fileExtensions ) )
222                                                 ->numParams( count( $fileExtensions ) )
223                                                 ->parseAsBlock() .
224                                         "</div>\n";
225                         } else {
226                                 # We have to list both preferred and prohibited
227                                 $fileBlacklist = array_unique( $config->get( 'FileBlacklist' ) );
228                                 $extensionsList =
229                                         '<div id="mw-upload-preferred">' .
230                                                 $this->msg( 'upload-preferred' )
231                                                         ->params( $this->getLanguage()->commaList( $fileExtensions ) )
232                                                         ->numParams( count( $fileExtensions ) )
233                                                         ->parseAsBlock() .
234                                         "</div>\n" .
235                                         '<div id="mw-upload-prohibited">' .
236                                                 $this->msg( 'upload-prohibited' )
237                                                         ->params( $this->getLanguage()->commaList( $fileBlacklist ) )
238                                                         ->numParams( count( $fileBlacklist ) )
239                                                         ->parseAsBlock() .
240                                         "</div>\n";
241                         }
242                 } else {
243                         # Everything is permitted.
244                         $extensionsList = '';
245                 }
246
247                 return $extensionsList;
248         }
249
250         /**
251          * Get the descriptor of the fieldset that contains the file description
252          * input. The section is 'description'
253          *
254          * @return array Descriptor array
255          */
256         protected function getDescriptionSection() {
257                 $config = $this->getConfig();
258                 if ( $this->mSessionKey ) {
259                         $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $this->getUser() );
260                         try {
261                                 $file = $stash->getFile( $this->mSessionKey );
262                         } catch ( Exception $e ) {
263                                 $file = null;
264                         }
265                         if ( $file ) {
266                                 global $wgContLang;
267
268                                 $mto = $file->transform( [ 'width' => 120 ] );
269                                 if ( $mto ) {
270                                         $this->addHeaderText(
271                                                 '<div class="thumb t' . $wgContLang->alignEnd() . '">' .
272                                                 Html::element( 'img', [
273                                                         'src' => $mto->getUrl(),
274                                                         'class' => 'thumbimage',
275                                                 ] ) . '</div>', 'description' );
276                                 }
277                         }
278                 }
279
280                 $descriptor = [
281                         'DestFile' => [
282                                 'type' => 'text',
283                                 'section' => 'description',
284                                 'id' => 'wpDestFile',
285                                 'label-message' => 'destfilename',
286                                 'size' => 60,
287                                 'default' => $this->mDestFile,
288                                 # @todo FIXME: Hack to work around poor handling of the 'default' option in HTMLForm
289                                 'nodata' => strval( $this->mDestFile ) !== '',
290                         ],
291                         'UploadDescription' => [
292                                 'type' => 'textarea',
293                                 'section' => 'description',
294                                 'id' => 'wpUploadDescription',
295                                 'label-message' => $this->mForReUpload
296                                         ? 'filereuploadsummary'
297                                         : 'fileuploadsummary',
298                                 'default' => $this->mComment,
299                                 'cols' => 80,
300                                 'rows' => 8,
301                         ]
302                 ];
303                 if ( $this->mTextAfterSummary ) {
304                         $descriptor['UploadFormTextAfterSummary'] = [
305                                 'type' => 'info',
306                                 'section' => 'description',
307                                 'default' => $this->mTextAfterSummary,
308                                 'raw' => true,
309                         ];
310                 }
311
312                 $descriptor += [
313                         'EditTools' => [
314                                 'type' => 'edittools',
315                                 'section' => 'description',
316                                 'message' => 'edittools-upload',
317                         ]
318                 ];
319
320                 if ( $this->mForReUpload ) {
321                         $descriptor['DestFile']['readonly'] = true;
322                 } else {
323                         $descriptor['License'] = [
324                                 'type' => 'select',
325                                 'class' => 'Licenses',
326                                 'section' => 'description',
327                                 'id' => 'wpLicense',
328                                 'label-message' => 'license',
329                         ];
330                 }
331
332                 if ( $config->get( 'UseCopyrightUpload' ) ) {
333                         $descriptor['UploadCopyStatus'] = [
334                                 'type' => 'text',
335                                 'section' => 'description',
336                                 'id' => 'wpUploadCopyStatus',
337                                 'label-message' => 'filestatus',
338                         ];
339                         $descriptor['UploadSource'] = [
340                                 'type' => 'text',
341                                 'section' => 'description',
342                                 'id' => 'wpUploadSource',
343                                 'label-message' => 'filesource',
344                         ];
345                 }
346
347                 return $descriptor;
348         }
349
350         /**
351          * Get the descriptor of the fieldset that contains the upload options,
352          * such as "watch this file". The section is 'options'
353          *
354          * @return array Descriptor array
355          */
356         protected function getOptionsSection() {
357                 $user = $this->getUser();
358                 if ( $user->isLoggedIn() ) {
359                         $descriptor = [
360                                 'Watchthis' => [
361                                         'type' => 'check',
362                                         'id' => 'wpWatchthis',
363                                         'label-message' => 'watchthisupload',
364                                         'section' => 'options',
365                                         'default' => $this->mWatch,
366                                 ]
367                         ];
368                 }
369                 if ( !$this->mHideIgnoreWarning ) {
370                         $descriptor['IgnoreWarning'] = [
371                                 'type' => 'check',
372                                 'id' => 'wpIgnoreWarning',
373                                 'label-message' => 'ignorewarnings',
374                                 'section' => 'options',
375                         ];
376                 }
377
378                 $descriptor['DestFileWarningAck'] = [
379                         'type' => 'hidden',
380                         'id' => 'wpDestFileWarningAck',
381                         'default' => $this->mDestWarningAck ? '1' : '',
382                 ];
383
384                 if ( $this->mForReUpload ) {
385                         $descriptor['ForReUpload'] = [
386                                 'type' => 'hidden',
387                                 'id' => 'wpForReUpload',
388                                 'default' => '1',
389                         ];
390                 }
391
392                 return $descriptor;
393         }
394
395         /**
396          * Add the upload JS and show the form.
397          */
398         public function show() {
399                 $this->addUploadJS();
400                 parent::show();
401         }
402
403         /**
404          * Add upload JS to the OutputPage
405          */
406         protected function addUploadJS() {
407                 $config = $this->getConfig();
408
409                 $useAjaxDestCheck = $config->get( 'UseAjax' ) && $config->get( 'AjaxUploadDestCheck' );
410                 $useAjaxLicensePreview = $config->get( 'UseAjax' ) &&
411                         $config->get( 'AjaxLicensePreview' ) && $config->get( 'EnableAPI' );
412                 $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
413
414                 $scriptVars = [
415                         'wgAjaxUploadDestCheck' => $useAjaxDestCheck,
416                         'wgAjaxLicensePreview' => $useAjaxLicensePreview,
417                         'wgUploadAutoFill' => !$this->mForReUpload &&
418                                 // If we received mDestFile from the request, don't autofill
419                                 // the wpDestFile textbox
420                                 $this->mDestFile === '',
421                         'wgUploadSourceIds' => $this->mSourceIds,
422                         'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
423                         'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
424                         'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
425                         'wgCapitalizeUploads' => MWNamespace::isCapitalized( NS_FILE ),
426                         'wgMaxUploadSize' => $this->mMaxUploadSize,
427                         'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
428                 ];
429
430                 $out = $this->getOutput();
431                 $out->addJsConfigVars( $scriptVars );
432
433                 $out->addModules( [
434                         'mediawiki.special.upload', // Extras for thumbnail and license preview.
435                 ] );
436         }
437
438         /**
439          * Empty function; submission is handled elsewhere.
440          *
441          * @return bool False
442          */
443         function trySubmit() {
444                 return false;
445         }
446 }