MediaWiki REL1_34
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( $user->getBlock() );
181 }
182
183 // Global blocks
184 if ( $user->isBlockedGlobally() ) {
185 throw new UserBlockedError( $user->getGlobalBlock() );
186 }
187
188 # Check whether we actually want to allow changing stuff
189 $this->checkReadOnly();
190
191 $this->loadRequest();
192
193 # Unsave the temporary file in case this was a cancelled upload
194 if ( $this->mCancelUpload && !$this->unsaveUploadedFile() ) {
195 # Something went wrong, so unsaveUploadedFile showed a warning
196 return;
197 }
198
199 # Process upload or show a form
200 if (
201 $this->mTokenOk && !$this->mCancelUpload &&
202 ( $this->mUpload && $this->mUploadClicked )
203 ) {
204 $this->processUpload();
205 } else {
206 # Backwards compatibility hook
207 // Avoid PHP 7.1 warning of passing $this by reference
208 $upload = $this;
209 if ( !Hooks::run( 'UploadForm:initial', [ &$upload ] ) ) {
210 wfDebug( "Hook 'UploadForm:initial' broke output of the upload form\n" );
211
212 return;
213 }
214 $this->showUploadForm( $this->getUploadForm() );
215 }
216
217 # Cleanup
218 if ( $this->mUpload ) {
219 $this->mUpload->cleanupTempFile();
220 }
221 }
222
228 protected function showUploadForm( $form ) {
229 # Add links if file was previously deleted
230 if ( $this->mDesiredDestName ) {
231 $this->showViewDeletedLinks();
232 }
233
234 if ( $form instanceof HTMLForm ) {
235 $form->show();
236 } else {
237 $this->getOutput()->addHTML( $form );
238 }
239 }
240
249 protected function getUploadForm( $message = '', $sessionKey = '', $hideIgnoreWarning = false ) {
250 # Initialize form
251 $context = new DerivativeContext( $this->getContext() );
252 $context->setTitle( $this->getPageTitle() ); // Remove subpage
253 $form = new UploadForm( [
254 'watch' => $this->getWatchCheck(),
255 'forreupload' => $this->mForReUpload,
256 'sessionkey' => $sessionKey,
257 'hideignorewarning' => $hideIgnoreWarning,
258 'destwarningack' => (bool)$this->mDestWarningAck,
259
260 'description' => $this->mComment,
261 'texttop' => $this->uploadFormTextTop,
262 'textaftersummary' => $this->uploadFormTextAfterSummary,
263 'destfile' => $this->mDesiredDestName,
264 ], $context, $this->getLinkRenderer() );
265
266 # Check the token, but only if necessary
267 if (
268 !$this->mTokenOk && !$this->mCancelUpload &&
269 ( $this->mUpload && $this->mUploadClicked )
270 ) {
271 $form->addPreText( $this->msg( 'session_fail_preview' )->parse() );
272 }
273
274 # Give a notice if the user is uploading a file that has been deleted or moved
275 # Note that this is independent from the message 'filewasdeleted'
276 $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
277 $delNotice = ''; // empty by default
278 if ( $desiredTitleObj instanceof Title && !$desiredTitleObj->exists() ) {
280
281 LogEventsList::showLogExtract( $delNotice, [ 'delete', 'move' ],
282 $desiredTitleObj,
283 '', [ 'lim' => 10,
284 'conds' => [ 'log_action != ' . $dbr->addQuotes( 'revision' ) ],
285 'showIfEmpty' => false,
286 'msgKey' => [ 'upload-recreate-warning' ] ]
287 );
288 }
289 $form->addPreText( $delNotice );
290
291 # Add text to form
292 $form->addPreText( '<div id="uploadtext">' .
293 $this->msg( 'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
294 '</div>' );
295 # Add upload error message
296 $form->addPreText( $message );
297
298 # Add footer to form
299 $uploadFooter = $this->msg( 'uploadfooter' );
300 if ( !$uploadFooter->isDisabled() ) {
301 $form->addPostText( '<div id="mw-upload-footer-message">'
302 . $uploadFooter->parseAsBlock() . "</div>\n" );
303 }
304
305 return $form;
306 }
307
311 protected function showViewDeletedLinks() {
312 $title = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
313 $user = $this->getUser();
314 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
315 // Show a subtitle link to deleted revisions (to sysops et al only)
316 if ( $title instanceof Title ) {
317 $count = $title->isDeleted();
318 if ( $count > 0 && $permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
319 $restorelink = $this->getLinkRenderer()->makeKnownLink(
320 SpecialPage::getTitleFor( 'Undelete', $title->getPrefixedText() ),
321 $this->msg( 'restorelink' )->numParams( $count )->text()
322 );
323 $link = $this->msg(
324 $permissionManager->userHasRight( $user, 'delete' ) ? 'thisisdeleted' : 'viewdeleted'
325 )->rawParams( $restorelink )->parseAsBlock();
326 $this->getOutput()->addHTML(
327 Html::rawElement(
328 'div',
329 [ 'id' => 'contentSub2' ],
330 $link
331 )
332 );
333 }
334 }
335 }
336
348 protected function showRecoverableUploadError( $message ) {
349 $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
350 if ( $stashStatus->isGood() ) {
351 $sessionKey = $stashStatus->getValue()->getFileKey();
352 $uploadWarning = 'upload-tryagain';
353 } else {
354 $sessionKey = null;
355 $uploadWarning = 'upload-tryagain-nostash';
356 }
357 $message = '<h2>' . $this->msg( 'uploaderror' )->escaped() . "</h2>\n" .
358 '<div class="error">' . $message . "</div>\n";
359
360 $form = $this->getUploadForm( $message, $sessionKey );
361 $form->setSubmitText( $this->msg( $uploadWarning )->escaped() );
362 $this->showUploadForm( $form );
363 }
364
373 protected function showUploadWarning( $warnings ) {
374 # If there are no warnings, or warnings we can ignore, return early.
375 # mDestWarningAck is set when some javascript has shown the warning
376 # to the user. mForReUpload is set when the user clicks the "upload a
377 # new version" link.
378 if ( !$warnings || ( count( $warnings ) == 1
379 && isset( $warnings['exists'] )
380 && ( $this->mDestWarningAck || $this->mForReUpload ) )
381 ) {
382 return false;
383 }
384
385 $stashStatus = $this->mUpload->tryStashFile( $this->getUser() );
386 if ( $stashStatus->isGood() ) {
387 $sessionKey = $stashStatus->getValue()->getFileKey();
388 $uploadWarning = 'uploadwarning-text';
389 } else {
390 $sessionKey = null;
391 $uploadWarning = 'uploadwarning-text-nostash';
392 }
393
394 // Add styles for the warning, reused from the live preview
395 $this->getOutput()->addModuleStyles( 'mediawiki.special' );
396
398 $warningHtml = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n"
399 . '<div class="mw-destfile-warning"><ul>';
400 foreach ( $warnings as $warning => $args ) {
401 if ( $warning == 'badfilename' ) {
402 $this->mDesiredDestName = Title::makeTitle( NS_FILE, $args )->getText();
403 }
404 if ( $warning == 'exists' ) {
405 $msg = "\t<li>" . self::getExistsWarning( $args ) . "</li>\n";
406 } elseif ( $warning == 'no-change' ) {
407 $file = $args;
408 $filename = $file->getTitle()->getPrefixedText();
409 $msg = "\t<li>" . $this->msg( 'fileexists-no-change', $filename )->parse() . "</li>\n";
410 } elseif ( $warning == 'duplicate-version' ) {
411 $file = $args[0];
412 $count = count( $args );
413 $filename = $file->getTitle()->getPrefixedText();
414 $message = $this->msg( 'fileexists-duplicate-version' )
415 ->params( $filename )
416 ->numParams( $count );
417 $msg = "\t<li>" . $message->parse() . "</li>\n";
418 } elseif ( $warning == 'was-deleted' ) {
419 # If the file existed before and was deleted, warn the user of this
420 $ltitle = SpecialPage::getTitleFor( 'Log' );
421 $llink = $linkRenderer->makeKnownLink(
422 $ltitle,
423 $this->msg( 'deletionlog' )->text(),
424 [],
425 [
426 'type' => 'delete',
427 'page' => Title::makeTitle( NS_FILE, $args )->getPrefixedText(),
428 ]
429 );
430 $msg = "\t<li>" . $this->msg( 'filewasdeleted' )->rawParams( $llink )->parse() . "</li>\n";
431 } elseif ( $warning == 'duplicate' ) {
432 $msg = $this->getDupeWarning( $args );
433 } elseif ( $warning == 'duplicate-archive' ) {
434 if ( $args === '' ) {
435 $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate-notitle' )->parse()
436 . "</li>\n";
437 } else {
438 $msg = "\t<li>" . $this->msg( 'file-deleted-duplicate',
439 Title::makeTitle( NS_FILE, $args )->getPrefixedText() )->parse()
440 . "</li>\n";
441 }
442 } else {
443 if ( $args === true ) {
444 $args = [];
445 } elseif ( !is_array( $args ) ) {
446 $args = [ $args ];
447 }
448 $msg = "\t<li>" . $this->msg( $warning, $args )->parse() . "</li>\n";
449 }
450 $warningHtml .= $msg;
451 }
452 $warningHtml .= "</ul></div>\n";
453 $warningHtml .= $this->msg( $uploadWarning )->parseAsBlock();
454
455 $form = $this->getUploadForm( $warningHtml, $sessionKey, /* $hideIgnoreWarning */ true );
456 $form->setSubmitText( $this->msg( 'upload-tryagain' )->text() );
457 $form->addButton( [
458 'name' => 'wpUploadIgnoreWarning',
459 'value' => $this->msg( 'ignorewarning' )->text()
460 ] );
461 $form->addButton( [
462 'name' => 'wpCancelUpload',
463 'value' => $this->msg( 'reuploaddesc' )->text()
464 ] );
465
466 $this->showUploadForm( $form );
467
468 # Indicate that we showed a form
469 return true;
470 }
471
477 protected function showUploadError( $message ) {
478 $message = '<h2>' . $this->msg( 'uploadwarning' )->escaped() . "</h2>\n" .
479 '<div class="error">' . $message . "</div>\n";
480 $this->showUploadForm( $this->getUploadForm( $message ) );
481 }
482
487 protected function processUpload() {
488 // Fetch the file if required
489 $status = $this->mUpload->fetchFile();
490 if ( !$status->isOK() ) {
491 $this->showUploadError( $this->getOutput()->parseAsInterface(
492 $status->getWikiText( false, false, $this->getLanguage() )
493 ) );
494
495 return;
496 }
497 // Avoid PHP 7.1 warning of passing $this by reference
498 $upload = $this;
499 if ( !Hooks::run( 'UploadForm:BeforeProcessing', [ &$upload ] ) ) {
500 wfDebug( "Hook 'UploadForm:BeforeProcessing' broke processing the file.\n" );
501 // This code path is deprecated. If you want to break upload processing
502 // do so by hooking into the appropriate hooks in UploadBase::verifyUpload
503 // and UploadBase::verifyFile.
504 // If you use this hook to break uploading, the user will be returned
505 // an empty form with no error message whatsoever.
506 return;
507 }
508
509 // Upload verification
510 $details = $this->mUpload->verifyUpload();
511 if ( $details['status'] != UploadBase::OK ) {
512 $this->processVerificationError( $details );
513
514 return;
515 }
516
517 // Verify permissions for this title
518 $permErrors = $this->mUpload->verifyTitlePermissions( $this->getUser() );
519 if ( $permErrors !== true ) {
520 $code = array_shift( $permErrors[0] );
521 $this->showRecoverableUploadError( $this->msg( $code, $permErrors[0] )->parse() );
522
523 return;
524 }
525
526 $this->mLocalFile = $this->mUpload->getLocalFile();
527
528 // Check warnings if necessary
529 if ( !$this->mIgnoreWarning ) {
530 $warnings = $this->mUpload->checkWarnings();
531 if ( $this->showUploadWarning( $warnings ) ) {
532 return;
533 }
534 }
535
536 // This is as late as we can throttle, after expected issues have been handled
537 if ( UploadBase::isThrottled( $this->getUser() ) ) {
539 $this->msg( 'actionthrottledtext' )->escaped()
540 );
541 return;
542 }
543
544 // Get the page text if this is not a reupload
545 if ( !$this->mForReUpload ) {
546 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
547 $this->mCopyrightStatus, $this->mCopyrightSource, $this->getConfig() );
548 } else {
549 $pageText = false;
550 }
551
552 $changeTags = $this->getRequest()->getVal( 'wpChangeTags' );
553 if ( is_null( $changeTags ) || $changeTags === '' ) {
554 $changeTags = [];
555 } else {
556 $changeTags = array_filter( array_map( 'trim', explode( ',', $changeTags ) ) );
557 }
558
559 if ( $changeTags ) {
561 $changeTags, $this->getUser() );
562 if ( !$changeTagsStatus->isOK() ) {
563 $this->showUploadError( $this->getOutput()->parseAsInterface(
564 $changeTagsStatus->getWikiText( false, false, $this->getLanguage() )
565 ) );
566
567 return;
568 }
569 }
570
571 $status = $this->mUpload->performUpload(
572 $this->mComment,
573 $pageText,
574 $this->mWatchthis,
575 $this->getUser(),
576 $changeTags
577 );
578
579 if ( !$status->isGood() ) {
581 $this->getOutput()->parseAsInterface(
582 $status->getWikiText( false, false, $this->getLanguage() )
583 )
584 );
585
586 return;
587 }
588
589 // Success, redirect to description page
590 $this->mUploadSuccessful = true;
591 // Avoid PHP 7.1 warning of passing $this by reference
592 $upload = $this;
593 Hooks::run( 'SpecialUploadComplete', [ &$upload ] );
594 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
595 }
596
606 public static function getInitialPageText( $comment = '', $license = '',
607 $copyStatus = '', $source = '', Config $config = null
608 ) {
609 if ( $config === null ) {
610 wfDebug( __METHOD__ . ' called without a Config instance passed to it' );
611 $config = MediaWikiServices::getInstance()->getMainConfig();
612 }
613
614 $msg = [];
615 $forceUIMsgAsContentMsg = (array)$config->get( 'ForceUIMsgAsContentMsg' );
616 /* These messages are transcluded into the actual text of the description page.
617 * Thus, forcing them as content messages makes the upload to produce an int: template
618 * instead of hardcoding it there in the uploader language.
619 */
620 foreach ( [ 'license-header', 'filedesc', 'filestatus', 'filesource' ] as $msgName ) {
621 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
622 $msg[$msgName] = "{{int:$msgName}}";
623 } else {
624 $msg[$msgName] = wfMessage( $msgName )->inContentLanguage()->text();
625 }
626 }
627
628 $licenseText = '';
629 if ( $license !== '' ) {
630 $licenseText = '== ' . $msg['license-header'] . " ==\n{{" . $license . "}}\n";
631 }
632
633 $pageText = $comment . "\n";
634 $headerText = '== ' . $msg['filedesc'] . ' ==';
635 if ( $comment !== '' && strpos( $comment, $headerText ) === false ) {
636 // prepend header to page text unless it's already there (or there is no content)
637 $pageText = $headerText . "\n" . $pageText;
638 }
639
640 if ( $config->get( 'UseCopyrightUpload' ) ) {
641 $pageText .= '== ' . $msg['filestatus'] . " ==\n" . $copyStatus . "\n";
642 $pageText .= $licenseText;
643 $pageText .= '== ' . $msg['filesource'] . " ==\n" . $source;
644 } else {
645 $pageText .= $licenseText;
646 }
647
648 // allow extensions to modify the content
649 Hooks::run( 'UploadForm:getInitialPageText', [ &$pageText, $msg, $config ] );
650
651 return $pageText;
652 }
653
666 protected function getWatchCheck() {
667 if ( $this->getUser()->getOption( 'watchdefault' ) ) {
668 // Watch all edits!
669 return true;
670 }
671
672 $desiredTitleObj = Title::makeTitleSafe( NS_FILE, $this->mDesiredDestName );
673 if ( $desiredTitleObj instanceof Title && $this->getUser()->isWatched( $desiredTitleObj ) ) {
674 // Already watched, don't change that
675 return true;
676 }
677
678 $local = MediaWikiServices::getInstance()->getRepoGroup()->getLocalRepo()
679 ->newFile( $this->mDesiredDestName );
680 if ( $local && $local->exists() ) {
681 // We're uploading a new version of an existing file.
682 // No creation, so don't watch it if we're not already.
683 return false;
684 } else {
685 // New page should get watched if that's our option.
686 return $this->getUser()->getOption( 'watchcreations' ) ||
687 $this->getUser()->getOption( 'watchuploads' );
688 }
689 }
690
697 protected function processVerificationError( $details ) {
698 switch ( $details['status'] ) {
701 $this->showRecoverableUploadError( $this->msg( 'minlength1' )->escaped() );
702 break;
704 $this->showRecoverableUploadError( $this->msg( 'illegalfilename',
705 $details['filtered'] )->parse() );
706 break;
708 $this->showRecoverableUploadError( $this->msg( 'filename-toolong' )->escaped() );
709 break;
711 $this->showRecoverableUploadError( $this->msg( 'filetype-missing' )->parse() );
712 break;
714 $this->showRecoverableUploadError( $this->msg( 'windows-nonascii-filename' )->parse() );
715 break;
716
719 $this->showUploadError( $this->msg( 'emptyfile' )->escaped() );
720 break;
722 $this->showUploadError( $this->msg( 'largefileserver' )->escaped() );
723 break;
725 $msg = $this->msg( 'filetype-banned-type' );
726 if ( isset( $details['blacklistedExt'] ) ) {
727 $msg->params( $this->getLanguage()->commaList( $details['blacklistedExt'] ) );
728 } else {
729 $msg->params( $details['finalExt'] );
730 }
731 $extensions = array_unique( $this->getConfig()->get( 'FileExtensions' ) );
732 $msg->params( $this->getLanguage()->commaList( $extensions ),
733 count( $extensions ) );
734
735 // Add PLURAL support for the first parameter. This results
736 // in a bit unlogical parameter sequence, but does not break
737 // old translations
738 if ( isset( $details['blacklistedExt'] ) ) {
739 $msg->params( count( $details['blacklistedExt'] ) );
740 } else {
741 $msg->params( 1 );
742 }
743
744 $this->showUploadError( $msg->parse() );
745 break;
747 unset( $details['status'] );
748 $code = array_shift( $details['details'] );
749 $this->showUploadError( $this->msg( $code, $details['details'] )->parse() );
750 break;
752 if ( is_array( $details['error'] ) ) { # allow hooks to return error details in an array
753 $args = $details['error'];
754 $error = array_shift( $args );
755 } else {
756 $error = $details['error'];
757 $args = null;
758 }
759
760 $this->showUploadError( $this->msg( $error, $args )->parse() );
761 break;
762 default:
763 throw new MWException( __METHOD__ . ": Unknown value `{$details['status']}`" );
764 }
765 }
766
772 protected function unsaveUploadedFile() {
773 if ( !( $this->mUpload instanceof UploadFromStash ) ) {
774 return true;
775 }
776 $success = $this->mUpload->unsaveUploadedFile();
777 if ( !$success ) {
778 $this->getOutput()->showFatalError(
779 $this->msg( 'filedeleteerror' )
780 ->params( $this->mUpload->getTempPath() )
781 ->escaped()
782 );
783
784 return false;
785 } else {
786 return true;
787 }
788 }
789
799 public static function getExistsWarning( $exists ) {
800 if ( !$exists ) {
801 return '';
802 }
803
804 $file = $exists['file'];
805 $filename = $file->getTitle()->getPrefixedText();
806 $warnMsg = null;
807
808 if ( $exists['warning'] == 'exists' ) {
809 // Exact match
810 $warnMsg = wfMessage( 'fileexists', $filename );
811 } elseif ( $exists['warning'] == 'page-exists' ) {
812 // Page exists but file does not
813 $warnMsg = wfMessage( 'filepageexists', $filename );
814 } elseif ( $exists['warning'] == 'exists-normalized' ) {
815 $warnMsg = wfMessage( 'fileexists-extension', $filename,
816 $exists['normalizedFile']->getTitle()->getPrefixedText() );
817 } elseif ( $exists['warning'] == 'thumb' ) {
818 // Swapped argument order compared with other messages for backwards compatibility
819 $warnMsg = wfMessage( 'fileexists-thumbnail-yes',
820 $exists['thumbFile']->getTitle()->getPrefixedText(), $filename );
821 } elseif ( $exists['warning'] == 'thumb-name' ) {
822 // Image w/o '180px-' does not exists, but we do not like these filenames
823 $name = $file->getName();
824 $badPart = substr( $name, 0, strpos( $name, '-' ) + 1 );
825 $warnMsg = wfMessage( 'file-thumbnail-no', $badPart );
826 } elseif ( $exists['warning'] == 'bad-prefix' ) {
827 $warnMsg = wfMessage( 'filename-bad-prefix', $exists['prefix'] );
828 }
829
830 return $warnMsg ? $warnMsg->title( $file->getTitle() )->parse() : '';
831 }
832
838 public function getDupeWarning( $dupes ) {
839 if ( !$dupes ) {
840 return '';
841 }
842
843 $gallery = ImageGalleryBase::factory( false, $this->getContext() );
844 $gallery->setShowBytes( false );
845 $gallery->setShowDimensions( false );
846 foreach ( $dupes as $file ) {
847 $gallery->add( $file->getTitle() );
848 }
849
850 return '<li>' .
851 $this->msg( 'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
852 $gallery->toHTML() . "</li>\n";
853 }
854
855 protected function getGroupName() {
856 return 'media';
857 }
858
867 public static function rotationEnabled() {
868 $bitmapHandler = new BitmapHandler();
869 return $bitmapHandler->autoRotateEnabled();
870 }
871}
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.
if( $line===false) $args
Definition cdb.php:64
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:131
Class to represent a local file in the wiki's own database.
Definition LocalFile.php:56
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
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.
getUser()
Shortcut to get the User executing 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,...
getContext()
Gets the context this SpecialPage is executed in.
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:4142
UploadBase and subclasses are the backend of MediaWiki's file uploads.
const EMPTY_FILE
static createFromRequest(&$request, $type=null)
Create a form of UploadBase depending on wpSourceType and initializes it.
const FILETYPE_MISSING
static isEnabled()
Returns true if uploads are enabled.
static isAllowed(UserIdentity $user)
Returns true if the user can use this upload module or else a string identifying the missing permissi...
const HOOK_ABORTED
const VERIFICATION_ERROR
const WINDOWS_NONASCII_FILENAME
const FILETYPE_BADTYPE
const FILE_TOO_LARGE
static isThrottled( $user)
Returns true if the user has surpassed the upload rate limit, false otherwise.
const ILLEGAL_FILENAME
const MIN_LENGTH_PARTNAME
const FILENAME_TOO_LONG
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:51
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
const NS_FILE
Definition Defines.php:75
Interface for configuration instances.
Definition Config.php:28
$context
Definition load.php:45
$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