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;
36  protected $mTextTop;
37  protected $mTextAfterSummary;
38 
39  protected $mSourceIds;
40 
41  protected $mMaxFileSize = [];
42 
44  protected $mMaxUploadSize = [];
45 
46  public function __construct( array $options = [], IContextSource $context = null,
47  LinkRenderer $linkRenderer = null
48  ) {
49  if ( $context instanceof IContextSource ) {
50  $this->setContext( $context );
51  }
52 
53  if ( !$linkRenderer ) {
54  $linkRenderer = MediaWikiServices::getInstance()->getLinkRenderer();
55  }
56 
57  $this->mWatch = !empty( $options['watch'] );
58  $this->mForReUpload = !empty( $options['forreupload'] );
59  $this->mSessionKey = $options['sessionkey'] ?? '';
60  $this->mHideIgnoreWarning = !empty( $options['hideignorewarning'] );
61  $this->mDestWarningAck = !empty( $options['destwarningack'] );
62  $this->mDestFile = $options['destfile'] ?? '';
63 
64  $this->mComment = $options['description'] ?? '';
65 
66  $this->mTextTop = $options['texttop'] ?? '';
67 
68  $this->mTextAfterSummary = $options['textaftersummary'] ?? '';
69 
70  $sourceDescriptor = $this->getSourceSection();
71  $descriptor = $sourceDescriptor
72  + $this->getDescriptionSection()
73  + $this->getOptionsSection();
74 
75  Hooks::run( 'UploadFormInitDescriptor', [ &$descriptor ] );
76  parent::__construct( $descriptor, $context, 'upload' );
77 
78  # Add a link to edit MediaWiki:Licenses
79  if ( MediaWikiServices::getInstance()
81  ->userHasRight( $this->getUser(), 'editinterface' )
82  ) {
83  $this->getOutput()->addModuleStyles( 'mediawiki.special' );
84  $licensesLink = $linkRenderer->makeKnownLink(
85  $this->msg( 'licenses' )->inContentLanguage()->getTitle(),
86  $this->msg( 'licenses-edit' )->text(),
87  [],
88  [ 'action' => 'edit' ]
89  );
90  $editLicenses = '<p class="mw-upload-editlicenses">' . $licensesLink . '</p>';
91  $this->addFooterText( $editLicenses, 'description' );
92  }
93 
94  # Set some form properties
95  $this->setSubmitText( $this->msg( 'uploadbtn' )->text() );
96  $this->setSubmitName( 'wpUpload' );
97  # Used message keys: 'accesskey-upload', 'tooltip-upload'
98  $this->setSubmitTooltip( 'upload' );
99  $this->setId( 'mw-upload-form' );
100 
101  # Build a list of IDs for javascript insertion
102  $this->mSourceIds = [];
103  foreach ( $sourceDescriptor as $field ) {
104  if ( !empty( $field['id'] ) ) {
105  $this->mSourceIds[] = $field['id'];
106  }
107  }
108  }
109 
116  protected function getSourceSection() {
117  if ( $this->mSessionKey ) {
118  return [
119  'SessionKey' => [
120  'type' => 'hidden',
121  'default' => $this->mSessionKey,
122  ],
123  'SourceType' => [
124  'type' => 'hidden',
125  'default' => 'Stash',
126  ],
127  ];
128  }
129 
130  $canUploadByUrl = UploadFromUrl::isEnabled()
131  && ( UploadFromUrl::isAllowed( $this->getUser() ) === true )
132  && $this->getConfig()->get( 'CopyUploadsFromSpecialUpload' );
133  $radio = $canUploadByUrl;
134  $selectedSourceType = strtolower( $this->getRequest()->getText( 'wpSourceType', 'File' ) );
135 
136  $descriptor = [];
137  if ( $this->mTextTop ) {
138  $descriptor['UploadFormTextTop'] = [
139  'type' => 'info',
140  'section' => 'source',
141  'default' => $this->mTextTop,
142  'raw' => true,
143  ];
144  }
145 
146  $this->mMaxUploadSize['file'] = min(
149  );
150 
151  $help = $this->msg( 'upload-maxfilesize',
152  $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['file'] )
153  )->parse();
154 
155  // If the user can also upload by URL, there are 2 different file size limits.
156  // This extra message helps stress which limit corresponds to what.
157  if ( $canUploadByUrl ) {
158  $help .= $this->msg( 'word-separator' )->escaped();
159  $help .= $this->msg( 'upload_source_file' )->parse();
160  }
161 
162  $descriptor['UploadFile'] = [
163  'class' => UploadSourceField::class,
164  'section' => 'source',
165  'type' => 'file',
166  'id' => 'wpUploadFile',
167  'radio-id' => 'wpSourceTypeFile',
168  'label-message' => 'sourcefilename',
169  'upload-type' => 'File',
170  'radio' => &$radio,
171  'help' => $help,
172  'checked' => $selectedSourceType == 'file',
173  ];
174 
175  if ( $canUploadByUrl ) {
176  $this->mMaxUploadSize['url'] = UploadBase::getMaxUploadSize( 'url' );
177  $descriptor['UploadFileURL'] = [
178  'class' => UploadSourceField::class,
179  'section' => 'source',
180  'id' => 'wpUploadFileURL',
181  'radio-id' => 'wpSourceTypeurl',
182  'label-message' => 'sourceurl',
183  'upload-type' => 'url',
184  'radio' => &$radio,
185  'help' => $this->msg( 'upload-maxfilesize',
186  $this->getContext()->getLanguage()->formatSize( $this->mMaxUploadSize['url'] )
187  )->parse() .
188  $this->msg( 'word-separator' )->escaped() .
189  $this->msg( 'upload_source_url' )->parse(),
190  'checked' => $selectedSourceType == 'url',
191  ];
192  }
193  Hooks::run( 'UploadFormSourceDescriptors', [ &$descriptor, &$radio, $selectedSourceType ] );
194 
195  $descriptor['Extensions'] = [
196  'type' => 'info',
197  'section' => 'source',
198  'default' => $this->getExtensionsMessage(),
199  'raw' => true,
200  ];
201 
202  return $descriptor;
203  }
204 
210  protected function getExtensionsMessage() {
211  # Print a list of allowed file extensions, if so configured. We ignore
212  # MIME type here, it's incomprehensible to most people and too long.
213  $config = $this->getConfig();
214 
215  if ( $config->get( 'CheckFileExtensions' ) ) {
216  $fileExtensions = array_unique( $config->get( 'FileExtensions' ) );
217  if ( $config->get( 'StrictFileExtensions' ) ) {
218  # Everything not permitted is banned
219  $extensionsList =
220  '<div id="mw-upload-permitted">' .
221  $this->msg( 'upload-permitted' )
222  ->params( $this->getLanguage()->commaList( $fileExtensions ) )
223  ->numParams( count( $fileExtensions ) )
224  ->parseAsBlock() .
225  "</div>\n";
226  } else {
227  # We have to list both preferred and prohibited
228  $fileBlacklist = array_unique( $config->get( 'FileBlacklist' ) );
229  $extensionsList =
230  '<div id="mw-upload-preferred">' .
231  $this->msg( 'upload-preferred' )
232  ->params( $this->getLanguage()->commaList( $fileExtensions ) )
233  ->numParams( count( $fileExtensions ) )
234  ->parseAsBlock() .
235  "</div>\n" .
236  '<div id="mw-upload-prohibited">' .
237  $this->msg( 'upload-prohibited' )
238  ->params( $this->getLanguage()->commaList( $fileBlacklist ) )
239  ->numParams( count( $fileBlacklist ) )
240  ->parseAsBlock() .
241  "</div>\n";
242  }
243  } else {
244  # Everything is permitted.
245  $extensionsList = '';
246  }
247 
248  return $extensionsList;
249  }
250 
257  protected function getDescriptionSection() {
258  $config = $this->getConfig();
259  if ( $this->mSessionKey ) {
260  $stash = RepoGroup::singleton()->getLocalRepo()->getUploadStash( $this->getUser() );
261  try {
262  $file = $stash->getFile( $this->mSessionKey );
263  } catch ( Exception $e ) {
264  $file = null;
265  }
266  if ( $file ) {
267  $mto = $file->transform( [ 'width' => 120 ] );
268  if ( $mto ) {
269  $this->addHeaderText(
270  '<div class="thumb t' .
271  MediaWikiServices::getInstance()->getContentLanguage()->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::class,
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 
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 
399  public function show() {
400  $this->addUploadJS();
401  return parent::show();
402  }
403 
407  protected function addUploadJS() {
408  $config = $this->getConfig();
409 
410  $this->mMaxUploadSize['*'] = UploadBase::getMaxUploadSize();
411 
412  $scriptVars = [
413  'wgAjaxUploadDestCheck' => $config->get( 'AjaxUploadDestCheck' ),
414  'wgAjaxLicensePreview' => $config->get( 'AjaxLicensePreview' ),
415  'wgUploadAutoFill' => !$this->mForReUpload &&
416  // If we received mDestFile from the request, don't autofill
417  // the wpDestFile textbox
418  $this->mDestFile === '',
419  'wgUploadSourceIds' => $this->mSourceIds,
420  'wgCheckFileExtensions' => $config->get( 'CheckFileExtensions' ),
421  'wgStrictFileExtensions' => $config->get( 'StrictFileExtensions' ),
422  'wgFileExtensions' => array_values( array_unique( $config->get( 'FileExtensions' ) ) ),
423  'wgCapitalizeUploads' => MediaWikiServices::getInstance()->getNamespaceInfo()->
424  isCapitalized( NS_FILE ),
425  'wgMaxUploadSize' => $this->mMaxUploadSize,
426  'wgFileCanRotate' => SpecialUpload::rotationEnabled(),
427  ];
428 
429  $out = $this->getOutput();
430  $out->addJsConfigVars( $scriptVars );
431 
432  $out->addModules( [
433  'mediawiki.special.upload', // Extras for thumbnail and license preview.
434  ] );
435  }
436 
442  function trySubmit() {
443  return false;
444  }
445 }
setContext(IContextSource $context)
getExtensionsMessage()
Get the messages indicating which extensions are preferred and prohibitted.
Definition: UploadForm.php:210
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
static rotationEnabled()
Should we rotate images in the preview on Special:Upload.
getOptionsSection()
Get the descriptor of the fieldset that contains the upload options, such as "watch this file"...
Definition: UploadForm.php:356
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:231
setSubmitName( $name)
Definition: HTMLForm.php:1414
addFooterText( $msg, $section=null)
Add footer text, inside the form.
Definition: HTMLForm.php:861
setSubmitTooltip( $name)
Definition: HTMLForm.php:1425
static getMaxUploadSize( $forType=null)
Get the MediaWiki maximum uploaded file size for given type of upload, based on $wgMaxUploadSize.
IContextSource $context
setId( $id)
Definition: HTMLForm.php:1524
getPermissionManager()
static isAllowed(UserIdentity $user)
Checks if the user is allowed to use the upload-by-URL feature.
setSubmitText( $t)
Set the text for the submit button.
Definition: HTMLForm.php:1366
static isEnabled()
Checks if the upload from URL feature is enabled.
Class that generates HTML links for pages.
__construct(array $options=[], IContextSource $context=null, LinkRenderer $linkRenderer=null)
Definition: UploadForm.php:46
addUploadJS()
Add upload JS to the OutputPage.
Definition: UploadForm.php:407
getSourceSection()
Get the descriptor of the fieldset that contains the file source selection.
Definition: UploadForm.php:116
static singleton()
Definition: RepoGroup.php:60
getTitle()
Get the title.
Definition: HTMLForm.php:1620
getContext()
Get the base IContextSource object.
$help
Definition: mcc.php:32
const NS_FILE
Definition: Defines.php:66
getDescriptionSection()
Get the descriptor of the fieldset that contains the file description input.
Definition: UploadForm.php:257
msg( $key,... $params)
Get a Message object with context set Parameters are the same as wfMessage()
array $mMaxUploadSize
Definition: UploadForm.php:44
static getMaxPhpUploadSize()
Get the PHP maximum uploaded file size, based on ini settings.
addHeaderText( $msg, $section=null)
Add HTML to the header, inside the form.
Definition: HTMLForm.php:806
Sub class of HTMLForm that provides the form section of SpecialUpload.
Definition: UploadForm.php:27
return true
Definition: router.php:92
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:200
trySubmit()
Empty function; submission is handled elsewhere.
Definition: UploadForm.php:442
show()
Add the upload JS and show the form.
Definition: UploadForm.php:399