MediaWiki REL1_39
SpecialUpload.php
Go to the documentation of this file.
1<?php
29
37
39 private $localRepo;
40
42 private $userOptionsLookup;
43
45 private $nsInfo;
46
48 private $watchlistManager;
49
56 public function __construct(
57 RepoGroup $repoGroup = null,
58 UserOptionsLookup $userOptionsLookup = null,
59 NamespaceInfo $nsInfo = null,
60 WatchlistManager $watchlistManager = null
61 ) {
62 parent::__construct( 'Upload', 'upload' );
63 // This class is extended and therefor fallback to global state - T265300
64 $services = MediaWikiServices::getInstance();
65 $repoGroup = $repoGroup ?? $services->getRepoGroup();
66 $this->localRepo = $repoGroup->getLocalRepo();
67 $this->userOptionsLookup = $userOptionsLookup ?? $services->getUserOptionsLookup();
68 $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
69 $this->watchlistManager = $watchlistManager ?? $services->getWatchlistManager();
70 }
71
72 public function doesWrites() {
73 return true;
74 }
75
79 public $mRequest;
81
83 public $mUpload;
84
88
93 public $mComment;
94 public $mLicense;
95
102
106
109
112 public $mTokenOk;
113
115 public $mUploadSuccessful = false;
116
121
125 protected function loadRequest() {
126 $this->mRequest = $request = $this->getRequest();
127 $this->mSourceType = $request->getVal( 'wpSourceType', 'file' );
128 $this->mUpload = UploadBase::createFromRequest( $request );
129 $this->mUploadClicked = $request->wasPosted()
130 && ( $request->getCheck( 'wpUpload' )
131 || $request->getCheck( 'wpUploadIgnoreWarning' ) );
132
133 // Guess the desired name from the filename if not provided
134 $this->mDesiredDestName = $request->getText( 'wpDestFile' );
135 if ( !$this->mDesiredDestName && $request->getFileName( 'wpUploadFile' ) !== null ) {
136 $this->mDesiredDestName = $request->getFileName( 'wpUploadFile' );
137 }
138 $this->mLicense = $request->getText( 'wpLicense' );
139
140 $this->mDestWarningAck = $request->getText( 'wpDestFileWarningAck' );
141 $this->mIgnoreWarning = $request->getCheck( 'wpIgnoreWarning' )
142 || $request->getCheck( 'wpUploadIgnoreWarning' );
143 $this->mWatchthis = $request->getBool( 'wpWatchthis' ) && $this->getUser()->isRegistered();
144 $this->mCopyrightStatus = $request->getText( 'wpUploadCopyStatus' );
145 $this->mCopyrightSource = $request->getText( 'wpUploadSource' );
146
147 $this->mForReUpload = $request->getBool( 'wpForReUpload' ); // updating a file
148
149 $commentDefault = '';
150 $commentMsg = $this->msg( 'upload-default-description' )->inContentLanguage();
151 if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
152 $commentDefault = $commentMsg->plain();
153 }
154 $this->mComment = $request->getText( 'wpUploadDescription', $commentDefault );
155
156 $this->mCancelUpload = $request->getCheck( 'wpCancelUpload' )
157 || $request->getCheck( 'wpReUpload' ); // b/w compat
158
159 // If it was posted check for the token (no remote POST'ing with user credentials)
160 $token = $request->getVal( 'wpEditToken' );
161 $this->mTokenOk = $this->getUser()->matchEditToken( $token );
162
163 $this->uploadFormTextTop = '';
164 $this->uploadFormTextAfterSummary = '';
165 }
166
175 public function userCanExecute( User $user ) {
176 return UploadBase::isEnabled() && parent::userCanExecute( $user );
177 }
178
189 public function execute( $par ) {
191
192 $this->setHeaders();
193 $this->outputHeader();
194
195 # Check uploading enabled
196 if ( !UploadBase::isEnabled() ) {
197 throw new ErrorPageError( 'uploaddisabled', 'uploaddisabledtext' );
198 }
199
200 $this->addHelpLink( 'Help:Managing files' );
201
202 # Check permissions
203 $user = $this->getUser();
204 $permissionRequired = UploadBase::isAllowed( $user );
205 if ( $permissionRequired !== true ) {
206 throw new PermissionsError( $permissionRequired );
207 }
208
209 # Check blocks
210 if ( $user->isBlockedFromUpload() ) {
211 throw new UserBlockedError(
212 // @phan-suppress-next-line PhanTypeMismatchArgumentNullable Block is checked and not null
213 $user->getBlock(),
214 $user,
215 $this->getLanguage(),
216 $this->getRequest()->getIP()
217 );
218 }
219
220 // Global blocks
221 if ( $user->isBlockedGlobally() ) {
222 throw new UserBlockedError(
223 $user->getGlobalBlock(),
224 $user,
225 $this->getLanguage(),
226 $this->getRequest()->getIP()
227 );
228 }
229
230 # Check whether we actually want to allow changing stuff
231 $this->checkReadOnly();
232
233 $this->loadRequest();
234
235 # Unsave the temporary file in case this was a cancelled upload
236 if ( $this->mCancelUpload && !$this->unsaveUploadedFile() ) {
237 # Something went wrong, so unsaveUploadedFile showed a warning
238 return;
239 }
240
241 # Process upload or show a form
242 if (
243 $this->mTokenOk && !$this->mCancelUpload &&
244 ( $this->mUpload && $this->mUploadClicked )
245 ) {
246 $this->processUpload();
247 } else {
248 # Backwards compatibility hook
249 if ( !$this->getHookRunner()->onUploadForm_initial( $this ) ) {
250 wfDebug( "Hook 'UploadForm:initial' broke output of the upload form" );
251
252 return;
253 }
254 $this->showUploadForm( $this->getUploadForm() );
255 }
256
257 # Cleanup
258 if ( $this->mUpload ) {
259 $this->mUpload->cleanupTempFile();
260 }
261 }
262
268 protected function showUploadForm( $form ) {
269 # Add links if file was previously deleted
270 if ( $this->mDesiredDestName ) {
271 $this->showViewDeletedLinks();
272 }
273
274 if ( $form instanceof HTMLForm ) {
275 $form->show();
276 } else {
277 $this->getOutput()->addHTML( $form );
278 }
279 }
280
289 protected function getUploadForm( $message = '', $sessionKey = '', $hideIgnoreWarning = false ) {
290 # Initialize form
291 $form = new UploadForm(
292 [
293 'watch' => $this->getWatchCheck(),
294 'forreupload' => $this->mForReUpload,
295 'sessionkey' => $sessionKey,
296 'hideignorewarning' => $hideIgnoreWarning,
297 'destwarningack' => (bool)$this->mDestWarningAck,
298
299 'description' => $this->mComment,
300 'texttop' => $this->uploadFormTextTop,
301 'textaftersummary' => $this->uploadFormTextAfterSummary,
302 'destfile' => $this->mDesiredDestName,
303 ],
304 $this->getContext(),
305 $this->getLinkRenderer(),
306 $this->localRepo,
307 $this->getContentLanguage(),
308 $this->nsInfo
309 );
310 $form->setTitle( $this->getPageTitle() ); // Remove subpage
311
312 # Check the token, but only if necessary
313 if (
314 !$this->mTokenOk && !$this->mCancelUpload &&
315 ( $this->mUpload && $this->mUploadClicked )
316 ) {
317 $form->addPreText( $this->msg( 'session_fail_preview' )->parse() );
318 }
319
320 # Give a notice if the user is uploading a file that has been deleted or moved
321 # Note that this is independent from the message 'filewasdeleted'
322 $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
323 $delNotice = ''; // empty by default
324 if ( $desiredTitleObj instanceof Title && !$desiredTitleObj->exists() ) {
325 LogEventsList::showLogExtract( $delNotice, [ 'delete', 'move' ],
326 $desiredTitleObj,
327 '', [ 'lim' => 10,
328 'conds' => [ 'log_action != ' . $this->localRepo->getReplicaDB()->addQuotes( 'revision' ) ],
329 'showIfEmpty' => false,
330 'msgKey' => [ 'upload-recreate-warning' ] ]
331 );
332 }
333 $form->addPreText( $delNotice );
334
335 # Add text to form
336 $form->addPreText( '<div id="uploadtext">' .
337 $this->msg( 'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
338 '</div>' );
339 # Add upload error message
340 $form->addPreText( $message );
341
342 # Add footer to form
343 $uploadFooter = $this->msg( 'uploadfooter' );
344 if ( !$uploadFooter->isDisabled() ) {
345 $form->addPostText( '<div id="mw-upload-footer-message">'
346 . $uploadFooter->parseAsBlock() . "</div>\n" );
347 }
348
349 return $form;
350 }
351
355 protected function showViewDeletedLinks() {
356 $title = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
357 $user = $this->getUser();
358 // Show a subtitle link to deleted revisions (to sysops et al only)
359 if ( $title instanceof Title ) {
360 $count = $title->getDeletedEditsCount();
361 if ( $count > 0 && $this->getAuthority()->isAllowed( 'deletedhistory' ) ) {
362 $restorelink = $this->getLinkRenderer()->makeKnownLink(
363 SpecialPage::getTitleFor( 'Undelete', $title->getPrefixedText() ),
364 $this->msg( 'restorelink' )->numParams( $count )->text()
365 );
366 $link = $this->msg(
367 $this->getAuthority()->isAllowed( 'delete' ) ? 'thisisdeleted' : 'viewdeleted'
368 )->rawParams( $restorelink )->parseAsBlock();
369 $this->getOutput()->addHTML(
370 Html::rawElement(
371 'div',
372 [ 'id' => 'contentSub2' ],
373 $link
374 )
375 );
376 }
377 }
378 }
379
391 protected function showRecoverableUploadError( $message ) {
392 $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
393 if ( $stashStatus->isGood() ) {
394 $sessionKey = $stashStatus->getValue()->getFileKey();
395 $uploadWarning = 'upload-tryagain';
396 } else {
397 $sessionKey = null;
398 $uploadWarning = 'upload-tryagain-nostash';
399 }
400 $message = '<h2>' . $this->msg( 'uploaderror' )->escaped() . '</h2>' .
401 Html::errorBox( $message );
402
403 $form = $this->getUploadForm( $message, $sessionKey );
404 $form->setSubmitText( $this->msg( $uploadWarning )->escaped() );
405 $this->showUploadForm( $form );
406 }
407
416 protected function showUploadWarning( $warnings ) {
417 # If there are no warnings, or warnings we can ignore, return early.
418 # mDestWarningAck is set when some javascript has shown the warning
419 # to the user. mForReUpload is set when the user clicks the "upload a
420 # new version" link.
421 if ( !$warnings || ( count( $warnings ) == 1
422 && isset( $warnings['exists'] )
423 && ( $this->mDestWarningAck || $this->mForReUpload ) )
424 ) {
425 return false;
426 }
427
428 $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
429 if ( $stashStatus->isGood() ) {
430 $sessionKey = $stashStatus->getValue()->getFileKey();
431 $uploadWarning = 'uploadwarning-text';
432 } else {
433 $sessionKey = null;
434 $uploadWarning = 'uploadwarning-text-nostash';
435 }
436
437 // Add styles for the warning, reused from the live preview
438 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
439
440 $linkRenderer = $this->getLinkRenderer();
441 $warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
442 . '<div class="mw-destfile-warning"><ul>';
443 foreach ( $warnings as $warning => $args ) {
444 if ( $warning == 'badfilename' ) {
445 $this->mDesiredDestName = Title::makeTitle( NS_FILE, $args )->getText();
446 }
447 if ( $warning == 'exists' ) {
448 $msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
449 } elseif ( $warning == 'no-change' ) {
450 $file = $args;
451 $filename = $file->getTitle()->getPrefixedText();
452 $msg = "\t<li>" . $this->msg( 'fileexists-no-change', $filename )->parse() . "</li>\n";
453 } elseif ( $warning == 'duplicate-version' ) {
454 $file = $args[0];
455 $count = count( $args );
456 $filename = $file->getTitle()->getPrefixedText();
457 $message = $this->msg( 'fileexists-duplicate-version' )
458 ->params( $filename )
459 ->numParams( $count );
460 $msg = "\t<li>" . $message->parse() . "</li>\n";
461 } elseif ( $warning == 'was-deleted' ) {
462 # If the file existed before and was deleted, warn the user of this
463 $ltitle = SpecialPage::getTitleFor( 'Log' );
464 $llink = $linkRenderer->makeKnownLink(
465 $ltitle,
466 $this->msg( 'deletionlog' )->text(),
467 [],
468 [
469 'type' => 'delete',
470 'page' => Title::makeTitle( NS_FILE, $args )->getPrefixedText(),
471 ]
472 );
473 $msg = "\t<li>" . $this->msg( 'filewasdeleted' )->rawParams( $llink )->parse() . "</li>\n";
474 } elseif ( $warning == 'duplicate' ) {
475 $msg = $this->getDupeWarning( $args );
476 } elseif ( $warning == 'duplicate-archive' ) {
477 if ( $args === '' ) {
478 $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate-notitle' )->parse()
479 . "</li>\n";
480 } else {
481 $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate',
482 Title::makeTitle( NS_FILE, $args )->getPrefixedText() )->parse()
483 . "</li>\n";
484 }
485 } else {
486 if ( $args === true ) {
487 $args = [];
488 } elseif ( !is_array( $args ) ) {
489 $args = [ $args ];
490 }
491 $msg = "\t<li>" . $this->msg( $warning, $args )->parse() . "</li>\n";
492 }
493 $warningHtml .= $msg;
494 }
495 $warningHtml .= "</ul></div>\n";
496 $warningHtml .= $this->msg( $uploadWarning )->parseAsBlock();
497
498 $form = $this->getUploadForm( $warningHtml, $sessionKey, /* $hideIgnoreWarning */ true );
499 $form->setSubmitTextMsg( 'upload-tryagain' );
500 $form->addButton( [
501 'name' => 'wpUploadIgnoreWarning',
502 'value' => $this->msg( 'ignorewarning' )->text()
503 ] );
504 $form->addButton( [
505 'name' => 'wpCancelUpload',
506 'value' => $this->msg( 'reuploaddesc' )->text()
507 ] );
508
509 $this->showUploadForm( $form );
510
511 # Indicate that we showed a form
512 return true;
513 }
514
520 protected function showUploadError( $message ) {
521 $message = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . '</h2>' .
522 Html::errorBox( $message );
523 $this->showUploadForm( $this->getUploadForm( $message ) );
524 }
525
530 protected function processUpload() {
531 // Fetch the file if required
532 $status = $this->mUpload->fetchFile();
533 if ( !$status->isOK() ) {
534 $this->showUploadError( $this->getOutput()->parseAsInterface(
535 $status->getWikiText( false, false, $this->getLanguage() )
536 ) );
537
538 return;
539 }
540 if ( !$this->getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
541 wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file." );
542 // This code path is deprecated. If you want to break upload processing
543 // do so by hooking into the appropriate hooks in UploadBase::verifyUpload
544 // and UploadBase::verifyFile.
545 // If you use this hook to break uploading, the user will be returned
546 // an empty form with no error message whatsoever.
547 return;
548 }
549
550 // Upload verification
551 $details = $this->mUpload->verifyUpload();
552 if ( $details['status'] != UploadBase::OK ) {
553 $this->processVerificationError( $details );
554
555 return;
556 }
557
558 // Verify permissions for this title
559 $user = $this->getUser();
560 $permErrors = $this->mUpload->verifyTitlePermissions( $user );
561 if ( $permErrors !== true ) {
562 $code = array_shift( $permErrors[0] );
563 $this->showRecoverableUploadError( $this->msg( $code, $permErrors[0] )->parse() );
564
565 return;
566 }
567
568 $this->mLocalFile = $this->mUpload->getLocalFile();
569
570 // Check warnings if necessary
571 if ( !$this->mIgnoreWarning ) {
572 $warnings = $this->mUpload->checkWarnings( $user );
573 if ( $this->showUploadWarning( $warnings ) ) {
574 return;
575 }
576 }
577
578 // This is as late as we can throttle, after expected issues have been handled
579 if ( UploadBase::isThrottled( $user ) ) {
581 $this->msg( 'actionthrottledtext' )->escaped()
582 );
583 return;
584 }
585
586 // Get the page text if this is not a reupload
587 if ( !$this->mForReUpload ) {
588 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
589 $this->mCopyrightStatus, $this->mCopyrightSource, $this->getConfig() );
590 } else {
591 $pageText = false;
592 }
593
594 $changeTags = $this->getRequest()->getVal( 'wpChangeTags' );
595 if ( $changeTags === null || $changeTags === '' ) {
596 $changeTags = [];
597 } else {
598 $changeTags = array_filter( array_map( 'trim', explode( ',', $changeTags ) ) );
599 }
600
601 if ( $changeTags ) {
603 $changeTags, $user );
604 if ( !$changeTagsStatus->isOK() ) {
605 $this->showUploadError( $this->getOutput()->parseAsInterface(
606 $changeTagsStatus->getWikiText( false, false, $this->getLanguage() )
607 ) );
608
609 return;
610 }
611 }
612
613 $status = $this->mUpload->performUpload(
614 $this->mComment,
615 $pageText,
616 $this->mWatchthis,
617 $user,
618 $changeTags
619 );
620
621 if ( !$status->isGood() ) {
623 $this->getOutput()->parseAsInterface(
624 $status->getWikiText( false, false, $this->getLanguage() )
625 )
626 );
627
628 return;
629 }
630
631 // Success, redirect to description page
632 $this->mUploadSuccessful = true;
633 $this->getHookRunner()->onSpecialUploadComplete( $this );
634 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
635 }
636
646 public static function getInitialPageText( $comment = '', $license = '',
647 $copyStatus = '', $source = '', Config $config = null
648 ) {
649 if ( $config === null ) {
650 wfDebug( __METHOD__ . ' called without a Config instance passed to it' );
651 $config = MediaWikiServices::getInstance()->getMainConfig();
652 }
653
654 $msg = [];
655 $forceUIMsgAsContentMsg = (array)$config->get( MainConfigNames::ForceUIMsgAsContentMsg );
656 /* These messages are transcluded into the actual text of the description page.
657 * Thus, forcing them as content messages makes the upload to produce an int: template
658 * instead of hardcoding it there in the uploader language.
659 */
660 foreach ( [ 'license-header', 'filedesc', 'filestatus', 'filesource' ] as $msgName ) {
661 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
662 $msg[$msgName] = "{{int:$msgName}}";
663 } else {
664 $msg[$msgName] = wfMessage( $msgName )->inContentLanguage()->text();
665 }
666 }
667
668 $licenseText = '';
669 if ( $license !== '' ) {
670 $licenseText = '== ' . $msg['license-header'] . " ==\n{{" . $license . "}}\n";
671 }
672
673 $pageText = $comment . "\n";
674 $headerText = '== ' . $msg['filedesc'] . ' ==';
675 if ( $comment !== '' && strpos( $comment, $headerText ) === false ) {
676 // prepend header to page text unless it's already there (or there is no content)
677 $pageText = $headerText . "\n" . $pageText;
678 }
679
680 if ( $config->get( MainConfigNames::UseCopyrightUpload ) ) {
681 $pageText .= '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n";
682 $pageText .= $licenseText;
683 $pageText .= '== ' . $msg['filesource'] . " ==\n" . $source;
684 } else {
685 $pageText .= $licenseText;
686 }
687
688 // allow extensions to modify the content
689 Hooks::runner()->onUploadForm_getInitialPageText( $pageText, $msg, $config );
690
691 return $pageText;
692 }
693
706 protected function getWatchCheck() {
707 $user = $this->getUser();
708 if ( $this->userOptionsLookup->getBoolOption( $user, 'watchdefault' ) ) {
709 // Watch all edits!
710 return true;
711 }
712
713 $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
714 if ( $desiredTitleObj instanceof Title &&
715 $this->watchlistManager->isWatched( $user, $desiredTitleObj ) ) {
716 // Already watched, don't change that
717 return true;
718 }
719
720 $local = $this->localRepo->newFile( $this->mDesiredDestName );
721 if ( $local && $local->exists() ) {
722 // We're uploading a new version of an existing file.
723 // No creation, so don't watch it if we're not already.
724 return false;
725 } else {
726 // New page should get watched if that's our option.
727 return $this->userOptionsLookup->getBoolOption( $user, 'watchcreations' ) ||
728 $this->userOptionsLookup->getBoolOption( $user, 'watchuploads' );
729 }
730 }
731
738 protected function processVerificationError( $details ) {
739 switch ( $details['status'] ) {
741 case UploadBase::MIN_LENGTH_PARTNAME:
742 $this->showRecoverableUploadError( $this->msg( 'minlength1' )->escaped() );
743 break;
744 case UploadBase::ILLEGAL_FILENAME:
745 $this->showRecoverableUploadError( $this->msg( 'illegalfilename',
746 $details['filtered'] )->parse() );
747 break;
748 case UploadBase::FILENAME_TOO_LONG:
749 $this->showRecoverableUploadError( $this->msg( 'filename-toolong' )->escaped() );
750 break;
751 case UploadBase::FILETYPE_MISSING:
752 $this->showRecoverableUploadError( $this->msg( 'filetype-missing' )->parse() );
753 break;
754 case UploadBase::WINDOWS_NONASCII_FILENAME:
755 $this->showRecoverableUploadError( $this->msg( 'windows-nonascii-filename' )->parse() );
756 break;
757
759 case UploadBase::EMPTY_FILE:
760 $this->showUploadError( $this->msg( 'emptyfile' )->escaped() );
761 break;
762 case UploadBase::FILE_TOO_LARGE:
763 $this->showUploadError( $this->msg( 'largefileserver' )->escaped() );
764 break;
765 case UploadBase::FILETYPE_BADTYPE:
766 $msg = $this->msg( 'filetype-banned-type' );
767 if ( isset( $details['blacklistedExt'] ) ) {
768 $msg->params( $this->getLanguage()->commaList( $details['blacklistedExt'] ) );
769 } else {
770 $msg->params( $details['finalExt'] );
771 }
772 $extensions =
773 array_unique( $this->getConfig()->get( MainConfigNames::FileExtensions ) );
774 $msg->params( $this->getLanguage()->commaList( $extensions ),
775 count( $extensions ) );
776
777 // Add PLURAL support for the first parameter. This results
778 // in a bit unlogical parameter sequence, but does not break
779 // old translations
780 if ( isset( $details['blacklistedExt'] ) ) {
781 $msg->params( count( $details['blacklistedExt'] ) );
782 } else {
783 $msg->params( 1 );
784 }
785
786 $this->showUploadError( $msg->parse() );
787 break;
788 case UploadBase::VERIFICATION_ERROR:
789 unset( $details['status'] );
790 $code = array_shift( $details['details'] );
791 $this->showUploadError( $this->msg( $code, $details['details'] )->parse() );
792 break;
793 case UploadBase::HOOK_ABORTED:
794 if ( is_array( $details['error'] ) ) { # allow hooks to return error details in an array
795 $args = $details['error'];
796 $error = array_shift( $args );
797 } else {
798 $error = $details['error'];
799 $args = null;
800 }
801
802 $this->showUploadError( $this->msg( $error, $args )->parse() );
803 break;
804 default:
805 throw new MWException( __METHOD__ . ": Unknown value `{$details['status']}`" );
806 }
807 }
808
814 protected function unsaveUploadedFile() {
815 if ( !( $this->mUpload instanceof UploadFromStash ) ) {
816 return true;
817 }
818 $success = $this->mUpload->unsaveUploadedFile();
819 if ( !$success ) {
820 $this->getOutput()->showFatalError(
821 $this->msg( 'filedeleteerror' )
822 ->params( $this->mUpload->getTempPath() )
823 ->escaped()
824 );
825
826 return false;
827 } else {
828 return true;
829 }
830 }
831
841 public static function getExistsWarning( $exists ) {
842 if ( !$exists ) {
843 return '';
844 }
845
846 $file = $exists['file'];
847 $filename = $file->getTitle()->getPrefixedText();
848 $warnMsg = null;
849
850 if ( $exists['warning'] == 'exists' ) {
851 // Exact match
852 $warnMsg = wfMessage( 'fileexists', $filename );
853 } elseif ( $exists['warning'] == 'page-exists' ) {
854 // Page exists but file does not
855 $warnMsg = wfMessage( 'filepageexists', $filename );
856 } elseif ( $exists['warning'] == 'exists-normalized' ) {
857 $warnMsg = wfMessage( 'fileexists-extension', $filename,
858 $exists['normalizedFile']->getTitle()->getPrefixedText() );
859 } elseif ( $exists['warning'] == 'thumb' ) {
860 // Swapped argument order compared with other messages for backwards compatibility
861 $warnMsg = wfMessage( 'fileexists-thumbnail-yes',
862 $exists['thumbFile']->getTitle()->getPrefixedText(), $filename );
863 } elseif ( $exists['warning'] == 'thumb-name' ) {
864 // Image w/o '180px-' does not exists, but we do not like these filenames
865 $name = $file->getName();
866 $badPart = substr( $name, 0, strpos( $name, '-' ) + 1 );
867 $warnMsg = wfMessage( 'file-thumbnail-no', $badPart );
868 } elseif ( $exists['warning'] == 'bad-prefix' ) {
869 $warnMsg = wfMessage( 'filename-bad-prefix', $exists['prefix'] );
870 }
871
872 return $warnMsg ? $warnMsg->page( $file->getTitle() )->parse() : '';
873 }
874
880 public function getDupeWarning( $dupes ) {
881 if ( !$dupes ) {
882 return '';
883 }
884
885 $gallery = ImageGalleryBase::factory( false, $this->getContext() );
886 $gallery->setShowBytes( false );
887 $gallery->setShowDimensions( false );
888 foreach ( $dupes as $file ) {
889 $gallery->add( $file->getTitle() );
890 }
891
892 return '<li>' .
893 $this->msg( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
894 $gallery->toHTML() . "</li>\n";
895 }
896
897 protected function getGroupName() {
898 return 'media';
899 }
900
909 public static function rotationEnabled() {
910 $bitmapHandler = new BitmapHandler();
911 return $bitmapHandler->autoRotateEnabled();
912 }
913}
getUser()
getAuthority()
const NS_FILE
Definition Defines.php:70
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getContext()
Generic handler for bitmap images.
static canAddTagsAccompanyingChange(array $tags, Authority $performer=null, $checkBlock=true)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
An error page which can definitely be safely rendered using the OutputPage.
WebRequest clone which takes values from a provided array.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:150
Local file in the wiki's own database.
Definition LocalFile.php:60
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
Definition LocalRepo.php:39
MediaWiki exception.
A class containing constants representing the names of configuration variables.
Service locator for MediaWiki core services.
Provides access to user options.
This is a utility class for dealing with namespaces that encodes all the "magic" behaviors of them ba...
Show an error when a user tries to do something they do not have the necessary permissions for.
Prioritized list of file repositories.
Definition RepoGroup.php:29
Parent class for all special pages.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getOutput()
Get the OutputPage being used for this instance.
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,...
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getConfig()
Shortcut to get main config object.
getRequest()
Get the WebRequest being used for this instance.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getPageTitle( $subpage=false)
Get a self-referential title object.
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
getLanguage()
Shortcut to get user's language.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
getContentLanguage()
Shortcut to get content language.
Form for handling uploads and special page.
processVerificationError( $details)
Provides output to the user for a result of UploadBase::verifyUpload.
UploadBase $mUpload
showViewDeletedLinks()
Shows the "view X deleted revisions link"".
getWatchCheck()
See if we should check the 'watch this page' checkbox on the form based on the user's preferences and...
loadRequest()
Initialize instance variables from request and create an Upload handler.
static getInitialPageText( $comment='', $license='', $copyStatus='', $source='', Config $config=null)
Get the initial image page text based on a comment and optional file status information.
showUploadWarning( $warnings)
Stashes the upload, shows the main form, but adds a "continue anyway button".
bool $mCancelUpload
The user clicked "Cancel and return to upload form" button.
unsaveUploadedFile()
Remove a temporarily kept file stashed by saveTempUploadedFile().
userCanExecute(User $user)
This page can be shown if uploading is enabled.
static getExistsWarning( $exists)
Functions for formatting warnings.
string $mDesiredDestName
User input variables from the "description" section.
showRecoverableUploadError( $message)
Stashes the upload and shows the main upload form.
string $uploadFormTextAfterSummary
Raw html injection point for hooks not using HTMLForm.
$mDestWarningAck
Hidden variables.
getDupeWarning( $dupes)
Construct a warning and a gallery from an array of duplicate files.
showUploadForm( $form)
Show the main upload form.
WebRequest FauxRequest $mRequest
Misc variables.
processUpload()
Do the upload.
bool $mUploadSuccessful
Subclasses can use this to determine whether a file was uploaded.
LocalFile $mLocalFile
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
getUploadForm( $message='', $sessionKey='', $hideIgnoreWarning=false)
Get an UploadForm instance with title and text properly set.
doesWrites()
Indicates whether this special page may perform database writes.
string $uploadFormTextTop
Raw html injection point for hooks not using HTMLForm.
bool $mForReUpload
The user followed an "overwrite this file" link.
$mIgnoreWarning
User input variables from the root section.
showUploadError( $message)
Show the upload form with error message, but do not stash the file.
static rotationEnabled()
Should we rotate images in the preview on Special:Upload.
__construct(RepoGroup $repoGroup=null, UserOptionsLookup $userOptionsLookup=null, NamespaceInfo $nsInfo=null, WatchlistManager $watchlistManager=null)
Represents a title within MediaWiki.
Definition Title.php:49
exists( $flags=0)
Check if page exists.
Definition Title.php:3477
UploadBase and subclasses are the backend of MediaWiki's file uploads.
Sub class of HTMLForm that provides the form section of SpecialUpload.
Implements uploading from previously stored file.
Show an error when the user tries to do something whilst blocked.
internal since 1.36
Definition User.php:70
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Interface for configuration instances.
Definition Config.php:30
if( $line===false) $args
Definition mcc.php:124
$source
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42