MediaWiki  master
McrUndoAction.php
Go to the documentation of this file.
1 <?php
15 
32 class McrUndoAction extends FormAction {
33 
34  protected $undo = 0, $undoafter = 0, $cur = 0;
35 
37  protected $curRev = null;
38 
40  private $readOnlyMode;
41 
43  private $revisionLookup;
44 
47 
49  private $useRCPatrol;
50 
59  public function __construct(
60  Page $page,
65  Config $config
66  ) {
67  parent::__construct( $page, $context );
68  $this->readOnlyMode = $readOnlyMode;
69  $this->revisionLookup = $revisionLookup;
70  $this->revisionRenderer = $revisionRenderer;
71  $this->useRCPatrol = $config->get( 'UseRCPatrol' );
72  }
73 
74  public function getName() {
75  return 'mcrundo';
76  }
77 
78  public function getDescription() {
79  return '';
80  }
81 
82  public function getRestriction() {
83  // Require 'edit' permission to even see this action (T297322)
84  return 'edit';
85  }
86 
87  public function show() {
88  // Send a cookie so anons get talk message notifications
89  // (copied from SubmitAction)
91 
92  // Some stuff copied from EditAction
94 
95  $out = $this->getOutput();
96  $out->setRobotPolicy( 'noindex,nofollow' );
97  if ( $this->getContext()->getConfig()->get( 'UseMediaWikiUIEverywhere' ) ) {
98  $out->addModuleStyles( [
99  'mediawiki.ui.input',
100  'mediawiki.ui.checkbox',
101  ] );
102  }
103 
104  // IP warning headers copied from EditPage
105  // (should more be copied?)
106  if ( $this->readOnlyMode->isReadOnly() ) {
107  $out->wrapWikiMsg(
108  "<div id=\"mw-read-only-warning\">\n$1\n</div>",
109  [ 'readonlywarning', $this->readOnlyMode->getReason() ]
110  );
111  } elseif ( $this->context->getUser()->isAnon() ) {
112  if ( !$this->getRequest()->getCheck( 'wpPreview' ) ) {
113  $out->wrapWikiMsg(
114  "<div id='mw-anon-edit-warning' class='warningbox'>\n$1\n</div>",
115  [ 'anoneditwarning',
116  // Log-in link
117  SpecialPage::getTitleFor( 'Userlogin' )->getFullURL( [
118  'returnto' => $this->getTitle()->getPrefixedDBkey()
119  ] ),
120  // Sign-up link
121  SpecialPage::getTitleFor( 'CreateAccount' )->getFullURL( [
122  'returnto' => $this->getTitle()->getPrefixedDBkey()
123  ] )
124  ]
125  );
126  } else {
127  $out->wrapWikiMsg( "<div id=\"mw-anon-preview-warning\" class=\"warningbox\">\n$1</div>",
128  'anonpreviewwarning'
129  );
130  }
131  }
132 
133  parent::show();
134  }
135 
136  protected function initFromParameters() {
137  $this->undoafter = $this->getRequest()->getInt( 'undoafter' );
138  $this->undo = $this->getRequest()->getInt( 'undo' );
139 
140  if ( $this->undo == 0 || $this->undoafter == 0 ) {
141  throw new ErrorPageError( 'mcrundofailed', 'mcrundo-missingparam' );
142  }
143 
144  $curRev = $this->getWikiPage()->getRevisionRecord();
145  if ( !$curRev ) {
146  throw new ErrorPageError( 'mcrundofailed', 'nopagetext' );
147  }
148  $this->curRev = $curRev;
149  $this->cur = $this->getRequest()->getInt( 'cur', $this->curRev->getId() );
150  }
151 
152  protected function checkCanExecute( User $user ) {
153  parent::checkCanExecute( $user );
154 
155  $this->initFromParameters();
156 
157  // We use getRevisionByTitle to verify the revisions belong to this page (T297322)
158  $title = $this->getTitle();
159  $undoRev = $this->revisionLookup->getRevisionByTitle( $title, $this->undo );
160  $oldRev = $this->revisionLookup->getRevisionByTitle( $title, $this->undoafter );
161 
162  if ( $undoRev === null || $oldRev === null ||
163  $undoRev->isDeleted( RevisionRecord::DELETED_TEXT ) ||
164  $oldRev->isDeleted( RevisionRecord::DELETED_TEXT )
165  ) {
166  throw new ErrorPageError( 'mcrundofailed', 'undo-norev' );
167  }
168 
169  return true;
170  }
171 
175  private function getNewRevision() {
176  $undoRev = $this->revisionLookup->getRevisionById( $this->undo );
177  $oldRev = $this->revisionLookup->getRevisionById( $this->undoafter );
179 
180  $isLatest = $curRev->getId() === $undoRev->getId();
181 
182  if ( $undoRev === null || $oldRev === null ||
183  $undoRev->isDeleted( RevisionRecord::DELETED_TEXT ) ||
184  $oldRev->isDeleted( RevisionRecord::DELETED_TEXT )
185  ) {
186  throw new ErrorPageError( 'mcrundofailed', 'undo-norev' );
187  }
188 
189  if ( $isLatest ) {
190  // Short cut! Undoing the current revision means we just restore the old.
191  return MutableRevisionRecord::newFromParentRevision( $oldRev );
192  }
193 
194  $newRev = MutableRevisionRecord::newFromParentRevision( $curRev );
195 
196  // Figure out the roles that need merging by first collecting all roles
197  // and then removing the ones that don't.
198  $rolesToMerge = array_unique( array_merge(
199  $oldRev->getSlotRoles(),
200  $undoRev->getSlotRoles(),
202  ) );
203 
204  // Any roles with the same content in $oldRev and $undoRev can be
205  // inherited because undo won't change them.
206  $rolesToMerge = array_intersect(
207  $rolesToMerge, $oldRev->getSlots()->getRolesWithDifferentContent( $undoRev->getSlots() )
208  );
209  if ( !$rolesToMerge ) {
210  throw new ErrorPageError( 'mcrundofailed', 'undo-nochange' );
211  }
212 
213  // Any roles with the same content in $oldRev and $curRev were already reverted
214  // and so can be inherited.
215  $rolesToMerge = array_intersect(
216  $rolesToMerge, $oldRev->getSlots()->getRolesWithDifferentContent( $curRev->getSlots() )
217  );
218  if ( !$rolesToMerge ) {
219  throw new ErrorPageError( 'mcrundofailed', 'undo-nochange' );
220  }
221 
222  // Any roles with the same content in $undoRev and $curRev weren't
223  // changed since and so can be reverted to $oldRev.
224  $diffRoles = array_intersect(
225  $rolesToMerge, $undoRev->getSlots()->getRolesWithDifferentContent( $curRev->getSlots() )
226  );
227  foreach ( array_diff( $rolesToMerge, $diffRoles ) as $role ) {
228  if ( $oldRev->hasSlot( $role ) ) {
229  $newRev->inheritSlot( $oldRev->getSlot( $role, RevisionRecord::RAW ) );
230  } else {
231  $newRev->removeSlot( $role );
232  }
233  }
234  $rolesToMerge = $diffRoles;
235 
236  // Any slot additions or removals not handled by the above checks can't be undone.
237  // There will be only one of the three revisions missing the slot:
238  // - !old means it was added in the undone revisions and modified after.
239  // Should it be removed entirely for the undo, or should the modified version be kept?
240  // - !undo means it was removed in the undone revisions and then readded with different content.
241  // Which content is should be kept, the old or the new?
242  // - !cur means it was changed in the undone revisions and then deleted after.
243  // Did someone delete vandalized content instead of undoing (meaning we should ideally restore
244  // it), or should it stay gone?
245  foreach ( $rolesToMerge as $role ) {
246  if ( !$oldRev->hasSlot( $role ) || !$undoRev->hasSlot( $role ) || !$curRev->hasSlot( $role ) ) {
247  throw new ErrorPageError( 'mcrundofailed', 'undo-failure' );
248  }
249  }
250 
251  // Try to merge anything that's left.
252  foreach ( $rolesToMerge as $role ) {
253  $oldContent = $oldRev->getSlot( $role, RevisionRecord::RAW )->getContent();
254  $undoContent = $undoRev->getSlot( $role, RevisionRecord::RAW )->getContent();
255  $curContent = $curRev->getSlot( $role, RevisionRecord::RAW )->getContent();
256  $newContent = $undoContent->getContentHandler()
257  ->getUndoContent( $curContent, $undoContent, $oldContent, $isLatest );
258  if ( !$newContent ) {
259  throw new ErrorPageError( 'mcrundofailed', 'undo-failure' );
260  }
261  $newRev->setSlot( SlotRecord::newUnsaved( $role, $newContent ) );
262  }
263 
264  return $newRev;
265  }
266 
267  private function generateDiffOrPreview() {
268  $newRev = $this->getNewRevision();
269  if ( $newRev->hasSameContent( $this->curRev ) ) {
270  throw new ErrorPageError( 'mcrundofailed', 'undo-nochange' );
271  }
272 
273  $diffEngine = new DifferenceEngine( $this->context );
274  $diffEngine->setRevisions( $this->curRev, $newRev );
275 
276  $oldtitle = $this->context->msg( 'currentrev' )->parse();
277  $newtitle = $this->context->msg( 'yourtext' )->parse();
278 
279  if ( $this->getRequest()->getCheck( 'wpPreview' ) ) {
280  $this->showPreview( $newRev );
281  return '';
282  } else {
283  $diffText = $diffEngine->getDiff( $oldtitle, $newtitle );
284  $diffEngine->showDiffStyle();
285  return '<div id="wikiDiff">' . $diffText . '</div>';
286  }
287  }
288 
289  private function showPreview( RevisionRecord $rev ) {
290  // Mostly copied from EditPage::getPreviewText()
291  $out = $this->getOutput();
292 
293  try {
294  $previewHTML = '';
295 
296  # provide a anchor link to the form
297  $continueEditing = '<span class="mw-continue-editing">' .
298  '[[#mw-mcrundo-form|' .
299  $this->context->getLanguage()->getArrow() . ' ' .
300  $this->context->msg( 'continue-editing' )->text() . ']]</span>';
301 
302  $note = $this->context->msg( 'previewnote' )->plain() . ' ' . $continueEditing;
303 
304  $parserOptions = $this->getWikiPage()->makeParserOptions( $this->context );
305  $parserOptions->setIsPreview( true );
306  $parserOptions->setIsSectionPreview( false );
307 
308  $parserOutput = $this->revisionRenderer
309  ->getRenderedRevision( $rev, $parserOptions, $this->context->getUser() )
310  ->getRevisionParserOutput();
311  $previewHTML = $parserOutput->getText( [
312  'enableSectionEditLinks' => false,
313  'includeDebugInfo' => true,
314  ] );
315 
316  $out->addParserOutputMetadata( $parserOutput );
317  if ( count( $parserOutput->getWarnings() ) ) {
318  $note .= "\n\n" . implode( "\n\n", $parserOutput->getWarnings() );
319  }
320  } catch ( MWContentSerializationException $ex ) {
321  $m = $this->context->msg(
322  'content-failed-to-parse',
323  $ex->getMessage()
324  );
325  $note .= "\n\n" . $m->parse();
326  $previewHTML = '';
327  }
328 
329  $previewhead = Html::rawElement(
330  'div', [ 'class' => 'previewnote' ],
332  'h2', [ 'id' => 'mw-previewheader' ],
333  $this->context->msg( 'preview' )->text()
334  ) .
335  Html::rawElement( 'div', [ 'class' => 'warningbox' ],
336  $out->parseAsInterface( $note )
337  )
338  );
339 
340  $pageViewLang = $this->getTitle()->getPageViewLanguage();
341  $attribs = [ 'lang' => $pageViewLang->getHtmlCode(), 'dir' => $pageViewLang->getDir(),
342  'class' => 'mw-content-' . $pageViewLang->getDir() ];
343  $previewHTML = Html::rawElement( 'div', $attribs, $previewHTML );
344 
345  $out->addHTML( $previewhead . $previewHTML );
346  }
347 
348  public function onSubmit( $data ) {
349  if ( !$this->getRequest()->getCheck( 'wpSave' ) ) {
350  // Diff or preview
351  return false;
352  }
353 
354  $updater = $this->getWikiPage()->newPageUpdater( $this->context->getUser() );
355  $curRev = $updater->grabParentRevision();
356  if ( !$curRev ) {
357  throw new ErrorPageError( 'mcrundofailed', 'nopagetext' );
358  }
359 
360  if ( $this->cur !== $curRev->getId() ) {
361  return Status::newFatal( 'mcrundo-changed' );
362  }
363 
364  $status = new PermissionStatus();
365  $this->getContext()->getAuthority()->authorizeWrite( 'edit', $this->getTitle(), $status );
366  if ( !$status->isOK() ) {
367  throw new PermissionsError( 'edit', $status );
368  }
369 
370  $newRev = $this->getNewRevision();
371  if ( !$newRev->hasSameContent( $curRev ) ) {
372  $hookRunner = Hooks::runner();
373  foreach ( $newRev->getSlotRoles() as $slotRole ) {
374  $slot = $newRev->getSlot( $slotRole, RevisionRecord::RAW );
375 
376  $status = new Status();
377  $hookResult = $hookRunner->onEditFilterMergedContent(
378  $this->getContext(),
379  $slot->getContent(),
380  $status,
381  trim( $this->getRequest()->getVal( 'wpSummary' ) ),
382  $this->getUser(),
383  false
384  );
385 
386  if ( !$hookResult ) {
387  if ( $status->isGood() ) {
388  $status->error( 'hookaborted' );
389  }
390 
391  return $status;
392  } elseif ( !$status->isOK() ) {
393  if ( !$status->getErrors() ) {
394  $status->error( 'hookaborted' );
395  }
396  return $status;
397  }
398  }
399 
400  // Copy new slots into the PageUpdater, and remove any removed slots.
401  // TODO: This interface is awful, there should be a way to just pass $newRev.
402  // TODO: MCR: test this once we can store multiple slots
403  foreach ( $newRev->getSlots()->getSlots() as $slot ) {
404  $updater->setSlot( $slot );
405  }
406  foreach ( $curRev->getSlotRoles() as $role ) {
407  if ( !$newRev->hasSlot( $role ) ) {
408  $updater->removeSlot( $role );
409  }
410  }
411 
412  $updater->markAsRevert( EditResult::REVERT_UNDO, $this->undo, $this->undoafter );
413 
414  if ( $this->useRCPatrol && $this->getContext()->getAuthority()
415  ->authorizeWrite( 'autopatrol', $this->getTitle() )
416  ) {
417  $updater->setRcPatrolStatus( RecentChange::PRC_AUTOPATROLLED );
418  }
419 
420  $updater->saveRevision(
421  CommentStoreComment::newUnsavedComment( trim( $this->getRequest()->getVal( 'wpSummary' ) ) ),
423  );
424 
425  return $updater->getStatus();
426  }
427 
428  return Status::newGood();
429  }
430 
431  protected function usesOOUI() {
432  return true;
433  }
434 
435  protected function getFormFields() {
436  $request = $this->getRequest();
437  $ret = [
438  'diff' => [
439  'type' => 'info',
440  'raw' => true,
441  'default' => function () {
442  return $this->generateDiffOrPreview();
443  }
444  ],
445  'summary' => [
446  'type' => 'text',
447  'id' => 'wpSummary',
448  'name' => 'wpSummary',
449  'cssclass' => 'mw-summary',
450  'label-message' => 'summary',
452  'value' => $request->getVal( 'wpSummary', '' ),
453  'size' => 60,
454  'spellcheck' => 'true',
455  ],
456  'summarypreview' => [
457  'type' => 'info',
458  'label-message' => 'summary-preview',
459  'raw' => true,
460  ],
461  ];
462 
463  if ( $request->getCheck( 'wpSummary' ) ) {
464  $ret['summarypreview']['default'] = Xml::tags( 'div', [ 'class' => 'mw-summary-preview' ],
465  Linker::commentBlock( trim( $request->getVal( 'wpSummary' ) ), $this->getTitle(), false )
466  );
467  } else {
468  unset( $ret['summarypreview'] );
469  }
470 
471  return $ret;
472  }
473 
474  protected function alterForm( HTMLForm $form ) {
475  $form->setWrapperLegendMsg( 'confirm-mcrundo-title' );
476 
477  $labelAsPublish = $this->context->getConfig()->get( 'EditSubmitButtonLabelPublish' );
478 
479  $form->setId( 'mw-mcrundo-form' );
480  $form->setSubmitName( 'wpSave' );
481  $form->setSubmitTooltip( $labelAsPublish ? 'publish' : 'save' );
482  $form->setSubmitTextMsg( $labelAsPublish ? 'publishchanges' : 'savechanges' );
483  $form->showCancel( true );
484  $form->setCancelTarget( $this->getTitle() );
485  $form->addButton( [
486  'name' => 'wpPreview',
487  'value' => '1',
488  'label-message' => 'showpreview',
489  'attribs' => Linker::tooltipAndAccesskeyAttribs( 'preview' ),
490  ] );
491  $form->addButton( [
492  'name' => 'wpDiff',
493  'value' => '1',
494  'label-message' => 'showdiff',
495  'attribs' => Linker::tooltipAndAccesskeyAttribs( 'diff' ),
496  ] );
497 
498  $this->addStatePropagationFields( $form );
499  }
500 
501  protected function addStatePropagationFields( HTMLForm $form ) {
502  $form->addHiddenField( 'undo', $this->undo );
503  $form->addHiddenField( 'undoafter', $this->undoafter );
504  $form->addHiddenField( 'cur', $this->curRev->getId() );
505  }
506 
507  public function onSuccess() {
508  $this->getOutput()->redirect( $this->getTitle()->getFullURL() );
509  }
510 
511  protected function preText() {
512  return '<div style="clear:both"></div>';
513  }
514 }
McrUndoAction\getRestriction
getRestriction()
Get the permission required to perform this action.
Definition: McrUndoAction.php:82
McrUndoAction\$undoafter
$undoafter
Definition: McrUndoAction.php:34
EDIT_AUTOSUMMARY
const EDIT_AUTOSUMMARY
Definition: Defines.php:131
CommentStoreComment\newUnsavedComment
static newUnsavedComment( $comment, array $data=null)
Create a new, unsaved CommentStoreComment.
Definition: CommentStoreComment.php:67
Page
Interface for type hinting (accepts WikiPage, Article, ImagePage, CategoryPage)
Definition: Page.php:29
McrUndoAction\$readOnlyMode
ReadOnlyMode $readOnlyMode
Definition: McrUndoAction.php:40
MediaWiki\Revision\RevisionRecord\getUser
getUser( $audience=self::FOR_PUBLIC, Authority $performer=null)
Fetch revision's author's user identity, if it's available to the specified audience.
Definition: RevisionRecord.php:389
McrUndoAction\generateDiffOrPreview
generateDiffOrPreview()
Definition: McrUndoAction.php:267
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
HTMLForm\setSubmitName
setSubmitName( $name)
Definition: HTMLForm.php:1599
Action\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: Action.php:146
HTMLForm\setSubmitTooltip
setSubmitTooltip( $name)
Definition: HTMLForm.php:1610
McrUndoAction\preText
preText()
Add pre- or post-text to the form.
Definition: McrUndoAction.php:511
ReadOnlyMode
A service class for fetching the wiki's current read-only mode.
Definition: ReadOnlyMode.php:11
McrUndoAction\show
show()
The basic pattern for actions is to display some sort of HTMLForm UI, maybe with some stuff underneat...
Definition: McrUndoAction.php:87
HTMLForm\showCancel
showCancel( $show=true)
Show a cancel button (or prevent it).
Definition: HTMLForm.php:1673
getAuthority
getAuthority()
HTMLForm\setCancelTarget
setCancelTarget( $target)
Sets the target where the user is redirected to after clicking cancel.
Definition: HTMLForm.php:1684
FormAction
An action which shows a form and does something based on the input from the form.
Definition: FormAction.php:30
McrUndoAction\alterForm
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
Definition: McrUndoAction.php:474
SpecialPage\getTitleFor
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,...
Definition: SpecialPage.php:131
McrUndoAction\getFormFields
getFormFields()
Get an HTMLForm descriptor array.
Definition: McrUndoAction.php:435
PermissionsError
Show an error when a user tries to do something they do not have the necessary permissions for.
Definition: PermissionsError.php:32
MediaWiki\Revision\RevisionRecord\hasSlot
hasSlot( $role)
Returns whether the given slot is defined in this revision.
Definition: RevisionRecord.php:197
McrUndoAction
Temporary action for MCR undos.
Definition: McrUndoAction.php:32
MediaWiki\Revision\RevisionLookup
Service for looking up page revisions.
Definition: RevisionLookup.php:38
Linker\tooltipAndAccesskeyAttribs
static tooltipAndAccesskeyAttribs( $name, array $msgParams=[], $options=null)
Returns the attributes for the tooltip and access key.
Definition: Linker.php:2222
Status
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
Action\getContext
getContext()
Get the IContextSource in use here.
Definition: Action.php:132
Config
Interface for configuration instances.
Definition: Config.php:30
McrUndoAction\getDescription
getDescription()
Returns the description that goes below the <h1> tag.
Definition: McrUndoAction.php:78
HTMLForm\addButton
addButton( $data)
Add a button to the form.
Definition: HTMLForm.php:1173
McrUndoAction\addStatePropagationFields
addStatePropagationFields(HTMLForm $form)
Definition: McrUndoAction.php:501
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
HTMLForm\addHiddenField
addHiddenField( $name, $value, array $attribs=[])
Add a hidden field to the output.
Definition: HTMLForm.php:1125
McrUndoAction\$cur
$cur
Definition: McrUndoAction.php:34
MWContentSerializationException
Exception representing a failure to serialize or unserialize a content object.
Definition: MWContentSerializationException.php:8
McrUndoAction\usesOOUI
usesOOUI()
Whether the form should use OOUI.
Definition: McrUndoAction.php:431
McrUndoAction\getNewRevision
getNewRevision()
Definition: McrUndoAction.php:175
$title
$title
Definition: testCompression.php:38
McrUndoAction\$curRev
RevisionRecord null $curRev
Definition: McrUndoAction.php:37
McrUndoAction\getName
getName()
Return the name of the action this object responds to.
Definition: McrUndoAction.php:74
Action\getWikiPage
getWikiPage()
Get a WikiPage object.
Definition: Action.php:195
MediaWiki\Storage\EditResult
Object for storing information about the effects of an edit.
Definition: EditResult.php:38
MediaWiki\Revision\RevisionRecord\getSlots
getSlots()
Returns the slots defined for this revision.
Definition: RevisionRecord.php:222
McrUndoAction\$useRCPatrol
bool $useRCPatrol
Definition: McrUndoAction.php:49
Action\getUser
getUser()
Shortcut to get the User being used for this instance.
Definition: Action.php:166
MediaWiki\Revision\RevisionRenderer
The RevisionRenderer service provides access to rendered output for revisions.
Definition: RevisionRenderer.php:45
MediaWiki\Session\SessionManager\getGlobalSession
static getGlobalSession()
If PHP's session_id() has been set, returns that session.
Definition: SessionManager.php:146
Action\$context
IContextSource $context
IContextSource if specified; otherwise we'll use the Context from the Page.
Definition: Action.php:66
Linker\commentBlock
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...
Definition: Linker.php:1549
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
HTMLForm\setId
setId( $id)
Definition: HTMLForm.php:1727
MediaWiki\Revision\MutableRevisionRecord
Definition: MutableRevisionRecord.php:44
Xml\tags
static tags( $element, $attribs, $contents)
Same as Xml::element(), but does not escape contents.
Definition: Xml.php:133
Hooks\runner
static runner()
Get a HookRunner instance for calling hooks using the new interfaces.
Definition: Hooks.php:173
Action\getTitle
getTitle()
Shortcut to get the Title object from the page.
Definition: Action.php:216
RecentChange\PRC_AUTOPATROLLED
const PRC_AUTOPATROLLED
Definition: RecentChange.php:94
IContextSource
Interface for objects which can provide a MediaWiki context on request.
Definition: IContextSource.php:58
MediaWiki\Permissions\PermissionStatus
A StatusValue for permission errors.
Definition: PermissionStatus.php:35
EDIT_UPDATE
const EDIT_UPDATE
Definition: Defines.php:126
CommentStore\COMMENT_CHARACTER_LIMIT
const COMMENT_CHARACTER_LIMIT
Maximum length of a comment in UTF-8 characters.
Definition: CommentStore.php:48
HTMLForm\setSubmitTextMsg
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1577
McrUndoAction\__construct
__construct(Page $page, IContextSource $context, ReadOnlyMode $readOnlyMode, RevisionLookup $revisionLookup, RevisionRenderer $revisionRenderer, Config $config)
Definition: McrUndoAction.php:59
MediaWiki\Revision\RevisionRecord\getSlotRoles
getSlotRoles()
Returns the slot names (roles) of all slots present in this revision.
Definition: RevisionRecord.php:207
MediaWiki\Revision\RevisionRecord\getId
getId( $wikiId=self::LOCAL)
Get revision ID.
Definition: RevisionRecord.php:279
McrUndoAction\$revisionLookup
RevisionLookup $revisionLookup
Definition: McrUndoAction.php:43
Action\$page
WikiPage Article ImagePage CategoryPage Page $page
Page on which we're performing the action.
Definition: Action.php:53
McrUndoAction\onSubmit
onSubmit( $data)
Process the form on POST submission.
Definition: McrUndoAction.php:348
HTMLForm\setWrapperLegendMsg
setWrapperLegendMsg( $msg)
Prompt the whole form to be wrapped in a "<fieldset>", with this message as its "<legend>" element.
Definition: HTMLForm.php:1782
McrUndoAction\checkCanExecute
checkCanExecute(User $user)
Checks if the given user (identified by an object) can perform this action.
Definition: McrUndoAction.php:152
McrUndoAction\initFromParameters
initFromParameters()
Definition: McrUndoAction.php:136
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:213
DifferenceEngine
DifferenceEngine is responsible for rendering the difference between two revisions as HTML.
Definition: DifferenceEngine.php:58
McrUndoAction\showPreview
showPreview(RevisionRecord $rev)
Definition: McrUndoAction.php:289
Action\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: Action.php:156
Action\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: Action.php:471
McrUndoAction\$undo
$undo
Definition: McrUndoAction.php:34
McrUndoAction\onSuccess
onSuccess()
Do something exciting on successful processing of the form.
Definition: McrUndoAction.php:507
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:235
McrUndoAction\$revisionRenderer
RevisionRenderer $revisionRenderer
Definition: McrUndoAction.php:46
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:30
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:67
MediaWiki\Revision\RevisionRecord\getSlot
getSlot( $role, $audience=self::FOR_PUBLIC, Authority $performer=null)
Returns meta-data for the given slot.
Definition: RevisionRecord.php:180
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:149