48use Psr\Log\LoggerInterface;
50use UnexpectedValueException;
72 private LoggerInterface $log;
86 parent::__construct(
'Upload',
'upload' );
89 $this->jobQueueGroup = $services->getJobQueueGroup();
90 $repoGroup ??= $services->getRepoGroup();
91 $this->localRepo = $repoGroup->getLocalRepo();
92 $this->userOptionsLookup = $userOptionsLookup ?? $services->getUserOptionsLookup();
93 $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
94 $this->watchlistManager = $watchlistManager ?? $services->getWatchlistManager();
99 $this->log = LoggerFactory::getInstance(
'SpecialUpload' );
169 $this->mRequest = $request = $this->
getRequest();
170 $this->mSourceType = $request->getVal(
'wpSourceType',
'file' );
171 $this->mUpload = UploadBase::createFromRequest( $request );
172 $this->mUploadClicked = $request->wasPosted()
173 && ( $request->getCheck(
'wpUpload' )
174 || $request->getCheck(
'wpUploadIgnoreWarning' ) );
177 $this->mDesiredDestName = $request->getText(
'wpDestFile' );
178 if ( !$this->mDesiredDestName && $request->getFileName(
'wpUploadFile' ) !== null ) {
179 $this->mDesiredDestName = $request->getFileName(
'wpUploadFile' );
181 $this->mLicense = $request->getText(
'wpLicense' );
183 $this->mDestWarningAck = $request->getText(
'wpDestFileWarningAck' );
184 $this->mIgnoreWarning = $request->getCheck(
'wpIgnoreWarning' )
185 || $request->getCheck(
'wpUploadIgnoreWarning' );
186 $this->mWatchthis = $request->getBool(
'wpWatchthis' ) && $this->
getUser()->isRegistered();
187 $this->mCopyrightStatus = $request->getText(
'wpUploadCopyStatus' );
188 $this->mCopyrightSource = $request->getText(
'wpUploadSource' );
190 $this->mForReUpload = $request->getBool(
'wpForReUpload' );
192 $commentDefault =
'';
193 $commentMsg = $this->
msg(
'upload-default-description' )->inContentLanguage();
194 if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
195 $commentDefault = $commentMsg->plain();
197 $this->mComment = $request->getText(
'wpUploadDescription', $commentDefault );
199 $this->mCancelUpload = $request->getCheck(
'wpCancelUpload' )
200 || $request->getCheck(
'wpReUpload' );
203 $token = $request->getVal(
'wpEditToken' );
204 $this->mTokenOk = $this->
getUser()->matchEditToken( $token );
209 $this->mCacheKey = \UploadFromUrl::getCacheKeyFromRequest( $request );
211 $this->mCacheKey =
'';
214 $this->uploadFormTextTop =
'';
215 $this->uploadFormTextAfterSummary =
'';
224 return ( $this->mSourceType ===
'url' && $this->allowAsync );
236 return UploadBase::isEnabled() && parent::userCanExecute( $user );
248 # Check uploading enabled
249 if ( !UploadBase::isEnabled() ) {
250 throw new ErrorPageError(
'uploaddisabled',
'uploaddisabledtext' );
257 $permissionRequired = UploadBase::isAllowed( $user );
258 if ( $permissionRequired !==
true ) {
263 if ( $user->isBlockedFromUpload() ) {
268 $this->getLanguage(),
269 $this->getRequest()->getIP()
273 # Check whether we actually want to allow changing stuff
278 # Unsave the temporary file in case this was a cancelled upload
280 # Something went wrong, so unsaveUploadedFile showed a warning
284 # If we have a cache key, show the upload status.
285 if ( $this->mTokenOk && $this->mCacheKey !==
'' ) {
286 if ( $this->mUpload && $this->mUploadClicked && !$this->mCancelUpload ) {
287 # If the user clicked the upload button, we need to process the upload
290 # Show the upload status
294 # Process upload or show a form
295 $this->mTokenOk && !$this->mCancelUpload &&
296 ( $this->mUpload && $this->mUploadClicked )
300 # Backwards compatibility hook
301 if ( !$this->
getHookRunner()->onUploadForm_initial( $this ) ) {
302 wfDebug(
"Hook 'UploadForm:initial' broke output of the upload form" );
310 if ( $this->mUpload ) {
311 $this->mUpload->cleanupTempFile();
322 $progress = UploadBase::getSessionStatus( $user, $this->mCacheKey );
324 $progress = [
'status' => Status::newFatal(
'invalid-cache-key' ) ];
326 $this->log->debug(
'Upload status: stage {stage}, result {result}', $progress );
328 $status = $progress[
'status'] ?? Status::newFatal(
'invalid-cache-key' );
329 $stage = $progress[
'stage'] ??
'unknown';
330 $result = $progress[
'result'] ??
'unknown';
338 $this->mUploadSuccessful =
true;
342 $title = Title::makeTitleSafe(
NS_FILE, $this->mRequest->getText(
'wpDestFile' ) );
344 $this->log->debug(
'Purging page', [
'title' => $title->getText() ] );
348 $this->
getOutput()->redirect( $this->mRequest->getText(
'wpDestUrl' ) );
351 $this->
showUploadWarning( UploadBase::unserializeWarnings( $progress[
'warnings'] ) );
354 $details = $status->getValue();
356 if ( is_array( $details ) && isset( $details[
'verification'] ) ) {
360 $status->getWikiText(
false,
false, $this->getLanguage() ) )
365 $this->showUploadProgress(
366 [
'active' =>
true,
'msg' =>
'upload-progress-processing' ]
372 $status->getWikiText(
false,
false, $this->getLanguage() ) )
379 $this->showUploadProgress( [
'active' =>
false,
'msg' =>
'upload-progress-queued' ] );
386 $this->showUploadProgress( [
'active' =>
true,
'msg' =>
'upload-progress-downloading' ] );
391 $status->getWikiText(
false,
false, $this->getLanguage() ) )
397 $status->getWikiText(
false,
false, $this->getLanguage() ) )
404 if ( $status->isOK() ) {
405 $status = Status::newFatal(
'upload-progress-unknown' );
407 $statusmsg = $this->
getOutput()->parseAsInterface(
408 $status->getWikiText(
false,
false, $this->getLanguage() )
410 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' . HTML::errorBox( $statusmsg );
426 private function showUploadProgress( $options ) {
429 $message = $this->
msg( $options[
'msg'] )->escaped();
430 $destUrl = $this->mRequest->getText(
'wpDestUrl',
'' );
431 if ( !$destUrl && $this->mUpload ) {
432 if ( !$this->mLocalFile ) {
433 $this->mLocalFile = $this->mUpload->getLocalFile();
437 if ( $this->mLocalFile ===
null ) {
440 $destUrl = $this->mLocalFile->getTitle()->getFullURL();
446 $destName = $this->mRequest->getText(
'wpDestFile' );
450 $sourceURL = $this->mRequest->getText(
'wpUploadFileURL' );
452 $form =
new HTMLForm( [
455 'default' => $this->mCacheKey,
459 'default' => $this->mSourceType,
463 'default' => $destUrl,
467 'default' => $destName,
471 'default' => $sourceURL,
474 $form->setSubmitText( $this->
msg(
'upload-refresh' )->escaped() );
477 $preHtml =
"<div id='upload-progress-message'>$message</div>";
478 $form->addPreHtml( $preHtml );
479 $form->setSubmitCallback(
480 static function ( $formData ) {
484 $form->prepareForm();
485 $this->
getOutput()->addHTML( $form->getHTML(
false ) );
509 protected function getUploadForm( $message =
'', $sessionKey =
'', $hideIgnoreWarning =
false ) {
514 'forreupload' => $this->mForReUpload,
515 'sessionkey' => $sessionKey,
516 'hideignorewarning' => $hideIgnoreWarning,
517 'destwarningack' => (
bool)$this->mDestWarningAck,
519 'description' => $this->mComment,
520 'texttop' => $this->uploadFormTextTop,
521 'textaftersummary' => $this->uploadFormTextAfterSummary,
522 'destfile' => $this->mDesiredDestName,
533 # Check the token, but only if necessary
535 !$this->mTokenOk && !$this->mCancelUpload &&
536 ( $this->mUpload && $this->mUploadClicked )
538 $form->addPreHtml( $this->
msg(
'session_fail_preview' )->parse() );
541 # Give a notice if the user is uploading a file that has been deleted or moved
542 # Note that this is independent from the message 'filewasdeleted'
543 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
545 if ( $desiredTitleObj instanceof
Title && !$desiredTitleObj->
exists() ) {
546 LogEventsList::showLogExtract( $delNotice, [
'delete',
'move' ],
549 'conds' => [ $this->localRepo->getReplicaDB()->expr(
'log_action',
'!=',
'revision' ) ],
550 'showIfEmpty' =>
false,
551 'msgKey' => [
'upload-recreate-warning' ] ]
554 $form->addPreHtml( $delNotice );
557 $form->addPreHtml(
'<div id="uploadtext">' .
558 $this->
msg(
'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
560 # Add upload error message
561 $form->addPreHtml( $message );
564 $uploadFooter = $this->
msg(
'uploadfooter' );
565 if ( !$uploadFooter->isDisabled() ) {
566 $form->addPostHtml(
'<div id="mw-upload-footer-message">'
567 . $uploadFooter->parseAsBlock() .
"</div>\n" );
585 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
586 if ( $stashStatus->isGood() ) {
587 $sessionKey = $stashStatus->getValue()->getFileKey();
588 $uploadWarning =
'upload-tryagain';
591 $uploadWarning =
'upload-tryagain-nostash';
593 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' .
594 Html::errorBox( $message );
597 $form->setSubmitText( $this->
msg( $uploadWarning )->escaped() );
610 # If there are no warnings, or warnings we can ignore, return early.
611 # mDestWarningAck is set when some javascript has shown the warning
612 # to the user. mForReUpload is set when the user clicks the "upload a
614 if ( !$warnings || ( count( $warnings ) == 1
615 && isset( $warnings[
'exists'] )
616 && ( $this->mDestWarningAck || $this->mForReUpload ) )
621 if ( $this->mUpload ) {
622 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
623 if ( $stashStatus->isGood() ) {
624 $sessionKey = $stashStatus->getValue()->getFileKey();
625 $uploadWarning =
'uploadwarning-text';
628 $uploadWarning =
'uploadwarning-text-nostash';
632 $uploadWarning =
'uploadwarning-text-nostash';
636 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
639 $warningHtml =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
"</h2>\n"
640 .
'<div class="mw-destfile-warning"><ul>';
641 foreach ( $warnings as $warning => $args ) {
642 if ( $warning ==
'badfilename' ) {
643 $this->mDesiredDestName = Title::makeTitle(
NS_FILE, $args )->getText();
645 if ( $warning ==
'exists' ) {
647 } elseif ( $warning ==
'no-change' ) {
649 $filename = $file->getTitle()->getPrefixedText();
650 $msg =
"\t<li>" . $this->
msg(
'fileexists-no-change', $filename )->parse() .
"</li>\n";
651 } elseif ( $warning ==
'duplicate-version' ) {
653 $count = count( $args );
654 $filename = $file->getTitle()->getPrefixedText();
655 $message = $this->
msg(
'fileexists-duplicate-version' )
656 ->params( $filename )
657 ->numParams( $count );
658 $msg =
"\t<li>" . $message->parse() .
"</li>\n";
659 } elseif ( $warning ==
'was-deleted' ) {
660 # If the file existed before and was deleted, warn the user of this
662 $llink = $linkRenderer->makeKnownLink(
664 $this->
msg(
'deletionlog' )->text(),
668 'page' => Title::makeTitle(
NS_FILE, $args )->getPrefixedText(),
671 $msg =
"\t<li>" . $this->
msg(
'filewasdeleted' )->rawParams( $llink )->parse() .
"</li>\n";
672 } elseif ( $warning ==
'duplicate' ) {
674 } elseif ( $warning ==
'duplicate-archive' ) {
675 if ( $args ===
'' ) {
676 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate-notitle' )->parse()
679 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate',
680 Title::makeTitle(
NS_FILE, $args )->getPrefixedText() )->parse()
684 if ( $args ===
true ) {
686 } elseif ( !is_array( $args ) ) {
689 $msg =
"\t<li>" . $this->
msg( $warning, $args )->parse() .
"</li>\n";
691 $warningHtml .= $msg;
693 $warningHtml .=
"</ul></div>\n";
694 $warningHtml .= $this->
msg( $uploadWarning )->parseAsBlock();
696 $form = $this->
getUploadForm( $warningHtml, $sessionKey,
true );
697 $form->setSubmitTextMsg(
'upload-tryagain' );
699 'name' =>
'wpUploadIgnoreWarning',
700 'value' => $this->
msg(
'ignorewarning' )->text()
703 'name' =>
'wpCancelUpload',
704 'value' => $this->
msg(
'reuploaddesc' )->text()
709 # Indicate that we showed a form
719 $message =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
'</h2>' .
720 Html::errorBox( $message );
731 if ( !$fetchFileStatus->isOK() ) {
733 $fetchFileStatus->getWikiText(
false,
false, $this->getLanguage() )
738 if ( !$this->
getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
739 wfDebug(
"Hook 'UploadForm:BeforeProcessing' broke processing the file." );
753 $details = $this->mUpload->verifyUpload();
754 if ( $details[
'status'] != UploadBase::OK ) {
762 $permErrors = $this->mUpload->verifyTitlePermissions( $user );
763 if ( $permErrors !==
true ) {
764 $code = array_shift( $permErrors[0] );
770 $this->mLocalFile = $this->mUpload->getLocalFile();
773 if ( !$this->mIgnoreWarning ) {
774 $warnings = $this->mUpload->checkWarnings( $user );
790 if ( !$this->mForReUpload ) {
791 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
792 $this->mCopyrightStatus, $this->mCopyrightSource,
793 $this->getConfig() );
797 $changeTags = $this->getRequest()->getVal(
'wpChangeTags' );
798 if ( $changeTags ===
null || $changeTags ===
'' ) {
801 $changeTags = array_filter( array_map(
'trim', explode(
',', $changeTags ) ) );
805 $changeTags, $this->getUser() );
806 if ( !$changeTagsStatus->isOK() ) {
807 $this->showUploadError( $this->getOutput()->parseAsInterface(
808 $changeTagsStatus->getWikiText(
false,
false, $this->getLanguage() )
814 return [ $pageText, $changeTags ];
823 $status = $this->mUpload->fetchFile();
824 if ( !$this->performUploadChecks( $status ) ) {
827 $user = $this->getUser();
828 $pageAndTags = $this->getPageTextAndTags();
829 if ( $pageAndTags ===
null ) {
832 [ $pageText, $changeTags ] = $pageAndTags;
834 $status = $this->mUpload->performUpload(
842 if ( !$status->isGood() ) {
843 $this->showRecoverableUploadError(
844 $this->getOutput()->parseAsInterface(
845 $status->getWikiText(
false,
false, $this->getLanguage() )
853 $this->mUploadSuccessful =
true;
854 $this->getHookRunner()->onSpecialUploadComplete( $this );
855 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
864 $this->showUploadError( $this->msg(
'uploaderror' )->escaped() );
869 $status = $this->mUpload->canFetchFile();
870 if ( !$this->performUploadChecks( $status ) ) {
871 $this->log->debug(
'Upload failed verification: {error}', [
'error' => $status ] );
875 $pageAndTags = $this->getPageTextAndTags();
876 if ( $pageAndTags ===
null ) {
879 [ $pageText, $changeTags ] = $pageAndTags;
882 $job = new \UploadFromUrlJob(
884 'filename' => $this->mUpload->getDesiredDestName(),
885 'url' => $this->mUpload->getUrl(),
886 'comment' => $this->mComment,
887 'tags' => $changeTags,
889 'watch' => $this->mWatchthis,
890 'watchlistexpiry' =>
null,
891 'session' => $this->getContext()->exportSession(),
892 'reupload' => $this->mForReUpload,
893 'ignorewarnings' => $this->mIgnoreWarning,
897 $cacheKey =
$job->getCacheKey();
898 UploadBase::setSessionStatus( $this->getUser(), $cacheKey, [
899 'status' => Status::newGood(),
903 $this->log->info(
"Submitting UploadFromUrlJob for {filename}",
904 [
'filename' => $this->mUpload->getDesiredDestName() ]
907 $this->jobQueueGroup->push(
$job );
909 $this->showUploadStatus( $this->getUser() );
924 if ( $config ===
null ) {
925 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
935 foreach ( [
'license-header',
'filedesc',
'filestatus',
'filesource' ] as $msgName ) {
936 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
937 $msg[$msgName] =
"{{int:$msgName}}";
939 $msg[$msgName] =
wfMessage( $msgName )->inContentLanguage()->text();
944 if ( $license !==
'' ) {
945 $licenseText =
'== ' . $msg[
'license-header'] .
" ==\n{{" . $license .
"}}\n";
948 $pageText = $comment .
"\n";
949 $headerText =
'== ' . $msg[
'filedesc'] .
' ==';
950 if ( $comment !==
'' && !str_contains( $comment, $headerText ) ) {
952 $pageText = $headerText .
"\n" . $pageText;
956 $pageText .=
'== ' . $msg[
'filestatus'] .
" ==\n" . $copyStatus .
"\n";
957 $pageText .= $licenseText;
958 $pageText .=
'== ' . $msg[
'filesource'] .
" ==\n" .
$source;
960 $pageText .= $licenseText;
965 ->onUploadForm_getInitialPageText( $pageText, $msg, $config );
983 $user = $this->getUser();
984 if ( $this->userOptionsLookup->getBoolOption( $user,
'watchdefault' ) ) {
989 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
990 if ( $desiredTitleObj instanceof
Title &&
991 $this->watchlistManager->isWatched( $user, $desiredTitleObj ) ) {
996 $local = $this->localRepo->newFile( $this->mDesiredDestName );
997 if ( $local && $local->exists() ) {
1003 return $this->userOptionsLookup->getBoolOption( $user,
'watchcreations' ) ||
1004 $this->userOptionsLookup->getBoolOption( $user,
'watchuploads' );
1014 switch ( $details[
'status'] ) {
1016 case UploadBase::MIN_LENGTH_PARTNAME:
1017 $this->showRecoverableUploadError( $this->msg(
'minlength1' )->escaped() );
1019 case UploadBase::ILLEGAL_FILENAME:
1020 $this->showRecoverableUploadError( $this->msg(
'illegalfilename',
1021 $details[
'filtered'] )->parse() );
1023 case UploadBase::FILENAME_TOO_LONG:
1024 $this->showRecoverableUploadError( $this->msg(
'filename-toolong' )->escaped() );
1026 case UploadBase::FILETYPE_MISSING:
1027 $this->showRecoverableUploadError( $this->msg(
'filetype-missing' )->parse() );
1029 case UploadBase::WINDOWS_NONASCII_FILENAME:
1030 $this->showRecoverableUploadError( $this->msg(
'windows-nonascii-filename' )->parse() );
1034 case UploadBase::EMPTY_FILE:
1035 $this->showUploadError( $this->msg(
'emptyfile' )->escaped() );
1037 case UploadBase::FILE_TOO_LARGE:
1038 $this->showUploadError( $this->msg(
'largefileserver' )->escaped() );
1040 case UploadBase::FILETYPE_BADTYPE:
1041 $msg = $this->msg(
'filetype-banned-type' );
1042 if ( isset( $details[
'blacklistedExt'] ) ) {
1043 $msg->params( $this->getLanguage()->commaList( $details[
'blacklistedExt'] ) );
1045 $msg->params( $details[
'finalExt'] );
1049 $msg->params( $this->getLanguage()->commaList( $extensions ),
1050 count( $extensions ) );
1055 if ( isset( $details[
'blacklistedExt'] ) ) {
1056 $msg->params( count( $details[
'blacklistedExt'] ) );
1061 $this->showUploadError( $msg->parse() );
1063 case UploadBase::VERIFICATION_ERROR:
1064 unset( $details[
'status'] );
1065 $code = array_shift( $details[
'details'] );
1066 $this->showUploadError( $this->msg( $code, $details[
'details'] )->parse() );
1068 case UploadBase::HOOK_ABORTED:
1069 if ( is_array( $details[
'error'] ) ) { # allow hooks to
return error details in an array
1070 $args = $details[
'error'];
1071 $error = array_shift( $args );
1073 $error = $details[
'error'];
1077 $this->showUploadError( $this->msg( $error, $args )->parse() );
1080 throw new UnexpectedValueException( __METHOD__ .
": Unknown value `{$details['status']}`" );
1093 $success = $this->mUpload->unsaveUploadedFile();
1095 $this->getOutput()->showErrorPage(
1098 [ $this->mUpload->getTempPath() ]
1121 $file = $exists[
'file'];
1122 $filename = $file->getTitle()->getPrefixedText();
1125 if ( $exists[
'warning'] ==
'exists' ) {
1127 $warnMsg =
wfMessage(
'fileexists', $filename );
1128 } elseif ( $exists[
'warning'] ==
'page-exists' ) {
1130 $warnMsg =
wfMessage(
'filepageexists', $filename );
1131 } elseif ( $exists[
'warning'] ==
'exists-normalized' ) {
1132 $warnMsg =
wfMessage(
'fileexists-extension', $filename,
1133 $exists[
'normalizedFile']->
getTitle()->getPrefixedText() );
1134 } elseif ( $exists[
'warning'] ==
'thumb' ) {
1136 $warnMsg =
wfMessage(
'fileexists-thumbnail-yes',
1137 $exists[
'thumbFile']->
getTitle()->getPrefixedText(), $filename );
1138 } elseif ( $exists[
'warning'] ==
'thumb-name' ) {
1140 $name = $file->getName();
1141 $badPart = substr( $name, 0, strpos( $name,
'-' ) + 1 );
1142 $warnMsg =
wfMessage(
'file-thumbnail-no', $badPart );
1143 } elseif ( $exists[
'warning'] ==
'bad-prefix' ) {
1144 $warnMsg =
wfMessage(
'filename-bad-prefix', $exists[
'prefix'] );
1147 return $warnMsg ? $warnMsg->page( $file->getTitle() )->parse() :
'';
1160 $gallery = ImageGalleryBase::factory(
false, $this->getContext() );
1161 $gallery->setShowBytes(
false );
1162 $gallery->setShowDimensions(
false );
1163 foreach ( $dupes as $file ) {
1164 $gallery->add( $file->getTitle() );
1168 $this->msg(
'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
1169 $gallery->toHTML() .
"</li>\n";
1186 return $bitmapHandler->autoRotateEnabled();
1194class_alias( SpecialUpload::class,
'SpecialUpload' );
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.
if(!defined('MW_SETUP_CALLBACK'))
Generic handler for bitmap images.
An error page which can definitely be safely rendered using the OutputPage.
Handle enqueueing of background jobs.
Local file in the wiki's own database.
Local repository that stores files in the local filesystem and registers them in the wiki's own datab...
A class containing constants representing the names of configuration variables.
const EnableAsyncUploads
Name constant for the EnableAsyncUploads setting, for use with Config::get()
const ForceUIMsgAsContentMsg
Name constant for the ForceUIMsgAsContentMsg setting, for use with Config::get()
const UseCopyrightUpload
Name constant for the UseCopyrightUpload setting, for use with Config::get()
const FileExtensions
Name constant for the FileExtensions setting, for use with Config::get()
const EnableAsyncUploadsByURL
Name constant for the EnableAsyncUploadsByURL setting, for use with Config::get()
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
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,...
getUser()
Shortcut to get the User executing this instance.
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
getPageTitle( $subpage=false)
Get a self-referential title object.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getConfig()
Shortcut to get main config object.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getContentLanguage()
Shortcut to get content language.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages By default the message key is the canonical name of...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Show an error when a user tries to do something they do not have the necessary permissions for.
Prioritized list of file repositories.
UploadBase and subclasses are the backend of MediaWiki's file uploads.
Implements uploading from previously stored file.
Implements uploading from a HTTP resource.
Show an error when the user tries to do something whilst blocked.
Special handling for representing file pages.
if(count( $args)< 1) $job