MediaWiki  master
UploadForm.php
Go to the documentation of this file.
1 <?php
23 
27 class UploadForm extends HTMLForm {
28  protected $mWatch;
29  protected $mForReUpload;
30  protected $mSessionKey;
32  protected $mDestWarningAck;
33  protected $mDestFile;
34 
35  protected $mComment;
37  protected $mTextTop;
39  protected $mTextAfterSummary;
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 = [],
67  IContextSource $context = null,
68  LinkRenderer $linkRenderer = null,
69  LocalRepo $localRepo = null,
71  NamespaceInfo $nsInfo = 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(
184  );
185 
186  $help = $this->msg( 'upload-maxfilesize' )->sizeParams( $this->mMaxUploadSize['file'] )->parse();
187 
188  // If the user can also upload by URL, there are 2 different file size limits.
189  // This extra message helps stress which limit corresponds to what.
190  if ( $canUploadByUrl ) {
191  $help .= $this->msg( 'word-separator' )->escaped();
192  $help .= $this->msg( 'upload_source_file' )->parse();
193  }
194 
195  $descriptor['UploadFile'] = [
196  'class' => UploadSourceField::class,
197  'section' => 'source',
198  'type' => 'file',
199  'id' => 'wpUploadFile',
200  'radio-id' => 'wpSourceTypeFile',
201  'label-message' => 'sourcefilename',
202  'upload-type' => 'File',
203  'radio' => &$radio,
204  'help' => $help,
205  'checked' => $selectedSourceType == 'file',
206  ];
207 
208  if ( $canUploadByUrl ) {
209  $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
210  $descriptor['UploadFileURL'] = [
211  'class' => UploadSourceField::class,
212  'section' => 'source',
213  'id' => 'wpUploadFileURL',
214  'radio-id' => 'wpSourceTypeurl',
215  'label-message' => 'sourceurl',
216  'upload-type' => 'url',
217  'radio' => &$radio,
218  'help' => $this->msg( 'upload-maxfilesize' )->sizeParams( $this->mMaxUploadSize['url'] )->parse() .
219  $this->msg( 'word-separator' )->escaped() .
220  $this->msg( 'upload_source_url' )->parse(),
221  'checked' => $selectedSourceType == 'url',
222  ];
223  }
224  $this->getHookRunner()->onUploadFormSourceDescriptors(
225  $descriptor, $radio, $selectedSourceType );
226 
227  $descriptor['Extensions'] = [
228  'type' => 'info',
229  'section' => 'source',
230  'default' => $this->getExtensionsMessage(),
231  'raw' => true,
232  ];
233 
234  return $descriptor;
235  }
236 
242  protected function getExtensionsMessage() {
243  # Print a list of allowed file extensions, if so configured. We ignore
244  # MIME type here, it's incomprehensible to most people and too long.
245  $config = $this->getConfig();
246 
247  if ( $config->get( 'CheckFileExtensions' ) ) {
248  $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
249  if ( $config->get( 'StrictFileExtensions' ) ) {
250  # Everything not permitted is banned
251  $extensionsList =
252  '<div id="mw-upload-permitted">' .
253  $this->msg( 'upload-permitted' )
254  ->params( $this->getLanguage()->commaList( $fileExtensions ) )
255  ->numParams( count( $fileExtensions ) )
256  ->parseAsBlock() .
257  "</div>\n";
258  } else {
259  # We have to list both preferred and prohibited
260  $prohibitedExtensions = array_unique( $config->get( 'ProhibitedFileExtensions' ) );
261  $extensionsList =
262  '<div id="mw-upload-preferred">' .
263  $this->msg( 'upload-preferred' )
264  ->params( $this->getLanguage()->commaList( $fileExtensions ) )
265  ->numParams( count( $fileExtensions ) )
266  ->parseAsBlock() .
267  "</div>\n" .
268  '<div id="mw-upload-prohibited">' .
269  $this->msg( 'upload-prohibited' )
270  ->params( $this->getLanguage()->commaList( $prohibitedExtensions ) )
271  ->numParams( count( $prohibitedExtensions ) )
272  ->parseAsBlock() .
273  "</div>\n";
274  }
275  } else {
276  # Everything is permitted.
277  $extensionsList = '';
278  }
279 
280  return $extensionsList;
281  }
282 
289  protected function getDescriptionSection() {
290  $config = $this->getConfig();
291  if ( $this->mSessionKey ) {
292  $stash = $this->localRepo->getUploadStash( $this->getUser() );
293  try {
294  $file = $stash->getFile( $this->mSessionKey );
295  } catch ( Exception $e ) {
296  $file = null;
297  }
298  if ( $file ) {
299  $mto = $file->transform( [ 'width' => 120 ] );
300  if ( $mto ) {
301  $this->addHeaderText(
302  '<div class="thumb t' .
303  $this->contentLanguage->alignEnd() . '">' .
304  Html::element( 'img', [
305  'src' => $mto->getUrl(),
306  'class' => 'thumbimage',
307  ] ) . '</div>', 'description' );
308  }
309  }
310  }
311 
312  $descriptor = [
313  'DestFile' => [
314  'type' => 'text',
315  'section' => 'description',
316  'id' => 'wpDestFile',
317  'label-message' => 'destfilename',
318  'size' => 60,
319  'default' => $this->mDestFile,
320  # @todo FIXME: Hack to work around poor handling of the 'default' option in HTMLForm
321  'nodata' => strval( $this->mDestFile ) !== '',
322  ],
323  'UploadDescription' => [
324  'type' => $this->mForReUpload
325  ? 'text'
326  : 'textarea',
327  'section' => 'description',
328  'id' => 'wpUploadDescription',
329  'label-message' => $this->mForReUpload
330  ? 'filereuploadsummary'
331  : 'fileuploadsummary',
332  'default' => $this->mComment,
333  ]
334  ];
335  if ( $this->mTextAfterSummary ) {
336  $descriptor['UploadFormTextAfterSummary'] = [
337  // @phan-suppress-next-line SecurityCheck-XSS mTextAfterSummary is raw html
338  'type' => 'info',
339  'section' => 'description',
340  'default' => $this->mTextAfterSummary,
341  'raw' => true,
342  ];
343  }
344 
345  $descriptor += [
346  'EditTools' => [
347  'type' => 'edittools',
348  'section' => 'description',
349  'message' => 'edittools-upload',
350  ]
351  ];
352 
353  if ( $this->mForReUpload ) {
354  $descriptor['DestFile']['readonly'] = true;
355  $descriptor['UploadDescription']['size'] = 60;
356  } else {
357  $descriptor['License'] = [
358  'type' => 'select',
359  'class' => Licenses::class,
360  'section' => 'description',
361  'id' => 'wpLicense',
362  'label-message' => 'license',
363  ];
364  $descriptor['UploadDescription']['rows'] = 8;
365  }
366 
367  if ( $config->get( 'UseCopyrightUpload' ) ) {
368  $descriptor['UploadCopyStatus'] = [
369  'type' => 'text',
370  'section' => 'description',
371  'id' => 'wpUploadCopyStatus',
372  'label-message' => 'filestatus',
373  ];
374  $descriptor['UploadSource'] = [
375  'type' => 'text',
376  'section' => 'description',
377  'id' => 'wpUploadSource',
378  'label-message' => 'filesource',
379  ];
380  }
381 
382  return $descriptor;
383  }
384 
391  protected function getOptionsSection() {
392  $user = $this->getUser();
393  if ( $user->isRegistered() ) {
394  $descriptor = [
395  'Watchthis' => [
396  'type' => 'check',
397  'id' => 'wpWatchthis',
398  'label-message' => 'watchthisupload',
399  'section' => 'options',
400  'default' => $this->mWatch,
401  ]
402  ];
403  }
404  if ( !$this->mHideIgnoreWarning ) {
405  $descriptor['IgnoreWarning'] = [
406  'type' => 'check',
407  'id' => 'wpIgnoreWarning',
408  'label-message' => 'ignorewarnings',
409  'section' => 'options',
410  ];
411  }
412 
413  $descriptor['DestFileWarningAck'] = [
414  'type' => 'hidden',
415  'id' => 'wpDestFileWarningAck',
416  'default' => $this->mDestWarningAck ? '1' : '',
417  ];
418 
419  if ( $this->mForReUpload ) {
420  $descriptor['ForReUpload'] = [
421  'type' => 'hidden',
422  'id' => 'wpForReUpload',
423  'default' => '1',
424  ];
425  }
426 
427  return $descriptor;
428  }
429 
434  public function show() {
435  $this->addUploadJS();
436  return parent::show();
437  }
438 
442  protected function addUploadJS() {
443  $config = $this->getConfig();
444 
445  $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
446 
447  $scriptVars = [
448  'wgAjaxUploadDestCheck' => $config->get( 'AjaxUploadDestCheck' ),
449  'wgAjaxLicensePreview' => $config->get( 'AjaxLicensePreview' ),
450  'wgUploadAutoFill' => !$this->mForReUpload &&
451  // If we received mDestFile from the request, don't autofill
452  // the wpDestFile textbox
453  $this->mDestFile === '',
454  'wgUploadSourceIds' => $this->mSourceIds,
455  'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
456  'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
457  'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
458  'wgMaxUploadSize' => $this->mMaxUploadSize,
459  'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
460  ];
461 
462  $out = $this->getOutput();
463  $out->addJsConfigVars( $scriptVars );
464 
465  $out->addModules( [
466  'mediawiki.special.upload', // Extras for thumbnail and license preview.
467  ] );
468  }
469 
475  public function trySubmit() {
476  return false;
477  }
478 }
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:39
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:72
UploadForm\$mMaxUploadSize
array $mMaxUploadSize
Definition: UploadForm.php:46
UploadForm\$mTextTop
string $mTextTop
raw html
Definition: UploadForm.php:37
UploadForm\getDescriptionSection
getDescriptionSection()
Get the descriptor of the fieldset that contains the file description input.
Definition: UploadForm.php:289
HTMLForm\setSubmitName
setSubmitName( $name)
Definition: HTMLForm.php:1442
UploadForm\show
show()
Add the upload JS and show the form.
Definition: UploadForm.php:434
UploadForm\$nsInfo
NamespaceInfo $nsInfo
Definition: UploadForm.php:55
UploadForm\getSourceSection
getSourceSection()
Get the descriptor of the fieldset that contains the file source selection.
Definition: UploadForm.php:150
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:200
HTMLForm\setSubmitTooltip
setSubmitTooltip( $name)
Definition: HTMLForm.php:1453
HTMLForm\addHeaderText
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition: HTMLForm.php:830
UploadForm\$mForReUpload
$mForReUpload
Definition: UploadForm.php:29
true
return true
Definition: router.php:90
MediaWiki\Linker\LinkRenderer
Class that generates HTML links for pages.
Definition: LinkRenderer.php:43
UploadBase\getMaxPhpUploadSize
static getMaxPhpUploadSize()
Get the PHP maximum uploaded file size, based on ini settings.
Definition: UploadBase.php:2227
UploadForm
Sub class of HTMLForm that provides the form section of SpecialUpload.
Definition: UploadForm.php:27
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
UploadForm\$mComment
$mComment
Definition: UploadForm.php:35
ContextSource\getRequest
getRequest()
Definition: ContextSource.php:81
ContextSource\getUser
getUser()
Definition: ContextSource.php:136
UploadForm\$mDestFile
$mDestFile
Definition: UploadForm.php:33
UploadForm\trySubmit
trySubmit()
Empty function; submission is handled elsewhere.
Definition: UploadForm.php:475
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:153
UploadForm\getExtensionsMessage
getExtensionsMessage()
Get the messages indicating which extensions are preferred and prohibitted.
Definition: UploadForm.php:242
UploadForm\$mHideIgnoreWarning
$mHideIgnoreWarning
Definition: UploadForm.php:31
UploadFromUrl\isEnabled
static isEnabled()
Checks if the upload from URL feature is enabled.
Definition: UploadFromUrl.php:63
ContextSource\getOutput
getOutput()
Definition: ContextSource.php:126
UploadFromUrl\isAllowed
static isAllowed(Authority $performer)
Checks if the user is allowed to use the upload-by-URL feature.
Definition: UploadFromUrl.php:50
ContextSource\setContext
setContext(IContextSource $context)
Definition: ContextSource.php:63
UploadForm\addUploadJS
addUploadJS()
Add upload JS to the OutputPage.
Definition: UploadForm.php:442
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:197
UploadForm\$mMaxFileSize
$mMaxFileSize
Definition: UploadForm.php:43
UploadForm\$localRepo
LocalRepo $localRepo
Definition: UploadForm.php:49
UploadForm\$mWatch
$mWatch
Definition: UploadForm.php:28
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:144
HTMLForm\setId
setId( $id)
Definition: HTMLForm.php:1570
SpecialUpload\rotationEnabled
static rotationEnabled()
Should we rotate images in the preview on Special:Upload.
Definition: SpecialUpload.php:907
UploadForm\$contentLanguage
Language $contentLanguage
Definition: UploadForm.php:52
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
UploadBase\getMaxUploadSize
static getMaxUploadSize( $forType=null)
Get MediaWiki's maximum uploaded file size for given type of upload, based on $wgMaxUploadSize.
Definition: UploadBase.php:2206
HTMLForm\setSubmitTextMsg
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1420
UploadForm\$mSourceIds
$mSourceIds
Definition: UploadForm.php:41
UploadForm\$mSessionKey
$mSessionKey
Definition: UploadForm.php:30
UploadForm\__construct
__construct(array $options=[], IContextSource $context=null, LinkRenderer $linkRenderer=null, LocalRepo $localRepo=null, Language $contentLanguage=null, NamespaceInfo $nsInfo=null)
Definition: UploadForm.php:65
HTMLForm\getTitle
getTitle()
Definition: HTMLForm.php:1666
$help
$help
Definition: mcc.php:32
NamespaceInfo
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Definition: NamespaceInfo.php:35
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:232
UploadForm\getOptionsSection
getOptionsSection()
Get the descriptor of the fieldset that contains the upload options, such as "watch this file".
Definition: UploadForm.php:391
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:42
LocalRepo
A repository that stores files in the local filesystem and registers them in the wiki's own database.
Definition: LocalRepo.php:41
HTMLForm\addFooterText
addFooterText( $msg, $section=null)
Add footer text, inside the form.
Definition: HTMLForm.php:886
UploadForm\$mDestWarningAck
$mDestWarningAck
Definition: UploadForm.php:32
UploadForm\$mTextAfterSummary
string $mTextAfterSummary
raw html
Definition: UploadForm.php:39
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:143