257 $updater = $this->wikiPageFactory->newFromTitle( $this->page )->newPageUpdater( $this->performer );
258 $currentRevision = $updater->grabParentRevision();
260 if ( !$currentRevision ) {
262 return StatusValue::newFatal(
'notanarticle' );
265 $currentEditor = $currentRevision->getUser( RevisionRecord::RAW );
266 $currentEditorForPublic = $currentRevision->getUser( RevisionRecord::FOR_PUBLIC );
268 if ( !$this->byUser->equals( $currentEditor ) ) {
269 $result = StatusValue::newGood( [
270 'current-revision-record' => $currentRevision
274 htmlspecialchars( $this->titleFormatter->getPrefixedText( $this->page ) ),
275 htmlspecialchars( $this->byUser->getName() ),
276 htmlspecialchars( $currentEditorForPublic ? $currentEditorForPublic->getName() :
'' )
281 $dbw = $this->loadBalancer->getConnectionRef(
DB_PRIMARY );
283 $revIndex = $dbw->indexExists(
'revision',
'page_timestamp', __METHOD__ )
285 :
'rev_page_timestamp';
290 $actorWhere = $this->actorMigration->getWhere( $dbw,
'rev_user', $currentEditor );
291 $targetRevisionRow = $dbw->selectRow(
292 [
'revision' ] + $actorWhere[
'tables'],
293 [
'rev_id',
'rev_timestamp',
'rev_deleted' ],
295 'rev_page' => $currentRevision->getPageId(),
296 'NOT(' . $actorWhere[
'conds'] .
')',
300 'USE INDEX' => [
'revision' => $revIndex ],
301 'ORDER BY' => [
'rev_timestamp DESC',
'rev_id DESC' ]
306 if ( $targetRevisionRow ===
false ) {
308 return StatusValue::newFatal(
'cantrollback' );
309 } elseif ( $targetRevisionRow->rev_deleted & RevisionRecord::DELETED_TEXT
310 || $targetRevisionRow->rev_deleted & RevisionRecord::DELETED_USER
313 return StatusValue::newFatal(
'notvisiblerev' );
317 $targetRevision = $this->revisionStore
318 ->getRevisionById( $targetRevisionRow->rev_id, RevisionStore::READ_LATEST );
323 if ( $this->performer->isAllowed(
'minoredit' ) ) {
332 $currentContent = $currentRevision->getContent( SlotRecord::MAIN );
333 $targetContent = $targetRevision->getContent( SlotRecord::MAIN );
334 $changingContentModel = $targetContent->getModel() !== $currentContent->getModel();
339 foreach ( $targetRevision->getSlots()->getSlots() as $slot ) {
340 $updater->inheritSlot( $slot );
345 foreach ( $currentRevision->getSlotRoles() as $role ) {
346 if ( !$targetRevision->hasSlot( $role ) ) {
347 $updater->removeSlot( $role );
351 $updater->setOriginalRevisionId( $targetRevision->getId() );
352 $oldestRevertedRevision = $this->revisionStore->getNextRevision(
354 RevisionStore::READ_LATEST
356 if ( $oldestRevertedRevision !==
null ) {
357 $updater->markAsRevert(
358 EditResult::REVERT_ROLLBACK,
359 $oldestRevertedRevision->getId(),
360 $currentRevision->getId()
367 if ( $this->options->get(
'UseRCPatrol' ) &&
368 $this->performer->authorizeWrite(
'autopatrol', $this->page )
370 $updater->setRcPatrolStatus( RecentChange::PRC_AUTOPATROLLED );
373 $summary = $this->getSummary( $currentRevision, $targetRevision );
376 $rev = $updater->saveRevision(
377 CommentStoreComment::newUnsavedComment( $summary ),
382 $this->updateRecentChange( $dbw, $currentRevision, $targetRevision );
384 if ( !$updater->wasSuccessful() ) {
385 return $updater->getStatus();
389 if ( $updater->isUnchanged() ) {
390 $result = StatusValue::newGood( [
391 'current-revision-record' => $currentRevision
395 htmlspecialchars( $this->titleFormatter->getPrefixedText( $this->page ) ),
396 htmlspecialchars( $this->byUser->getName() ),
397 htmlspecialchars( $currentEditorForPublic ? $currentEditorForPublic->getName() :
'' )
402 if ( $changingContentModel ) {
406 $log->setPerformer( $this->performer->getUser() );
407 $log->setTarget(
new TitleValue( $this->page->getNamespace(), $this->page->getDBkey() ) );
408 $log->setComment( $summary );
409 $log->setParameters( [
410 '4::oldmodel' => $currentContent->getModel(),
411 '5::newmodel' => $targetContent->getModel(),
414 $logId = $log->insert( $dbw );
415 $log->publish( $logId );
418 $wikiPage = $this->wikiPageFactory->newFromTitle( $this->page );
420 $this->hookRunner->onRollbackComplete(
422 $this->performer->getUser(),
427 return StatusValue::newGood( [
428 'summary' => $summary,
429 'current-revision-record' => $currentRevision,
430 'target-revision-record' => $targetRevision,
431 'newid' => $rev->getId(),
432 'tags' => array_merge( $this->tags, $updater->getEditResult()->getRevertTags() )
483 $currentEditorForPublic = $current->getUser(
RevisionRecord::FOR_PUBLIC );
484 if ( !$this->summary ) {
485 if ( !$currentEditorForPublic ) {
486 $summary = MessageValue::new(
'revertpage-nouser' );
487 } elseif ( $this->options->get(
'DisableAnonTalk' ) && !$currentEditorForPublic->isRegistered() ) {
488 $summary = MessageValue::new(
'revertpage-anon' );
490 $summary = MessageValue::new(
'revertpage' );
493 $summary = $this->summary;
496 $targetEditorForPublic = $target->
getUser( RevisionRecord::FOR_PUBLIC );
499 $targetEditorForPublic ? $targetEditorForPublic->getName() :
null,
500 $currentEditorForPublic ? $currentEditorForPublic->getName() :
null,
506 if ( $summary instanceof MessageValue ) {
507 $summary = (
new Converter() )->convertMessageValue( $summary );
508 $summary = $summary->params(
$args )->inContentLanguage()->text();
510 $summary = (
new RawMessage( $summary,
$args ) )->inContentLanguage()->plain();
514 return trim( $summary );