49use Psr\Log\LoggerInterface;
51use UnexpectedValueException;
73 private LoggerInterface $log;
87 parent::__construct(
'Upload',
'upload' );
90 $this->jobQueueGroup = $services->getJobQueueGroup();
91 $repoGroup ??= $services->getRepoGroup();
92 $this->localRepo = $repoGroup->getLocalRepo();
93 $this->userOptionsLookup = $userOptionsLookup ?? $services->getUserOptionsLookup();
94 $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
95 $this->watchlistManager = $watchlistManager ?? $services->getWatchlistManager();
100 $this->log = LoggerFactory::getInstance(
'SpecialUpload' );
170 $this->mRequest = $request = $this->
getRequest();
171 $this->mSourceType = $request->getVal(
'wpSourceType',
'file' );
172 $this->mUpload = UploadBase::createFromRequest( $request );
173 $this->mUploadClicked = $request->wasPosted()
174 && ( $request->getCheck(
'wpUpload' )
175 || $request->getCheck(
'wpUploadIgnoreWarning' ) );
178 $this->mDesiredDestName = $request->getText(
'wpDestFile' );
179 if ( !$this->mDesiredDestName && $request->getFileName(
'wpUploadFile' ) !== null ) {
180 $this->mDesiredDestName = $request->getFileName(
'wpUploadFile' );
182 $this->mLicense = $request->getText(
'wpLicense' );
184 $this->mDestWarningAck = $request->getText(
'wpDestFileWarningAck' );
185 $this->mIgnoreWarning = $request->getCheck(
'wpIgnoreWarning' )
186 || $request->getCheck(
'wpUploadIgnoreWarning' );
187 $this->mWatchthis = $request->getBool(
'wpWatchthis' ) && $this->
getUser()->isRegistered();
188 $this->mCopyrightStatus = $request->getText(
'wpUploadCopyStatus' );
189 $this->mCopyrightSource = $request->getText(
'wpUploadSource' );
191 $this->mForReUpload = $request->getBool(
'wpForReUpload' );
193 $commentDefault =
'';
194 $commentMsg = $this->
msg(
'upload-default-description' )->inContentLanguage();
195 if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
196 $commentDefault = $commentMsg->plain();
198 $this->mComment = $request->getText(
'wpUploadDescription', $commentDefault );
200 $this->mCancelUpload = $request->getCheck(
'wpCancelUpload' )
201 || $request->getCheck(
'wpReUpload' );
204 $token = $request->getVal(
'wpEditToken' );
205 $this->mTokenOk = $this->
getUser()->matchEditToken( $token );
210 $this->mCacheKey = \UploadFromUrl::getCacheKeyFromRequest( $request );
212 $this->mCacheKey =
'';
215 $this->uploadFormTextTop =
'';
216 $this->uploadFormTextAfterSummary =
'';
225 return ( $this->mSourceType ===
'url' && $this->allowAsync );
237 return UploadBase::isEnabled() && parent::userCanExecute( $user );
249 # Check uploading enabled
250 if ( !UploadBase::isEnabled() ) {
251 throw new ErrorPageError(
'uploaddisabled',
'uploaddisabledtext' );
258 $permissionRequired = UploadBase::isAllowed( $user );
259 if ( $permissionRequired !==
true ) {
264 if ( $user->isBlockedFromUpload() ) {
269 $this->getLanguage(),
270 $this->getRequest()->getIP()
274 # Check whether we actually want to allow changing stuff
279 # Unsave the temporary file in case this was a cancelled upload
281 # Something went wrong, so unsaveUploadedFile showed a warning
285 # If we have a cache key, show the upload status.
286 if ( $this->mTokenOk && $this->mCacheKey !==
'' ) {
287 if ( $this->mUpload && $this->mUploadClicked && !$this->mCancelUpload ) {
288 # If the user clicked the upload button, we need to process the upload
291 # Show the upload status
295 # Process upload or show a form
296 $this->mTokenOk && !$this->mCancelUpload &&
297 ( $this->mUpload && $this->mUploadClicked )
301 # Backwards compatibility hook
302 if ( !$this->
getHookRunner()->onUploadForm_initial( $this ) ) {
303 wfDebug(
"Hook 'UploadForm:initial' broke output of the upload form" );
311 if ( $this->mUpload ) {
312 $this->mUpload->cleanupTempFile();
323 $progress = UploadBase::getSessionStatus( $user, $this->mCacheKey );
325 $progress = [
'status' => Status::newFatal(
'invalid-cache-key' ) ];
327 $this->log->debug(
'Upload status: stage {stage}, result {result}', $progress );
329 $status = $progress[
'status'] ?? Status::newFatal(
'invalid-cache-key' );
330 $stage = $progress[
'stage'] ??
'unknown';
331 $result = $progress[
'result'] ??
'unknown';
339 $this->mUploadSuccessful =
true;
343 $title = Title::makeTitleSafe(
NS_FILE, $this->mRequest->getText(
'wpDestFile' ) );
345 $this->log->debug(
'Purging page', [
'title' => $title->getText() ] );
349 $this->
getOutput()->redirect( $this->mRequest->getText(
'wpDestUrl' ) );
352 $this->
showUploadWarning( UploadBase::unserializeWarnings( $progress[
'warnings'] ) );
355 $details = $status->getValue();
357 if ( is_array( $details ) && isset( $details[
'verification'] ) ) {
361 $status->getWikiText(
false,
false, $this->getLanguage() ) )
366 $this->showUploadProgress(
367 [
'active' =>
true,
'msg' =>
'upload-progress-processing' ]
373 $status->getWikiText(
false,
false, $this->getLanguage() ) )
380 $this->showUploadProgress( [
'active' =>
false,
'msg' =>
'upload-progress-queued' ] );
387 $this->showUploadProgress( [
'active' =>
true,
'msg' =>
'upload-progress-downloading' ] );
392 $status->getWikiText(
false,
false, $this->getLanguage() ) )
398 $status->getWikiText(
false,
false, $this->getLanguage() ) )
405 if ( $status->isOK() ) {
406 $status = Status::newFatal(
'upload-progress-unknown' );
408 $statusmsg = $this->
getOutput()->parseAsInterface(
409 $status->getWikiText(
false,
false, $this->getLanguage() )
411 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' . HTML::errorBox( $statusmsg );
427 private function showUploadProgress( $options ) {
430 $message = $this->
msg( $options[
'msg'] )->escaped();
431 $destUrl = $this->mRequest->getText(
'wpDestUrl',
'' );
432 if ( !$destUrl && $this->mUpload ) {
433 if ( !$this->mLocalFile ) {
434 $this->mLocalFile = $this->mUpload->getLocalFile();
438 if ( $this->mLocalFile ===
null ) {
441 $destUrl = $this->mLocalFile->getTitle()->getFullURL();
447 $destName = $this->mRequest->getText(
'wpDestFile' );
451 $sourceURL = $this->mRequest->getText(
'wpUploadFileURL' );
453 $form =
new HTMLForm( [
456 'default' => $this->mCacheKey,
460 'default' => $this->mSourceType,
464 'default' => $destUrl,
468 'default' => $destName,
472 'default' => $sourceURL,
475 $form->setSubmitText( $this->
msg(
'upload-refresh' )->escaped() );
478 $preHtml =
"<div id='upload-progress-message'>$message</div>";
479 $form->addPreHtml( $preHtml );
480 $form->setSubmitCallback(
481 static function ( $formData ) {
485 $form->prepareForm();
486 $this->
getOutput()->addHTML( $form->getHTML(
false ) );
510 protected function getUploadForm( $message =
'', $sessionKey =
'', $hideIgnoreWarning =
false ) {
515 'forreupload' => $this->mForReUpload,
516 'sessionkey' => $sessionKey,
517 'hideignorewarning' => $hideIgnoreWarning,
518 'destwarningack' => (
bool)$this->mDestWarningAck,
520 'description' => $this->mComment,
521 'texttop' => $this->uploadFormTextTop,
522 'textaftersummary' => $this->uploadFormTextAfterSummary,
523 'destfile' => $this->mDesiredDestName,
534 # Check the token, but only if necessary
536 !$this->mTokenOk && !$this->mCancelUpload &&
537 ( $this->mUpload && $this->mUploadClicked )
539 $form->addPreHtml( $this->
msg(
'session_fail_preview' )->parse() );
542 # Give a notice if the user is uploading a file that has been deleted or moved
543 # Note that this is independent from the message 'filewasdeleted'
544 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
546 if ( $desiredTitleObj instanceof
Title && !$desiredTitleObj->
exists() ) {
547 LogEventsList::showLogExtract( $delNotice, [
'delete',
'move' ],
550 'conds' => [ $this->localRepo->getReplicaDB()->expr(
'log_action',
'!=',
'revision' ) ],
551 'showIfEmpty' =>
false,
552 'msgKey' => [
'upload-recreate-warning' ] ]
555 $form->addPreHtml( $delNotice );
558 $form->addPreHtml(
'<div id="uploadtext">' .
559 $this->
msg(
'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
561 # Add upload error message
562 $form->addPreHtml( $message );
565 $uploadFooter = $this->
msg(
'uploadfooter' );
566 if ( !$uploadFooter->isDisabled() ) {
567 $form->addPostHtml(
'<div id="mw-upload-footer-message">'
568 . $uploadFooter->parseAsBlock() .
"</div>\n" );
586 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
587 if ( $stashStatus->isGood() ) {
588 $sessionKey = $stashStatus->getValue()->getFileKey();
589 $uploadWarning =
'upload-tryagain';
592 $uploadWarning =
'upload-tryagain-nostash';
594 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' .
595 Html::errorBox( $message );
598 $form->setSubmitText( $this->
msg( $uploadWarning )->escaped() );
611 # If there are no warnings, or warnings we can ignore, return early.
612 # mDestWarningAck is set when some javascript has shown the warning
613 # to the user. mForReUpload is set when the user clicks the "upload a
615 if ( !$warnings || ( count( $warnings ) == 1
616 && isset( $warnings[
'exists'] )
617 && ( $this->mDestWarningAck || $this->mForReUpload ) )
622 if ( $this->mUpload ) {
623 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
624 if ( $stashStatus->isGood() ) {
625 $sessionKey = $stashStatus->getValue()->getFileKey();
626 $uploadWarning =
'uploadwarning-text';
629 $uploadWarning =
'uploadwarning-text-nostash';
633 $uploadWarning =
'uploadwarning-text-nostash';
637 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
640 $warningHtml =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
"</h2>\n"
641 .
'<div class="mw-destfile-warning"><ul>';
642 foreach ( $warnings as $warning => $args ) {
643 if ( $warning ==
'badfilename' ) {
644 $this->mDesiredDestName = Title::makeTitle(
NS_FILE, $args )->getText();
646 if ( $warning ==
'exists' ) {
648 } elseif ( $warning ==
'no-change' ) {
650 $filename = $file->getTitle()->getPrefixedText();
651 $msg =
"\t<li>" . $this->
msg(
'fileexists-no-change', $filename )->parse() .
"</li>\n";
652 } elseif ( $warning ==
'duplicate-version' ) {
654 $count = count( $args );
655 $filename = $file->getTitle()->getPrefixedText();
656 $message = $this->
msg(
'fileexists-duplicate-version' )
657 ->params( $filename )
658 ->numParams( $count );
659 $msg =
"\t<li>" . $message->parse() .
"</li>\n";
660 } elseif ( $warning ==
'was-deleted' ) {
661 # If the file existed before and was deleted, warn the user of this
663 $llink = $linkRenderer->makeKnownLink(
665 $this->
msg(
'deletionlog' )->text(),
669 'page' => Title::makeTitle(
NS_FILE, $args )->getPrefixedText(),
672 $msg =
"\t<li>" . $this->
msg(
'filewasdeleted' )->rawParams( $llink )->parse() .
"</li>\n";
673 } elseif ( $warning ==
'duplicate' ) {
675 } elseif ( $warning ==
'duplicate-archive' ) {
676 if ( $args ===
'' ) {
677 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate-notitle' )->parse()
680 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate',
681 Title::makeTitle(
NS_FILE, $args )->getPrefixedText() )->parse()
685 if ( $args ===
true ) {
687 } elseif ( !is_array( $args ) ) {
690 $msg =
"\t<li>" . $this->
msg( $warning, $args )->parse() .
"</li>\n";
692 $warningHtml .= $msg;
694 $warningHtml .=
"</ul></div>\n";
695 $warningHtml .= $this->
msg( $uploadWarning )->parseAsBlock();
697 $form = $this->
getUploadForm( $warningHtml, $sessionKey,
true );
698 $form->setSubmitTextMsg(
'upload-tryagain' );
700 'name' =>
'wpUploadIgnoreWarning',
701 'value' => $this->
msg(
'ignorewarning' )->text()
704 'name' =>
'wpCancelUpload',
705 'value' => $this->
msg(
'reuploaddesc' )->text()
710 # Indicate that we showed a form
720 $message =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
'</h2>' .
721 Html::errorBox( $message );
732 if ( !$fetchFileStatus->isOK() ) {
734 $fetchFileStatus->getWikiText(
false,
false, $this->getLanguage() )
739 if ( !$this->
getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
740 wfDebug(
"Hook 'UploadForm:BeforeProcessing' broke processing the file." );
754 $details = $this->mUpload->verifyUpload();
755 if ( $details[
'status'] != UploadBase::OK ) {
763 $permErrors = $this->mUpload->verifyTitlePermissions( $user );
764 if ( $permErrors !==
true ) {
765 $code = array_shift( $permErrors[0] );
771 $this->mLocalFile = $this->mUpload->getLocalFile();
774 if ( !$this->mIgnoreWarning ) {
775 $warnings = $this->mUpload->checkWarnings( $user );
791 if ( !$this->mForReUpload ) {
792 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
793 $this->mCopyrightStatus, $this->mCopyrightSource,
794 $this->getConfig() );
798 $changeTags = $this->getRequest()->getVal(
'wpChangeTags' );
799 if ( $changeTags ===
null || $changeTags ===
'' ) {
802 $changeTags = array_filter( array_map(
'trim', explode(
',', $changeTags ) ) );
806 $changeTags, $this->getUser() );
807 if ( !$changeTagsStatus->isOK() ) {
808 $this->showUploadError( $this->getOutput()->parseAsInterface(
809 $changeTagsStatus->getWikiText(
false,
false, $this->getLanguage() )
815 return [ $pageText, $changeTags ];
824 $status = $this->mUpload->fetchFile();
825 if ( !$this->performUploadChecks( $status ) ) {
828 $user = $this->getUser();
829 $pageAndTags = $this->getPageTextAndTags();
830 if ( $pageAndTags ===
null ) {
833 [ $pageText, $changeTags ] = $pageAndTags;
835 $status = $this->mUpload->performUpload(
843 if ( !$status->isGood() ) {
844 $this->showRecoverableUploadError(
845 $this->getOutput()->parseAsInterface(
846 $status->getWikiText(
false,
false, $this->getLanguage() )
854 $this->mUploadSuccessful =
true;
855 $this->getHookRunner()->onSpecialUploadComplete( $this );
856 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
865 $this->showUploadError( $this->msg(
'uploaderror' )->escaped() );
870 $status = $this->mUpload->canFetchFile();
871 if ( !$this->performUploadChecks( $status ) ) {
872 $this->log->debug(
'Upload failed verification: {error}', [
'error' => $status ] );
876 $pageAndTags = $this->getPageTextAndTags();
877 if ( $pageAndTags ===
null ) {
880 [ $pageText, $changeTags ] = $pageAndTags;
883 $job = new \UploadFromUrlJob(
885 'filename' => $this->mUpload->getDesiredDestName(),
886 'url' => $this->mUpload->getUrl(),
887 'comment' => $this->mComment,
888 'tags' => $changeTags,
890 'watch' => $this->mWatchthis,
891 'watchlistexpiry' =>
null,
892 'session' => $this->getContext()->exportSession(),
893 'reupload' => $this->mForReUpload,
894 'ignorewarnings' => $this->mIgnoreWarning,
898 $cacheKey =
$job->getCacheKey();
899 UploadBase::setSessionStatus( $this->getUser(), $cacheKey, [
900 'status' => Status::newGood(),
904 $this->log->info(
"Submitting UploadFromUrlJob for {filename}",
905 [
'filename' => $this->mUpload->getDesiredDestName() ]
908 $this->jobQueueGroup->push(
$job );
910 $this->showUploadStatus( $this->getUser() );
925 if ( $config ===
null ) {
926 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
936 foreach ( [
'license-header',
'filedesc',
'filestatus',
'filesource' ] as $msgName ) {
937 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
938 $msg[$msgName] =
"{{int:$msgName}}";
940 $msg[$msgName] =
wfMessage( $msgName )->inContentLanguage()->text();
945 if ( $license !==
'' ) {
946 $licenseText =
'== ' . $msg[
'license-header'] .
" ==\n{{" . $license .
"}}\n";
949 $pageText = $comment .
"\n";
950 $headerText =
'== ' . $msg[
'filedesc'] .
' ==';
951 if ( $comment !==
'' && !str_contains( $comment, $headerText ) ) {
953 $pageText = $headerText .
"\n" . $pageText;
957 $pageText .=
'== ' . $msg[
'filestatus'] .
" ==\n" . $copyStatus .
"\n";
958 $pageText .= $licenseText;
959 $pageText .=
'== ' . $msg[
'filesource'] .
" ==\n" .
$source;
961 $pageText .= $licenseText;
966 ->onUploadForm_getInitialPageText( $pageText, $msg, $config );
984 $user = $this->getUser();
985 if ( $this->userOptionsLookup->getBoolOption( $user,
'watchdefault' ) ) {
990 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
991 if ( $desiredTitleObj instanceof
Title &&
992 $this->watchlistManager->isWatched( $user, $desiredTitleObj ) ) {
997 $local = $this->localRepo->newFile( $this->mDesiredDestName );
998 if ( $local && $local->exists() ) {
1004 return $this->userOptionsLookup->getBoolOption( $user,
'watchcreations' ) ||
1005 $this->userOptionsLookup->getBoolOption( $user,
'watchuploads' );
1015 switch ( $details[
'status'] ) {
1017 case UploadBase::MIN_LENGTH_PARTNAME:
1018 $this->showRecoverableUploadError( $this->msg(
'minlength1' )->escaped() );
1020 case UploadBase::ILLEGAL_FILENAME:
1021 $this->showRecoverableUploadError( $this->msg(
'illegalfilename',
1022 $details[
'filtered'] )->parse() );
1024 case UploadBase::FILENAME_TOO_LONG:
1025 $this->showRecoverableUploadError( $this->msg(
'filename-toolong' )->escaped() );
1027 case UploadBase::FILETYPE_MISSING:
1028 $this->showRecoverableUploadError( $this->msg(
'filetype-missing' )->parse() );
1030 case UploadBase::WINDOWS_NONASCII_FILENAME:
1031 $this->showRecoverableUploadError( $this->msg(
'windows-nonascii-filename' )->parse() );
1035 case UploadBase::EMPTY_FILE:
1036 $this->showUploadError( $this->msg(
'emptyfile' )->escaped() );
1038 case UploadBase::FILE_TOO_LARGE:
1039 $this->showUploadError( $this->msg(
'largefileserver' )->escaped() );
1041 case UploadBase::FILETYPE_BADTYPE:
1042 $msg = $this->msg(
'filetype-banned-type' );
1043 if ( isset( $details[
'blacklistedExt'] ) ) {
1044 $msg->params( $this->getLanguage()->commaList( $details[
'blacklistedExt'] ) );
1046 $msg->params( $details[
'finalExt'] );
1050 $msg->params( $this->getLanguage()->commaList( $extensions ),
1051 count( $extensions ) );
1056 if ( isset( $details[
'blacklistedExt'] ) ) {
1057 $msg->params( count( $details[
'blacklistedExt'] ) );
1062 $this->showUploadError( $msg->parse() );
1064 case UploadBase::VERIFICATION_ERROR:
1065 unset( $details[
'status'] );
1066 $code = array_shift( $details[
'details'] );
1067 $this->showUploadError( $this->msg( $code, $details[
'details'] )->parse() );
1069 case UploadBase::HOOK_ABORTED:
1070 # allow hooks to return error details in an array, or as a single string key
1072 $this->showUploadError( $this->msg( $msg )->parse() );
1075 throw new UnexpectedValueException( __METHOD__ .
": Unknown value `{$details['status']}`" );
1088 $success = $this->mUpload->unsaveUploadedFile();
1090 $this->getOutput()->showErrorPage(
1093 [ $this->mUpload->getTempPath() ]
1116 $file = $exists[
'file'];
1117 $filename = $file->getTitle()->getPrefixedText();
1120 if ( $exists[
'warning'] ==
'exists' ) {
1122 $warnMsg =
wfMessage(
'fileexists', $filename );
1123 } elseif ( $exists[
'warning'] ==
'page-exists' ) {
1125 $warnMsg =
wfMessage(
'filepageexists', $filename );
1126 } elseif ( $exists[
'warning'] ==
'exists-normalized' ) {
1127 $warnMsg =
wfMessage(
'fileexists-extension', $filename,
1128 $exists[
'normalizedFile']->
getTitle()->getPrefixedText() );
1129 } elseif ( $exists[
'warning'] ==
'thumb' ) {
1131 $warnMsg =
wfMessage(
'fileexists-thumbnail-yes',
1132 $exists[
'thumbFile']->
getTitle()->getPrefixedText(), $filename );
1133 } elseif ( $exists[
'warning'] ==
'thumb-name' ) {
1135 $name = $file->getName();
1136 $badPart = substr( $name, 0, strpos( $name,
'-' ) + 1 );
1137 $warnMsg =
wfMessage(
'file-thumbnail-no', $badPart );
1138 } elseif ( $exists[
'warning'] ==
'bad-prefix' ) {
1139 $warnMsg =
wfMessage(
'filename-bad-prefix', $exists[
'prefix'] );
1142 return $warnMsg ? $warnMsg->page( $file->getTitle() )->parse() :
'';
1155 $gallery = ImageGalleryBase::factory(
false, $this->getContext() );
1156 $gallery->setShowBytes(
false );
1157 $gallery->setShowDimensions(
false );
1158 foreach ( $dupes as $file ) {
1159 $gallery->add( $file->getTitle() );
1163 $this->msg(
'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
1164 $gallery->toHTML() .
"</li>\n";
1181 return $bitmapHandler->autoRotateEnabled();
1189class_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