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' );
163 $this->mRequest = $request = $this->
getRequest();
164 $this->mSourceType = $request->getVal(
'wpSourceType',
'file' );
165 $this->mUpload = UploadBase::createFromRequest( $request );
166 $this->mUploadClicked = $request->wasPosted()
167 && ( $request->getCheck(
'wpUpload' )
168 || $request->getCheck(
'wpUploadIgnoreWarning' ) );
171 $this->mDesiredDestName = $request->getText(
'wpDestFile' );
172 if ( !$this->mDesiredDestName && $request->getFileName(
'wpUploadFile' ) !== null ) {
173 $this->mDesiredDestName = $request->getFileName(
'wpUploadFile' );
175 $this->mLicense = $request->getText(
'wpLicense' );
177 $this->mDestWarningAck = $request->getText(
'wpDestFileWarningAck' );
178 $this->mIgnoreWarning = $request->getCheck(
'wpIgnoreWarning' )
179 || $request->getCheck(
'wpUploadIgnoreWarning' );
180 $this->mWatchthis = $request->getBool(
'wpWatchthis' ) && $this->
getUser()->isRegistered();
181 $this->mCopyrightStatus = $request->getText(
'wpUploadCopyStatus' );
182 $this->mCopyrightSource = $request->getText(
'wpUploadSource' );
184 $this->mForReUpload = $request->getBool(
'wpForReUpload' );
186 $commentDefault =
'';
187 $commentMsg = $this->
msg(
'upload-default-description' )->inContentLanguage();
188 if ( !$this->mForReUpload && !$commentMsg->isDisabled() ) {
189 $commentDefault = $commentMsg->plain();
191 $this->mComment = $request->getText(
'wpUploadDescription', $commentDefault );
193 $this->mCancelUpload = $request->getCheck(
'wpCancelUpload' )
194 || $request->getCheck(
'wpReUpload' );
197 $token = $request->getVal(
'wpEditToken' );
198 $this->mTokenOk = $this->
getUser()->matchEditToken( $token );
203 $this->mCacheKey = \UploadFromUrl::getCacheKeyFromRequest( $request );
205 $this->mCacheKey =
'';
208 $this->uploadFormTextTop =
'';
209 $this->uploadFormTextAfterSummary =
'';
218 return ( $this->mSourceType ===
'url' && $this->allowAsync );
230 return UploadBase::isEnabled() && parent::userCanExecute( $user );
242 # Check uploading enabled
243 if ( !UploadBase::isEnabled() ) {
244 throw new ErrorPageError(
'uploaddisabled',
'uploaddisabledtext' );
251 $permissionRequired = UploadBase::isAllowed( $user );
252 if ( $permissionRequired !==
true ) {
257 if ( $user->isBlockedFromUpload() ) {
262 $this->getLanguage(),
263 $this->getRequest()->getIP()
267 # Check whether we actually want to allow changing stuff
272 # Unsave the temporary file in case this was a cancelled upload
274 # Something went wrong, so unsaveUploadedFile showed a warning
278 # If we have a cache key, show the upload status.
279 if ( $this->mTokenOk && $this->mCacheKey !==
'' ) {
280 if ( $this->mUpload && $this->mUploadClicked && !$this->mCancelUpload ) {
281 # If the user clicked the upload button, we need to process the upload
284 # Show the upload status
288 # Process upload or show a form
289 $this->mTokenOk && !$this->mCancelUpload &&
290 ( $this->mUpload && $this->mUploadClicked )
294 # Backwards compatibility hook
295 if ( !$this->
getHookRunner()->onUploadForm_initial( $this ) ) {
296 wfDebug(
"Hook 'UploadForm:initial' broke output of the upload form" );
304 if ( $this->mUpload ) {
305 $this->mUpload->cleanupTempFile();
316 $progress = UploadBase::getSessionStatus( $user, $this->mCacheKey );
317 if ( $progress ==
false ) {
318 $progress = [
'status' => Status::newFatal(
'invalid-cache-key' ) ];
320 $this->log->debug(
'Upload status: stage {stage}, result {result}', $progress );
322 $status = $progress[
'status'] ?? Status::newFatal(
'invalid-cache-key' );
323 $stage = $progress[
'stage'] ??
'unknown';
324 $result = $progress[
'result'] ??
'unknown';
332 $this->mUploadSuccessful =
true;
336 $title = Title::makeTitleSafe(
NS_FILE, $this->mRequest->getText(
'wpDestFile' ) );
338 $this->log->debug(
'Purging page', [
'title' => $title->getText() ] );
342 $this->
getOutput()->redirect( $this->mRequest->getText(
'wpDestUrl' ) );
345 $this->
showUploadWarning( UploadBase::unserializeWarnings( $progress[
'warnings'] ) );
348 $details = $status->getValue();
350 if ( is_array( $details ) && isset( $details[
'verification'] ) ) {
354 $status->getWikiText(
false,
false, $this->getLanguage() ) )
359 $this->showUploadProgress(
360 [
'active' =>
true,
'msg' =>
'upload-progress-processing' ]
367 $this->showUploadProgress( [
'active' =>
false,
'msg' =>
'upload-progress-queued' ] );
374 $this->showUploadProgress( [
'active' =>
true,
'msg' =>
'upload-progress-downloading' ] );
379 $status->getWikiText(
false,
false, $this->getLanguage() ) )
386 if ( $status->isOK() ) {
387 $status = Status::newFatal(
'upload-progress-unknown' );
389 $statusmsg = $this->
getOutput()->parseAsInterface(
390 $status->getWikiText(
false,
false, $this->getLanguage() )
392 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' . HTML::errorBox( $statusmsg );
408 private function showUploadProgress( $options ) {
411 $message = $this->
msg( $options[
'msg'] )->escaped();
412 $destUrl = $this->mRequest->getText(
'wpDestUrl',
'' );
413 if ( !$destUrl && $this->mUpload ) {
414 if ( !$this->mLocalFile ) {
415 $this->mLocalFile = $this->mUpload->getLocalFile();
419 if ( $this->mLocalFile ===
null ) {
422 $destUrl = $this->mLocalFile->getTitle()->getFullURL();
428 $destName = $this->mRequest->getText(
'wpDestFile' );
432 $sourceURL = $this->mRequest->getText(
'wpUploadFileURL' );
434 $form =
new HTMLForm( [
437 'default' => $this->mCacheKey,
441 'default' => $this->mSourceType,
445 'default' => $destUrl,
449 'default' => $destName,
453 'default' => $sourceURL,
456 $form->setSubmitText( $this->
msg(
'upload-refresh' )->escaped() );
459 $preHtml =
"<div id='upload-progress-message'>$message</div>";
460 $form->addPreHtml( $preHtml );
461 $form->setSubmitCallback(
462 static function ( $formData ) {
466 $form->prepareForm();
467 $this->
getOutput()->addHTML( $form->getHTML(
false ) );
491 protected function getUploadForm( $message =
'', $sessionKey =
'', $hideIgnoreWarning =
false ) {
496 'forreupload' => $this->mForReUpload,
497 'sessionkey' => $sessionKey,
498 'hideignorewarning' => $hideIgnoreWarning,
499 'destwarningack' => (
bool)$this->mDestWarningAck,
501 'description' => $this->mComment,
502 'texttop' => $this->uploadFormTextTop,
503 'textaftersummary' => $this->uploadFormTextAfterSummary,
504 'destfile' => $this->mDesiredDestName,
515 # Check the token, but only if necessary
517 !$this->mTokenOk && !$this->mCancelUpload &&
518 ( $this->mUpload && $this->mUploadClicked )
520 $form->addPreText( $this->
msg(
'session_fail_preview' )->parse() );
523 # Give a notice if the user is uploading a file that has been deleted or moved
524 # Note that this is independent from the message 'filewasdeleted'
525 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
527 if ( $desiredTitleObj instanceof
Title && !$desiredTitleObj->
exists() ) {
528 LogEventsList::showLogExtract( $delNotice, [
'delete',
'move' ],
531 'conds' => [ $this->localRepo->getReplicaDB()->expr(
'log_action',
'!=',
'revision' ) ],
532 'showIfEmpty' =>
false,
533 'msgKey' => [
'upload-recreate-warning' ] ]
536 $form->addPreText( $delNotice );
539 $form->addPreText(
'<div id="uploadtext">' .
540 $this->
msg(
'uploadtext', [ $this->mDesiredDestName ] )->parseAsBlock() .
542 # Add upload error message
543 $form->addPreText( $message );
546 $uploadFooter = $this->
msg(
'uploadfooter' );
547 if ( !$uploadFooter->isDisabled() ) {
548 $form->addPostText(
'<div id="mw-upload-footer-message">'
549 . $uploadFooter->parseAsBlock() .
"</div>\n" );
567 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
568 if ( $stashStatus->isGood() ) {
569 $sessionKey = $stashStatus->getValue()->getFileKey();
570 $uploadWarning =
'upload-tryagain';
573 $uploadWarning =
'upload-tryagain-nostash';
575 $message =
'<h2>' . $this->
msg(
'uploaderror' )->escaped() .
'</h2>' .
576 Html::errorBox( $message );
579 $form->setSubmitText( $this->
msg( $uploadWarning )->escaped() );
592 # If there are no warnings, or warnings we can ignore, return early.
593 # mDestWarningAck is set when some javascript has shown the warning
594 # to the user. mForReUpload is set when the user clicks the "upload a
596 if ( !$warnings || ( count( $warnings ) == 1
597 && isset( $warnings[
'exists'] )
598 && ( $this->mDestWarningAck || $this->mForReUpload ) )
603 if ( $this->mUpload ) {
604 $stashStatus = $this->mUpload->tryStashFile( $this->
getUser() );
605 if ( $stashStatus->isGood() ) {
606 $sessionKey = $stashStatus->getValue()->getFileKey();
607 $uploadWarning =
'uploadwarning-text';
610 $uploadWarning =
'uploadwarning-text-nostash';
614 $uploadWarning =
'uploadwarning-text-nostash';
618 $this->
getOutput()->addModuleStyles(
'mediawiki.special' );
621 $warningHtml =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
"</h2>\n"
622 .
'<div class="mw-destfile-warning"><ul>';
623 foreach ( $warnings as $warning => $args ) {
624 if ( $warning ==
'badfilename' ) {
625 $this->mDesiredDestName = Title::makeTitle(
NS_FILE, $args )->getText();
627 if ( $warning ==
'exists' ) {
629 } elseif ( $warning ==
'no-change' ) {
631 $filename = $file->getTitle()->getPrefixedText();
632 $msg =
"\t<li>" . $this->
msg(
'fileexists-no-change', $filename )->parse() .
"</li>\n";
633 } elseif ( $warning ==
'duplicate-version' ) {
635 $count = count( $args );
636 $filename = $file->getTitle()->getPrefixedText();
637 $message = $this->
msg(
'fileexists-duplicate-version' )
638 ->params( $filename )
639 ->numParams( $count );
640 $msg =
"\t<li>" . $message->parse() .
"</li>\n";
641 } elseif ( $warning ==
'was-deleted' ) {
642 # If the file existed before and was deleted, warn the user of this
644 $llink = $linkRenderer->makeKnownLink(
646 $this->
msg(
'deletionlog' )->text(),
650 'page' => Title::makeTitle(
NS_FILE, $args )->getPrefixedText(),
653 $msg =
"\t<li>" . $this->
msg(
'filewasdeleted' )->rawParams( $llink )->parse() .
"</li>\n";
654 } elseif ( $warning ==
'duplicate' ) {
656 } elseif ( $warning ==
'duplicate-archive' ) {
657 if ( $args ===
'' ) {
658 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate-notitle' )->parse()
661 $msg =
"\t<li>" . $this->
msg(
'file-deleted-duplicate',
662 Title::makeTitle(
NS_FILE, $args )->getPrefixedText() )->parse()
666 if ( $args ===
true ) {
668 } elseif ( !is_array( $args ) ) {
671 $msg =
"\t<li>" . $this->
msg( $warning, $args )->parse() .
"</li>\n";
673 $warningHtml .= $msg;
675 $warningHtml .=
"</ul></div>\n";
676 $warningHtml .= $this->
msg( $uploadWarning )->parseAsBlock();
678 $form = $this->
getUploadForm( $warningHtml, $sessionKey,
true );
679 $form->setSubmitTextMsg(
'upload-tryagain' );
681 'name' =>
'wpUploadIgnoreWarning',
682 'value' => $this->
msg(
'ignorewarning' )->text()
685 'name' =>
'wpCancelUpload',
686 'value' => $this->
msg(
'reuploaddesc' )->text()
691 # Indicate that we showed a form
701 $message =
'<h2>' . $this->
msg(
'uploadwarning' )->escaped() .
'</h2>' .
702 Html::errorBox( $message );
713 if ( !$fetchFileStatus->isOK() ) {
715 $fetchFileStatus->getWikiText(
false,
false, $this->getLanguage() )
720 if ( !$this->
getHookRunner()->onUploadForm_BeforeProcessing( $this ) ) {
721 wfDebug(
"Hook 'UploadForm:BeforeProcessing' broke processing the file." );
735 $details = $this->mUpload->verifyUpload();
736 if ( $details[
'status'] != UploadBase::OK ) {
744 $permErrors = $this->mUpload->verifyTitlePermissions( $user );
745 if ( $permErrors !==
true ) {
746 $code = array_shift( $permErrors[0] );
752 $this->mLocalFile = $this->mUpload->getLocalFile();
755 if ( !$this->mIgnoreWarning ) {
756 $warnings = $this->mUpload->checkWarnings( $user );
772 if ( !$this->mForReUpload ) {
773 $pageText = self::getInitialPageText( $this->mComment, $this->mLicense,
774 $this->mCopyrightStatus, $this->mCopyrightSource,
775 $this->getConfig() );
779 $changeTags = $this->
getRequest()->getVal(
'wpChangeTags' );
780 if ( $changeTags ===
null || $changeTags ===
'' ) {
783 $changeTags = array_filter( array_map(
'trim', explode(
',', $changeTags ) ) );
787 $changeTags, $this->
getUser() );
788 if ( !$changeTagsStatus->isOK() ) {
789 $this->showUploadError( $this->getOutput()->parseAsInterface(
790 $changeTagsStatus->getWikiText(
false,
false, $this->getLanguage() )
796 return [ $pageText, $changeTags ];
805 $status = $this->mUpload->fetchFile();
806 if ( !$this->performUploadChecks( $status ) ) {
810 $pageAndTags = $this->getPageTextAndTags();
811 if ( $pageAndTags ===
null ) {
814 [ $pageText, $changeTags ] = $pageAndTags;
816 $status = $this->mUpload->performUpload(
824 if ( !$status->isGood() ) {
825 $this->showRecoverableUploadError(
826 $this->getOutput()->parseAsInterface(
827 $status->getWikiText(
false,
false, $this->getLanguage() )
835 $this->mUploadSuccessful =
true;
836 $this->getHookRunner()->onSpecialUploadComplete( $this );
837 $this->getOutput()->redirect( $this->mLocalFile->getTitle()->getFullURL() );
846 $this->showUploadError( $this->msg(
'uploaderror' )->escaped() );
851 $status = $this->mUpload->canFetchFile();
852 if ( !$this->performUploadChecks( $status ) ) {
853 $this->log->debug(
'Upload failed verification: {error}', [
'error' => $status ] );
857 $pageAndTags = $this->getPageTextAndTags();
858 if ( $pageAndTags ===
null ) {
861 [ $pageText, $changeTags ] = $pageAndTags;
864 $job = new \UploadFromUrlJob(
866 'filename' => $this->mUpload->getDesiredDestName(),
867 'url' => $this->mUpload->getUrl(),
868 'comment' => $this->mComment,
869 'tags' => $changeTags,
871 'watch' => $this->mWatchthis,
872 'watchlistexpiry' =>
null,
873 'session' => $this->getContext()->exportSession(),
874 'reupload' => $this->mForReUpload,
875 'ignorewarnings' => $this->mIgnoreWarning,
879 $cacheKey =
$job->getCacheKey();
880 UploadBase::setSessionStatus( $this->
getUser(), $cacheKey, [
881 'status' => Status::newGood(),
885 $this->log->info(
"Submitting UploadFromUrlJob for {filename}",
886 [
'filename' => $this->mUpload->getDesiredDestName() ]
889 $this->jobQueueGroup->push(
$job );
891 $this->showUploadStatus( $this->
getUser() );
906 if ( $config ===
null ) {
907 wfDebug( __METHOD__ .
' called without a Config instance passed to it' );
917 foreach ( [
'license-header',
'filedesc',
'filestatus',
'filesource' ] as $msgName ) {
918 if ( in_array( $msgName, $forceUIMsgAsContentMsg ) ) {
919 $msg[$msgName] =
"{{int:$msgName}}";
921 $msg[$msgName] =
wfMessage( $msgName )->inContentLanguage()->text();
926 if ( $license !==
'' ) {
927 $licenseText =
'== ' . $msg[
'license-header'] .
" ==\n{{" . $license .
"}}\n";
930 $pageText = $comment .
"\n";
931 $headerText =
'== ' . $msg[
'filedesc'] .
' ==';
932 if ( $comment !==
'' && !str_contains( $comment, $headerText ) ) {
934 $pageText = $headerText .
"\n" . $pageText;
938 $pageText .=
'== ' . $msg[
'filestatus'] .
" ==\n" . $copyStatus .
"\n";
939 $pageText .= $licenseText;
940 $pageText .=
'== ' . $msg[
'filesource'] .
" ==\n" .
$source;
942 $pageText .= $licenseText;
947 ->onUploadForm_getInitialPageText( $pageText, $msg, $config );
966 if ( $this->userOptionsLookup->getBoolOption( $user,
'watchdefault' ) ) {
971 $desiredTitleObj = Title::makeTitleSafe(
NS_FILE, $this->mDesiredDestName );
972 if ( $desiredTitleObj instanceof
Title &&
973 $this->watchlistManager->isWatched( $user, $desiredTitleObj ) ) {
978 $local = $this->localRepo->newFile( $this->mDesiredDestName );
979 if ( $local && $local->exists() ) {
985 return $this->userOptionsLookup->getBoolOption( $user,
'watchcreations' ) ||
986 $this->userOptionsLookup->getBoolOption( $user,
'watchuploads' );
996 switch ( $details[
'status'] ) {
998 case UploadBase::MIN_LENGTH_PARTNAME:
999 $this->showRecoverableUploadError( $this->msg(
'minlength1' )->escaped() );
1001 case UploadBase::ILLEGAL_FILENAME:
1002 $this->showRecoverableUploadError( $this->msg(
'illegalfilename',
1003 $details[
'filtered'] )->parse() );
1005 case UploadBase::FILENAME_TOO_LONG:
1006 $this->showRecoverableUploadError( $this->msg(
'filename-toolong' )->escaped() );
1008 case UploadBase::FILETYPE_MISSING:
1009 $this->showRecoverableUploadError( $this->msg(
'filetype-missing' )->parse() );
1011 case UploadBase::WINDOWS_NONASCII_FILENAME:
1012 $this->showRecoverableUploadError( $this->msg(
'windows-nonascii-filename' )->parse() );
1016 case UploadBase::EMPTY_FILE:
1017 $this->showUploadError( $this->msg(
'emptyfile' )->escaped() );
1019 case UploadBase::FILE_TOO_LARGE:
1020 $this->showUploadError( $this->msg(
'largefileserver' )->escaped() );
1022 case UploadBase::FILETYPE_BADTYPE:
1023 $msg = $this->msg(
'filetype-banned-type' );
1024 if ( isset( $details[
'blacklistedExt'] ) ) {
1025 $msg->params( $this->getLanguage()->commaList( $details[
'blacklistedExt'] ) );
1027 $msg->params( $details[
'finalExt'] );
1031 $msg->params( $this->getLanguage()->commaList( $extensions ),
1032 count( $extensions ) );
1037 if ( isset( $details[
'blacklistedExt'] ) ) {
1038 $msg->params( count( $details[
'blacklistedExt'] ) );
1043 $this->showUploadError( $msg->parse() );
1045 case UploadBase::VERIFICATION_ERROR:
1046 unset( $details[
'status'] );
1047 $code = array_shift( $details[
'details'] );
1048 $this->showUploadError( $this->msg( $code, $details[
'details'] )->parse() );
1050 case UploadBase::HOOK_ABORTED:
1051 if ( is_array( $details[
'error'] ) ) { # allow hooks to
return error details in an array
1052 $args = $details[
'error'];
1053 $error = array_shift( $args );
1055 $error = $details[
'error'];
1059 $this->showUploadError( $this->msg( $error, $args )->parse() );
1062 throw new UnexpectedValueException( __METHOD__ .
": Unknown value `{$details['status']}`" );
1075 $success = $this->mUpload->unsaveUploadedFile();
1077 $this->getOutput()->showFatalError(
1078 $this->msg(
'filedeleteerror' )
1079 ->params( $this->mUpload->getTempPath() )
1103 $file = $exists[
'file'];
1104 $filename = $file->getTitle()->getPrefixedText();
1107 if ( $exists[
'warning'] ==
'exists' ) {
1109 $warnMsg =
wfMessage(
'fileexists', $filename );
1110 } elseif ( $exists[
'warning'] ==
'page-exists' ) {
1112 $warnMsg =
wfMessage(
'filepageexists', $filename );
1113 } elseif ( $exists[
'warning'] ==
'exists-normalized' ) {
1114 $warnMsg =
wfMessage(
'fileexists-extension', $filename,
1115 $exists[
'normalizedFile']->
getTitle()->getPrefixedText() );
1116 } elseif ( $exists[
'warning'] ==
'thumb' ) {
1118 $warnMsg =
wfMessage(
'fileexists-thumbnail-yes',
1119 $exists[
'thumbFile']->
getTitle()->getPrefixedText(), $filename );
1120 } elseif ( $exists[
'warning'] ==
'thumb-name' ) {
1122 $name = $file->getName();
1123 $badPart = substr( $name, 0, strpos( $name,
'-' ) + 1 );
1124 $warnMsg =
wfMessage(
'file-thumbnail-no', $badPart );
1125 } elseif ( $exists[
'warning'] ==
'bad-prefix' ) {
1126 $warnMsg =
wfMessage(
'filename-bad-prefix', $exists[
'prefix'] );
1129 return $warnMsg ? $warnMsg->page( $file->getTitle() )->parse() :
'';
1142 $gallery = ImageGalleryBase::factory(
false, $this->
getContext() );
1143 $gallery->setShowBytes(
false );
1144 $gallery->setShowDimensions(
false );
1145 foreach ( $dupes as $file ) {
1146 $gallery->add( $file->getTitle() );
1150 $this->msg(
'file-exists-duplicate' )->numParams( count( $dupes ) )->parse() .
1151 $gallery->toHTML() .
"</li>\n";
1168 return $bitmapHandler->autoRotateEnabled();
1176class_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 Per default the message key is the canonical name o...
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