MediaWiki REL1_35
SpecialUpload.php
Go to the documentation of this file.
1<?php
26
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;
51
53 public $mUpload;
54
58
63 public $mComment;
64 public $mLicense;
65
72
76
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 ) {
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() ) {
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(
335 Html::rawElement(
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
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 ) {
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'] ) {
705 case UploadBase::MIN_LENGTH_PARTNAME:
706 $this->showRecoverableUploadError( $this->msg( 'minlength1' )->escaped() );
707 break;
708 case UploadBase::ILLEGAL_FILENAME:
709 $this->showRecoverableUploadError( $this->msg( 'illegalfilename',
710 $details['filtered'] )->parse() );
711 break;
712 case UploadBase::FILENAME_TOO_LONG:
713 $this->showRecoverableUploadError( $this->msg( 'filename-toolong' )->escaped() );
714 break;
715 case UploadBase::FILETYPE_MISSING:
716 $this->showRecoverableUploadError( $this->msg( 'filetype-missing' )->parse() );
717 break;
718 case UploadBase::WINDOWS_NONASCII_FILENAME:
719 $this->showRecoverableUploadError( $this->msg( 'windows-nonascii-filename' )->parse() );
720 break;
721
723 case UploadBase::EMPTY_FILE:
724 $this->showUploadError( $this->msg( 'emptyfile' )->escaped() );
725 break;
726 case UploadBase::FILE_TOO_LARGE:
727 $this->showUploadError( $this->msg( 'largefileserver' )->escaped() );
728 break;
729 case UploadBase::FILETYPE_BADTYPE:
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;
751 case UploadBase::VERIFICATION_ERROR:
752 unset( $details['status'] );
753 $code = array_shift( $details['details'] );
754 $this->showUploadError( $this->msg( $code, $details['details'] )->parse() );
755 break;
756 case UploadBase::HOOK_ABORTED:
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}
getUser()
wfDebug( $text, $dest='all', array $context=[])
Sends a line to the debug log if enabled or, optionally, to a comment in output.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getContext()
Generic handler for bitmap images.
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...
An IContextSource implementation which will inherit context from another source but allow individual ...
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:135
Class to represent a local file in the wiki's own database.
Definition LocalFile.php:59
MediaWiki exception.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Show an error when a user tries to do something they do not have the necessary permissions for.
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.
MediaWiki Linker LinkRenderer null $linkRenderer
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 revivions 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".
$uploadFormTextTop
Text injection points for hooks not using HTMLForm.
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.
$mDestWarningAck
Hidden variables.
getDupeWarning( $dupes)
Construct a warning and a gallery from an array of duplicate files.
showUploadForm( $form)
Show the main upload form.
__construct( $request=null)
Get data POSTed through the form and assign them to the object.
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.
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.
Represents a title within MediaWiki.
Definition Title.php:42
exists( $flags=0)
Check if page exists.
Definition Title.php:4012
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.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:60
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
const NS_FILE
Definition Defines.php:76
Interface for configuration instances.
Definition Config.php:30
if( $line===false) $args
Definition mcc.php:124
$source
const DB_REPLICA
Definition defines.php:25
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42