149 parent::__construct(
'Undelete',
'deletedhistory' );
173 $this->mAction = $request->getRawVal(
'action' );
174 if ( $par !==
null && $par !==
'' ) {
175 $this->mTarget = $par;
177 $this->mTarget = $request->getVal(
'target' );
180 $this->mTargetObj =
null;
182 if ( $this->mTarget !==
null && $this->mTarget !==
'' ) {
183 $this->mTargetObj = Title::newFromText( $this->mTarget );
186 $this->mSearchPrefix = $request->getText(
'prefix' );
187 $time = $request->getVal(
'timestamp' );
188 $this->mTimestamp = $time ?
wfTimestamp( TS_MW, $time ) :
'';
189 $this->mFilename = $request->getVal(
'file' );
191 $posted = $request->wasPosted() &&
192 $user->matchEditToken( $request->getVal(
'wpEditToken' ) );
193 $this->mRestore = $request->getCheck(
'restore' ) && $posted;
194 $this->mRevdel = $request->getCheck(
'revdel' ) && $posted;
195 $this->mInvert = $request->getCheck(
'invert' ) && $posted;
196 $this->mPreview = $request->getCheck(
'preview' ) && $posted;
197 $this->mDiff = $request->getCheck(
'diff' );
198 $this->mDiffOnly = $request->getBool(
'diffonly',
199 $this->userOptionsLookup->getOption( $this->getUser(),
'diffonly' ) );
200 $this->mComment = $request->getText(
'wpComment' );
201 $this->mUnsuppress = $request->getVal(
'wpUnsuppress' ) &&
202 $this->permissionManager->userHasRight( $user,
'suppressrevision' );
203 $this->mToken = $request->getVal(
'token' );
206 $this->mAllowed =
true;
207 $this->mCanView =
true;
208 } elseif ( $this->
isAllowed(
'deletedtext' ) ) {
209 $this->mAllowed =
false;
210 $this->mCanView =
true;
211 $this->mRestore =
false;
213 $this->mAllowed =
false;
214 $this->mCanView =
false;
215 $this->mTimestamp =
'';
216 $this->mRestore =
false;
219 if ( $this->mRestore || $this->mInvert ) {
221 $this->mFileVersions = [];
222 foreach ( $request->getValues() as $key => $val ) {
224 if ( preg_match(
'/^ts(\d{14})$/', $key,
$matches ) ) {
225 array_push( $timestamps,
$matches[1] );
228 if ( preg_match(
'/^fileid(\d+)$/', $key,
$matches ) ) {
229 $this->mFileVersions[] = intval(
$matches[1] );
232 rsort( $timestamps );
233 $this->mTargetTimestamp = $timestamps;
246 $user = $user ?: $this->
getUser();
247 $block = $user->getBlock();
249 if ( $this->mTargetObj !==
null ) {
250 return $this->permissionManager->userCan( $permission, $user, $this->mTargetObj );
252 $hasRight = $this->permissionManager->userHasRight( $user, $permission );
253 $sitewideBlock = $block && $block->isSitewide();
254 return $permission ===
'undelete' ? ( $hasRight && !$sitewideBlock ) : $hasRight;
259 return $this->
isAllowed( $this->mRestriction, $user );
270 if ( !parent::userCanExecute( $user ) ) {
277 $this->mTargetObj && $this->permissionManager->isBlockedFrom( $user, $this->mTargetObj ) ) {
294 $this->
addHelpLink(
'Help:Deletion_and_undeletion' );
301 if ( $this->mTargetObj ===
null ) {
302 $out->addWikiMsg(
'undelete-header' );
304 # Not all users can just browse every deleted page from the list
305 if ( $this->permissionManager->userHasRight( $user,
'browsearchive' ) ) {
313 if ( $this->mAllowed ) {
314 $out->setPageTitle( $this->
msg(
'undeletepage' ) );
316 $out->setPageTitle( $this->
msg(
'viewdeletedpage' ) );
319 $this->
getSkin()->setRelevantTitle( $this->mTargetObj );
321 if ( $this->mTimestamp !==
'' ) {
323 } elseif ( $this->mFilename !==
null && $this->mTargetObj->inNamespace(
NS_FILE ) ) {
326 if ( !
$file->exists() ) {
327 $out->addWikiMsg(
'filedelete-nofile', $this->mFilename );
328 } elseif ( !
$file->userCan( File::DELETED_FILE, $user ) ) {
329 if (
$file->isDeleted( File::DELETED_RESTRICTED ) ) {
334 } elseif ( !$user->matchEditToken( $this->mToken, $this->mFilename ) ) {
337 $this->
showFile( $this->mFilename );
339 } elseif ( $this->mAction ===
'submit' ) {
340 if ( $this->mRestore ) {
342 } elseif ( $this->mRevdel ) {
358 foreach ( $this->
getRequest()->getValues() as $key => $val ) {
360 if ( preg_match(
"/^ts(\d{14})$/", $key,
$matches ) ) {
361 $revisionRecord = $this->archivedRevisionLookup
362 ->getRevisionRecordByTimestamp( $this->mTargetObj,
$matches[1] );
363 if ( $revisionRecord ) {
365 $revisions[ $revisionRecord->getId() ] = 1;
371 'type' =>
'revision',
373 'target' => $this->mTargetObj->getPrefixedText()
381 $out->setPageTitle( $this->
msg(
'undelete-search-title' ) );
382 $fuzzySearch = $this->
getRequest()->getVal(
'fuzzy',
'1' );
387 $fields[] =
new OOUI\ActionFieldLayout(
388 new OOUI\TextInputWidget( [
390 'inputId' =>
'prefix',
392 'value' => $this->mSearchPrefix,
395 new OOUI\ButtonInputWidget( [
396 'label' => $this->
msg(
'undelete-search-submit' )->text(),
397 'flags' => [
'primary',
'progressive' ],
398 'inputId' =>
'searchUndelete',
402 'label' =>
new OOUI\HtmlSnippet(
404 $fuzzySearch ?
'undelete-search-full' :
'undelete-search-prefix'
411 $fieldset =
new OOUI\FieldsetLayout( [
412 'label' => $this->
msg(
'undelete-search-box' )->text(),
416 $form =
new OOUI\FormLayout( [
421 $form->appendContent(
423 new OOUI\HtmlSnippet(
424 Html::hidden(
'title', $this->
getPageTitle()->getPrefixedDBkey() ) .
425 Html::hidden(
'fuzzy', $fuzzySearch )
430 new OOUI\PanelLayout( [
438 # List undeletable articles
439 if ( $this->mSearchPrefix ) {
442 if ( $fuzzySearch ) {
443 $result = PageArchive::listPagesBySearch( $this->mSearchPrefix );
445 $result = PageArchive::listPagesByPrefix( $this->mSearchPrefix );
460 if ( $result->numRows() == 0 ) {
461 $out->addWikiMsg(
'undelete-no-results' );
466 $out->addWikiMsg(
'undeletepagetext', $this->
getLanguage()->formatNum( $result->numRows() ) );
470 $out->addHTML(
"<ul id='undeleteResultsList'>\n" );
471 foreach ( $result as $row ) {
472 $title = Title::makeTitleSafe( $row->ar_namespace, $row->ar_title );
476 $title->getPrefixedText(),
478 [
'target' =>
$title->getPrefixedText() ]
482 $item = Html::element(
484 [
'class' =>
'mw-invalidtitle' ],
492 $revs = $this->
msg(
'undeleterevisions' )->numParams( $row->count )->parse();
496 [
'class' =>
'undeleteResult' ],
502 $out->addHTML(
"</ul>\n" );
508 if ( !preg_match(
'/[0-9]{14}/', $timestamp ) ) {
517 $this->
msg(
'undelete-back-to-list' )->text(),
519 [
'target' => $this->mTargetObj->getPrefixedText() ]
522 $subtitle =
"< $listLink";
523 $out->setSubtitle( $subtitle );
528 $archive, $this->mTargetObj )
532 $revRecord = $this->archivedRevisionLookup->getRevisionRecordByTimestamp( $this->mTargetObj, $timestamp );
537 $out->addWikiMsg(
'undeleterevision-missing' );
541 if ( $revRecord->isDeleted( RevisionRecord::DELETED_TEXT ) ) {
543 $titleText = $this->mTargetObj->getPrefixedDBkey();
544 if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
545 $msg = $revRecord->isDeleted( RevisionRecord::DELETED_RESTRICTED )
546 ? [
'rev-suppressed-text-permission', $titleText ]
547 : [
'rev-deleted-text-permission', $titleText ];
550 $this->
msg( $msg[0], $msg[1] )->parse(),
557 $msg = $revRecord->isDeleted( RevisionRecord::DELETED_RESTRICTED )
558 ? [
'rev-suppressed-text-view', $titleText ]
559 : [
'rev-deleted-text-view', $titleText ];
562 $this->
msg( $msg[0], $msg[1] )->parse(),
569 if ( $this->mDiff ) {
570 $previousRevRecord = $this->archivedRevisionLookup
571 ->getPreviousRevisionRecord( $this->mTargetObj, $timestamp );
572 if ( $previousRevRecord ) {
573 $this->
showDiff( $previousRevRecord, $revRecord );
574 if ( $this->mDiffOnly ) {
578 $out->addHTML(
'<hr />' );
580 $out->addWikiMsg(
'undelete-nodiff' );
585 $this->
getPageTitle( $this->mTargetObj->getPrefixedDBkey() ),
586 $this->mTargetObj->getPrefixedText()
593 $time =
$lang->userTimeAndDate( $timestamp, $user );
594 $d =
$lang->userDate( $timestamp, $user );
595 $t =
$lang->userTime( $timestamp, $user );
600 RevisionRecord::FOR_THIS_USER,
611 'id' =>
'mw-undelete-revision',
612 'class' => $this->mPreview || $isText ?
'warningbox' :
'',
618 if ( !$this->mDiff ) {
625 $out->addHTML(
"$revdel " );
634 $out->addHTML( Html::closeElement(
'div' ) );
636 if ( $this->mPreview || !$isText ) {
639 $popts = $out->parserOptions();
641 $rendered = $this->revisionRenderer->getRenderedRevision(
645 [
'audience' => RevisionRecord::FOR_THIS_USER ]
650 $pout = $rendered->getRevisionParserOutput();
652 $out->addParserOutput( $pout, [
653 'enableSectionEditLinks' =>
false,
661 '@phan-var TextContent $content';
664 $sourceView = Xml::element(
'textarea', [
665 'readonly' =>
'readonly',
670 $buttonFields[] =
new OOUI\ButtonInputWidget( [
673 'label' => $this->
msg(
'showpreview' )->text()
679 $buttonFields[] =
new OOUI\ButtonInputWidget( [
682 'label' => $this->
msg(
'showdiff' )->text()
687 Xml::openElement(
'div', [
688 'style' =>
'clear: both' ] ) .
689 Xml::openElement(
'form', [
691 'action' => $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] ) ] ) .
692 Xml::element(
'input', [
695 'value' => $this->mTargetObj->getPrefixedDBkey() ] ) .
696 Xml::element(
'input', [
698 'name' =>
'timestamp',
699 'value' => $timestamp ] ) .
700 Xml::element(
'input', [
702 'name' =>
'wpEditToken',
703 'value' => $user->getEditToken() ] ) .
704 new OOUI\FieldLayout(
706 'content' =>
new OOUI\HorizontalLayout( [
707 'items' => $buttonFields
711 Xml::closeElement(
'form' ) .
712 Xml::closeElement(
'div' )
730 $diffContext->setTitle( $currentTitle );
731 $diffContext->setWikiPage( $this->wikiPageFactory->newFromTitle( $currentTitle ) );
733 $contentModel = $currentRevRecord->
getSlot(
738 $diffEngine = $this->contentHandlerFactory->getContentHandler( $contentModel )
739 ->createDifferenceEngine( $diffContext );
741 $diffEngine->setRevisions( $previousRevRecord, $currentRevRecord );
742 $diffEngine->showDiffStyle();
743 $formattedDiff = $diffEngine->getDiff(
748 $this->
getOutput()->addHTML(
"<div>$formattedDiff</div>\n" );
762 'target' => $this->mTargetObj->getPrefixedText(),
768 $targetQuery = [
'oldid' => $revRecord->
getId() ];
780 $minor = $revRecord->
isMinor() ? ChangesList::flag(
'minor' ) :
'';
782 $dbr = $this->loadBalancer->getConnectionRef( ILoadBalancer::DB_REPLICA );
783 $tagIds =
$dbr->selectFieldValues(
786 [
'ct_rev_id' => $revRecord->
getId() ],
790 foreach ( $tagIds as $tagId ) {
792 $tags[] = $this->changeTagDefStore->getName( (
int)$tagId );
797 $tags = implode(
',', $tags );
802 return '<div id="mw-diff-' . $prefix .
'title1"><strong>' .
815 '<div id="mw-diff-' . $prefix .
'title2">' .
818 '<div id="mw-diff-' . $prefix .
'title3">' .
821 '<div id="mw-diff-' . $prefix .
'title5">' .
822 $tagSummary[0] .
'<br />' .
835 $out->addWikiMsg(
'undelete-show-file-confirm',
836 $this->mTargetObj->getText(),
837 $lang->userDate(
$file->getTimestamp(), $user ),
838 $lang->userTime(
$file->getTimestamp(), $user ) );
840 Xml::openElement(
'form', [
843 'target' => $this->mTarget,
845 'token' => $user->getEditToken( $key ),
849 Xml::submitButton( $this->msg(
'undelete-show-file-submit' )->text() ) .
861 # We mustn't allow the output to be CDN cached, otherwise
862 # if an admin previews a deleted image, and it's cached, then
863 # a user without appropriate permissions can toddle off and
864 # nab the image, and CDN will serve it
866 $response->header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', 0 ) .
' GMT' );
867 $response->header(
'Cache-Control: no-cache, no-store, max-age=0, must-revalidate' );
868 $response->header(
'Pragma: no-cache' );
870 $path = $this->localRepo->getZonePath(
'deleted' ) .
'/' . $this->localRepo->getDeletedHashPath( $key ) . $key;
871 $this->localRepo->streamFileWithStatus(
$path );
878 if ( $this->mAllowed ) {
879 $out->addModules(
'mediawiki.misc-authed-ooui' );
882 "<div class='mw-undelete-pagetitle'>\n$1\n</div>\n",
883 [
'undeletepagetitle',
wfEscapeWikiText( $this->mTargetObj->getPrefixedText() ) ]
888 $this->
getHookRunner()->onUndeleteForm__showHistory( $archive, $this->mTargetObj );
890 $out->addHTML( Html::openElement(
'div', [
'class' =>
'mw-undelete-history' ] ) );
891 if ( $this->mAllowed ) {
892 $out->addWikiMsg(
'undeletehistory' );
893 $out->addWikiMsg(
'undeleterevdel' );
895 $out->addWikiMsg(
'undeletehistorynoadmin' );
897 $out->addHTML( Html::closeElement(
'div' ) );
899 # List all stored revisions
900 $revisions = $this->archivedRevisionLookup->listRevisions( $this->mTargetObj );
901 $files = $archive->listFiles();
903 $haveRevisions = $revisions && $revisions->numRows() > 0;
904 $haveFiles = $files && $files->numRows() > 0;
906 # Batch existence check on user and talk pages
907 if ( $haveRevisions || $haveFiles ) {
908 $batch = $this->linkBatchFactory->newLinkBatch();
909 if ( $haveRevisions ) {
910 foreach ( $revisions as $row ) {
911 $batch->add(
NS_USER, $row->ar_user_text );
914 $revisions->seek( 0 );
917 foreach ( $files as $row ) {
918 $batch->add(
NS_USER, $row->fa_user_text );
926 if ( $this->mAllowed ) {
929 $action = $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] );
930 # Start the form here
931 $form =
new OOUI\FormLayout( [
938 # Show relevant lines from the deletion log:
939 $deleteLogPage =
new LogPage(
'delete' );
940 $out->addHTML( Xml::element(
'h2',
null, $deleteLogPage->getName()->text() ) .
"\n" );
941 LogEventsList::showLogExtract( $out,
'delete', $this->mTargetObj );
942 # Show relevant lines from the suppression log:
943 $suppressLogPage =
new LogPage(
'suppress' );
944 if ( $this->permissionManager->userHasRight( $this->getUser(),
'suppressionlog' ) ) {
945 $out->addHTML( Xml::element(
'h2',
null, $suppressLogPage->getName()->text() ) .
"\n" );
946 LogEventsList::showLogExtract( $out,
'suppress', $this->mTargetObj );
949 if ( $this->mAllowed && ( $haveRevisions || $haveFiles ) ) {
951 $fields[] =
new OOUI\Layout( [
952 'content' =>
new OOUI\HtmlSnippet( $this->
msg(
'undeleteextrahelp' )->parseAsBlock() )
955 $fields[] =
new OOUI\FieldLayout(
956 new OOUI\TextInputWidget( [
957 'name' =>
'wpComment',
958 'inputId' =>
'wpComment',
960 'value' => $this->mComment,
965 'maxLength' => CommentStore::COMMENT_CHARACTER_LIMIT,
968 'label' => $this->
msg(
'undeletecomment' )->text(),
973 $fields[] =
new OOUI\FieldLayout(
975 'content' =>
new OOUI\HorizontalLayout( [
977 new OOUI\ButtonInputWidget( [
979 'inputId' =>
'mw-undelete-submit',
981 'label' => $this->
msg(
'undeletebtn' )->text(),
982 'flags' => [
'primary',
'progressive' ],
985 new OOUI\ButtonInputWidget( [
987 'inputId' =>
'mw-undelete-invert',
989 'label' => $this->
msg(
'undeleteinvert' )->text()
996 if ( $this->permissionManager->userHasRight( $this->getUser(),
'suppressrevision' ) ) {
997 $fields[] =
new OOUI\FieldLayout(
998 new OOUI\CheckboxInputWidget( [
999 'name' =>
'wpUnsuppress',
1000 'inputId' =>
'mw-undelete-unsuppress',
1004 'label' => $this->
msg(
'revdelete-unsuppress' )->text(),
1005 'align' =>
'inline',
1010 $fieldset =
new OOUI\FieldsetLayout( [
1011 'label' => $this->
msg(
'undelete-fieldset-title' )->text(),
1012 'id' =>
'mw-undelete-table',
1016 $form->appendContent(
1017 new OOUI\PanelLayout( [
1018 'expanded' =>
false,
1021 'content' => $fieldset,
1023 new OOUI\HtmlSnippet(
1024 Html::hidden(
'target', $this->mTarget ) .
1025 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() )
1031 $history .= Xml::element(
'h2',
null, $this->
msg(
'history' )->text() ) .
"\n";
1033 if ( $haveRevisions ) {
1034 # Show the page's stored (deleted) history
1036 if ( $this->permissionManager->userHasRight( $this->getUser(),
'deleterevision' ) ) {
1037 $history .= Html::element(
1042 'class' =>
'deleterevision-log-submit mw-log-deleterevision-button'
1044 $this->
msg(
'showhideselectedversions' )->text()
1048 $history .= Html::openElement(
'ul', [
'class' =>
'mw-undelete-revlist' ] );
1049 $remaining = $revisions->numRows();
1050 $firstRev = $this->revisionStore->getFirstRevision( $this->mTargetObj );
1051 $earliestLiveTime = $firstRev ? $firstRev->getTimestamp() :
null;
1053 foreach ( $revisions as $row ) {
1058 $history .= Html::closeElement(
'ul' );
1060 $out->addWikiMsg(
'nohistory' );
1064 $history .= Xml::element(
'h2',
null, $this->
msg(
'filehist' )->text() ) .
"\n";
1065 $history .= Html::openElement(
'ul', [
'class' =>
'mw-undelete-revlist' ] );
1066 foreach ( $files as $row ) {
1070 $history .= Html::closeElement(
'ul' );
1073 if ( $this->mAllowed ) {
1074 # Slip in the hidden controls here
1075 $misc = Html::hidden(
'target', $this->mTarget );
1076 $misc .= Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() );
1079 $form->appendContent(
new OOUI\HtmlSnippet( $history ) );
1080 $out->addHTML( (
string)$form );
1082 $out->addHTML( $history );
1089 $revRecord = $this->revisionStore->newRevisionFromArchiveRow(
1091 RevisionStore::READ_NORMAL,
1098 if ( $this->mAllowed ) {
1099 if ( $this->mInvert ) {
1100 if ( in_array( $ts, $this->mTargetTimestamp ) ) {
1101 $checkBox = Xml::check(
"ts$ts" );
1103 $checkBox = Xml::check(
"ts$ts",
true );
1106 $checkBox = Xml::check(
"ts$ts" );
1114 if ( $this->mCanView ) {
1117 if ( !$revRecord->userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
1118 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
1119 $last = $this->
msg(
'diff' )->escaped();
1120 } elseif ( $remaining > 0 || ( $earliestLiveTime && $ts > $earliestLiveTime ) ) {
1121 $pageLink = $this->
getPageLink( $revRecord, $titleObj, $ts );
1124 $this->
msg(
'diff' )->text(),
1127 'target' => $this->mTargetObj->getPrefixedText(),
1133 $pageLink = $this->
getPageLink( $revRecord, $titleObj, $ts );
1134 $last = $this->
msg(
'diff' )->escaped();
1137 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
1138 $last = $this->
msg(
'diff' )->escaped();
1145 $minor = $revRecord->isMinor() ? ChangesList::flag(
'minor' ) :
'';
1148 $size = $row->ar_len;
1149 if ( $size !==
null ) {
1164 $attribs[
'class'] = implode(
' ', $classes );
1167 $revisionRow = $this->
msg(
'undelete-revision-row2' )
1180 return Xml::tags(
'li', $attribs, $revisionRow ) .
"\n";
1189 if ( $this->mCanView && $row->fa_storage_key ) {
1190 if ( $this->mAllowed ) {
1191 $checkBox = Xml::check(
'fileid' . $row->fa_id );
1193 $key = urlencode( $row->fa_storage_key );
1196 $pageLink = htmlspecialchars( $this->
getLanguage()->userTimeAndDate( $ts, $user ) );
1199 $data = $this->
msg(
'widthheight' )->numParams( $row->fa_width, $row->fa_height )->text();
1200 $bytes = $this->
msg(
'parentheses' )
1201 ->plaintextParams( $this->
msg(
'nbytes' )->numParams( $row->fa_size )->text() )
1203 $data = htmlspecialchars( $data .
' ' . $bytes );
1207 $canHide = $this->
isAllowed(
'deleterevision' );
1208 if ( $canHide || (
$file->getVisibility() && $this->isAllowed(
'deletedhistory' ) ) ) {
1209 if ( !
$file->userCan( File::DELETED_RESTRICTED, $user ) ) {
1214 'type' =>
'filearchive',
1215 'target' => $this->mTargetObj->getPrefixedDBkey(),
1216 'ids' => $row->fa_id
1219 $file->isDeleted( File::DELETED_RESTRICTED ), $canHide );
1225 return "<li>$checkBox $revdlink $pageLink . . $userLink $data $comment</li>\n";
1238 $time = $this->
getLanguage()->userTimeAndDate( $ts, $user );
1240 if ( !$revRecord->
userCan( RevisionRecord::DELETED_TEXT, $this->getAuthority() ) ) {
1243 return Html::rawElement(
1245 [
'class' =>
'history-deleted' ],
1246 htmlspecialchars( $time )
1255 'target' => $this->mTargetObj->getPrefixedText(),
1260 if ( $revRecord->
isDeleted( RevisionRecord::DELETED_TEXT ) ) {
1262 $link =
'<span class="' . $class .
'">' . $link .
'</span>';
1280 $time = $this->
getLanguage()->userTimeAndDate( $ts, $user );
1282 if ( !
$file->userCan( File::DELETED_FILE, $user ) ) {
1284 return Html::rawElement(
1286 [
'class' =>
'history-deleted' ],
1287 htmlspecialchars( $time )
1296 'target' => $this->mTargetObj->getPrefixedText(),
1298 'token' => $user->getEditToken( $key )
1302 if (
$file->isDeleted( File::DELETED_FILE ) ) {
1303 $link =
'<span class="history-deleted">' . $link .
'</span>';
1318 return Html::rawElement(
1320 [
'class' =>
'history-deleted' ],
1321 $this->
msg(
'rev-deleted-user' )->escaped()
1328 if (
$file->isDeleted( File::DELETED_USER ) ) {
1329 $link = Html::rawElement(
1331 [
'class' =>
'history-deleted' ],
1346 if ( !
$file->userCan( File::DELETED_COMMENT, $this->getAuthority() ) ) {
1347 return Html::rawElement(
1349 [
'class' =>
'history-deleted' ],
1352 [
'class' =>
'comment' ],
1353 $this->
msg(
'rev-deleted-comment' )->escaped()
1361 if (
$file->isDeleted( File::DELETED_COMMENT ) ) {
1362 $link = Html::rawElement(
1364 [
'class' =>
'history-deleted' ],
1373 if ( $this->
getConfig()->
get(
'UploadMaintenance' )
1374 && $this->mTargetObj->getNamespace() ===
NS_FILE
1376 throw new ErrorPageError(
'undelete-error',
'filedelete-maintenance' );
1382 $undeletePage = $this->undeletePageFactory->newUndeletePage(
1383 $this->wikiPageFactory->newFromTitle( $this->mTargetObj ),
1384 $this->getAuthority()
1386 $status = $undeletePage
1387 ->setUndeleteOnlyTimestamps( $this->mTargetTimestamp )
1388 ->setUndeleteOnlyFileVersions( $this->mFileVersions )
1389 ->setUnsuppress( $this->mUnsuppress )
1391 ->undeleteIfAllowed( $this->mComment );
1393 if ( !$status->isGood() ) {
1394 $out->setPageTitle( $this->
msg(
'undelete-error' ) );
1395 $out->wrapWikiTextAsInterface(
1397 Status::wrap( $status )->getWikiText(
1406 $restoredRevs = $status->getValue()[UndeletePage::REVISIONS_RESTORED];
1407 $restoredFiles = $status->getValue()[UndeletePage::FILES_RESTORED];
1409 if ( $restoredRevs === 0 && $restoredFiles === 0 ) {
1411 $out->setPageTitle( $this->
msg(
'undelete-error' ) );
1413 if ( $status->getValue()[UndeletePage::FILES_RESTORED] !== 0 ) {
1415 $this->mTargetObj, $this->mFileVersions, $this->
getUser(), $this->mComment );
1432 return $this->
prefixSearchString( $search, $limit, $offset, $this->searchEngineFactory );
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.
An error page which can definitely be safely rendered using the OutputPage.
static userLink( $userId, $userName, $altUserName=false)
Make user link (or user contributions for unregistered users)
static getRevisionDeletedClass(RevisionRecord $revisionRecord)
Returns css class of a deleted revision.
static revComment(RevisionRecord $revRecord, $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 getRevDeleteLink(Authority $performer, RevisionRecord $revRecord, LinkTarget $title)
Get a revision-deletion link, or disabled link, or nothing, depending on user permissions & the setti...
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(RevisionRecord $revRecord, $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.
A repository that stores files in the local filesystem and registers them in the wiki's own database.
Class to simplify the use of log pages.
Used to show archived pages and eventually restore them.
Show an error when a user tries to do something they do not have the necessary permissions for.
Prioritized list of file repositories.
getLocalRepo()
Get the local repository, i.e.
Factory class for SearchEngine.
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.
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.
LinkRenderer null $linkRenderer
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getAuthority()
Shortcut to get the Authority executing this instance.
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.
displayRestrictionError()
Output an error message telling the user what access level they have to have.
prefixSearchString( $search, $limit, $offset, SearchEngineFactory $searchEngineFactory=null)
Perform a regular substring search for prefixSearchSubpages.
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.
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.
RevisionStore $revisionStore
getFileComment( $file)
Fetch file upload comment if it's available to this user.
showDiff(RevisionRecord $previousRevRecord, RevisionRecord $currentRevRecord)
Build a diff display between this and the previous either deleted or non-deleted edit.
IContentHandlerFactory $contentHandlerFactory
showFileConfirmationForm( $key)
Show a form confirming whether a tokenless user really wants to see a file.
UndeletePageFactory $undeletePageFactory
prefixSearchSubpages( $search, $limit, $offset)
Return an array of subpages beginning with $search that this special page will accept.
RevisionRenderer $revisionRenderer
showFile( $key)
Show a deleted file version requested by the visitor.
PermissionManager $permissionManager
LinkBatchFactory $linkBatchFactory
diffHeader(RevisionRecord $revRecord, $prefix)
NameTableStore $changeTagDefStore
getFileUser( $file)
Fetch file's user id if it's available to this user.
WikiPageFactory $wikiPageFactory
ILoadBalancer $loadBalancer
string[] $mTargetTimestamp
string $mSearchPrefix
Search prefix.
execute( $par)
Default execute method Checks user permissions.
__construct(PermissionManager $permissionManager, RevisionStore $revisionStore, RevisionRenderer $revisionRenderer, IContentHandlerFactory $contentHandlerFactory, NameTableStore $changeTagDefStore, LinkBatchFactory $linkBatchFactory, RepoGroup $repoGroup, ILoadBalancer $loadBalancer, UserOptionsLookup $userOptionsLookup, WikiPageFactory $wikiPageFactory, SearchEngineFactory $searchEngineFactory, UndeletePageFactory $undeletePageFactory, ArchivedRevisionLookup $archivedRevisionLookup)
showRevision( $timestamp)
getFileLink( $file, $titleObj, $ts, $key)
Fetch image view link if it's available to all users.
ArchivedRevisionLookup $archivedRevisionLookup
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.to override 1.19 void|never
doesWrites()
Indicates whether this special page may perform database writes.
UserOptionsLookup $userOptionsLookup
isAllowed( $permission, User $user=null)
Checks whether a user is allowed the permission for the specific title if one is set.
SearchEngineFactory $searchEngineFactory
userCanExecute(User $user)
Checks if the given user (identified by an object) can execute this special page (as defined by $mRes...
getPageLink(RevisionRecord $revRecord, $titleObj, $ts)
Fetch revision text link if it's available to all users.
formatRevisionRow( $row, $earliestLiveTime, $remaining)
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.
Show an error when the user tries to do something whilst blocked.
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