67 parent::__construct(
'Undelete',
'deletedhistory' );
78 $this->mAction = $request->getVal(
'action' );
79 if ( $par !==
null && $par !==
'' ) {
80 $this->mTarget = $par;
82 $this->mTarget = $request->getVal(
'target' );
85 $this->mTargetObj =
null;
87 if ( $this->mTarget !==
null && $this->mTarget !==
'' ) {
88 $this->mTargetObj = Title::newFromText( $this->mTarget );
91 $this->mSearchPrefix = $request->getText(
'prefix' );
92 $time = $request->getVal(
'timestamp' );
93 $this->mTimestamp = $time ?
wfTimestamp( TS_MW, $time ) :
'';
94 $this->mFilename = $request->getVal(
'file' );
96 $posted = $request->wasPosted() &&
97 $user->matchEditToken( $request->getVal(
'wpEditToken' ) );
98 $this->mRestore = $request->getCheck(
'restore' ) && $posted;
99 $this->mRevdel = $request->getCheck(
'revdel' ) && $posted;
100 $this->mInvert = $request->getCheck(
'invert' ) && $posted;
101 $this->mPreview = $request->getCheck(
'preview' ) && $posted;
102 $this->mDiff = $request->getCheck(
'diff' );
103 $this->mDiffOnly = $request->getBool(
'diffonly', $this->
getUser()->getOption(
'diffonly' ) );
104 $this->mComment = $request->getText(
'wpComment' );
105 $this->mUnsuppress = $request->getVal(
'wpUnsuppress' ) && MediaWikiServices::getInstance()
106 ->getPermissionManager()
107 ->userHasRight( $user,
'suppressrevision' );
108 $this->mToken = $request->getVal(
'token' );
110 $block = $user->getBlock();
111 if ( $this->
isAllowed(
'undelete' ) && !( $block && $block->isSitewide() ) ) {
112 $this->mAllowed =
true;
113 $this->mCanView =
true;
114 } elseif ( $this->
isAllowed(
'deletedtext' ) ) {
115 $this->mAllowed =
false;
116 $this->mCanView =
true;
117 $this->mRestore =
false;
119 $this->mAllowed =
false;
120 $this->mCanView =
false;
121 $this->mTimestamp =
'';
122 $this->mRestore =
false;
125 if ( $this->mRestore || $this->mInvert ) {
127 $this->mFileVersions = [];
128 foreach ( $request->getValues() as $key => $val ) {
130 if ( preg_match(
'/^ts(\d{14})$/', $key,
$matches ) ) {
131 array_push( $timestamps,
$matches[1] );
134 if ( preg_match(
'/^fileid(\d+)$/', $key,
$matches ) ) {
135 $this->mFileVersions[] = intval(
$matches[1] );
138 rsort( $timestamps );
139 $this->mTargetTimestamp = $timestamps;
152 $user = $user ?: $this->
getUser();
153 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
155 if ( $this->mTargetObj !==
null ) {
156 return $permissionManager->userCan( $permission, $user, $this->mTargetObj );
158 return $permissionManager->userHasRight( $user, $permission );
163 return $this->
isAllowed( $this->mRestriction, $user );
173 $this->
addHelpLink(
'Help:Deletion_and_undeletion' );
180 if ( is_null( $this->mTargetObj ) ) {
181 $out->addWikiMsg(
'undelete-header' );
183 # Not all users can just browse every deleted page from the list
184 if ( MediaWikiServices::getInstance()
186 ->userHasRight( $user,
'browsearchive' )
195 if ( $this->mAllowed ) {
196 $out->setPageTitle( $this->
msg(
'undeletepage' ) );
198 $out->setPageTitle( $this->
msg(
'viewdeletedpage' ) );
201 $this->
getSkin()->setRelevantTitle( $this->mTargetObj );
203 if ( $this->mTimestamp !==
'' ) {
205 } elseif ( $this->mFilename !==
null && $this->mTargetObj->inNamespace(
NS_FILE ) ) {
208 if ( !
$file->exists() ) {
209 $out->addWikiMsg(
'filedelete-nofile', $this->mFilename );
210 } elseif ( !
$file->userCan( File::DELETED_FILE, $user ) ) {
211 if (
$file->isDeleted( File::DELETED_RESTRICTED ) ) {
216 } elseif ( !$user->matchEditToken( $this->mToken, $this->mFilename ) ) {
219 $this->
showFile( $this->mFilename );
221 } elseif ( $this->mAction ===
'submit' ) {
222 if ( $this->mRestore ) {
224 } elseif ( $this->mRevdel ) {
242 foreach ( $this->
getRequest()->getValues() as $key => $val ) {
244 if ( preg_match(
"/^ts(\d{14})$/", $key,
$matches ) ) {
245 $revisions[$archive->getRevision(
$matches[1] )->getId()] = 1;
250 'type' =>
'revision',
252 'target' => $this->mTargetObj->getPrefixedText()
260 $out->setPageTitle( $this->
msg(
'undelete-search-title' ) );
261 $fuzzySearch = $this->
getRequest()->getVal(
'fuzzy',
true );
266 $fields[] =
new OOUI\ActionFieldLayout(
267 new OOUI\TextInputWidget( [
269 'inputId' =>
'prefix',
271 'value' => $this->mSearchPrefix,
274 new OOUI\ButtonInputWidget( [
275 'label' => $this->
msg(
'undelete-search-submit' )->text(),
276 'flags' => [
'primary',
'progressive' ],
277 'inputId' =>
'searchUndelete',
281 'label' =>
new OOUI\HtmlSnippet(
283 $fuzzySearch ?
'undelete-search-full' :
'undelete-search-prefix'
290 $fieldset =
new OOUI\FieldsetLayout( [
291 'label' => $this->
msg(
'undelete-search-box' )->text(),
295 $form =
new OOUI\FormLayout( [
300 $form->appendContent(
302 new OOUI\HtmlSnippet(
303 Html::hidden(
'title', $this->
getPageTitle()->getPrefixedDBkey() ) .
304 Html::hidden(
'fuzzy', $fuzzySearch )
309 new OOUI\PanelLayout( [
317 # List undeletable articles
318 if ( $this->mSearchPrefix ) {
321 if ( $fuzzySearch ) {
339 if ( $result->numRows() == 0 ) {
340 $out->addWikiMsg(
'undelete-no-results' );
345 $out->addWikiMsg(
'undeletepagetext', $this->
getLanguage()->formatNum( $result->numRows() ) );
349 $out->addHTML(
"<ul id='undeleteResultsList'>\n" );
350 foreach ( $result as $row ) {
351 $title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title );
355 $title->getPrefixedText(),
357 [
'target' =>
$title->getPrefixedText() ]
361 $item = Html::element(
363 [
'class' =>
'mw-invalidtitle' ],
371 $revs = $this->
msg(
'undeleterevisions' )->numParams( $row->count )->parse();
375 [
'class' =>
'undeleteResult' ],
381 $out->addHTML(
"</ul>\n" );
387 if ( !preg_match(
'/[0-9]{14}/', $timestamp ) ) {
392 if ( !Hooks::run(
'UndeleteForm::showRevision', [ &$archive, $this->mTargetObj ] ) ) {
395 $rev = $archive->getRevision( $timestamp );
401 $out->addWikiMsg(
'undeleterevision-missing' );
406 if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
407 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
409 "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
410 $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
411 'rev-suppressed-text-permission' :
'rev-deleted-text-permission'
418 "<div class='mw-warning plainlinks'>\n$1\n</div>\n",
419 $rev->isDeleted( RevisionRecord::DELETED_RESTRICTED ) ?
420 'rev-suppressed-text-view' :
'rev-deleted-text-view'
422 $out->addHTML(
'<br />' );
426 if ( $this->mDiff ) {
427 $previousRev = $archive->getPreviousRevision( $timestamp );
428 if ( $previousRev ) {
429 $this->
showDiff( $previousRev, $rev );
430 if ( $this->mDiffOnly ) {
434 $out->addHTML(
'<hr />' );
436 $out->addWikiMsg(
'undelete-nodiff' );
441 $this->
getPageTitle( $this->mTargetObj->getPrefixedDBkey() ),
442 $this->mTargetObj->getPrefixedText()
449 $time =
$lang->userTimeAndDate( $timestamp, $user );
450 $d =
$lang->userDate( $timestamp, $user );
451 $t =
$lang->userTime( $timestamp, $user );
454 $content = $rev->getContent( RevisionRecord::FOR_THIS_USER, $user );
459 if ( $this->mPreview || $isText ) {
460 $openDiv =
'<div id="mw-undelete-revision" class="mw-warning">';
462 $openDiv =
'<div id="mw-undelete-revision">';
464 $out->addHTML( $openDiv );
467 if ( !$this->mDiff ) {
470 $out->addHTML(
"$revdel " );
479 $out->addHTML(
'</div>' );
481 if ( !Hooks::run(
'UndeleteShowRevision', [ $this->mTargetObj, $rev ] ) ) {
485 if ( $this->mPreview || !$isText ) {
488 $popts = $out->parserOptions();
489 $renderer = MediaWikiServices::getInstance()->getRevisionRenderer();
491 $rendered = $renderer->getRenderedRevision(
492 $rev->getRevisionRecord(),
495 [
'audience' => RevisionRecord::FOR_THIS_USER ]
500 $pout = $rendered->getRevisionParserOutput();
502 $out->addParserOutput( $pout, [
503 'enableSectionEditLinks' =>
false,
511 '@phan-var TextContent $content';
514 $sourceView = Xml::element(
'textarea', [
515 'readonly' =>
'readonly',
520 $buttonFields[] =
new OOUI\ButtonInputWidget( [
523 'label' => $this->
msg(
'showpreview' )->text()
529 $buttonFields[] =
new OOUI\ButtonInputWidget( [
532 'label' => $this->
msg(
'showdiff' )->text()
537 Xml::openElement(
'div', [
538 'style' =>
'clear: both' ] ) .
539 Xml::openElement(
'form', [
541 'action' => $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] ) ] ) .
542 Xml::element(
'input', [
545 'value' => $this->mTargetObj->getPrefixedDBkey() ] ) .
546 Xml::element(
'input', [
548 'name' =>
'timestamp',
549 'value' => $timestamp ] ) .
550 Xml::element(
'input', [
552 'name' =>
'wpEditToken',
553 'value' => $user->getEditToken() ] ) .
554 new OOUI\FieldLayout(
556 'content' =>
new OOUI\HorizontalLayout( [
557 'items' => $buttonFields
561 Xml::closeElement(
'form' ) .
562 Xml::closeElement(
'div' )
575 $diffContext->setTitle( $currentRev->getTitle() );
576 $diffContext->setWikiPage( WikiPage::factory( $currentRev->getTitle() ) );
578 $diffEngine = $currentRev->getContentHandler()->createDifferenceEngine( $diffContext );
579 $diffEngine->setRevisions( $previousRev->getRevisionRecord(), $currentRev->getRevisionRecord() );
580 $diffEngine->showDiffStyle();
581 $formattedDiff = $diffEngine->getDiff(
586 $this->
getOutput()->addHTML(
"<div>$formattedDiff</div>\n" );
595 $isDeleted = !( $rev->getId() && $rev->getTitle() );
600 'target' => $this->mTargetObj->getPrefixedText(),
601 'timestamp' =>
wfTimestamp( TS_MW, $rev->getTimestamp() )
605 $targetPage = $rev->getTitle();
606 $targetQuery = [
'oldid' => $rev->getId() ];
623 [
'ct_rev_id' => $rev->getId() ],
627 $changeTagDefStore = MediaWikiServices::getInstance()->getChangeTagDefStore();
628 foreach ( $tagIds as $tagId ) {
630 $tags[] = $changeTagDefStore->getName( (
int)$tagId );
635 $tags = implode(
',', $tags );
640 return '<div id="mw-diff-' . $prefix .
'title1"><strong>' .
645 $lang->userTimeAndDate( $rev->getTimestamp(), $user ),
646 $lang->userDate( $rev->getTimestamp(), $user ),
647 $lang->userTime( $rev->getTimestamp(), $user )
653 '<div id="mw-diff-' . $prefix .
'title2">' .
656 '<div id="mw-diff-' . $prefix .
'title3">' .
659 '<div id="mw-diff-' . $prefix .
'title5">' .
660 $tagSummary[0] .
'<br />' .
673 $out->addWikiMsg(
'undelete-show-file-confirm',
674 $this->mTargetObj->getText(),
675 $lang->userDate(
$file->getTimestamp(), $user ),
676 $lang->userTime(
$file->getTimestamp(), $user ) );
678 Xml::openElement(
'form', [
681 'target' => $this->mTarget,
683 'token' => $user->getEditToken( $key ),
687 Xml::submitButton( $this->msg(
'undelete-show-file-submit' )->text() ) .
699 # We mustn't allow the output to be CDN cached, otherwise
700 # if an admin previews a deleted image, and it's cached, then
701 # a user without appropriate permissions can toddle off and
702 # nab the image, and CDN will serve it
704 $response->header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', 0 ) .
' GMT' );
705 $response->header(
'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
708 $repo = RepoGroup::singleton()->getLocalRepo();
709 $path = $repo->getZonePath(
'deleted' ) .
'/' . $repo->getDeletedHashPath( $key ) . $key;
710 $repo->streamFileWithStatus(
$path );
717 if ( $this->mAllowed ) {
718 $out->addModules(
'mediawiki.special.undelete' );
721 "<div class='mw-undelete-pagetitle'>\n$1\n</div>\n",
722 [
'undeletepagetitle',
wfEscapeWikiText( $this->mTargetObj->getPrefixedText() ) ]
726 Hooks::run(
'UndeleteForm::showHistory', [ &$archive, $this->mTargetObj ] );
728 $out->addHTML(
'<div class="mw-undelete-history">' );
729 if ( $this->mAllowed ) {
730 $out->addWikiMsg(
'undeletehistory' );
731 $out->addWikiMsg(
'undeleterevdel' );
733 $out->addWikiMsg(
'undeletehistorynoadmin' );
735 $out->addHTML(
'</div>' );
737 # List all stored revisions
738 $revisions = $archive->listRevisions();
739 $files = $archive->listFiles();
741 $haveRevisions = $revisions && $revisions->numRows() > 0;
742 $haveFiles = $files && $files->numRows() > 0;
744 # Batch existence check on user and talk pages
745 if ( $haveRevisions ) {
747 foreach ( $revisions as $row ) {
748 $batch->addObj( Title::makeTitleSafe(
NS_USER, $row->ar_user_text ) );
749 $batch->addObj( Title::makeTitleSafe(
NS_USER_TALK, $row->ar_user_text ) );
752 $revisions->seek( 0 );
756 foreach ( $files as $row ) {
757 $batch->addObj( Title::makeTitleSafe(
NS_USER, $row->fa_user_text ) );
758 $batch->addObj( Title::makeTitleSafe(
NS_USER_TALK, $row->fa_user_text ) );
764 if ( $this->mAllowed ) {
767 $action = $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] );
768 # Start the form here
769 $form =
new OOUI\FormLayout( [
776 # Show relevant lines from the deletion log:
777 $deleteLogPage =
new LogPage(
'delete' );
778 $out->addHTML( Xml::element(
'h2',
null, $deleteLogPage->getName()->text() ) .
"\n" );
780 # Show relevant lines from the suppression log:
781 $suppressLogPage =
new LogPage(
'suppress' );
782 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
783 if ( $permissionManager->userHasRight( $this->getUser(),
'suppressionlog' ) ) {
784 $out->addHTML( Xml::element(
'h2',
null, $suppressLogPage->getName()->text() ) .
"\n" );
788 if ( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) {
790 $fields[] =
new OOUI\Layout( [
791 'content' =>
new OOUI\HtmlSnippet( $this->
msg(
'undeleteextrahelp' )->parseAsBlock() )
794 $fields[] =
new OOUI\FieldLayout(
795 new OOUI\TextInputWidget( [
796 'name' =>
'wpComment',
797 'inputId' =>
'wpComment',
799 'value' => $this->mComment,
804 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
807 'label' => $this->
msg(
'undeletecomment' )->text(),
812 $fields[] =
new OOUI\FieldLayout(
814 'content' =>
new OOUI\HorizontalLayout( [
816 new OOUI\ButtonInputWidget( [
818 'inputId' =>
'mw-undelete-submit',
820 'label' => $this->
msg(
'undeletebtn' )->text(),
821 'flags' => [
'primary',
'progressive' ],
824 new OOUI\ButtonInputWidget( [
826 'inputId' =>
'mw-undelete-invert',
828 'label' => $this->
msg(
'undeleteinvert' )->text()
835 if ( $permissionManager->userHasRight( $this->getUser(),
'suppressrevision' ) ) {
836 $fields[] =
new OOUI\FieldLayout(
837 new OOUI\CheckboxInputWidget( [
838 'name' =>
'wpUnsuppress',
839 'inputId' =>
'mw-undelete-unsuppress',
843 'label' => $this->
msg(
'revdelete-unsuppress' )->text(),
849 $fieldset =
new OOUI\FieldsetLayout( [
850 'label' => $this->
msg(
'undelete-fieldset-title' )->text(),
851 'id' =>
'mw-undelete-table',
855 $form->appendContent(
856 new OOUI\PanelLayout( [
860 'content' => $fieldset,
862 new OOUI\HtmlSnippet(
863 Html::hidden(
'target', $this->mTarget ) .
864 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() )
870 $history .= Xml::element(
'h2',
null, $this->
msg(
'history' )->text() ) .
"\n";
872 if ( $haveRevisions ) {
873 # Show the page's stored (deleted) history
875 if ( $permissionManager->userHasRight( $this->getUser(),
'deleterevision' ) ) {
876 $history .= Html::element(
881 'class' =>
'deleterevision-log-submit mw-log-deleterevision-button'
883 $this->
msg(
'showhideselectedversions' )->text()
887 $history .=
'<ul class="mw-undelete-revlist">';
888 $remaining = $revisions->numRows();
889 $earliestLiveTime = $this->mTargetObj->getEarliestRevTime();
891 foreach ( $revisions as $row ) {
898 $out->addWikiMsg(
'nohistory' );
902 $history .= Xml::element(
'h2',
null, $this->
msg(
'filehist' )->text() ) .
"\n";
903 $history .=
'<ul class="mw-undelete-revlist">';
904 foreach ( $files as $row ) {
911 if ( $this->mAllowed ) {
912 # Slip in the hidden controls here
913 $misc = Html::hidden(
'target', $this->mTarget );
914 $misc .= Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() );
917 $form->appendContent(
new OOUI\HtmlSnippet( $history ) );
918 $out->addHTML( $form );
920 $out->addHTML( $history );
927 $rev = Revision::newFromArchiveRow( $row,
929 'title' => $this->mTargetObj
935 if ( $this->mAllowed ) {
936 if ( $this->mInvert ) {
937 if ( in_array( $ts, $this->mTargetTimestamp ) ) {
938 $checkBox = Xml::check(
"ts$ts" );
940 $checkBox = Xml::check(
"ts$ts",
true );
943 $checkBox = Xml::check(
"ts$ts" );
951 if ( $this->mCanView ) {
954 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $this->getUser() ) ) {
955 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
956 $last = $this->
msg(
'diff' )->escaped();
957 } elseif ( $remaining > 0 || ( $earliestLiveTime && $ts > $earliestLiveTime ) ) {
958 $pageLink = $this->
getPageLink( $rev, $titleObj, $ts );
961 $this->
msg(
'diff' )->text(),
964 'target' => $this->mTargetObj->getPrefixedText(),
970 $pageLink = $this->
getPageLink( $rev, $titleObj, $ts );
971 $last = $this->
msg(
'diff' )->escaped();
974 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
975 $last = $this->
msg(
'diff' )->escaped();
985 $size = $row->ar_len;
986 if ( !is_null( $size ) ) {
1001 $attribs[
'class'] = implode(
' ', $classes );
1004 $revisionRow = $this->
msg(
'undelete-revision-row2' )
1017 return Xml::tags(
'li', $attribs, $revisionRow ) .
"\n";
1026 if ( $this->mCanView && $row->fa_storage_key ) {
1027 if ( $this->mAllowed ) {
1028 $checkBox = Xml::check(
'fileid' . $row->fa_id );
1030 $key = urlencode( $row->fa_storage_key );
1033 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
1036 $data = $this->
msg(
'widthheight' )->numParams( $row->fa_width, $row->fa_height )->text();
1037 $bytes = $this->
msg(
'parentheses' )
1038 ->plaintextParams( $this->
msg(
'nbytes' )->numParams( $row->fa_size )->text() )
1040 $data = htmlspecialchars( $data .
' ' . $bytes );
1044 $canHide = $this->
isAllowed(
'deleterevision' );
1045 if ( $canHide || (
$file->getVisibility() && $this->isAllowed(
'deletedhistory' ) ) ) {
1046 if ( !
$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
1051 'type' =>
'filearchive',
1052 'target' => $this->mTargetObj->getPrefixedDBkey(),
1053 'ids' => $row->fa_id
1056 $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
1062 return "<li>$checkBox $revdlink $pageLink . . $userLink $data $comment</li>\n";
1075 $time = $this->
getLanguage()->userTimeAndDate( $ts, $user );
1077 if ( !$rev->userCan( RevisionRecord::DELETED_TEXT, $user ) ) {
1078 return '<span class="history-deleted">' . $time .
'</span>';
1086 'target' => $this->mTargetObj->getPrefixedText(),
1091 if ( $rev->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
1092 $link =
'<span class="history-deleted">' . $link .
'</span>';
1110 $time = $this->
getLanguage()->userTimeAndDate( $ts, $user );
1112 if ( !
$file->userCan( File::DELETED_FILE, $user ) ) {
1113 return '<span class="history-deleted">' . htmlspecialchars( $time ) .
'</span>';
1121 'target' => $this->mTargetObj->getPrefixedText(),
1123 'token' => $user->getEditToken( $key )
1127 if (
$file->isDeleted( File::DELETED_FILE ) ) {
1128 $link =
'<span class="history-deleted">' . $link .
'</span>';
1141 if ( !
$file->userCan( File::DELETED_USER, $this->getUser() ) ) {
1142 return '<span class="history-deleted">' .
1143 $this->
msg(
'rev-deleted-user' )->escaped() .
1150 if (
$file->isDeleted( File::DELETED_USER ) ) {
1151 $link =
'<span class="history-deleted">' . $link .
'</span>';
1164 if ( !
$file->userCan( File::DELETED_COMMENT, $this->getUser() ) ) {
1165 return '<span class="history-deleted"><span class="comment">' .
1166 $this->
msg(
'rev-deleted-comment' )->escaped() .
'</span></span>';
1171 if (
$file->isDeleted( File::DELETED_COMMENT ) ) {
1172 $link =
'<span class="history-deleted">' . $link .
'</span>';
1179 if ( $this->
getConfig()->
get(
'UploadMaintenance' )
1180 && $this->mTargetObj->getNamespace() ==
NS_FILE
1182 throw new ErrorPageError(
'undelete-error',
'filedelete-maintenance' );
1189 Hooks::run(
'UndeleteForm::undelete', [ &$archive, $this->mTargetObj ] );
1190 $ok = $archive->undelete(
1191 $this->mTargetTimestamp,
1193 $this->mFileVersions,
1198 if ( is_array( $ok ) ) {
1200 Hooks::run(
'FileUndeleteComplete', [
1201 $this->mTargetObj, $this->mFileVersions,
1202 $this->
getUser(), $this->mComment ] );
1208 $out->setPageTitle( $this->
msg(
'undelete-error' ) );
1212 $status = $archive->getRevisionStatus();
1213 if ( $status && !$status->isGood() ) {
1214 $out->wrapWikiTextAsInterface(
1216 '<div id="mw-error-cannotundelete">' .
1217 $status->getWikiText(
1220 $this->getLanguage()
1226 $status = $archive->getFileStatus();
1227 if ( $status && !$status->isGood() ) {
1228 $out->wrapWikiTextAsInterface(
1230 $status->getWikiText(
1231 'undelete-error-short',
1232 'undelete-error-long',
1233 $this->getLanguage()
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Class representing a row of the 'filearchive' table.
static newFromRow( $row)
Loads a file object from the filearchive table.
static flag( $flag, IContextSource $context=null)
Make an "<abbr>" element for a given change flag.
An error page which can definitely be safely rendered using the OutputPage.
Class representing a list of titles The execute() method checks them all for existence and adds them ...
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
static getRevDeleteLink(User $user, Revision $rev, LinkTarget $title)
Get a revision-deletion link, or disabled link, or nothing, depending on user permissions & the setti...
static revComment(Revision $rev, $local=false, $isPublic=false, $useParentheses=true)
Wrap and format the given revision's comment block, if the current user is allowed to view it.
static revDeleteLinkDisabled( $delete=true)
Creates a dead (show/hide) link for deleting revisions/log entries.
static getInvalidTitleDescription(IContextSource $context, $namespace, $title)
Get a message saying that an invalid title was encountered.
static formatRevisionSize( $size)
static commentBlock( $comment, $title=null, $local=false, $wikiId=null, $useParentheses=true)
Wrap a comment in standard punctuation and formatting if it's non-empty, otherwise return empty strin...
static revUserTools( $rev, $isPublic=false, $useParentheses=true)
Generate a user tool link cluster if the current user is allowed to view it.
static userToolLinks( $userId, $userText, $redContribsWhenNoEdits=false, $flags=0, $edits=null, $useParentheses=true)
Generate standard user tool links (talk, contributions, block link, etc.)
static revDeleteLink( $query=[], $restricted=false, $delete=true)
Creates a (show/hide) link for deleting revisions/log entries.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Class to simplify the use of log pages.
Used to show archived pages and eventually restore them.
static listPagesBySearch( $term)
List deleted pages recorded in the archive matching the given term, using search engine archive.
static listPagesByPrefix( $prefix)
List deleted pages recorded in the archive table matching the given title prefix.
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.
getSkin()
Shortcut to get the skin being used for this instance.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
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.
prefixSearchString( $search, $limit, $offset)
Perform a regular substring search for prefixSearchSubpages.
MediaWiki Linker LinkRenderer null $linkRenderer
Special page allowing users with the appropriate permissions to view and restore deleted content.
redirectToRevDel()
Convert submitted form data to format expected by RevisionDelete and redirect the request.
showList( $result)
Generic list of deleted pages.
getFileComment( $file)
Fetch file upload comment if it's available to this user.
int[] null $mFileVersions
diffHeader( $rev, $prefix)
showFileConfirmationForm( $key)
Show a form confirming whether a tokenless user really wants to see a file.
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
showFile( $key)
Show a deleted file version requested by the visitor.
getPageLink( $rev, $titleObj, $ts)
Fetch revision text link if it's available to all users.
getFileUser( $file)
Fetch file's user id if it's available to this user.
string $mSearchPrefix
Search prefix.
execute( $par)
Default execute method Checks user permissions.
showRevision( $timestamp)
getFileLink( $file, $titleObj, $ts, $key)
Fetch image view link if it's available to all users.
doesWrites()
Indicates whether this special page may perform database writes.
isAllowed( $permission, User $user=null)
Checks whether a user is allowed the permission for the specific title if one is set.
userCanExecute(User $user)
Checks if the given user (identified by an object) can execute this special page (as defined by $mRes...
formatRevisionRow( $row, $earliestLiveTime, $remaining)
showDiff( $previousRev, $currentRev)
Build a diff display between this and the previous either deleted or non-deleted edit.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Content object implementation for representing flat text.
Represents a title within MediaWiki.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
if(!isset( $args[0])) $lang