Go to the documentation of this file.
79 'check-label' =>
'revdelete-hide-text',
80 'success' =>
'revdelete-success',
81 'failure' =>
'revdelete-failure',
82 'text' =>
'revdelete-text-text',
83 'selected' =>
'revdelete-selected-text',
86 'check-label' =>
'revdelete-hide-text',
87 'success' =>
'revdelete-success',
88 'failure' =>
'revdelete-failure',
89 'text' =>
'revdelete-text-text',
90 'selected' =>
'revdelete-selected-text',
93 'check-label' =>
'revdelete-hide-image',
94 'success' =>
'revdelete-success',
95 'failure' =>
'revdelete-failure',
96 'text' =>
'revdelete-text-file',
97 'selected' =>
'revdelete-selected-file',
100 'check-label' =>
'revdelete-hide-image',
101 'success' =>
'revdelete-success',
102 'failure' =>
'revdelete-failure',
103 'text' =>
'revdelete-text-file',
104 'selected' =>
'revdelete-selected-file',
107 'check-label' =>
'revdelete-hide-name',
108 'success' =>
'logdelete-success',
109 'failure' =>
'logdelete-failure',
110 'text' =>
'logdelete-text',
111 'selected' =>
'logdelete-selected',
121 parent::__construct(
'Revisiondelete',
'deleterevision' );
142 $this->submitClicked = $request->wasPosted() && $request->getBool(
'wpSubmit' );
143 # Handle our many different possible input types.
144 $ids = $request->getVal(
'ids' );
145 if ( !is_null(
$ids ) ) {
146 # Allow CSV, for backwards compatibility, or a single ID for show/hide links
147 $this->ids = explode(
',',
$ids );
150 $this->ids = array_keys( $request->getArray(
'ids', [] ) );
153 $this->ids = array_unique( array_filter( $this->ids ) );
155 $this->typeName = $request->getVal(
'type' );
158 # For reviewing deleted files...
159 $this->archiveName = $request->getVal(
'file' );
160 $this->token = $request->getVal(
'token' );
161 if ( $this->archiveName && $this->targetObj ) {
170 if ( !$this->typeName || count( $this->ids ) == 0 ) {
171 throw new ErrorPageError(
'revdelete-nooldid-title',
'revdelete-nooldid-text' );
174 # Allow the list type to adjust the passed target
181 # We need a target page!
182 if ( $this->targetObj ===
null ) {
183 $output->addWikiMsg(
'undelete-header' );
189 if ( $this->permissionManager->isBlockedFrom( $user, $this->targetObj ) ) {
201 $pageIsSuppressed = $list->areAnySuppressed();
202 $this->mIsAllowed = $this->mIsAllowed && !( $canViewSuppressedOnly && $pageIsSuppressed );
204 $this->otherReason = $request->getVal(
'wpReason' );
205 # Give a link to the logs/hist for this page
208 # Initialise checkboxes
210 # Messages: revdelete-hide-text, revdelete-hide-image, revdelete-hide-name
211 [ $this->typeLabels[
'check-label'],
'wpHidePrimary',
214 [
'revdelete-hide-comment',
'wpHideComment', RevisionRecord::DELETED_COMMENT ],
215 [
'revdelete-hide-user',
'wpHideUser', RevisionRecord::DELETED_USER ]
218 $this->checks[] = [
'revdelete-hide-restricted',
219 'wpHideRestricted', RevisionRecord::DELETED_RESTRICTED ];
222 # Either submit or create our form
223 if ( $this->mIsAllowed && $this->submitClicked ) {
231 # Show relevant lines from the deletion log
232 $deleteLogPage =
new LogPage(
'delete' );
233 $output->addHTML(
"<h2>" . $deleteLogPage->getName()->escaped() .
"</h2>\n" );
239 [
'lim' => 25,
'conds' => $qc,
'useMaster' => $this->wasSaved ]
242 # Show relevant lines from the suppression log
244 $suppressLogPage =
new LogPage(
'suppress' );
245 $output->addHTML(
"<h2>" . $suppressLogPage->getName()->escaped() .
"</h2>\n" );
251 [
'lim' => 25,
'conds' => $qc,
'useMaster' => $this->wasSaved ]
261 # Give a link to the logs/hist for this page
262 if ( $this->targetObj ) {
264 $this->
getSkin()->setRelevantTitle( $this->targetObj );
269 $this->
msg(
'viewpagelogs' )->text(),
271 [
'page' => $this->targetObj->getPrefixedText() ]
273 if ( !$this->targetObj->isSpecialPage() ) {
274 # Give a link to the page history
277 $this->
msg(
'pagehist' )->text(),
279 [
'action' =>
'history' ]
281 # Link to deleted edits
282 if ( MediaWikiServices::getInstance()
284 ->userHasRight( $this->
getUser(),
'undelete' )
289 $this->
msg(
'deletedhist' )->text(),
291 [
'target' => $this->targetObj->getPrefixedDBkey() ]
295 # Logs themselves don't have histories or archived revisions
307 $conds[
'log_type'] = [
'delete',
'suppress' ];
308 $conds[
'log_action'] = $this->
getList()->getLogAction();
324 $oimage = $repo->newFromArchiveName( $this->targetObj,
$archiveName );
327 if ( !$oimage->exists() ) {
328 $this->
getOutput()->addWikiMsg(
'revdelete-no-file' );
340 if ( !$user->matchEditToken( $this->token,
$archiveName ) ) {
342 $this->
getOutput()->addWikiMsg(
'revdelete-show-file-confirm',
343 $this->targetObj->getText(),
344 $lang->userDate( $oimage->getTimestamp(), $user ),
345 $lang->userTime( $oimage->getTimestamp(), $user ) );
350 'target' => $this->targetObj->getPrefixedDBkey(),
363 # We mustn't allow the output to be CDN cached, otherwise
364 # if an admin previews a deleted image, and it's cached, then
365 # a user without appropriate permissions can toddle off and
366 # nab the image, and CDN will serve it
367 $this->
getRequest()->response()->header(
'Expires: ' . gmdate(
'D, d M Y H:i:s', 0 ) .
' GMT' );
369 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate'
371 $this->
getRequest()->response()->header(
'Pragma: no-cache' );
373 $key = $oimage->getStorageKey();
374 $path = $repo->getZonePath(
'deleted' ) .
'/' . $repo->getDeletedHashPath( $key ) . $key;
375 $repo->streamFileWithStatus(
$path );
383 if ( is_null( $this->revDelList ) ) {
385 $this->typeName, $this->
getContext(), $this->targetObj, $this->ids
401 $out->wrapWikiMsg(
"<strong>$1</strong>", [ $this->typeLabels[
'selected'],
402 $this->
getLanguage()->formatNum( count( $this->ids ) ), $this->targetObj->getPrefixedText() ] );
405 $out->addHTML(
"<ul>" );
410 for ( $list->reset(); $list->current(); $list->next() ) {
411 $item = $list->current();
413 if ( !$item->canView() ) {
414 if ( !$this->submitClicked ) {
417 $userAllowed =
false;
421 $out->addHTML( $item->getHTML() );
424 if ( !$numRevisions ) {
425 throw new ErrorPageError(
'revdelete-nooldid-title',
'revdelete-nooldid-text' );
428 $out->addHTML(
"</ul>" );
433 if ( !$userAllowed ) {
438 if ( $this->mIsAllowed ) {
439 $out->addModules( [
'mediawiki.special.revisionDelete' ] );
440 $out->addModuleStyles( [
'mediawiki.special',
441 'mediawiki.interface.helpers.styles' ] );
444 'action' => $this->
getPageTitle()->getLocalURL( [
'action' =>
'submit' ] ),
445 'id' =>
'mw-revdel-form-revisions' ] ) .
450 '<td class="mw-label">' .
451 Xml::label( $this->
msg(
'revdelete-log' )->text(),
'wpRevDeleteReasonList' ) .
453 '<td class="mw-input">' .
455 $this->
msg(
'revdelete-reason-dropdown' )->inContentLanguage()->text(),
456 $this->
msg(
'revdelete-reasonotherlist' )->inContentLanguage()->text(),
457 $this->
getRequest()->getText(
'wpRevDeleteReasonList',
'other' ),
'wpReasonDropDown'
461 '<td class="mw-label">' .
462 Xml::label( $this->
msg(
'revdelete-otherreason' )->text(),
'wpReason' ) .
464 '<td class="mw-input">' .
465 Xml::input(
'wpReason', 60, $this->otherReason, [
476 '<td class="mw-submit">' .
478 [
'name' =>
'wpSubmit' ] ) .
482 Html::hidden(
'wpEditToken', $this->
getUser()->getEditToken() ) .
483 Html::hidden(
'target', $this->targetObj->getPrefixedText() ) .
484 Html::hidden(
'type', $this->typeName ) .
485 Html::hidden(
'ids', implode(
',', $this->ids ) ) .
489 if ( MediaWikiServices::getInstance()
491 ->userHasRight( $this->
getUser(),
'editinterface' )
494 $this->
msg(
'revdelete-reason-dropdown' )->inContentLanguage()->
getTitle(),
495 $this->
msg(
'revdelete-edit-reasonlist' )->text(),
497 [
'action' =>
'edit' ]
499 $form .=
Xml::tags(
'p', [
'class' =>
'mw-revdel-editreasons' ], $link ) .
"\n";
504 $out->addHTML( $form );
514 "<strong>$1</strong>\n$2", $this->typeLabels[
'text'],
515 'revdelete-text-others'
518 if ( MediaWikiServices::getInstance()
520 ->userHasRight( $this->
getUser(),
'suppressrevision' )
522 $this->
getOutput()->addWikiMsg(
'revdelete-suppress-text' );
525 if ( $this->mIsAllowed ) {
526 $this->
getOutput()->addWikiMsg(
'revdelete-confirm' );
537 if ( $list->length() == 1 ) {
539 $bitfield = $list->current()->getBits();
541 if ( $this->submitClicked ) {
545 foreach ( $this->checks as $item ) {
548 list( $message, $name, $field ) = $item;
550 $this->
msg( $message )->text(),
556 if ( $field == RevisionRecord::DELETED_RESTRICTED ) {
557 $innerHTML =
"<b>$innerHTML</b>";
561 $html .=
"<tr>$line</tr>\n";
566 $html .=
'<th class="mw-revdel-checkbox">'
567 . $this->
msg(
'revdelete-radio-same' )->escaped() .
'</th>';
568 $html .=
'<th class="mw-revdel-checkbox">'
569 . $this->
msg(
'revdelete-radio-unset' )->escaped() .
'</th>';
570 $html .=
'<th class="mw-revdel-checkbox">'
571 . $this->
msg(
'revdelete-radio-set' )->escaped() .
'</th>';
572 $html .=
"<th></th></tr>\n";
573 foreach ( $this->checks as $item ) {
576 list( $message, $name, $field ) = $item;
578 if ( $this->submitClicked ) {
579 $selected = $this->
getRequest()->getInt( $name, 0 );
583 $line =
'<td class="mw-revdel-checkbox">' .
Xml::radio( $name, -1, $selected == -1 ) .
'</td>';
584 $line .=
'<td class="mw-revdel-checkbox">' .
Xml::radio( $name, 0, $selected == 0 ) .
'</td>';
585 $line .=
'<td class="mw-revdel-checkbox">' .
Xml::radio( $name, 1, $selected == 1 ) .
'</td>';
586 $label = $this->
msg( $message )->escaped();
587 if ( $field == RevisionRecord::DELETED_RESTRICTED ) {
588 $label =
"<b>$label</b>";
590 $line .=
"<td>$label</td>";
591 $html .=
"<tr>$line</tr>\n";
606 # Check edit token on submission
608 if ( $this->submitClicked && !$this->
getUser()->matchEditToken(
$token ) ) {
609 $this->
getOutput()->addWikiMsg(
'sessionfailure' );
615 $listReason = $this->
getRequest()->getText(
'wpRevDeleteReasonList',
'other' );
616 $comment = $listReason;
617 if ( $comment ===
'other' ) {
619 } elseif ( $this->otherReason !==
'' ) {
621 $comment .= $this->
msg(
'colon-separator' )->inContentLanguage()->text()
624 # Can the user set this field?
625 if ( $bitParams[RevisionRecord::DELETED_RESTRICTED] == 1
626 && !MediaWikiServices::getInstance()
628 ->userHasRight( $this->
getUser(),
'suppressrevision' )
632 # If the save went through, go to success message...
639 # ...otherwise, bounce back to form...
651 $this->
getOutput()->setPageTitle( $this->
msg(
'actioncomplete' ) );
653 "<div class=\"successbox\">\n$1\n</div>",
654 $this->typeLabels[
'success']
656 $this->wasSaved =
true;
657 $this->revDelList->reloadFromMaster();
667 $this->
getOutput()->setPageTitle( $this->
msg(
'actionfailed' ) );
668 $this->
getOutput()->wrapWikiTextAsInterface(
670 $status->getWikiText( $this->typeLabels[
'failure'],
false, $this->getLanguage() )
682 foreach ( $this->checks as $item ) {
683 list( , $name, $field ) = $item;
684 $val = $this->
getRequest()->getInt( $name, 0 );
685 if ( $val < -1 || $val > 1 ) {
688 $bitfield[$field] = $val;
690 if ( !isset( $bitfield[RevisionRecord::DELETED_RESTRICTED] ) ) {
691 $bitfield[RevisionRecord::DELETED_RESTRICTED] = 0;
703 protected function save( array $bitPars, $reason ) {
704 return $this->
getList()->setVisibility(
705 [
'value' => $bitPars,
'comment' => $reason ]
getPageTitle( $subpage=false)
Get a self-referential title object.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Show an error when the user tries to do something whilst blocked.
getOutput()
Get the OutputPage being used for this instance.
bool $wasSaved
Was the DB modified in this request.
if(!isset( $args[0])) $lang
Shortcut to construct a special page which is unlisted by default.
static label( $label, $id, $attribs=[])
Convenience function to build an HTML form label.
array $typeLabels
UI Labels about the current type.
static radio( $name, $value, $checked=false, $attribs=[])
Convenience function to build an HTML radio button.
RevDelList $revDelList
RevDelList object, storing the list of items to be deleted/undeleted.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
Special page allowing users with the appropriate permissions to view and hide revisions.
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,...
getSkin()
Shortcut to get the skin being used for this instance.
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Show an error when a user tries to do something they do not have the necessary permissions for.
getLanguage()
Shortcut to get user's language.
static openElement( $element, $attribs=null)
This opens an XML element.
getList()
Get the list object for this request.
bool $submitClicked
True if the submit button was clicked, and the form was posted.
showConvenienceLinks()
Show some useful links in the subtitle.
save(array $bitPars, $reason)
Do the write operations.
static fieldset( $legend=false, $content=false, $attribs=[])
Shortcut for creating fieldsets.
getLogQueryCond()
Get the condition used for fetching log snippets.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
string $typeName
Deletion type, may be revision, archive, oldimage, filearchive, logging.
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
failure( $status)
Report that the submit operation failed.
Class to simplify the use of log pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
getUser()
Shortcut to get the User executing this instance.
string $archiveName
Archive name, for reviewing deleted files.
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
array $checks
Array of checkbox specs (message, name, deletion bits)
extractBitParams()
Put together an array that contains -1, 0, or the *_deleted const for each bit.
static createList( $typeName, IContextSource $context, Title $title, array $ids)
Instantiate the appropriate list class for a given list of IDs.
getContext()
Gets the context this SpecialPage is executed in.
Title $targetObj
Title object for target parameter.
showForm()
Show a list of items that we will operate on, and show a form with checkboxes which will allow the us...
doesWrites()
Indicates whether this special page may perform database writes.
static getRevdelConstant( $typeName)
Get the revision deletion constant for the RevDel type.
success()
Report that the submit operation succeeded.
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
tryShowFile( $archiveName)
Show a deleted file version requested by the visitor.
getRequest()
Get the WebRequest being used for this instance.
addUsageText()
Show some introductory text.
static $UILabels
UI labels for each type.
PermissionManager $permissionManager
Represents a title within MediaWiki.
static closeElement( $element)
Shortcut to close an XML element.
static listDropDown( $name='', $list='', $other='', $selected='', $class='', $tabindex=null)
Build a drop-down box from a textual list.
string $token
Edit token for securing image views against XSS.
array $ids
Target ID list.
static getRelationType( $typeName)
Get DB field name for URL param...
static getCanonicalTypeName( $typeName)
Gets the canonical type name, if any.
static input( $name, $size=false, $value=false, $attribs=[])
Convenience function to build an HTML text input field.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
MediaWiki Linker LinkRenderer null $linkRenderer
execute( $par)
Default execute method Checks user permissions.
static extractBitfield(array $bitPars, $oldfield)
Put together a rev_deleted bitfield.
An error page which can definitely be safely rendered using the OutputPage.
static suggestTarget( $typeName, $target, array $ids)
Suggest a target for the revision deletion.
submit()
UI entry point for form submission.
static getRestriction( $typeName)
Get the user right required for the RevDel type.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
bool $mIsAllowed
Whether user is allowed to perform the action.
__construct(PermissionManager $permissionManager)
static submitButton( $value, $attribs=[])
Convenience function to build an HTML submit button When $wgUseMediaWikiUIEverywhere is true it will ...
static checkLabel( $label, $name, $id, $checked=false, $attribs=[])
Convenience function to build an HTML checkbox with a label.