MediaWiki REL1_39
UploadForm.php
Go to the documentation of this file.
1<?php
24use Wikimedia\RequestTimeout\TimeoutException;
25
29class UploadForm extends HTMLForm {
30 protected $mWatch;
31 protected $mForReUpload;
32 protected $mSessionKey;
35 protected $mDestFile;
36
37 protected $mComment;
39 protected $mTextTop;
42
43 protected $mSourceIds;
44
45 protected $mMaxFileSize = [];
46
48 protected $mMaxUploadSize = [];
49
51 private $localRepo;
52
54 private $contentLanguage;
55
57 private $nsInfo;
58
67 public function __construct(
68 array $options = [],
69 IContextSource $context = null,
70 LinkRenderer $linkRenderer = null,
71 LocalRepo $localRepo = null,
72 Language $contentLanguage = null,
73 NamespaceInfo $nsInfo = null
74 ) {
75 if ( $context instanceof IContextSource ) {
76 $this->setContext( $context );
77 }
78
79 $services = MediaWikiServices::getInstance();
80 if ( !$linkRenderer ) {
81 $linkRenderer = $services->getLinkRenderer();
82 }
83 if ( !$localRepo ) {
84 $localRepo = $services->getRepoGroup()->getLocalRepo();
85 }
86 if ( !$contentLanguage ) {
87 $contentLanguage = $services->getContentLanguage();
88 }
89 if ( !$nsInfo ) {
90 $nsInfo = $services->getNamespaceInfo();
91 }
92 $this->localRepo = $localRepo;
93 $this->contentLanguage = $contentLanguage;
94 $this->nsInfo = $nsInfo;
95
96 $this->mWatch = !empty( $options['watch'] );
97 $this->mForReUpload = !empty( $options['forreupload'] );
98 $this->mSessionKey = $options['sessionkey'] ?? '';
99 $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
100 $this->mDestWarningAck = !empty( $options['destwarningack'] );
101 $this->mDestFile = $options['destfile'] ?? '';
102
103 $this->mComment = $options['description'] ?? '';
104
105 $this->mTextTop = $options['texttop'] ?? '';
106
107 $this->mTextAfterSummary = $options['textaftersummary'] ?? '';
108
109 $sourceDescriptor = $this->getSourceSection();
110 $descriptor = $sourceDescriptor
111 + $this->getDescriptionSection()
112 + $this->getOptionsSection();
113
114 $this->getHookRunner()->onUploadFormInitDescriptor( $descriptor );
115 parent::__construct( $descriptor, $this->getContext(), 'upload' );
116
117 # Add a link to edit MediaWiki:Licenses
118 if ( $this->getAuthority()->isAllowed( 'editinterface' ) ) {
119 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
120 $licensesLink = $linkRenderer->makeKnownLink(
121 $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
122 $this->msg( 'licenses-edit' )->text(),
123 [],
124 [ 'action' => 'edit' ]
125 );
126 $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
127 $this->addFooterText( $editLicenses, 'description' );
128 }
129
130 # Set some form properties
131 $this->setSubmitTextMsg( 'uploadbtn' );
132 $this->setSubmitName( 'wpUpload' );
133 # Used message keys: 'accesskey-upload', 'tooltip-upload'
134 $this->setSubmitTooltip( 'upload' );
135 $this->setId( 'mw-upload-form' );
136
137 # Build a list of IDs for javascript insertion
138 $this->mSourceIds = [];
139 foreach ( $sourceDescriptor as $field ) {
140 if ( !empty( $field['id'] ) ) {
141 $this->mSourceIds[] = $field['id'];
142 }
143 }
144 }
145
152 protected function getSourceSection() {
153 if ( $this->mSessionKey ) {
154 return [
155 'SessionKey' => [
156 'type' => 'hidden',
157 'default' => $this->mSessionKey,
158 ],
159 'SourceType' => [
160 'type' => 'hidden',
161 'default' => 'Stash',
162 ],
163 ];
164 }
165
166 $canUploadByUrl = UploadFromUrl::isEnabled()
167 && ( UploadFromUrl::isAllowed( $this->getAuthority() ) === true )
168 && $this->getConfig()->get( MainConfigNames::CopyUploadsFromSpecialUpload );
169 $radio = $canUploadByUrl;
170 $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
171
172 $descriptor = [];
173 if ( $this->mTextTop ) {
174 $descriptor['UploadFormTextTop'] = [
175 'type' => 'info',
176 'section' => 'source',
177 'default' => $this->mTextTop,
178 'raw' => true,
179 ];
180 }
181
182 $this->mMaxUploadSize['file'] = min(
183 UploadBase::getMaxUploadSize( 'file' ),
184 UploadBase::getMaxPhpUploadSize()
185 );
186
187 $help = $this->msg( 'upload-maxfilesize' )->sizeParams( $this->mMaxUploadSize['file'] )->parse();
188
189 // If the user can also upload by URL, there are 2 different file size limits.
190 // This extra message helps stress which limit corresponds to what.
191 if ( $canUploadByUrl ) {
192 $help .= $this->msg( 'word-separator' )->escaped();
193 $help .= $this->msg( 'upload_source_file' )->parse();
194 }
195
196 $descriptor['UploadFile'] = [
197 'class' => UploadSourceField::class,
198 'section' => 'source',
199 'type' => 'file',
200 'id' => 'wpUploadFile',
201 'radio-id' => 'wpSourceTypeFile',
202 'label-message' => 'sourcefilename',
203 'upload-type' => 'File',
204 'radio' => &$radio,
205 'help' => $help,
206 'checked' => $selectedSourceType == 'file',
207 ];
208
209 if ( $canUploadByUrl ) {
210 $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
211 $descriptor['UploadFileURL'] = [
212 'class' => UploadSourceField::class,
213 'section' => 'source',
214 'id' => 'wpUploadFileURL',
215 'radio-id' => 'wpSourceTypeurl',
216 'label-message' => 'sourceurl',
217 'upload-type' => 'url',
218 'radio' => &$radio,
219 'help' => $this->msg( 'upload-maxfilesize' )->sizeParams( $this->mMaxUploadSize['url'] )->parse() .
220 $this->msg( 'word-separator' )->escaped() .
221 $this->msg( 'upload_source_url' )->parse(),
222 'checked' => $selectedSourceType == 'url',
223 ];
224 }
225 $this->getHookRunner()->onUploadFormSourceDescriptors(
226 $descriptor, $radio, $selectedSourceType );
227
228 $descriptor['Extensions'] = [
229 'type' => 'info',
230 'section' => 'source',
231 'default' => $this->getExtensionsMessage(),
232 'raw' => true,
233 ];
234
235 return $descriptor;
236 }
237
243 protected function getExtensionsMessage() {
244 # Print a list of allowed file extensions, if so configured. We ignore
245 # MIME type here, it's incomprehensible to most people and too long.
246 $config = $this->getConfig();
247
248 if ( $config->get( MainConfigNames::CheckFileExtensions ) ) {
249 $fileExtensions = array_unique( $config->get( MainConfigNames::FileExtensions ) );
250 if ( $config->get( MainConfigNames::StrictFileExtensions ) ) {
251 # Everything not permitted is banned
252 $extensionsList =
253 '<div id="mw-upload-permitted">' .
254 $this->msg( 'upload-permitted' )
255 ->params( $this->getLanguage()->commaList( $fileExtensions ) )
256 ->numParams( count( $fileExtensions ) )
257 ->parseAsBlock() .
258 "</div>\n";
259 } else {
260 # We have to list both preferred and prohibited
261 $prohibitedExtensions =
262 array_unique( $config->get( MainConfigNames::ProhibitedFileExtensions ) );
263 $extensionsList =
264 '<div id="mw-upload-preferred">' .
265 $this->msg( 'upload-preferred' )
266 ->params( $this->getLanguage()->commaList( $fileExtensions ) )
267 ->numParams( count( $fileExtensions ) )
268 ->parseAsBlock() .
269 "</div>\n" .
270 '<div id="mw-upload-prohibited">' .
271 $this->msg( 'upload-prohibited' )
272 ->params( $this->getLanguage()->commaList( $prohibitedExtensions ) )
273 ->numParams( count( $prohibitedExtensions ) )
274 ->parseAsBlock() .
275 "</div>\n";
276 }
277 } else {
278 # Everything is permitted.
279 $extensionsList = '';
280 }
281
282 return $extensionsList;
283 }
284
291 protected function getDescriptionSection() {
292 $config = $this->getConfig();
293 if ( $this->mSessionKey ) {
294 $stash = $this->localRepo->getUploadStash( $this->getUser() );
295 try {
296 $file = $stash->getFile( $this->mSessionKey );
297 } catch ( TimeoutException $e ) {
298 throw $e;
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 'type' => 'info',
342 'section' => 'description',
343 'default' => $this->mTextAfterSummary,
344 'raw' => true,
345 ];
346 }
347
348 $descriptor += [
349 'EditTools' => [
350 'type' => 'edittools',
351 'section' => 'description',
352 'message' => 'edittools-upload',
353 ]
354 ];
355
356 if ( $this->mForReUpload ) {
357 $descriptor['DestFile']['readonly'] = true;
358 $descriptor['UploadDescription']['size'] = 60;
359 } else {
360 $descriptor['License'] = [
361 'type' => 'select',
362 'class' => Licenses::class,
363 'section' => 'description',
364 'id' => 'wpLicense',
365 'label-message' => 'license',
366 ];
367 $descriptor['UploadDescription']['rows'] = 8;
368 }
369
370 if ( $config->get( MainConfigNames::UseCopyrightUpload ) ) {
371 $descriptor['UploadCopyStatus'] = [
372 'type' => 'text',
373 'section' => 'description',
374 'id' => 'wpUploadCopyStatus',
375 'label-message' => 'filestatus',
376 ];
377 $descriptor['UploadSource'] = [
378 'type' => 'text',
379 'section' => 'description',
380 'id' => 'wpUploadSource',
381 'label-message' => 'filesource',
382 ];
383 }
384
385 return $descriptor;
386 }
387
394 protected function getOptionsSection() {
395 $user = $this->getUser();
396 if ( $user->isRegistered() ) {
397 $descriptor = [
398 'Watchthis' => [
399 'type' => 'check',
400 'id' => 'wpWatchthis',
401 'label-message' => 'watchthisupload',
402 'section' => 'options',
403 'default' => $this->mWatch,
404 ]
405 ];
406 }
407 if ( !$this->mHideIgnoreWarning ) {
408 $descriptor['IgnoreWarning'] = [
409 'type' => 'check',
410 'id' => 'wpIgnoreWarning',
411 'label-message' => 'ignorewarnings',
412 'section' => 'options',
413 ];
414 }
415
416 $descriptor['DestFileWarningAck'] = [
417 'type' => 'hidden',
418 'id' => 'wpDestFileWarningAck',
419 'default' => $this->mDestWarningAck ? '1' : '',
420 ];
421
422 if ( $this->mForReUpload ) {
423 $descriptor['ForReUpload'] = [
424 'type' => 'hidden',
425 'id' => 'wpForReUpload',
426 'default' => '1',
427 ];
428 }
429
430 return $descriptor;
431 }
432
437 public function show() {
438 $this->addUploadJS();
439 return parent::show();
440 }
441
445 protected function addUploadJS() {
446 $config = $this->getConfig();
447
448 $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
449
450 $scriptVars = [
451 'wgAjaxLicensePreview' => $config->get( MainConfigNames::AjaxLicensePreview ),
452 'wgUploadAutoFill' => !$this->mForReUpload &&
453 // If we received mDestFile from the request, don't autofill
454 // the wpDestFile textbox
455 $this->mDestFile === '',
456 'wgUploadSourceIds' => $this->mSourceIds,
457 'wgCheckFileExtensions' => $config->get( MainConfigNames::CheckFileExtensions ),
458 'wgStrictFileExtensions' => $config->get( MainConfigNames::StrictFileExtensions ),
459 'wgFileExtensions' =>
460 array_values( array_unique( $config->get( MainConfigNames::FileExtensions ) ) ),
461 'wgMaxUploadSize' => $this->mMaxUploadSize,
462 'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
463 ];
464
465 $out = $this->getOutput();
466 $out->addJsConfigVars( $scriptVars );
467
468 $out->addModules( [
469 'mediawiki.special.upload', // Extras for thumbnail and license preview.
470 ] );
471 }
472
478 public function trySubmit() {
479 return false;
480 }
481}
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
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:150
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.
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition HTMLForm.php:937
setSubmitTooltip( $name)
Base class for language-specific code.
Definition Language.php:53
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Definition LocalRepo.php:39
Class that generates HTML anchor link elements for pages.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
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
show()
Add the upload JS and show the form.
trySubmit()
Empty function; submission is handled elsewhere.
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 prohibited.
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