MediaWiki REL1_34
SpecialRevisionDelete.php
Go to the documentation of this file.
1<?php
27
36 protected $wasSaved = false;
37
40
42 private $ids;
43
45 private $archiveName;
46
48 private $token;
49
51 private $targetObj;
52
54 private $typeName;
55
57 private $checks;
58
60 private $typeLabels;
61
63 private $revDelList;
64
66 private $mIsAllowed;
67
69 private $otherReason;
70
73
77 private static $UILabels = [
78 'revision' => [
79 'check-label' => 'revdelete-hide-text',
80 'success' => 'revdelete-success',
81 'failure' => 'revdelete-failure',
82 'text' => 'revdelete-text-text',
83 'selected' => 'revdelete-selected-text',
84 ],
85 'archive' => [
86 'check-label' => 'revdelete-hide-text',
87 'success' => 'revdelete-success',
88 'failure' => 'revdelete-failure',
89 'text' => 'revdelete-text-text',
90 'selected' => 'revdelete-selected-text',
91 ],
92 'oldimage' => [
93 'check-label' => 'revdelete-hide-image',
94 'success' => 'revdelete-success',
95 'failure' => 'revdelete-failure',
96 'text' => 'revdelete-text-file',
97 'selected' => 'revdelete-selected-file',
98 ],
99 'filearchive' => [
100 'check-label' => 'revdelete-hide-image',
101 'success' => 'revdelete-success',
102 'failure' => 'revdelete-failure',
103 'text' => 'revdelete-text-file',
104 'selected' => 'revdelete-selected-file',
105 ],
106 'logging' => [
107 'check-label' => 'revdelete-hide-name',
108 'success' => 'logdelete-success',
109 'failure' => 'logdelete-failure',
110 'text' => 'logdelete-text',
111 'selected' => 'logdelete-selected',
112 ],
113 ];
114
121 parent::__construct( 'Revisiondelete', 'deleterevision' );
122
123 $this->permissionManager = $permissionManager;
124 }
125
126 public function doesWrites() {
127 return true;
128 }
129
130 public function execute( $par ) {
132
133 $this->checkPermissions();
134 $this->checkReadOnly();
135
136 $output = $this->getOutput();
137 $user = $this->getUser();
138
139 $this->setHeaders();
140 $this->outputHeader();
141 $request = $this->getRequest();
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 );
148 } else {
149 # Array input
150 $this->ids = array_keys( $request->getArray( 'ids', [] ) );
151 }
152 // $this->ids = array_map( 'intval', $this->ids );
153 $this->ids = array_unique( array_filter( $this->ids ) );
154
155 $this->typeName = $request->getVal( 'type' );
156 $this->targetObj = Title::newFromText( $request->getText( 'target' ) );
157
158 # For reviewing deleted files...
159 $this->archiveName = $request->getVal( 'file' );
160 $this->token = $request->getVal( 'token' );
161 if ( $this->archiveName && $this->targetObj ) {
162 $this->tryShowFile( $this->archiveName );
163
164 return;
165 }
166
167 $this->typeName = RevisionDeleter::getCanonicalTypeName( $this->typeName );
168
169 # No targets?
170 if ( !$this->typeName || count( $this->ids ) == 0 ) {
171 throw new ErrorPageError( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
172 }
173
174 # Allow the list type to adjust the passed target
175 $this->targetObj = RevisionDeleter::suggestTarget(
176 $this->typeName,
177 $this->targetObj,
178 $this->ids
179 );
180
181 # We need a target page!
182 if ( $this->targetObj === null ) {
183 $output->addWikiMsg( 'undelete-header' );
184
185 return;
186 }
187
188 // Check blocks
189 if ( $this->permissionManager->isBlockedFrom( $user, $this->targetObj ) ) {
190 throw new UserBlockedError( $user->getBlock() );
191 }
192
193 $this->typeLabels = self::$UILabels[$this->typeName];
194 $list = $this->getList();
195 $list->reset();
196 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
197 $this->mIsAllowed = $permissionManager->userHasRight( $user,
198 RevisionDeleter::getRestriction( $this->typeName ) );
199 $canViewSuppressedOnly = $permissionManager->userHasRight( $user, 'viewsuppressed' ) &&
200 !$permissionManager->userHasRight( $user, 'suppressrevision' );
201 $pageIsSuppressed = $list->areAnySuppressed();
202 $this->mIsAllowed = $this->mIsAllowed && !( $canViewSuppressedOnly && $pageIsSuppressed );
203
204 $this->otherReason = $request->getVal( 'wpReason' );
205 # Give a link to the logs/hist for this page
206 $this->showConvenienceLinks();
207
208 # Initialise checkboxes
209 $this->checks = [
210 # Messages: revdelete-hide-text, revdelete-hide-image, revdelete-hide-name
211 [ $this->typeLabels['check-label'], 'wpHidePrimary',
212 RevisionDeleter::getRevdelConstant( $this->typeName )
213 ],
214 [ 'revdelete-hide-comment', 'wpHideComment', RevisionRecord::DELETED_COMMENT ],
215 [ 'revdelete-hide-user', 'wpHideUser', RevisionRecord::DELETED_USER ]
216 ];
217 if ( $permissionManager->userHasRight( $user, 'suppressrevision' ) ) {
218 $this->checks[] = [ 'revdelete-hide-restricted',
219 'wpHideRestricted', RevisionRecord::DELETED_RESTRICTED ];
220 }
221
222 # Either submit or create our form
223 if ( $this->mIsAllowed && $this->submitClicked ) {
224 $this->submit();
225 } else {
226 $this->showForm();
227 }
228
229 if ( $permissionManager->userHasRight( $user, 'deletedhistory' ) ) {
230 $qc = $this->getLogQueryCond();
231 # Show relevant lines from the deletion log
232 $deleteLogPage = new LogPage( 'delete' );
233 $output->addHTML( "<h2>" . $deleteLogPage->getName()->escaped() . "</h2>\n" );
235 $output,
236 'delete',
237 $this->targetObj,
238 '', /* user */
239 [ 'lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved ]
240 );
241 }
242 # Show relevant lines from the suppression log
243 if ( $permissionManager->userHasRight( $user, 'suppressionlog' ) ) {
244 $suppressLogPage = new LogPage( 'suppress' );
245 $output->addHTML( "<h2>" . $suppressLogPage->getName()->escaped() . "</h2>\n" );
247 $output,
248 'suppress',
249 $this->targetObj,
250 '',
251 [ 'lim' => 25, 'conds' => $qc, 'useMaster' => $this->wasSaved ]
252 );
253 }
254 }
255
259 protected function showConvenienceLinks() {
261 # Give a link to the logs/hist for this page
262 if ( $this->targetObj ) {
263 // Also set header tabs to be for the target.
264 $this->getSkin()->setRelevantTitle( $this->targetObj );
265
266 $links = [];
267 $links[] = $linkRenderer->makeKnownLink(
269 $this->msg( 'viewpagelogs' )->text(),
270 [],
271 [ 'page' => $this->targetObj->getPrefixedText() ]
272 );
273 if ( !$this->targetObj->isSpecialPage() ) {
274 # Give a link to the page history
275 $links[] = $linkRenderer->makeKnownLink(
276 $this->targetObj,
277 $this->msg( 'pagehist' )->text(),
278 [],
279 [ 'action' => 'history' ]
280 );
281 # Link to deleted edits
282 if ( MediaWikiServices::getInstance()
284 ->userHasRight( $this->getUser(), 'undelete' )
285 ) {
286 $undelete = SpecialPage::getTitleFor( 'Undelete' );
287 $links[] = $linkRenderer->makeKnownLink(
288 $undelete,
289 $this->msg( 'deletedhist' )->text(),
290 [],
291 [ 'target' => $this->targetObj->getPrefixedDBkey() ]
292 );
293 }
294 }
295 # Logs themselves don't have histories or archived revisions
296 $this->getOutput()->addSubtitle( $this->getLanguage()->pipeList( $links ) );
297 }
298 }
299
304 protected function getLogQueryCond() {
305 $conds = [];
306 // Revision delete logs for these item
307 $conds['log_type'] = [ 'delete', 'suppress' ];
308 $conds['log_action'] = $this->getList()->getLogAction();
309 $conds['ls_field'] = RevisionDeleter::getRelationType( $this->typeName );
310 $conds['ls_value'] = $this->ids;
311
312 return $conds;
313 }
314
322 protected function tryShowFile( $archiveName ) {
323 $repo = RepoGroup::singleton()->getLocalRepo();
324 $oimage = $repo->newFromArchiveName( $this->targetObj, $archiveName );
325 $oimage->load();
326 // Check if user is allowed to see this file
327 if ( !$oimage->exists() ) {
328 $this->getOutput()->addWikiMsg( 'revdelete-no-file' );
329
330 return;
331 }
332 $user = $this->getUser();
333 if ( !$oimage->userCan( File::DELETED_FILE, $user ) ) {
334 if ( $oimage->isDeleted( File::DELETED_RESTRICTED ) ) {
335 throw new PermissionsError( 'suppressrevision' );
336 } else {
337 throw new PermissionsError( 'deletedtext' );
338 }
339 }
340 if ( !$user->matchEditToken( $this->token, $archiveName ) ) {
341 $lang = $this->getLanguage();
342 $this->getOutput()->addWikiMsg( 'revdelete-show-file-confirm',
343 $this->targetObj->getText(),
344 $lang->userDate( $oimage->getTimestamp(), $user ),
345 $lang->userTime( $oimage->getTimestamp(), $user ) );
346 $this->getOutput()->addHTML(
347 Xml::openElement( 'form', [
348 'method' => 'POST',
349 'action' => $this->getPageTitle()->getLocalURL( [
350 'target' => $this->targetObj->getPrefixedDBkey(),
351 'file' => $archiveName,
352 'token' => $user->getEditToken( $archiveName ),
353 ] )
354 ]
355 ) .
356 Xml::submitButton( $this->msg( 'revdelete-show-file-submit' )->text() ) .
357 '</form>'
358 );
359
360 return;
361 }
362 $this->getOutput()->disable();
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' );
368 $this->getRequest()->response()->header(
369 'Cache-Control: no-cache, no-store, max-age=0, must-revalidate'
370 );
371 $this->getRequest()->response()->header( 'Pragma: no-cache' );
372
373 $key = $oimage->getStorageKey();
374 $path = $repo->getZonePath( 'deleted' ) . '/' . $repo->getDeletedHashPath( $key ) . $key;
375 $repo->streamFileWithStatus( $path );
376 }
377
382 protected function getList() {
383 if ( is_null( $this->revDelList ) ) {
384 $this->revDelList = RevisionDeleter::createList(
385 $this->typeName, $this->getContext(), $this->targetObj, $this->ids
386 );
387 }
388
389 return $this->revDelList;
390 }
391
396 protected function showForm() {
397 $userAllowed = true;
398
399 // Messages: revdelete-selected-text, revdelete-selected-file, logdelete-selected
400 $out = $this->getOutput();
401 $out->wrapWikiMsg( "<strong>$1</strong>", [ $this->typeLabels['selected'],
402 $this->getLanguage()->formatNum( count( $this->ids ) ), $this->targetObj->getPrefixedText() ] );
403
404 $this->addHelpLink( 'Help:RevisionDelete' );
405 $out->addHTML( "<ul>" );
406
407 $numRevisions = 0;
408 // Live revisions...
409 $list = $this->getList();
410 for ( $list->reset(); $list->current(); $list->next() ) {
411 $item = $list->current();
412
413 if ( !$item->canView() ) {
414 if ( !$this->submitClicked ) {
415 throw new PermissionsError( 'suppressrevision' );
416 }
417 $userAllowed = false;
418 }
419
420 $numRevisions++;
421 $out->addHTML( $item->getHTML() );
422 }
423
424 if ( !$numRevisions ) {
425 throw new ErrorPageError( 'revdelete-nooldid-title', 'revdelete-nooldid-text' );
426 }
427
428 $out->addHTML( "</ul>" );
429 // Explanation text
430 $this->addUsageText();
431
432 // Normal sysops can always see what they did, but can't always change it
433 if ( !$userAllowed ) {
434 return;
435 }
436
437 // Show form if the user can submit
438 if ( $this->mIsAllowed ) {
439 $out->addModules( [ 'mediawiki.special.revisionDelete' ] );
440 $out->addModuleStyles( [ 'mediawiki.special',
441 'mediawiki.interface.helpers.styles' ] );
442
443 $form = Xml::openElement( 'form', [ 'method' => 'post',
444 'action' => $this->getPageTitle()->getLocalURL( [ 'action' => 'submit' ] ),
445 'id' => 'mw-revdel-form-revisions' ] ) .
446 Xml::fieldset( $this->msg( 'revdelete-legend' )->text() ) .
447 $this->buildCheckBoxes() .
448 Xml::openElement( 'table' ) .
449 "<tr>\n" .
450 '<td class="mw-label">' .
451 Xml::label( $this->msg( 'revdelete-log' )->text(), 'wpRevDeleteReasonList' ) .
452 '</td>' .
453 '<td class="mw-input">' .
454 Xml::listDropDown( 'wpRevDeleteReasonList',
455 $this->msg( 'revdelete-reason-dropdown' )->inContentLanguage()->text(),
456 $this->msg( 'revdelete-reasonotherlist' )->inContentLanguage()->text(),
457 $this->getRequest()->getText( 'wpRevDeleteReasonList', 'other' ), 'wpReasonDropDown'
458 ) .
459 '</td>' .
460 "</tr><tr>\n" .
461 '<td class="mw-label">' .
462 Xml::label( $this->msg( 'revdelete-otherreason' )->text(), 'wpReason' ) .
463 '</td>' .
464 '<td class="mw-input">' .
465 Xml::input( 'wpReason', 60, $this->otherReason, [
466 'id' => 'wpReason',
467 // HTML maxlength uses "UTF-16 code units", which means that characters outside BMP
468 // (e.g. emojis) count for two each. This limit is overridden in JS to instead count
469 // Unicode codepoints.
470 // "- 155" is to leave room for the 'wpRevDeleteReasonList' value.
471 'maxlength' => CommentStore::COMMENT_CHARACTER_LIMIT - 155,
472 ] ) .
473 '</td>' .
474 "</tr><tr>\n" .
475 '<td></td>' .
476 '<td class="mw-submit">' .
477 Xml::submitButton( $this->msg( 'revdelete-submit', $numRevisions )->text(),
478 [ 'name' => 'wpSubmit' ] ) .
479 '</td>' .
480 "</tr>\n" .
481 Xml::closeElement( 'table' ) .
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 ) ) .
486 Xml::closeElement( 'fieldset' ) . "\n" .
487 Xml::closeElement( 'form' ) . "\n";
488 // Show link to edit the dropdown reasons
489 if ( MediaWikiServices::getInstance()
491 ->userHasRight( $this->getUser(), 'editinterface' )
492 ) {
493 $link = $this->getLinkRenderer()->makeKnownLink(
494 $this->msg( 'revdelete-reason-dropdown' )->inContentLanguage()->getTitle(),
495 $this->msg( 'revdelete-edit-reasonlist' )->text(),
496 [],
497 [ 'action' => 'edit' ]
498 );
499 $form .= Xml::tags( 'p', [ 'class' => 'mw-revdel-editreasons' ], $link ) . "\n";
500 }
501 } else {
502 $form = '';
503 }
504 $out->addHTML( $form );
505 }
506
511 protected function addUsageText() {
512 // Messages: revdelete-text-text, revdelete-text-file, logdelete-text
513 $this->getOutput()->wrapWikiMsg(
514 "<strong>$1</strong>\n$2", $this->typeLabels['text'],
515 'revdelete-text-others'
516 );
517
518 if ( MediaWikiServices::getInstance()
520 ->userHasRight( $this->getUser(), 'suppressrevision' )
521 ) {
522 $this->getOutput()->addWikiMsg( 'revdelete-suppress-text' );
523 }
524
525 if ( $this->mIsAllowed ) {
526 $this->getOutput()->addWikiMsg( 'revdelete-confirm' );
527 }
528 }
529
533 protected function buildCheckBoxes() {
534 $html = '<table>';
535 // If there is just one item, use checkboxes
536 $list = $this->getList();
537 if ( $list->length() == 1 ) {
538 $list->reset();
539 $bitfield = $list->current()->getBits(); // existing field
540
541 if ( $this->submitClicked ) {
542 $bitfield = RevisionDeleter::extractBitfield( $this->extractBitParams(), $bitfield );
543 }
544
545 foreach ( $this->checks as $item ) {
546 // Messages: revdelete-hide-text, revdelete-hide-image, revdelete-hide-name,
547 // revdelete-hide-comment, revdelete-hide-user, revdelete-hide-restricted
548 list( $message, $name, $field ) = $item;
549 $innerHTML = Xml::checkLabel(
550 $this->msg( $message )->text(),
551 $name,
552 $name,
553 $bitfield & $field
554 );
555
556 if ( $field == RevisionRecord::DELETED_RESTRICTED ) {
557 $innerHTML = "<b>$innerHTML</b>";
558 }
559
560 $line = Xml::tags( 'td', [ 'class' => 'mw-input' ], $innerHTML );
561 $html .= "<tr>$line</tr>\n";
562 }
563 } else {
564 // Otherwise, use tri-state radios
565 $html .= '<tr>';
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 ) {
574 // Messages: revdelete-hide-text, revdelete-hide-image, revdelete-hide-name,
575 // revdelete-hide-comment, revdelete-hide-user, revdelete-hide-restricted
576 list( $message, $name, $field ) = $item;
577 // If there are several items, use third state by default...
578 if ( $this->submitClicked ) {
579 $selected = $this->getRequest()->getInt( $name, 0 /* unchecked */ );
580 } else {
581 $selected = -1; // use existing field
582 }
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>";
589 }
590 $line .= "<td>$label</td>";
591 $html .= "<tr>$line</tr>\n";
592 }
593 }
594
595 $html .= '</table>';
596
597 return $html;
598 }
599
605 protected function submit() {
606 # Check edit token on submission
607 $token = $this->getRequest()->getVal( 'wpEditToken' );
608 if ( $this->submitClicked && !$this->getUser()->matchEditToken( $token ) ) {
609 $this->getOutput()->addWikiMsg( 'sessionfailure' );
610
611 return false;
612 }
613 $bitParams = $this->extractBitParams();
614 // from dropdown
615 $listReason = $this->getRequest()->getText( 'wpRevDeleteReasonList', 'other' );
616 $comment = $listReason;
617 if ( $comment === 'other' ) {
618 $comment = $this->otherReason;
619 } elseif ( $this->otherReason !== '' ) {
620 // Entry from drop down menu + additional comment
621 $comment .= $this->msg( 'colon-separator' )->inContentLanguage()->text()
623 }
624 # Can the user set this field?
625 if ( $bitParams[RevisionRecord::DELETED_RESTRICTED] == 1
626 && !MediaWikiServices::getInstance()
628 ->userHasRight( $this->getUser(), 'suppressrevision' )
629 ) {
630 throw new PermissionsError( 'suppressrevision' );
631 }
632 # If the save went through, go to success message...
633 $status = $this->save( $bitParams, $comment );
634 if ( $status->isGood() ) {
635 $this->success();
636
637 return true;
638 } else {
639 # ...otherwise, bounce back to form...
640 $this->failure( $status );
641 }
642
643 return false;
644 }
645
649 protected function success() {
650 // Messages: revdelete-success, logdelete-success
651 $this->getOutput()->setPageTitle( $this->msg( 'actioncomplete' ) );
652 $this->getOutput()->wrapWikiMsg(
653 "<div class=\"successbox\">\n$1\n</div>",
654 $this->typeLabels['success']
655 );
656 $this->wasSaved = true;
657 $this->revDelList->reloadFromMaster();
658 $this->showForm();
659 }
660
665 protected function failure( $status ) {
666 // Messages: revdelete-failure, logdelete-failure
667 $this->getOutput()->setPageTitle( $this->msg( 'actionfailed' ) );
668 $this->getOutput()->wrapWikiTextAsInterface(
669 'errorbox',
670 $status->getWikiText( $this->typeLabels['failure'], false, $this->getLanguage() )
671 );
672 $this->showForm();
673 }
674
680 protected function extractBitParams() {
681 $bitfield = [];
682 foreach ( $this->checks as $item ) {
683 list( /* message */, $name, $field ) = $item;
684 $val = $this->getRequest()->getInt( $name, 0 /* unchecked */ );
685 if ( $val < -1 || $val > 1 ) {
686 $val = -1; // -1 for existing value
687 }
688 $bitfield[$field] = $val;
689 }
690 if ( !isset( $bitfield[RevisionRecord::DELETED_RESTRICTED] ) ) {
691 $bitfield[RevisionRecord::DELETED_RESTRICTED] = 0;
692 }
693
694 return $bitfield;
695 }
696
703 protected function save( array $bitPars, $reason ) {
704 return $this->getList()->setVisibility(
705 [ 'value' => $bitPars, 'comment' => $reason ]
706 );
707 }
708
709 protected function getGroupName() {
710 return 'pagetools';
711 }
712}
getPermissionManager()
$line
Definition cdb.php:59
An error page which can definitely be safely rendered using the OutputPage.
const DELETED_RESTRICTED
Definition File.php:66
const DELETED_FILE
Definition File.php:63
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Class to simplify the use of log pages.
Definition LogPage.php:33
MediaWikiServices is the service locator for the application scope of MediaWiki.
A service class for checking permissions To obtain an instance, use MediaWikiServices::getInstance()-...
userHasRight(UserIdentity $user, $action='')
Testing a permission.
Page revision base class.
Show an error when a user tries to do something they do not have the necessary permissions for.
static getCanonicalTypeName( $typeName)
Gets the canonical type name, if any.
static createList( $typeName, IContextSource $context, Title $title, array $ids)
Instantiate the appropriate list class for a given list of IDs.
static getRelationType( $typeName)
Get DB field name for URL param... Future code for other things may also track other types of revisio...
static suggestTarget( $typeName, $target, array $ids)
Suggest a target for the revision deletion.
static extractBitfield(array $bitPars, $oldfield)
Put together a rev_deleted bitfield.
static getRevdelConstant( $typeName)
Get the revision deletion constant for the RevDel type.
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...
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.
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.
MediaWiki Linker LinkRenderer null $linkRenderer
Special page allowing users with the appropriate permissions to view and hide revisions.
string $token
Edit token for securing image views against XSS.
bool $mIsAllowed
Whether user is allowed to perform the action.
showForm()
Show a list of items that we will operate on, and show a form with checkboxes which will allow the us...
tryShowFile( $archiveName)
Show a deleted file version requested by the visitor.
string $archiveName
Archive name, for reviewing deleted files.
save(array $bitPars, $reason)
Do the write operations.
success()
Report that the submit operation succeeded.
addUsageText()
Show some introductory text.
array $typeLabels
UI Labels about the current type.
bool $wasSaved
Was the DB modified in this request.
getLogQueryCond()
Get the condition used for fetching log snippets.
PermissionManager $permissionManager
RevDelList $revDelList
RevDelList object, storing the list of items to be deleted/undeleted.
showConvenienceLinks()
Show some useful links in the subtitle.
doesWrites()
Indicates whether this special page may perform database writes.
execute( $par)
Default execute method Checks user permissions.
array $checks
Array of checkbox specs (message, name, deletion bits)
failure( $status)
Report that the submit operation failed.
__construct(PermissionManager $permissionManager)
static $UILabels
UI labels for each type.
submit()
UI entry point for form submission.
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Title $targetObj
Title object for target parameter.
extractBitParams()
Put together an array that contains -1, 0, or the *_deleted const for each bit.
bool $submitClicked
True if the submit button was clicked, and the form was posted.
string $typeName
Deletion type, may be revision, archive, oldimage, filearchive, logging.
getList()
Get the list object for this request.
array $ids
Target ID list.
Represents a title within MediaWiki.
Definition Title.php:42
Shortcut to construct a special page which is unlisted by default.
Show an error when the user tries to do something whilst blocked.
if(!isset( $args[0])) $lang