MediaWiki REL1_37
UploadForm.php
Go to the documentation of this file.
1<?php
23
27class UploadForm extends HTMLForm {
28 protected $mWatch;
29 protected $mForReUpload;
30 protected $mSessionKey;
33 protected $mDestFile;
34
35 protected $mComment;
37 protected $mTextTop;
40
41 protected $mSourceIds;
42
43 protected $mMaxFileSize = [];
44
46 protected $mMaxUploadSize = [];
47
49 private $localRepo;
50
53
55 private $nsInfo;
56
65 public function __construct(
66 array $options = [],
68 LinkRenderer $linkRenderer = null,
69 LocalRepo $localRepo = null,
72 ) {
73 if ( $context instanceof IContextSource ) {
74 $this->setContext( $context );
75 }
76
77 $services = MediaWikiServices::getInstance();
78 if ( !$linkRenderer ) {
79 $linkRenderer = $services->getLinkRenderer();
80 }
81 if ( !$localRepo ) {
82 $localRepo = $services->getRepoGroup()->getLocalRepo();
83 }
84 if ( !$contentLanguage ) {
85 $contentLanguage = $services->getContentLanguage();
86 }
87 if ( !$nsInfo ) {
88 $nsInfo = $services->getNamespaceInfo();
89 }
90 $this->localRepo = $localRepo;
91 $this->contentLanguage = $contentLanguage;
92 $this->nsInfo = $nsInfo;
93
94 $this->mWatch = !empty( $options['watch'] );
95 $this->mForReUpload = !empty( $options['forreupload'] );
96 $this->mSessionKey = $options['sessionkey'] ?? '';
97 $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
98 $this->mDestWarningAck = !empty( $options['destwarningack'] );
99 $this->mDestFile = $options['destfile'] ?? '';
100
101 $this->mComment = $options['description'] ?? '';
102
103 $this->mTextTop = $options['texttop'] ?? '';
104
105 $this->mTextAfterSummary = $options['textaftersummary'] ?? '';
106
107 $sourceDescriptor = $this->getSourceSection();
108 $descriptor = $sourceDescriptor
109 + $this->getDescriptionSection()
110 + $this->getOptionsSection();
111
112 $this->getHookRunner()->onUploadFormInitDescriptor( $descriptor );
113 parent::__construct( $descriptor, $context, 'upload' );
114
115 # Add a link to edit MediaWiki:Licenses
116 if ( $this->getAuthority()->isAllowed( 'editinterface' ) ) {
117 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
118 $licensesLink = $linkRenderer->makeKnownLink(
119 $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
120 $this->msg( 'licenses-edit' )->text(),
121 [],
122 [ 'action' => 'edit' ]
123 );
124 $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
125 $this->addFooterText( $editLicenses, 'description' );
126 }
127
128 # Set some form properties
129 $this->setSubmitTextMsg( 'uploadbtn' );
130 $this->setSubmitName( 'wpUpload' );
131 # Used message keys: 'accesskey-upload', 'tooltip-upload'
132 $this->setSubmitTooltip( 'upload' );
133 $this->setId( 'mw-upload-form' );
134
135 # Build a list of IDs for javascript insertion
136 $this->mSourceIds = [];
137 foreach ( $sourceDescriptor as $field ) {
138 if ( !empty( $field['id'] ) ) {
139 $this->mSourceIds[] = $field['id'];
140 }
141 }
142 }
143
150 protected function getSourceSection() {
151 if ( $this->mSessionKey ) {
152 return [
153 'SessionKey' => [
154 'type' => 'hidden',
155 'default' => $this->mSessionKey,
156 ],
157 'SourceType' => [
158 'type' => 'hidden',
159 'default' => 'Stash',
160 ],
161 ];
162 }
163
164 $canUploadByUrl = UploadFromUrl::isEnabled()
165 && ( UploadFromUrl::isAllowed( $this->getUser() ) === true )
166 && $this->getConfig()->get( 'CopyUploadsFromSpecialUpload' );
167 $radio = $canUploadByUrl;
168 $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
169
170 $descriptor = [];
171 if ( $this->mTextTop ) {
172 $descriptor['UploadFormTextTop'] = [
173 // @phan-suppress-next-line SecurityCheck-XSS mTextTop is raw html
174 'type' => 'info',
175 'section' => 'source',
176 'default' => $this->mTextTop,
177 'raw' => true,
178 ];
179 }
180
181 $this->mMaxUploadSize['file'] = min(
182 UploadBase::getMaxUploadSize( 'file' ),
183 UploadBase::getMaxPhpUploadSize()
184 );
185
186 $help = $this->msg( 'upload-maxfilesize',
187 $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['file'] )
188 )->parse();
189
190 // If the user can also upload by URL, there are 2 different file size limits.
191 // This extra message helps stress which limit corresponds to what.
192 if ( $canUploadByUrl ) {
193 $help .= $this->msg( 'word-separator' )->escaped();
194 $help .= $this->msg( 'upload_source_file' )->parse();
195 }
196
197 $descriptor['UploadFile'] = [
198 'class' => UploadSourceField::class,
199 'section' => 'source',
200 'type' => 'file',
201 'id' => 'wpUploadFile',
202 'radio-id' => 'wpSourceTypeFile',
203 'label-message' => 'sourcefilename',
204 'upload-type' => 'File',
205 'radio' => &$radio,
206 'help' => $help,
207 'checked' => $selectedSourceType == 'file',
208 ];
209
210 if ( $canUploadByUrl ) {
211 $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
212 $descriptor['UploadFileURL'] = [
213 'class' => UploadSourceField::class,
214 'section' => 'source',
215 'id' => 'wpUploadFileURL',
216 'radio-id' => 'wpSourceTypeurl',
217 'label-message' => 'sourceurl',
218 'upload-type' => 'url',
219 'radio' => &$radio,
220 'help' => $this->msg( 'upload-maxfilesize',
221 $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['url'] )
222 )->parse() .
223 $this->msg( 'word-separator' )->escaped() .
224 $this->msg( 'upload_source_url' )->parse(),
225 'checked' => $selectedSourceType == 'url',
226 ];
227 }
228 $this->getHookRunner()->onUploadFormSourceDescriptors(
229 $descriptor, $radio, $selectedSourceType );
230
231 $descriptor['Extensions'] = [
232 'type' => 'info',
233 'section' => 'source',
234 'default' => $this->getExtensionsMessage(),
235 'raw' => true,
236 ];
237
238 return $descriptor;
239 }
240
246 protected function getExtensionsMessage() {
247 # Print a list of allowed file extensions, if so configured. We ignore
248 # MIME type here, it's incomprehensible to most people and too long.
249 $config = $this->getConfig();
250
251 if ( $config->get( 'CheckFileExtensions' ) ) {
252 $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
253 if ( $config->get( 'StrictFileExtensions' ) ) {
254 # Everything not permitted is banned
255 $extensionsList =
256 '<div id="mw-upload-permitted">' .
257 $this->msg( 'upload-permitted' )
258 ->params( $this->getLanguage()->commaList( $fileExtensions ) )
259 ->numParams( count( $fileExtensions ) )
260 ->parseAsBlock() .
261 "</div>\n";
262 } else {
263 # We have to list both preferred and prohibited
264 $prohibitedExtensions = array_unique( $config->get( 'ProhibitedFileExtensions' ) );
265 $extensionsList =
266 '<div id="mw-upload-preferred">' .
267 $this->msg( 'upload-preferred' )
268 ->params( $this->getLanguage()->commaList( $fileExtensions ) )
269 ->numParams( count( $fileExtensions ) )
270 ->parseAsBlock() .
271 "</div>\n" .
272 '<div id="mw-upload-prohibited">' .
273 $this->msg( 'upload-prohibited' )
274 ->params( $this->getLanguage()->commaList( $prohibitedExtensions ) )
275 ->numParams( count( $prohibitedExtensions ) )
276 ->parseAsBlock() .
277 "</div>\n";
278 }
279 } else {
280 # Everything is permitted.
281 $extensionsList = '';
282 }
283
284 return $extensionsList;
285 }
286
293 protected function getDescriptionSection() {
294 $config = $this->getConfig();
295 if ( $this->mSessionKey ) {
296 $stash = $this->localRepo->getUploadStash( $this->getUser() );
297 try {
298 $file = $stash->getFile( $this->mSessionKey );
299 } catch ( Exception $e ) {
300 $file = null;
301 }
302 if ( $file ) {
303 $mto = $file->transform( [ 'width' => 120 ] );
304 if ( $mto ) {
305 $this->addHeaderText(
306 '<div class="thumb t' .
307 $this->contentLanguage->alignEnd() . '">' .
308 Html::element( 'img', [
309 'src' => $mto->getUrl(),
310 'class' => 'thumbimage',
311 ] ) . '</div>', 'description' );
312 }
313 }
314 }
315
316 $descriptor = [
317 'DestFile' => [
318 'type' => 'text',
319 'section' => 'description',
320 'id' => 'wpDestFile',
321 'label-message' => 'destfilename',
322 'size' => 60,
323 'default' => $this->mDestFile,
324 # @todo FIXME: Hack to work around poor handling of the 'default' option in HTMLForm
325 'nodata' => strval( $this->mDestFile ) !== '',
326 ],
327 'UploadDescription' => [
328 'type' => $this->mForReUpload
329 ? 'text'
330 : 'textarea',
331 'section' => 'description',
332 'id' => 'wpUploadDescription',
333 'label-message' => $this->mForReUpload
334 ? 'filereuploadsummary'
335 : 'fileuploadsummary',
336 'default' => $this->mComment,
337 ]
338 ];
339 if ( $this->mTextAfterSummary ) {
340 $descriptor['UploadFormTextAfterSummary'] = [
341 // @phan-suppress-next-line SecurityCheck-XSS mTextAfterSummary is raw html
342 'type' => 'info',
343 'section' => 'description',
344 'default' => $this->mTextAfterSummary,
345 'raw' => true,
346 ];
347 }
348
349 $descriptor += [
350 'EditTools' => [
351 'type' => 'edittools',
352 'section' => 'description',
353 'message' => 'edittools-upload',
354 ]
355 ];
356
357 if ( $this->mForReUpload ) {
358 $descriptor['DestFile']['readonly'] = true;
359 $descriptor['UploadDescription']['size'] = 60;
360 } else {
361 $descriptor['License'] = [
362 'type' => 'select',
363 'class' => Licenses::class,
364 'section' => 'description',
365 'id' => 'wpLicense',
366 'label-message' => 'license',
367 ];
368 $descriptor['UploadDescription']['rows'] = 8;
369 }
370
371 if ( $config->get( 'UseCopyrightUpload' ) ) {
372 $descriptor['UploadCopyStatus'] = [
373 'type' => 'text',
374 'section' => 'description',
375 'id' => 'wpUploadCopyStatus',
376 'label-message' => 'filestatus',
377 ];
378 $descriptor['UploadSource'] = [
379 'type' => 'text',
380 'section' => 'description',
381 'id' => 'wpUploadSource',
382 'label-message' => 'filesource',
383 ];
384 }
385
386 return $descriptor;
387 }
388
395 protected function getOptionsSection() {
396 $user = $this->getUser();
397 if ( $user->isRegistered() ) {
398 $descriptor = [
399 'Watchthis' => [
400 'type' => 'check',
401 'id' => 'wpWatchthis',
402 'label-message' => 'watchthisupload',
403 'section' => 'options',
404 'default' => $this->mWatch,
405 ]
406 ];
407 }
408 if ( !$this->mHideIgnoreWarning ) {
409 $descriptor['IgnoreWarning'] = [
410 'type' => 'check',
411 'id' => 'wpIgnoreWarning',
412 'label-message' => 'ignorewarnings',
413 'section' => 'options',
414 ];
415 }
416
417 $descriptor['DestFileWarningAck'] = [
418 'type' => 'hidden',
419 'id' => 'wpDestFileWarningAck',
420 'default' => $this->mDestWarningAck ? '1' : '',
421 ];
422
423 if ( $this->mForReUpload ) {
424 $descriptor['ForReUpload'] = [
425 'type' => 'hidden',
426 'id' => 'wpForReUpload',
427 'default' => '1',
428 ];
429 }
430
431 return $descriptor;
432 }
433
438 public function show() {
439 $this->addUploadJS();
440 return parent::show();
441 }
442
446 protected function addUploadJS() {
447 $config = $this->getConfig();
448
449 $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
450
451 $scriptVars = [
452 'wgAjaxUploadDestCheck' => $config->get( 'AjaxUploadDestCheck' ),
453 'wgAjaxLicensePreview' => $config->get( 'AjaxLicensePreview' ),
454 'wgUploadAutoFill' => !$this->mForReUpload &&
455 // If we received mDestFile from the request, don't autofill
456 // the wpDestFile textbox
457 $this->mDestFile === '',
458 'wgUploadSourceIds' => $this->mSourceIds,
459 'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
460 'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
461 'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
462 'wgCapitalizeUploads' => $this->nsInfo->isCapitalized( NS_FILE ),
463 'wgMaxUploadSize' => $this->mMaxUploadSize,
464 'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
465 ];
466
467 $out = $this->getOutput();
468 $out->addJsConfigVars( $scriptVars );
469
470 $out->addModules( [
471 'mediawiki.special.upload', // Extras for thumbnail and license preview.
472 ] );
473 }
474
480 public function trySubmit() {
481 return false;
482 }
483}
const NS_FILE
Definition Defines.php:70
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
IContextSource $context
getContext()
Get the base IContextSource object.
setContext(IContextSource $context)
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:143
setSubmitName( $name)
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
setId( $id)
addFooterText( $msg, $section=null)
Add footer text, inside the form.
Definition HTMLForm.php:886
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition HTMLForm.php:830
setSubmitTooltip( $name)
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition Language.php:42
A repository that stores files in the local filesystem and registers them in the wiki's own database.
Definition LocalRepo.php:41
Class that generates HTML links for pages.
MediaWikiServices is the service locator for the application scope of MediaWiki.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Sub class of HTMLForm that provides the form section of SpecialUpload.
string $mTextAfterSummary
raw html
Language $contentLanguage
show()
Add the upload JS and show the form.
NamespaceInfo $nsInfo
trySubmit()
Empty function; submission is handled elsewhere.
LocalRepo $localRepo
getDescriptionSection()
Get the descriptor of the fieldset that contains the file description input.
getOptionsSection()
Get the descriptor of the fieldset that contains the upload options, such as "watch this file".
addUploadJS()
Add upload JS to the OutputPage.
__construct(array $options=[], IContextSource $context=null, LinkRenderer $linkRenderer=null, LocalRepo $localRepo=null, Language $contentLanguage=null, NamespaceInfo $nsInfo=null)
getSourceSection()
Get the descriptor of the fieldset that contains the file source selection.
string $mTextTop
raw html
getExtensionsMessage()
Get the messages indicating which extensions are preferred and prohibitted.
array $mMaxUploadSize
static isAllowed(Authority $performer)
Checks if the user is allowed to use the upload-by-URL feature.
static isEnabled()
Checks if the upload from URL feature is enabled.
Interface for objects which can provide a MediaWiki context on request.
$help
Definition mcc.php:32
return true
Definition router.php:92
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42