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->setSubmitText( $this->msg( 'uploadbtn' )->text() );
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',
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  $fileBlacklist = array_unique( $config->get( 'FileBlacklist' ) );
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( $fileBlacklist ) )
275  ->numParams( count( $fileBlacklist ) )
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 }
ContextSource\$context
IContextSource $context
Definition: ContextSource.php:38
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:71
UploadForm\$mMaxUploadSize
array $mMaxUploadSize
Definition: UploadForm.php:46
UploadForm\$mTextTop
string $mTextTop
raw html
Definition: UploadForm.php:37
ContextSource\getContext
getContext()
Get the base IContextSource object.
Definition: ContextSource.php:46
UploadForm\getDescriptionSection
getDescriptionSection()
Get the descriptor of the fieldset that contains the file description input.
Definition: UploadForm.php:293
HTMLForm\setSubmitName
setSubmitName( $name)
Definition: HTMLForm.php:1442
UploadForm\show
show()
Add the upload JS and show the form.
Definition: UploadForm.php:438
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:173
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:826
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:41
UploadBase\getMaxPhpUploadSize
static getMaxPhpUploadSize()
Get the PHP maximum uploaded file size, based on ini settings.
Definition: UploadBase.php:2252
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:80
ContextSource\getUser
getUser()
Definition: ContextSource.php:135
UploadForm\$mDestFile
$mDestFile
Definition: UploadForm.php:33
UploadForm\trySubmit
trySubmit()
Empty function; submission is handled elsewhere.
Definition: UploadForm.php:480
ContextSource\getLanguage
getLanguage()
Definition: ContextSource.php:151
HTMLForm\setSubmitText
setSubmitText( $t)
Set the text for the submit button.
Definition: HTMLForm.php:1394
UploadForm\getExtensionsMessage
getExtensionsMessage()
Get the messages indicating which extensions are preferred and prohibitted.
Definition: UploadForm.php:246
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:125
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:62
UploadForm\addUploadJS
addUploadJS()
Add upload JS to the OutputPage.
Definition: UploadForm.php:446
ContextSource\msg
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
Definition: ContextSource.php:195
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:142
HTMLForm\setId
setId( $id)
Definition: HTMLForm.php:1552
SpecialUpload\rotationEnabled
static rotationEnabled()
Should we rotate images in the preview on Special:Upload.
Definition: SpecialUpload.php:899
UploadForm\$contentLanguage
Language $contentLanguage
Definition: UploadForm.php:52
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:57
UploadBase\getMaxUploadSize
static getMaxUploadSize( $forType=null)
Get MediaWiki's maximum uploaded file size for given type of upload, based on $wgMaxUploadSize.
Definition: UploadBase.php:2231
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:1647
$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:234
NS_FILE
const NS_FILE
Definition: Defines.php:70
UploadForm\getOptionsSection
getOptionsSection()
Get the descriptor of the fieldset that contains the upload options, such as "watch this file".
Definition: UploadForm.php:395
Language
Internationalisation code See https://www.mediawiki.org/wiki/Special:MyLanguage/Localisation for more...
Definition: Language.php:43
LocalRepo
A repository that stores files in the local filesystem and registers them in the wiki's own database.
Definition: LocalRepo.php:37
HTMLForm\addFooterText
addFooterText( $msg, $section=null)
Add footer text, inside the form.
Definition: HTMLForm.php:882
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:140