public static function incrementReverts(Page $article, $rev, $baseRevId = false, $user = null)
 {
     global $wgRequest;
     # Was this an edit by an auto-sighter that undid another edit?
     $undid = $wgRequest->getInt('undidRev');
     if ($rev && $undid && $user->isAllowed('autoreview')) {
         // Note: $rev->getTitle() might be undefined (no rev id?)
         $badRev = Revision::newFromTitle($article->getTitle(), $undid);
         if ($badRev && $badRev->getRawUser() && $badRev->getRawUser() != $rev->getRawUser()) {
             FRUserCounters::incCount($badRev->getRawUser(), 'revertedEdits');
         }
     }
     return true;
 }
 /**
  * Submit the form parameters for the page config to the DB.
  *
  * @return mixed (true on success, error string on failure)
  */
 public function doSubmit()
 {
     # Double-check permissions
     if (!$this->isAllowed()) {
         return 'review_denied';
     }
     # We can only approve actual revisions...
     if ($this->getAction() === 'approve') {
         $rev = Revision::newFromTitle($this->page, $this->oldid);
         # Check for archived/deleted revisions...
         if (!$rev || $rev->getVisibility()) {
             return 'review_bad_oldid';
         }
         # Check for review conflicts...
         if ($this->lastChangeTime !== null) {
             // API uses null
             $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : '';
             if ($lastChange !== $this->lastChangeTime) {
                 return 'review_conflict_oldid';
             }
         }
         $status = $this->approveRevision($rev, $this->oldFrev);
         # We can only unapprove approved revisions...
     } elseif ($this->getAction() === 'unapprove') {
         # Check for review conflicts...
         if ($this->lastChangeTime !== null) {
             // API uses null
             $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : '';
             if ($lastChange !== $this->lastChangeTime) {
                 return 'review_conflict_oldid';
             }
         }
         # Check if we can find this flagged rev...
         if (!$this->oldFrev) {
             return 'review_not_flagged';
         }
         $status = $this->unapproveRevision($this->oldFrev);
     } elseif ($this->getAction() === 'reject') {
         $newRev = Revision::newFromTitle($this->page, $this->oldid);
         $oldRev = Revision::newFromTitle($this->page, $this->refid);
         # Do not mess with archived/deleted revisions
         if (!$oldRev || $oldRev->isDeleted(Revision::DELETED_TEXT)) {
             return 'review_bad_oldid';
         } elseif (!$newRev || $newRev->isDeleted(Revision::DELETED_TEXT)) {
             return 'review_bad_oldid';
         }
         # Check that the revs are in order
         if ($oldRev->getTimestamp() > $newRev->getTimestamp()) {
             return 'review_cannot_undo';
         }
         # Make sure we are only rejecting pending changes
         $srev = FlaggedRevision::newFromStable($this->page, FR_MASTER);
         if ($srev && $oldRev->getTimestamp() < $srev->getRevTimestamp()) {
             return 'review_cannot_reject';
             // not really a use case
         }
         $article = new WikiPage($this->page);
         # Get text with changes after $oldRev up to and including $newRev removed
         $new_text = $article->getUndoText($newRev, $oldRev);
         if ($new_text === false) {
             return 'review_cannot_undo';
         }
         $baseRevId = $newRev->isCurrent() ? $oldRev->getId() : 0;
         # Actually make the edit...
         $editStatus = $article->doEdit($new_text, $this->getComment(), 0, $baseRevId, $this->user);
         $status = $editStatus->isOK() ? true : 'review_cannot_undo';
         if ($editStatus->isOK() && class_exists('EchoEvent') && $editStatus->value['revision']) {
             $affectedRevisions = array();
             // revid -> userid
             $revisions = wfGetDB(DB_SLAVE)->select('revision', array('rev_id', 'rev_user'), array('rev_id <= ' . $newRev->getId(), 'rev_timestamp <= ' . $newRev->getTimestamp(), 'rev_id > ' . $oldRev->getId(), 'rev_timestamp > ' . $oldRev->getTimestamp(), 'rev_page' => $article->getId()), __METHOD__);
             foreach ($revisions as $row) {
                 $affectedRevisions[$row->rev_id] = $row->rev_user;
             }
             EchoEvent::create(array('type' => 'reverted', 'title' => $this->page, 'extra' => array('revid' => $editStatus->value['revision']->getId(), 'reverted-users-ids' => array_values($affectedRevisions), 'reverted-revision-ids' => array_keys($affectedRevisions), 'method' => 'flaggedrevs-reject'), 'agent' => $this->user));
         }
         # If this undid one edit by another logged-in user, update user tallies
         if ($status === true && $newRev->getParentId() == $oldRev->getId() && $newRev->getRawUser()) {
             if ($newRev->getRawUser() != $this->user->getId()) {
                 // no self-reverts
                 FRUserCounters::incCount($newRev->getRawUser(), 'revertedEdits');
             }
         }
     }
     # Watch page if set to do so
     if ($status === true) {
         if ($this->user->getOption('flaggedrevswatch') && !$this->page->userIsWatching()) {
             $this->user->addWatch($this->page);
         }
     }
     return $status;
 }
 /**
  * Submit the form parameters for the page config to the DB.
  *
  * @return mixed (true on success, error string on failure)
  */
 public function doSubmit()
 {
     # Double-check permissions
     if (!$this->isAllowed()) {
         return 'review_denied';
     }
     # We can only approve actual revisions...
     if ($this->getAction() === 'approve') {
         $rev = Revision::newFromTitle($this->page, $this->oldid);
         # Check for archived/deleted revisions...
         if (!$rev || $rev->getVisibility()) {
             return 'review_bad_oldid';
         }
         # Check for review conflicts...
         if ($this->lastChangeTime !== null) {
             // API uses null
             $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : '';
             if ($lastChange !== $this->lastChangeTime) {
                 return 'review_conflict_oldid';
             }
         }
         $status = $this->approveRevision($rev, $this->oldFrev);
         # We can only unapprove approved revisions...
     } elseif ($this->getAction() === 'unapprove') {
         # Check for review conflicts...
         if ($this->lastChangeTime !== null) {
             // API uses null
             $lastChange = $this->oldFrev ? $this->oldFrev->getTimestamp() : '';
             if ($lastChange !== $this->lastChangeTime) {
                 return 'review_conflict_oldid';
             }
         }
         # Check if we can find this flagged rev...
         if (!$this->oldFrev) {
             return 'review_not_flagged';
         }
         $status = $this->unapproveRevision($this->oldFrev);
     } elseif ($this->getAction() === 'reject') {
         $newRev = Revision::newFromTitle($this->page, $this->oldid);
         $oldRev = Revision::newFromTitle($this->page, $this->refid);
         # Do not mess with archived/deleted revisions
         if (!$oldRev || $oldRev->isDeleted(Revision::DELETED_TEXT)) {
             return 'review_bad_oldid';
         } elseif (!$newRev || $newRev->isDeleted(Revision::DELETED_TEXT)) {
             return 'review_bad_oldid';
         }
         # Check that the revs are in order
         if ($oldRev->getTimestamp() > $newRev->getTimestamp()) {
             return 'review_cannot_undo';
         }
         # Make sure we are only rejecting pending changes
         $srev = FlaggedRevision::newFromStable($this->page, FR_MASTER);
         if ($srev && $oldRev->getTimestamp() < $srev->getRevTimestamp()) {
             return 'review_cannot_reject';
             // not really a use case
         }
         $article = new WikiPage($this->page);
         # Get text with changes after $oldRev up to and including $newRev removed
         $new_text = $article->getUndoText($newRev, $oldRev);
         if ($new_text === false) {
             return 'review_cannot_undo';
         }
         $baseRevId = $newRev->isCurrent() ? $oldRev->getId() : 0;
         # Actually make the edit...
         $editStatus = $article->doEdit($new_text, $this->getComment(), 0, $baseRevId, $this->user);
         $status = $editStatus->isOK() ? true : 'review_cannot_undo';
         # If this undid one edit by another logged-in user, update user tallies
         if ($status === true && $newRev->getParentId() == $oldRev->getId() && $newRev->getRawUser()) {
             if ($newRev->getRawUser() != $this->user->getId()) {
                 // no self-reverts
                 FRUserCounters::incCount($newRev->getRawUser(), 'revertedEdits');
             }
         }
     }
     # Watch page if set to do so
     if ($status === true) {
         if ($this->user->getOption('flaggedrevswatch') && !$this->page->userIsWatching()) {
             $this->user->addWatch($this->page);
         }
     }
     return $status;
 }