MediaWiki  master
SpecialUpload.php
Go to the documentation of this file.
1 <?php
26 
33 class SpecialUpload extends SpecialPage {
38  public function __construct( $request = null ) {
39  parent::__construct( 'Upload', 'upload' );
40  }
41 
42  public function doesWrites() {
43  return true;
44  }
45 
49  public $mRequest;
50  public $mSourceType;
51 
53  public $mUpload;
54 
56  public $mLocalFile;
58 
63  public $mComment;
64  public $mLicense;
65 
69  public $mWatchthis;
72 
76 
78  public $mForReUpload;
79 
82  public $mTokenOk;
83 
85  public $mUploadSuccessful = false;
86 
90 
94  protected function loadRequest() {
95  $this->mRequest = $request = $this->getRequest();
96  $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
97  $this->mUpload = UploadBase::createFromRequest( $request );
98  $this->mUploadClicked = $request->wasPosted()
99  && ( $request->getCheck( 'wpUpload' )
100  || $request->getCheck( 'wpUploadIgnoreWarning' ) );
101 
102  // Guess the desired name from the filename if not provided
103  $this->mDesiredDestName = $request->getText( 'wpDestFile' );
104  if ( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
105  $this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
106  }
107  $this->mLicense = $request->getText( 'wpLicense' );
108 
109  $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
110  $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
111  || $request->getCheck( 'wpUploadIgnoreWarning' );
112  $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isLoggedIn();
113  $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
114  $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
115 
116  $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
117 
118  $commentDefault = '';
119  $commentMsg = $this->msg( 'upload-default-description' )->inContentLanguage();
120  if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
121  $commentDefault = $commentMsg->plain();
122  }
123  $this->mComment = $request->getText( 'wpUploadDescription', $commentDefault );
124 
125  $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
126  || $request->getCheck( 'wpReUpload' ); // b/w compat
127 
128  // If it was posted check for the token (no remote POST'ing with user credentials)
129  $token = $request->getVal( 'wpEditToken' );
130  $this->mTokenOk = $this->getUser()->matchEditToken( $token );
131 
132  $this->uploadFormTextTop = '';
133  $this->uploadFormTextAfterSummary = '';
134  }
135 
144  public function userCanExecute( User $user ) {
145  return UploadBase::isEnabled() && parent::userCanExecute( $user );
146  }
147 
158  public function execute( $par ) {
159  $this->useTransactionalTimeLimit();
160 
161  $this->setHeaders();
162  $this->outputHeader();
163 
164  # Check uploading enabled
165  if ( !UploadBase::isEnabled() ) {
166  throw new ErrorPageError( 'uploaddisabled', 'uploaddisabledtext' );
167  }
168 
169  $this->addHelpLink( 'Help:Managing files' );
170 
171  # Check permissions
172  $user = $this->getUser();
173  $permissionRequired = UploadBase::isAllowed( $user );
174  if ( $permissionRequired !== true ) {
175  throw new PermissionsError( $permissionRequired );
176  }
177 
178  # Check blocks
179  if ( $user->isBlockedFromUpload() ) {
180  throw new UserBlockedError(
181  $user->getBlock(),
182  $user,
183  $this->getLanguage(),
184  $this->getRequest()->getIP()
185  );
186  }
187 
188  // Global blocks
189  if ( $user->isBlockedGlobally() ) {
190  throw new UserBlockedError(
191  $user->getGlobalBlock(),
192  $user,
193  $this->getLanguage(),
194  $this->getRequest()->getIP()
195  );
196  }
197 
198  # Check whether we actually want to allow changing stuff
199  $this->checkReadOnly();
200 
201  $this->loadRequest();
202 
203  # Unsave the temporary file in case this was a cancelled upload
204  if ( $this->mCancelUpload && !$this->unsaveUploadedFile() ) {
205  # Something went wrong, so unsaveUploadedFile showed a warning
206  return;
207  }
208 
209  # Process upload or show a form
210  if (
211  $this->mTokenOk && !$this->mCancelUpload &&
212  ( $this->mUpload && $this->mUploadClicked )
213  ) {
214  $this->processUpload();
215  } else {
216  # Backwards compatibility hook
217  if ( !$this->getHookRunner()->onUploadForm_initial( $this ) ) {
218  wfDebug( "Hook 'UploadForm:initial' broke output of the upload form" );
219 
220  return;
221  }
222  $this->showUploadForm( $this->getUploadForm() );
223  }
224 
225  # Cleanup
226  if ( $this->mUpload ) {
227  $this->mUpload->cleanupTempFile();
228  }
229  }
230 
236  protected function showUploadForm( $form ) {
237  # Add links if file was previously deleted
238  if ( $this->mDesiredDestName ) {
239  $this->showViewDeletedLinks();
240  }
241 
242  if ( $form instanceof HTMLForm ) {
243  $form->show();
244  } else {
245  $this->getOutput()->addHTML( $form );
246  }
247  }
248 
257  protected function getUploadForm( $message = '', $sessionKey = '', $hideIgnoreWarning = false ) {
258  # Initialize form
259  $context = new DerivativeContext( $this->getContext() );
260  $context->setTitle( $this->getPageTitle() ); // Remove subpage
261  $form = new UploadForm( [
262  'watch' => $this->getWatchCheck(),
263  'forreupload' => $this->mForReUpload,
264  'sessionkey' => $sessionKey,
265  'hideignorewarning' => $hideIgnoreWarning,
266  'destwarningack' => (bool)$this->mDestWarningAck,
267 
268  'description' => $this->mComment,
269  'texttop' => $this->uploadFormTextTop,
270  'textaftersummary' => $this->uploadFormTextAfterSummary,
271  'destfile' => $this->mDesiredDestName,
272  ], $context, $this->getLinkRenderer() );
273 
274  # Check the token, but only if necessary
275  if (
276  !$this->mTokenOk && !$this->mCancelUpload &&
277  ( $this->mUpload && $this->mUploadClicked )
278  ) {
279  $form->addPreText( $this->msg( 'session_fail_preview' )->parse() );
280  }
281 
282  # Give a notice if the user is uploading a file that has been deleted or moved
283  # Note that this is independent from the message 'filewasdeleted'
284  $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
285  $delNotice = ''; // empty by default
286  if ( $desiredTitleObj instanceof Title && !$desiredTitleObj->exists() ) {
287  $dbr = wfGetDB( DB_REPLICA );
288 
289  LogEventsList::showLogExtract( $delNotice, [ 'delete', 'move' ],
290  $desiredTitleObj,
291  '', [ 'lim' => 10,
292  'conds' => [ 'log_action != ' . $dbr->addQuotes( 'revision' ) ],
293  'showIfEmpty' => false,
294  'msgKey' => [ 'upload-recreate-warning' ] ]
295  );
296  }
297  $form->addPreText( $delNotice );
298 
299  # Add text to form
300  $form->addPreText( '<div id="uploadtext">' .
301  $this->msg( 'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
302  '</div>' );
303  # Add upload error message
304  $form->addPreText( $message );
305 
306  # Add footer to form
307  $uploadFooter = $this->msg( 'uploadfooter' );
308  if ( !$uploadFooter->isDisabled() ) {
309  $form->addPostText( '<div id="mw-upload-footer-message">'
310  . $uploadFooter->parseAsBlock() . "</div>\n" );
311  }
312 
313  return $form;
314  }
315 
319  protected function showViewDeletedLinks() {
320  $title = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
321  $user = $this->getUser();
322  $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
323  // Show a subtitle link to deleted revisions (to sysops et al only)
324  if ( $title instanceof Title ) {
325  $count = $title->isDeleted();
326  if ( $count > 0 && $permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
327  $restorelink = $this->getLinkRenderer()->makeKnownLink(
328  SpecialPage::getTitleFor( 'Undelete', $title->getPrefixedText() ),
329  $this->msg( 'restorelink' )->numParams( $count )->text()
330  );
331  $link = $this->msg(
332  $permissionManager->userHasRight( $user, 'delete' ) ? 'thisisdeleted' : 'viewdeleted'
333  )->rawParams( $restorelink )->parseAsBlock();
334  $this->getOutput()->addHTML(
336  'div',
337  [ 'id' => 'contentSub2' ],
338  $link
339  )
340  );
341  }
342  }
343  }
344 
356  protected function showRecoverableUploadError( $message ) {
357  $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
358  if ( $stashStatus->isGood() ) {
359  $sessionKey = $stashStatus->getValue()->getFileKey();
360  $uploadWarning = 'upload-tryagain';
361  } else {
362  $sessionKey = null;
363  $uploadWarning = 'upload-tryagain-nostash';
364  }
365  $message = '<h2>' . $this->msg( 'uploaderror' )->escaped() . "</h2>\n" .
366  '<div class="error">' . $message . "</div>\n";
367 
368  $form = $this->getUploadForm( $message, $sessionKey );
369  $form->setSubmitText( $this->msg( $uploadWarning )->escaped() );
370  $this->showUploadForm( $form );
371  }
372 
381  protected function showUploadWarning( $warnings ) {
382  # If there are no warnings, or warnings we can ignore, return early.
383  # mDestWarningAck is set when some javascript has shown the warning
384  # to the user. mForReUpload is set when the user clicks the "upload a
385  # new version" link.
386  if ( !$warnings || ( count( $warnings ) == 1
387  && isset( $warnings['exists'] )
388  && ( $this->mDestWarningAck || $this->mForReUpload ) )
389  ) {
390  return false;
391  }
392 
393  $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
394  if ( $stashStatus->isGood() ) {
395  $sessionKey = $stashStatus->getValue()->getFileKey();
396  $uploadWarning = 'uploadwarning-text';
397  } else {
398  $sessionKey = null;
399  $uploadWarning = 'uploadwarning-text-nostash';
400  }
401 
402  // Add styles for the warning, reused from the live preview
403  $this->getOutput()->addModuleStyles( 'mediawiki.special' );
404 
405  $linkRenderer = $this->getLinkRenderer();
406  $warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
407  . '<div class="mw-destfile-warning"><ul>';
408  foreach ( $warnings as $warning => $args ) {
409  if ( $warning == 'badfilename' ) {
410  $this->mDesiredDestName = Title::makeTitle( NS_FILE, $args )->getText();
411  }
412  if ( $warning == 'exists' ) {
413  $msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
414  } elseif ( $warning == 'no-change' ) {
415  $file = $args;
416  $filename = $file->getTitle()->getPrefixedText();
417  $msg = "\t<li>" . $this->msg( 'fileexists-no-change', $filename )->parse() . "</li>\n";
418  } elseif ( $warning == 'duplicate-version' ) {
419  $file = $args[0];
420  $count = count( $args );
421  $filename = $file->getTitle()->getPrefixedText();
422  $message = $this->msg( 'fileexists-duplicate-version' )
423  ->params( $filename )
424  ->numParams( $count );
425  $msg = "\t<li>" . $message->parse() . "</li>\n";
426  } elseif ( $warning == 'was-deleted' ) {
427  # If the file existed before and was deleted, warn the user of this
428  $ltitle = SpecialPage::getTitleFor( 'Log' );
429  $llink = $linkRenderer->makeKnownLink(
430  $ltitle,
431  $this->msg( 'deletionlog' )->text(),
432  [],
433  [
434  'type' => 'delete',
435  'page' => Title::makeTitle( NS_FILE, $args )->getPrefixedText(),
436  ]
437  );
438  $msg = "\t<li>" . $this->msg( 'filewasdeleted' )->rawParams( $llink )->parse() . "</li>\n";
439  } elseif ( $warning == 'duplicate' ) {
440  $msg = $this->getDupeWarning( $args );
441  } elseif ( $warning == 'duplicate-archive' ) {
442  if ( $args === '' ) {
443  $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate-notitle' )->parse()
444  . "</li>\n";
445  } else {
446  $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate',
447  Title::makeTitle( NS_FILE, $args )->getPrefixedText() )->parse()
448  . "</li>\n";
449  }
450  } else {
451  if ( $args === true ) {
452  $args = [];
453  } elseif ( !is_array( $args ) ) {
454  $args = [ $args ];
455  }
456  $msg = "\t<li>" . $this->msg( $warning, $args )->parse() . "</li>\n";
457  }
458  $warningHtml .= $msg;
459  }
460  $warningHtml .= "</ul></div>\n";
461  $warningHtml .= $this->msg( $uploadWarning )->parseAsBlock();
462 
463  $form = $this->getUploadForm( $warningHtml, $sessionKey, /* $hideIgnoreWarning */ true );
464  $form->setSubmitText( $this->msg( 'upload-tryagain' )->text() );
465  $form->addButton( [
466  'name' => 'wpUploadIgnoreWarning',
467  'value' => $this->msg( 'ignorewarning' )->text()
468  ] );
469  $form->addButton( [
470  'name' => 'wpCancelUpload',
471  'value' => $this->msg( 'reuploaddesc' )->text()
472  ] );
473 
474  $this->showUploadForm( $form );
475 
476  # Indicate that we showed a form
477  return true;
478  }
479 
485  protected function showUploadError( $message ) {
486  $message = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n" .
487  '<div class="error">' . $message . "</div>\n";
488  $this->showUploadForm( $this->getUploadForm( $message ) );
489  }
490 
495  protected function processUpload() {
496  // Fetch the file if required
497  $status = $this->mUpload->fetchFile();
498  if ( !$status->isOK() ) {
499  $this->showUploadError( $this->getOutput()->parseAsInterface(
500  $status->getWikiText( false, false, $this->getLanguage() )
501  ) );
502 
503  return;
504  }
505  if ( !$this->getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
506  wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file." );
507  // This code path is deprecated. If you want to break upload processing
508  // do so by hooking into the appropriate hooks in UploadBase::verifyUpload
509  // and UploadBase::verifyFile.
510  // If you use this hook to break uploading, the user will be returned
511  // an empty form with no error message whatsoever.
512  return;
513  }
514 
515  // Upload verification
516  $details = $this->mUpload->verifyUpload();
517  if ( $details['status'] != UploadBase::OK ) {
518  $this->processVerificationError( $details );
519 
520  return;
521  }
522 
523  // Verify permissions for this title
524  $user = $this->getUser();
525  $permErrors = $this->mUpload->verifyTitlePermissions( $user );
526  if ( $permErrors !== true ) {
527  $code = array_shift( $permErrors[0] );
528  $this->showRecoverableUploadError( $this->msg( $code, $permErrors[0] )->parse() );
529 
530  return;
531  }
532 
533  $this->mLocalFile = $this->mUpload->getLocalFile();
534 
535  // Check warnings if necessary
536  if ( !$this->mIgnoreWarning ) {
537  $warnings = $this->mUpload->checkWarnings( $user );
538  if ( $this->showUploadWarning( $warnings ) ) {
539  return;
540  }
541  }
542 
543  // This is as late as we can throttle, after expected issues have been handled
544  if ( UploadBase::isThrottled( $user ) ) {
546  $this->msg( 'actionthrottledtext' )->escaped()
547  );
548  return;
549  }
550 
551  // Get the page text if this is not a reupload
552  if ( !$this->mForReUpload ) {
553  $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
554  $this->mCopyrightStatus, $this->mCopyrightSource, $this->getConfig() );
555  } else {
556  $pageText = false;
557  }
558 
559  $changeTags = $this->getRequest()->getVal( 'wpChangeTags' );
560  if ( $changeTags === null || $changeTags === '' ) {
561  $changeTags = [];
562  } else {
563  $changeTags = array_filter( array_map( 'trim', explode( ',', $changeTags ) ) );
564  }
565 
566  if ( $changeTags ) {
567  $changeTagsStatus = ChangeTags::canAddTagsAccompanyingChange(
568  $changeTags, $user );
569  if ( !$changeTagsStatus->isOK() ) {
570  $this->showUploadError( $this->getOutput()->parseAsInterface(
571  $changeTagsStatus->getWikiText( false, false, $this->getLanguage() )
572  ) );
573 
574  return;
575  }
576  }
577 
578  $status = $this->mUpload->performUpload(
579  $this->mComment,
580  $pageText,
581  $this->mWatchthis,
582  $user,
583  $changeTags
584  );
585 
586  if ( !$status->isGood() ) {
588  $this->getOutput()->parseAsInterface(
589  $status->getWikiText( false, false, $this->getLanguage() )
590  )
591  );
592 
593  return;
594  }
595 
596  // Success, redirect to description page
597  $this->mUploadSuccessful = true;
598  $this->getHookRunner()->onSpecialUploadComplete( $this );
599  $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
600  }
601 
611  public static function getInitialPageText( $comment = '', $license = '',
612  $copyStatus = '', $source = '', Config $config = null
613  ) {
614  if ( $config === null ) {
615  wfDebug( __METHOD__ . ' called without a Config instance passed to it' );
616  $config = MediaWikiServices::getInstance()->getMainConfig();
617  }
618 
619  $msg = [];
620  $forceUIMsgAsContentMsg = (array)$config->get( 'ForceUIMsgAsContentMsg' );
621  /* These messages are transcluded into the actual text of the description page.
622  * Thus, forcing them as content messages makes the upload to produce an int: template
623  * instead of hardcoding it there in the uploader language.
624  */
625  foreach ( [ 'license-header', 'filedesc', 'filestatus', 'filesource' ] as $msgName ) {
626  if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
627  $msg[$msgName] = "{{int:$msgName}}";
628  } else {
629  $msg[$msgName] = wfMessage( $msgName )->inContentLanguage()->text();
630  }
631  }
632 
633  $licenseText = '';
634  if ( $license !== '' ) {
635  $licenseText = '== ' . $msg['license-header'] . " ==\n{{" . $license . "}}\n";
636  }
637 
638  $pageText = $comment . "\n";
639  $headerText = '== ' . $msg['filedesc'] . ' ==';
640  if ( $comment !== '' && strpos( $comment, $headerText ) === false ) {
641  // prepend header to page text unless it's already there (or there is no content)
642  $pageText = $headerText . "\n" . $pageText;
643  }
644 
645  if ( $config->get( 'UseCopyrightUpload' ) ) {
646  $pageText .= '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n";
647  $pageText .= $licenseText;
648  $pageText .= '== ' . $msg['filesource'] . " ==\n" . $source;
649  } else {
650  $pageText .= $licenseText;
651  }
652 
653  // allow extensions to modify the content
654  Hooks::runner()->onUploadForm_getInitialPageText( $pageText, $msg, $config );
655 
656  return $pageText;
657  }
658 
671  protected function getWatchCheck() {
672  if ( $this->getUser()->getOption( 'watchdefault' ) ) {
673  // Watch all edits!
674  return true;
675  }
676 
677  $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
678  if ( $desiredTitleObj instanceof Title && $this->getUser()->isWatched( $desiredTitleObj ) ) {
679  // Already watched, don't change that
680  return true;
681  }
682 
683  $local = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
684  ->newFile( $this->mDesiredDestName );
685  if ( $local && $local->exists() ) {
686  // We're uploading a new version of an existing file.
687  // No creation, so don't watch it if we're not already.
688  return false;
689  } else {
690  // New page should get watched if that's our option.
691  return $this->getUser()->getOption( 'watchcreations' ) ||
692  $this->getUser()->getOption( 'watchuploads' );
693  }
694  }
695 
702  protected function processVerificationError( $details ) {
703  switch ( $details['status'] ) {
706  $this->showRecoverableUploadError( $this->msg( 'minlength1' )->escaped() );
707  break;
709  $this->showRecoverableUploadError( $this->msg( 'illegalfilename',
710  $details['filtered'] )->parse() );
711  break;
713  $this->showRecoverableUploadError( $this->msg( 'filename-toolong' )->escaped() );
714  break;
716  $this->showRecoverableUploadError( $this->msg( 'filetype-missing' )->parse() );
717  break;
719  $this->showRecoverableUploadError( $this->msg( 'windows-nonascii-filename' )->parse() );
720  break;
721 
724  $this->showUploadError( $this->msg( 'emptyfile' )->escaped() );
725  break;
727  $this->showUploadError( $this->msg( 'largefileserver' )->escaped() );
728  break;
730  $msg = $this->msg( 'filetype-banned-type' );
731  if ( isset( $details['blacklistedExt'] ) ) {
732  $msg->params( $this->getLanguage()->commaList( $details['blacklistedExt'] ) );
733  } else {
734  $msg->params( $details['finalExt'] );
735  }
736  $extensions = array_unique( $this->getConfig()->get( 'FileExtensions' ) );
737  $msg->params( $this->getLanguage()->commaList( $extensions ),
738  count( $extensions ) );
739 
740  // Add PLURAL support for the first parameter. This results
741  // in a bit unlogical parameter sequence, but does not break
742  // old translations
743  if ( isset( $details['blacklistedExt'] ) ) {
744  $msg->params( count( $details['blacklistedExt'] ) );
745  } else {
746  $msg->params( 1 );
747  }
748 
749  $this->showUploadError( $msg->parse() );
750  break;
752  unset( $details['status'] );
753  $code = array_shift( $details['details'] );
754  $this->showUploadError( $this->msg( $code, $details['details'] )->parse() );
755  break;
757  if ( is_array( $details['error'] ) ) { # allow hooks to return error details in an array
758  $args = $details['error'];
759  $error = array_shift( $args );
760  } else {
761  $error = $details['error'];
762  $args = null;
763  }
764 
765  $this->showUploadError( $this->msg( $error, $args )->parse() );
766  break;
767  default:
768  throw new MWException( __METHOD__ . ": Unknown value `{$details['status']}`" );
769  }
770  }
771 
777  protected function unsaveUploadedFile() {
778  if ( !( $this->mUpload instanceof UploadFromStash ) ) {
779  return true;
780  }
781  $success = $this->mUpload->unsaveUploadedFile();
782  if ( !$success ) {
783  $this->getOutput()->showFatalError(
784  $this->msg( 'filedeleteerror' )
785  ->params( $this->mUpload->getTempPath() )
786  ->escaped()
787  );
788 
789  return false;
790  } else {
791  return true;
792  }
793  }
794 
804  public static function getExistsWarning( $exists ) {
805  if ( !$exists ) {
806  return '';
807  }
808 
809  $file = $exists['file'];
810  $filename = $file->getTitle()->getPrefixedText();
811  $warnMsg = null;
812 
813  if ( $exists['warning'] == 'exists' ) {
814  // Exact match
815  $warnMsg = wfMessage( 'fileexists', $filename );
816  } elseif ( $exists['warning'] == 'page-exists' ) {
817  // Page exists but file does not
818  $warnMsg = wfMessage( 'filepageexists', $filename );
819  } elseif ( $exists['warning'] == 'exists-normalized' ) {
820  $warnMsg = wfMessage( 'fileexists-extension', $filename,
821  $exists['normalizedFile']->getTitle()->getPrefixedText() );
822  } elseif ( $exists['warning'] == 'thumb' ) {
823  // Swapped argument order compared with other messages for backwards compatibility
824  $warnMsg = wfMessage( 'fileexists-thumbnail-yes',
825  $exists['thumbFile']->getTitle()->getPrefixedText(), $filename );
826  } elseif ( $exists['warning'] == 'thumb-name' ) {
827  // Image w/o '180px-' does not exists, but we do not like these filenames
828  $name = $file->getName();
829  $badPart = substr( $name, 0, strpos( $name, '-' ) + 1 );
830  $warnMsg = wfMessage( 'file-thumbnail-no', $badPart );
831  } elseif ( $exists['warning'] == 'bad-prefix' ) {
832  $warnMsg = wfMessage( 'filename-bad-prefix', $exists['prefix'] );
833  }
834 
835  return $warnMsg ? $warnMsg->title( $file->getTitle() )->parse() : '';
836  }
837 
843  public function getDupeWarning( $dupes ) {
844  if ( !$dupes ) {
845  return '';
846  }
847 
848  $gallery = ImageGalleryBase::factory( false, $this->getContext() );
849  $gallery->setShowBytes( false );
850  $gallery->setShowDimensions( false );
851  foreach ( $dupes as $file ) {
852  $gallery->add( $file->getTitle() );
853  }
854 
855  return '<li>' .
856  $this->msg( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
857  $gallery->toHTML() . "</li>\n";
858  }
859 
860  protected function getGroupName() {
861  return 'media';
862  }
863 
872  public static function rotationEnabled() {
873  $bitmapHandler = new BitmapHandler();
874  return $bitmapHandler->autoRotateEnabled();
875  }
876 }
UploadBase
Definition: UploadBase.php:45
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:697
SpecialUpload\getInitialPageText
static getInitialPageText( $comment='', $license='', $copyStatus='', $source='', Config $config=null)
Get the initial image page text based on a comment and optional file status information.
Definition: SpecialUpload.php:611
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:828
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:35
UploadBase\VERIFICATION_ERROR
const VERIFICATION_ERROR
Definition: UploadBase.php:108
SpecialUpload\userCanExecute
userCanExecute(User $user)
This page can be shown if uploading is enabled.
Definition: SpecialUpload.php:144
UploadBase\isAllowed
static isAllowed(UserIdentity $user)
Returns true if the user can use this upload module or else a string identifying the missing permissi...
Definition: UploadBase.php:155
UserBlockedError
Show an error when the user tries to do something whilst blocked.
Definition: UserBlockedError.php:31
UploadBase\isThrottled
static isThrottled( $user)
Returns true if the user has surpassed the upload rate limit, false otherwise.
Definition: UploadBase.php:172
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:744
UploadBase\FILE_TOO_LARGE
const FILE_TOO_LARGE
Definition: UploadBase.php:110
UploadBase\MIN_LENGTH_PARTNAME
const MIN_LENGTH_PARTNAME
Definition: UploadBase.php:103
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
SpecialUpload\$mSourceType
$mSourceType
Definition: SpecialUpload.php:50
SpecialUpload\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialUpload.php:860
SpecialUpload\doesWrites
doesWrites()
Indicates whether this special page may perform database writes.
Definition: SpecialUpload.php:42
UploadBase\isEnabled
static isEnabled()
Returns true if uploads are enabled.
Definition: UploadBase.php:141
SpecialUpload\$mUploadClicked
$mUploadClicked
Definition: SpecialUpload.php:57
UploadForm
Sub class of HTMLForm that provides the form section of SpecialUpload.
Definition: UploadForm.php:27
NS_FILE
const NS_FILE
Definition: Defines.php:75
SpecialUpload\processUpload
processUpload()
Do the upload.
Definition: SpecialUpload.php:495
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
SpecialUpload\$mCopyrightStatus
$mCopyrightStatus
Definition: SpecialUpload.php:70
SpecialUpload\unsaveUploadedFile
unsaveUploadedFile()
Remove a temporarily kept file stashed by saveTempUploadedFile().
Definition: SpecialUpload.php:777
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1219
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:92
UploadFromStash
Implements uploading from previously stored file.
Definition: UploadFromStash.php:32
SpecialUpload\$mLocalFile
LocalFile $mLocalFile
Definition: SpecialUpload.php:56
UploadBase\HOOK_ABORTED
const HOOK_ABORTED
Definition: UploadBase.php:109
SpecialPage\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: SpecialPage.php:934
UploadBase\OK
const OK
Definition: UploadBase.php:101
PermissionsError
Show an error when a user tries to do something they do not have the necessary permissions for.
Definition: PermissionsError.php:31
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:774
$success
$success
Definition: NoLocalSettings.php:42
SpecialUpload\showViewDeletedLinks
showViewDeletedLinks()
Shows the "view X deleted revivions link"".
Definition: SpecialUpload.php:319
UploadBase\EMPTY_FILE
const EMPTY_FILE
Definition: UploadBase.php:102
SpecialUpload\$mDestWarningAck
$mDestWarningAck
Hidden variables.
Definition: SpecialUpload.php:75
SpecialUpload\getExistsWarning
static getExistsWarning( $exists)
Functions for formatting warnings.
Definition: SpecialUpload.php:804
$dbr
$dbr
Definition: testCompression.php:54
SpecialUpload\showUploadWarning
showUploadWarning( $warnings)
Stashes the upload, shows the main form, but adds a "continue anyway button".
Definition: SpecialUpload.php:381
SpecialUpload\getDupeWarning
getDupeWarning( $dupes)
Construct a warning and a gallery from an array of duplicate files.
Definition: SpecialUpload.php:843
SpecialUpload\showRecoverableUploadError
showRecoverableUploadError( $message)
Stashes the upload and shows the main upload form.
Definition: SpecialUpload.php:356
Config
Interface for configuration instances.
Definition: Config.php:30
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:31
SpecialPage\addHelpLink
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Definition: SpecialPage.php:864
SpecialPage\getHookRunner
getHookRunner()
Definition: SpecialPage.php:1010
MWException
MediaWiki exception.
Definition: MWException.php:29
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:794
SpecialUpload\$mRequest
WebRequest FauxRequest $mRequest
Misc variables.
Definition: SpecialUpload.php:49
BitmapHandler
Generic handler for bitmap images.
Definition: BitmapHandler.php:32
SpecialUpload\$mDesiredDestName
string $mDesiredDestName
User input variables from the "description" section.
Definition: SpecialUpload.php:62
SpecialUpload\$uploadFormTextAfterSummary
$uploadFormTextAfterSummary
Definition: SpecialUpload.php:89
UploadBase\WINDOWS_NONASCII_FILENAME
const WINDOWS_NONASCII_FILENAME
Definition: UploadBase.php:111
SpecialUpload\$mCancelUpload
bool $mCancelUpload
The user clicked "Cancel and return to upload form" button.
Definition: SpecialUpload.php:81
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2467
$args
if( $line===false) $args
Definition: mcc.php:124
SpecialUpload\execute
execute( $par)
Definition: SpecialUpload.php:158
SpecialUpload\$mCopyrightSource
$mCopyrightSource
Definition: SpecialUpload.php:71
$title
$title
Definition: testCompression.php:38
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!...
Definition: SpecialPage.php:571
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:754
SpecialUpload\$mUpload
UploadBase $mUpload
Definition: SpecialUpload.php:53
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:592
LogEventsList\showLogExtract
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Definition: LogEventsList.php:639
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
SpecialUpload\$mComment
$mComment
Definition: SpecialUpload.php:63
SpecialUpload\loadRequest
loadRequest()
Initialize instance variables from request and create an Upload handler.
Definition: SpecialUpload.php:94
wfDebug
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:909
LocalFile
Class to represent a local file in the wiki's own database.
Definition: LocalFile.php:59
SpecialUpload
Form for handling uploads and special page.
Definition: SpecialUpload.php:33
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:717
SpecialUpload\$mForReUpload
bool $mForReUpload
The user followed an "overwrite this file" link.
Definition: SpecialUpload.php:78
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:618
SpecialUpload\$mLicense
$mLicense
Definition: SpecialUpload.php:64
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:41
SpecialUpload\getUploadForm
getUploadForm( $message='', $sessionKey='', $hideIgnoreWarning=false)
Get an UploadForm instance with title and text properly set.
Definition: SpecialUpload.php:257
SpecialUpload\rotationEnabled
static rotationEnabled()
Should we rotate images in the preview on Special:Upload.
Definition: SpecialUpload.php:872
SpecialUpload\showUploadError
showUploadError( $message)
Show the upload form with error message, but do not stash the file.
Definition: SpecialUpload.php:485
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:172
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:734
SpecialUpload\showUploadForm
showUploadForm( $form)
Show the main upload form.
Definition: SpecialUpload.php:236
UploadBase\FILENAME_TOO_LONG
const FILENAME_TOO_LONG
Definition: UploadBase.php:112
UploadBase\ILLEGAL_FILENAME
const ILLEGAL_FILENAME
Definition: UploadBase.php:104
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:42
UploadBase\createFromRequest
static createFromRequest(&$request, $type=null)
Create a form of UploadBase depending on wpSourceType and initializes it.
Definition: UploadBase.php:186
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:944
ChangeTags\canAddTagsAccompanyingChange
static canAddTagsAccompanyingChange(array $tags, User $user=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
Definition: ChangeTags.php:544
Title
Represents a title within MediaWiki.
Definition: Title.php:42
SpecialUpload\$mWatchthis
$mWatchthis
Definition: SpecialUpload.php:69
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
getTitle
getTitle()
Definition: RevisionSearchResultTrait.php:81
Title\exists
exists( $flags=0)
Check if page exists.
Definition: Title.php:4003
$source
$source
Definition: mwdoc-filter.php:34
SpecialUpload\__construct
__construct( $request=null)
Get data POSTed through the form and assign them to the object.
Definition: SpecialUpload.php:38
ImageGalleryBase\factory
static factory( $mode=false, IContextSource $context=null)
Get a new image gallery.
Definition: ImageGalleryBase.php:116
SpecialPage\checkReadOnly
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
Definition: SpecialPage.php:356
SpecialUpload\processVerificationError
processVerificationError( $details)
Provides output to the user for a result of UploadBase::verifyUpload.
Definition: SpecialUpload.php:702
SpecialPage\$linkRenderer
MediaWiki Linker LinkRenderer null $linkRenderer
Definition: SpecialPage.php:71
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:30
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
SpecialUpload\$uploadFormTextTop
$uploadFormTextTop
Text injection points for hooks not using HTMLForm.
Definition: SpecialUpload.php:88
SpecialUpload\$mUploadSuccessful
bool $mUploadSuccessful
Subclasses can use this to determine whether a file was uploaded.
Definition: SpecialUpload.php:85
SpecialPage\outputHeader
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
Definition: SpecialPage.php:662
SpecialUpload\$mTokenOk
$mTokenOk
Definition: SpecialUpload.php:82
SpecialUpload\$mIgnoreWarning
$mIgnoreWarning
User input variables from the root section.
Definition: SpecialUpload.php:68
SpecialUpload\getWatchCheck
getWatchCheck()
See if we should check the 'watch this page' checkbox on the form based on the user's preferences and...
Definition: SpecialUpload.php:671
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:135
UploadBase\FILETYPE_MISSING
const FILETYPE_MISSING
Definition: UploadBase.php:106
UploadBase\FILETYPE_BADTYPE
const FILETYPE_BADTYPE
Definition: UploadBase.php:107