52use Psr\Log\LoggerInterface;
54use UnexpectedValueException;
76 private LoggerInterface $log;
90 parent::__construct(
'Upload',
'upload' );
93 $this->jobQueueGroup = $services->getJobQueueGroup();
94 $repoGroup ??= $services->getRepoGroup();
95 $this->localRepo = $repoGroup->getLocalRepo();
96 $this->userOptionsLookup = $userOptionsLookup ?? $services->getUserOptionsLookup();
97 $this->nsInfo = $nsInfo ?? $services->getNamespaceInfo();
98 $this->watchlistManager = $watchlistManager ?? $services->getWatchlistManager();
103 $this->log = LoggerFactory::getInstance(
'SpecialUpload' );
165 $this->mRequest = $request = $this->
getRequest();
166 $this->mSourceType = $request->getVal(
'wpSourceType',
'file' );
167 $this->mUpload = UploadBase::createFromRequest( $request );
168 $this->mUploadClicked = $request->wasPosted()
169 && ( $request->getCheck(
'wpUpload' )
170 || $request->getCheck(
'wpUploadIgnoreWarning' ) );
173 $this->mDesiredDestName = $request->getText(
'wpDestFile' );
174 if ( !$this->mDesiredDestName && $request->getFileName(
'wpUploadFile' ) !== null ) {
175 $this->mDesiredDestName = $request->getFileName(
'wpUploadFile' );
177 $this->mLicense = $request->getText(
'wpLicense' );
179 $this->mDestWarningAck = $request->getText(
'wpDestFileWarningAck' );
180 $this->mIgnoreWarning = $request->getCheck(
'wpIgnoreWarning' )
181 || $request->getCheck(
'wpUploadIgnoreWarning' );
182 $this->mWatchthis = $request->getBool(
'wpWatchthis' ) && $this->
getUser()->isRegistered();
183 $this->mCopyrightStatus = $request->getText(
'wpUploadCopyStatus' );
184 $this->mCopyrightSource = $request->getText(
'wpUploadSource' );
186 $this->mForReUpload = $request->getBool(
'wpForReUpload' );
188 $commentDefault =
'';
189 $commentMsg = $this->
msg(
'upload-default-description' )->inContentLanguage();
190 if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
191 $commentDefault = $commentMsg->plain();
193 $this->mComment = $request->getText(
'wpUploadDescription', $commentDefault );
195 $this->mCancelUpload = $request->getCheck(
'wpCancelUpload' )
196 || $request->getCheck(
'wpReUpload' );
199 $token = $request->getVal(
'wpEditToken' );
200 $this->mTokenOk = $this->
getUser()->matchEditToken( $token );
205 $this->mCacheKey = \UploadFromUrl::getCacheKeyFromRequest( $request );
207 $this->mCacheKey =
'';
210 $this->uploadFormTextTop =
'';
211 $this->uploadFormTextAfterSummary =
'';
220 return ( $this->mSourceType ===
'url' && $this->allowAsync );
232 return UploadBase::isEnabled() && parent::userCanExecute( $user );
244 # Check uploading enabled
245 if ( !UploadBase::isEnabled() ) {
246 throw new ErrorPageError(
'uploaddisabled',
'uploaddisabledtext' );
253 $permissionRequired = UploadBase::isAllowed( $user );
254 if ( $permissionRequired !==
true ) {
259 if ( $user->isBlockedFromUpload() ) {
264 $this->getLanguage(),
265 $this->getRequest()->getIP()
269 # Check whether we actually want to allow changing stuff
274 # Unsave the temporary file in case this was a cancelled upload
276 # Something went wrong, so unsaveUploadedFile showed a warning
280 # If we have a cache key, show the upload status.
281 if ( $this->mTokenOk && $this->mCacheKey !==
'' ) {
282 if ( $this->mUpload && $this->mUploadClicked && !$this->mCancelUpload ) {
283 # If the user clicked the upload button, we need to process the upload
286 # Show the upload status
290 # Process upload or show a form
291 $this->mTokenOk && !$this->mCancelUpload &&
292 ( $this->mUpload && $this->mUploadClicked )
296 # Backwards compatibility hook
297 if ( !$this->
getHookRunner()->onUploadForm_initial( $this ) ) {
298 wfDebug(
"Hook 'UploadForm:initial' broke output of the upload form" );
306 if ( $this->mUpload ) {
307 $this->mUpload->cleanupTempFile();
318 $progress = UploadBase::getSessionStatus( $user, $this->mCacheKey );
320 $progress = [
'status' => Status::newFatal(
'invalid-cache-key' ) ];
322 $this->log->debug(
'Upload status: stage {stage}, result {result}', $progress );
324 $status = $progress[
'status'] ?? Status::newFatal(
'invalid-cache-key' );
325 $stage = $progress[
'stage'] ??
'unknown';
326 $result = $progress[
'result'] ??
'unknown';
334 $this->mUploadSuccessful =
true;
338 $title = Title::makeTitleSafe(
NS_FILE, $this->mRequest->getText(
'wpDestFile' ) );
340 $this->log->debug(
'Purging page', [
'title' => $title->getText() ] );
344 $this->
getOutput()->redirect( $this->mRequest->getText(
'wpDestUrl' ) );
347 $this->
showUploadWarning( UploadBase::unserializeWarnings( $progress[
'warnings'] ) );
350 $details = $status->getValue();
352 if ( is_array( $details ) && isset( $details[
'verification'] ) ) {
356 $status->getWikiText(
false,
false, $this->getLanguage() ) )
361 $this->showUploadProgress(
362 [
'active' =>
true,
'msg' =>
'upload-progress-processing' ]
368 $status->getWikiText(
false,
false, $this->getLanguage() ) )
375 $this->showUploadProgress( [
'active' =>
false,
'msg' =>
'upload-progress-queued' ] );
382 $this->showUploadProgress( [
'active' =>
true,
'msg' =>
'upload-progress-downloading' ] );
387 $status->getWikiText(
false,
false, $this->getLanguage() ) )
393 $status->getWikiText(
false,
false, $this->getLanguage() ) )
400 if ( $status->isOK() ) {
401 $status = Status::newFatal(
'upload-progress-unknown' );
403 $statusmsg = $this->
getOutput()->parseAsInterface(
404 $status->getWikiText(
false,
false, $this->getLanguage() )
406 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' . HTML::errorBox( $statusmsg );
422 private function showUploadProgress( $options ) {
425 $message = $this->
msg( $options[
'msg'] )->escaped();
426 $destUrl = $this->mRequest->getText(
'wpDestUrl',
'' );
427 if ( !$destUrl && $this->mUpload ) {
428 if ( !$this->mLocalFile ) {
429 $this->mLocalFile = $this->mUpload->getLocalFile();
433 if ( $this->mLocalFile ===
null ) {
436 $destUrl = $this->mLocalFile->getTitle()->getFullURL();
442 $destName = $this->mRequest->getText(
'wpDestFile' );
446 $sourceURL = $this->mRequest->getText(
'wpUploadFileURL' );
448 $form =
new HTMLForm( [
451 'default' => $this->mCacheKey,
455 'default' => $this->mSourceType,
459 'default' => $destUrl,
463 'default' => $destName,
467 'default' => $sourceURL,
470 $form->setSubmitText( $this->
msg(
'upload-refresh' )->escaped() );
473 $preHtml =
"<div id='upload-progress-message'>$message</div>";
474 $form->addPreHtml( $preHtml );
475 $form->setSubmitCallback(
476 static function ( $formData ) {
480 $form->prepareForm();
481 $this->
getOutput()->addHTML( $form->getHTML(
false ) );
505 protected function getUploadForm( $message =
'', $sessionKey =
'', $hideIgnoreWarning =
false ) {
510 'forreupload' => $this->mForReUpload,
511 'sessionkey' => $sessionKey,
512 'hideignorewarning' => $hideIgnoreWarning,
513 'destwarningack' => (
bool)$this->mDestWarningAck,
515 'description' => $this->mComment,
516 'texttop' => $this->uploadFormTextTop,
517 'textaftersummary' => $this->uploadFormTextAfterSummary,
518 'destfile' => $this->mDesiredDestName,
529 # Check the token, but only if necessary
531 !$this->mTokenOk && !$this->mCancelUpload &&
532 ( $this->mUpload && $this->mUploadClicked )
534 $form->addPreText( $this->
msg(
'session_fail_preview' )->parse() );
537 # Give a notice if the user is uploading a file that has been deleted or moved
538 # Note that this is independent from the message 'filewasdeleted'
539 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
541 if ( $desiredTitleObj instanceof
Title && !$desiredTitleObj->
exists() ) {
542 LogEventsList::showLogExtract( $delNotice, [
'delete',
'move' ],
545 'conds' => [ $this->localRepo->getReplicaDB()->expr(
'log_action',
'!=',
'revision' ) ],
546 'showIfEmpty' =>
false,
547 'msgKey' => [
'upload-recreate-warning' ] ]
550 $form->addPreText( $delNotice );
553 $form->addPreText(
'<div id="uploadtext">' .
554 $this->
msg(
'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
556 # Add upload error message
557 $form->addPreText( $message );
560 $uploadFooter = $this->
msg(
'uploadfooter' );
561 if ( !$uploadFooter->isDisabled() ) {
562 $form->addPostText(
'<div id="mw-upload-footer-message">'
563 . $uploadFooter->parseAsBlock() .
"</div>\n" );
581 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
582 if ( $stashStatus->isGood() ) {
583 $sessionKey = $stashStatus->getValue()->getFileKey();
584 $uploadWarning =
'upload-tryagain';
587 $uploadWarning =
'upload-tryagain-nostash';
589 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' .
590 Html::errorBox( $message );
593 $form->setSubmitText( $this->
msg( $uploadWarning )->escaped() );
606 # If there are no warnings, or warnings we can ignore, return early.
607 # mDestWarningAck is set when some javascript has shown the warning
608 # to the user. mForReUpload is set when the user clicks the "upload a
610 if ( !$warnings || ( count( $warnings ) == 1
611 && isset( $warnings[
'exists'] )
612 && ( $this->mDestWarningAck || $this->mForReUpload ) )
617 if ( $this->mUpload ) {
618 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
619 if ( $stashStatus->isGood() ) {
620 $sessionKey = $stashStatus->getValue()->getFileKey();
621 $uploadWarning =
'uploadwarning-text';
624 $uploadWarning =
'uploadwarning-text-nostash';
628 $uploadWarning =
'uploadwarning-text-nostash';
632 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
635 $warningHtml =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
"</h2>\n"
636 .
'<div class="mw-destfile-warning"><ul>';
637 foreach ( $warnings as $warning => $args ) {
638 if ( $warning ==
'badfilename' ) {
639 $this->mDesiredDestName = Title::makeTitle(
NS_FILE, $args )->getText();
641 if ( $warning ==
'exists' ) {
643 } elseif ( $warning ==
'no-change' ) {
645 $filename = $file->getTitle()->getPrefixedText();
646 $msg =
"\t<li>" . $this->
msg(
'fileexists-no-change', $filename )->parse() .
"</li>\n";
647 } elseif ( $warning ==
'duplicate-version' ) {
649 $count = count( $args );
650 $filename = $file->getTitle()->getPrefixedText();
651 $message = $this->
msg(
'fileexists-duplicate-version' )
652 ->params( $filename )
653 ->numParams( $count );
654 $msg =
"\t<li>" . $message->parse() .
"</li>\n";
655 } elseif ( $warning ==
'was-deleted' ) {
656 # If the file existed before and was deleted, warn the user of this
658 $llink = $linkRenderer->makeKnownLink(
660 $this->
msg(
'deletionlog' )->text(),
664 'page' => Title::makeTitle(
NS_FILE, $args )->getPrefixedText(),
667 $msg =
"\t<li>" . $this->
msg(
'filewasdeleted' )->rawParams( $llink )->parse() .
"</li>\n";
668 } elseif ( $warning ==
'duplicate' ) {
670 } elseif ( $warning ==
'duplicate-archive' ) {
671 if ( $args ===
'' ) {
672 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate-notitle' )->parse()
675 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate',
676 Title::makeTitle(
NS_FILE, $args )->getPrefixedText() )->parse()
680 if ( $args ===
true ) {
682 } elseif ( !is_array( $args ) ) {
685 $msg =
"\t<li>" . $this->
msg( $warning, $args )->parse() .
"</li>\n";
687 $warningHtml .= $msg;
689 $warningHtml .=
"</ul></div>\n";
690 $warningHtml .= $this->
msg( $uploadWarning )->parseAsBlock();
692 $form = $this->
getUploadForm( $warningHtml, $sessionKey,
true );
693 $form->setSubmitTextMsg(
'upload-tryagain' );
695 'name' =>
'wpUploadIgnoreWarning',
696 'value' => $this->
msg(
'ignorewarning' )->text()
699 'name' =>
'wpCancelUpload',
700 'value' => $this->
msg(
'reuploaddesc' )->text()
705 # Indicate that we showed a form
715 $message =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
'</h2>' .
716 Html::errorBox( $message );
727 if ( !$fetchFileStatus->isOK() ) {
729 $fetchFileStatus->getWikiText(
false,
false, $this->getLanguage() )
734 if ( !$this->
getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
735 wfDebug(
"Hook 'UploadForm:BeforeProcessing' broke processing the file." );
749 $details = $this->mUpload->verifyUpload();
750 if ( $details[
'status'] != UploadBase::OK ) {
758 $permErrors = $this->mUpload->verifyTitlePermissions( $user );
759 if ( $permErrors !==
true ) {
760 $code = array_shift( $permErrors[0] );
766 $this->mLocalFile = $this->mUpload->getLocalFile();
769 if ( !$this->mIgnoreWarning ) {
770 $warnings = $this->mUpload->checkWarnings( $user );
786 if ( !$this->mForReUpload ) {
787 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
788 $this->mCopyrightStatus, $this->mCopyrightSource,
789 $this->getConfig() );
793 $changeTags = $this->
getRequest()->getVal(
'wpChangeTags' );
794 if ( $changeTags ===
null || $changeTags ===
'' ) {
797 $changeTags = array_filter( array_map(
'trim', explode(
',', $changeTags ) ) );
801 $changeTags, $this->
getUser() );
802 if ( !$changeTagsStatus->isOK() ) {
803 $this->showUploadError( $this->getOutput()->parseAsInterface(
804 $changeTagsStatus->getWikiText(
false,
false, $this->getLanguage() )
810 return [ $pageText, $changeTags ];
819 $status = $this->mUpload->fetchFile();
820 if ( !$this->performUploadChecks( $status ) ) {
824 $pageAndTags = $this->getPageTextAndTags();
825 if ( $pageAndTags ===
null ) {
828 [ $pageText, $changeTags ] = $pageAndTags;
830 $status = $this->mUpload->performUpload(
838 if ( !$status->isGood() ) {
839 $this->showRecoverableUploadError(
840 $this->getOutput()->parseAsInterface(
841 $status->getWikiText(
false,
false, $this->getLanguage() )
849 $this->mUploadSuccessful =
true;
850 $this->getHookRunner()->onSpecialUploadComplete( $this );
851 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
860 $this->showUploadError( $this->msg(
'uploaderror' )->escaped() );
865 $status = $this->mUpload->canFetchFile();
866 if ( !$this->performUploadChecks( $status ) ) {
867 $this->log->debug(
'Upload failed verification: {error}', [
'error' => $status ] );
871 $pageAndTags = $this->getPageTextAndTags();
872 if ( $pageAndTags ===
null ) {
875 [ $pageText, $changeTags ] = $pageAndTags;
878 $job = new \UploadFromUrlJob(
880 'filename' => $this->mUpload->getDesiredDestName(),
881 'url' => $this->mUpload->getUrl(),
882 'comment' => $this->mComment,
883 'tags' => $changeTags,
885 'watch' => $this->mWatchthis,
886 'watchlistexpiry' =>
null,
887 'session' => $this->getContext()->exportSession(),
888 'reupload' => $this->mForReUpload,
889 'ignorewarnings' => $this->mIgnoreWarning,
893 $cacheKey =
$job->getCacheKey();
894 UploadBase::setSessionStatus( $this->
getUser(), $cacheKey, [
895 'status' => Status::newGood(),
899 $this->log->info(
"Submitting UploadFromUrlJob for {filename}",
900 [
'filename' => $this->mUpload->getDesiredDestName() ]
903 $this->jobQueueGroup->push(
$job );
905 $this->showUploadStatus( $this->
getUser() );
920 if ( $config ===
null ) {
921 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
931 foreach ( [
'license-header',
'filedesc',
'filestatus',
'filesource' ] as $msgName ) {
932 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
933 $msg[$msgName] =
"{{int:$msgName}}";
935 $msg[$msgName] =
wfMessage( $msgName )->inContentLanguage()->text();
940 if ( $license !==
'' ) {
941 $licenseText =
'== ' . $msg[
'license-header'] .
" ==\n{{" . $license .
"}}\n";
944 $pageText = $comment .
"\n";
945 $headerText =
'== ' . $msg[
'filedesc'] .
' ==';
946 if ( $comment !==
'' && !str_contains( $comment, $headerText ) ) {
948 $pageText = $headerText .
"\n" . $pageText;
952 $pageText .=
'== ' . $msg[
'filestatus'] .
" ==\n" . $copyStatus .
"\n";
953 $pageText .= $licenseText;
954 $pageText .=
'== ' . $msg[
'filesource'] .
" ==\n" .
$source;
956 $pageText .= $licenseText;
961 ->onUploadForm_getInitialPageText( $pageText, $msg, $config );
980 if ( $this->userOptionsLookup->getBoolOption( $user,
'watchdefault' ) ) {
985 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
986 if ( $desiredTitleObj instanceof
Title &&
987 $this->watchlistManager->isWatched( $user, $desiredTitleObj ) ) {
992 $local = $this->localRepo->newFile( $this->mDesiredDestName );
993 if ( $local && $local->exists() ) {
999 return $this->userOptionsLookup->getBoolOption( $user,
'watchcreations' ) ||
1000 $this->userOptionsLookup->getBoolOption( $user,
'watchuploads' );
1010 switch ( $details[
'status'] ) {
1012 case UploadBase::MIN_LENGTH_PARTNAME:
1013 $this->showRecoverableUploadError( $this->msg(
'minlength1' )->escaped() );
1015 case UploadBase::ILLEGAL_FILENAME:
1016 $this->showRecoverableUploadError( $this->msg(
'illegalfilename',
1017 $details[
'filtered'] )->parse() );
1019 case UploadBase::FILENAME_TOO_LONG:
1020 $this->showRecoverableUploadError( $this->msg(
'filename-toolong' )->escaped() );
1022 case UploadBase::FILETYPE_MISSING:
1023 $this->showRecoverableUploadError( $this->msg(
'filetype-missing' )->parse() );
1025 case UploadBase::WINDOWS_NONASCII_FILENAME:
1026 $this->showRecoverableUploadError( $this->msg(
'windows-nonascii-filename' )->parse() );
1030 case UploadBase::EMPTY_FILE:
1031 $this->showUploadError( $this->msg(
'emptyfile' )->escaped() );
1033 case UploadBase::FILE_TOO_LARGE:
1034 $this->showUploadError( $this->msg(
'largefileserver' )->escaped() );
1036 case UploadBase::FILETYPE_BADTYPE:
1037 $msg = $this->msg(
'filetype-banned-type' );
1038 if ( isset( $details[
'blacklistedExt'] ) ) {
1039 $msg->params( $this->getLanguage()->commaList( $details[
'blacklistedExt'] ) );
1041 $msg->params( $details[
'finalExt'] );
1045 $msg->params( $this->getLanguage()->commaList( $extensions ),
1046 count( $extensions ) );
1051 if ( isset( $details[
'blacklistedExt'] ) ) {
1052 $msg->params( count( $details[
'blacklistedExt'] ) );
1057 $this->showUploadError( $msg->parse() );
1059 case UploadBase::VERIFICATION_ERROR:
1060 unset( $details[
'status'] );
1061 $code = array_shift( $details[
'details'] );
1062 $this->showUploadError( $this->msg( $code, $details[
'details'] )->parse() );
1064 case UploadBase::HOOK_ABORTED:
1065 if ( is_array( $details[
'error'] ) ) { # allow hooks to
return error details in an array
1066 $args = $details[
'error'];
1067 $error = array_shift( $args );
1069 $error = $details[
'error'];
1073 $this->showUploadError( $this->msg( $error, $args )->parse() );
1076 throw new UnexpectedValueException( __METHOD__ .
": Unknown value `{$details['status']}`" );
1089 $success = $this->mUpload->unsaveUploadedFile();
1091 $this->getOutput()->showErrorPage(
1094 [ $this->mUpload->getTempPath() ]
1117 $file = $exists[
'file'];
1118 $filename = $file->getTitle()->getPrefixedText();
1121 if ( $exists[
'warning'] ==
'exists' ) {
1123 $warnMsg =
wfMessage(
'fileexists', $filename );
1124 } elseif ( $exists[
'warning'] ==
'page-exists' ) {
1126 $warnMsg =
wfMessage(
'filepageexists', $filename );
1127 } elseif ( $exists[
'warning'] ==
'exists-normalized' ) {
1128 $warnMsg =
wfMessage(
'fileexists-extension', $filename,
1129 $exists[
'normalizedFile']->
getTitle()->getPrefixedText() );
1130 } elseif ( $exists[
'warning'] ==
'thumb' ) {
1132 $warnMsg =
wfMessage(
'fileexists-thumbnail-yes',
1133 $exists[
'thumbFile']->
getTitle()->getPrefixedText(), $filename );
1134 } elseif ( $exists[
'warning'] ==
'thumb-name' ) {
1136 $name = $file->getName();
1137 $badPart = substr( $name, 0, strpos( $name,
'-' ) + 1 );
1138 $warnMsg =
wfMessage(
'file-thumbnail-no', $badPart );
1139 } elseif ( $exists[
'warning'] ==
'bad-prefix' ) {
1140 $warnMsg =
wfMessage(
'filename-bad-prefix', $exists[
'prefix'] );
1143 return $warnMsg ? $warnMsg->page( $file->getTitle() )->parse() :
'';
1156 $gallery = ImageGalleryBase::factory(
false, $this->
getContext() );
1157 $gallery->setShowBytes(
false );
1158 $gallery->setShowDimensions(
false );
1159 foreach ( $dupes as $file ) {
1160 $gallery->add( $file->getTitle() );
1164 $this->msg(
'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
1165 $gallery->toHTML() .
"</li>\n";
1182 return $bitmapHandler->autoRotateEnabled();
1190class_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