コード例 #1
0
 protected function autoreview_current(User $user)
 {
     $this->output("Auto-reviewing all current page versions...\n");
     if (!$user->getID()) {
         $this->output("Invalid user specified.\n");
         return;
     } elseif (!$user->isAllowed('review')) {
         $this->output("User specified (id: {$user->getID()}) does not have \"review\" rights.\n");
         return;
     }
     $db = wfGetDB(DB_MASTER);
     $this->output("Reviewer username: "******"\n");
     $start = $db->selectField('page', 'MIN(page_id)', false, __METHOD__);
     $end = $db->selectField('page', 'MAX(page_id)', false, __METHOD__);
     if (is_null($start) || is_null($end)) {
         $this->output("...page table seems to be empty.\n");
         return;
     }
     # Do remaining chunk
     $end += $this->mBatchSize - 1;
     $blockStart = $start;
     $blockEnd = $start + $this->mBatchSize - 1;
     $count = 0;
     $changed = 0;
     $flags = FlaggedRevs::quickTags(FR_CHECKED);
     // Assume basic level
     while ($blockEnd <= $end) {
         $this->output("...doing page_id from {$blockStart} to {$blockEnd}\n");
         $res = $db->select(array('page', 'revision'), '*', array("page_id BETWEEN {$blockStart} AND {$blockEnd}", 'page_namespace' => FlaggedRevs::getReviewNamespaces(), 'rev_id = page_latest'), __METHOD__);
         # Go through and autoreview the current version of every page...
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             $rev = Revision::newFromRow($row);
             # Is it already reviewed?
             $frev = FlaggedRevision::newFromTitle($title, $row->page_latest, FR_MASTER);
             # Rev should exist, but to be safe...
             if (!$frev && $rev) {
                 $article = new Article($title);
                 $db->begin();
                 FlaggedRevs::autoReviewEdit($article, $user, $rev, $flags, true);
                 FlaggedRevs::HTMLCacheUpdates($article->getTitle());
                 $db->commit();
                 $changed++;
             }
             $count++;
         }
         $db->freeResult($res);
         $blockStart += $this->mBatchSize - 1;
         $blockEnd += $this->mBatchSize - 1;
         // XXX: Don't let deferred jobs array get absurdly large (bug 24375)
         DeferredUpdates::doUpdates('commit');
         wfWaitForSlaves(5);
     }
     $this->output("Auto-reviewing of all pages complete ..." . "{$count} rows [{$changed} changed]\n");
 }
コード例 #2
0
 /**
  * If this edit will be auto-reviewed on submit
  * Note: checking wpReviewEdit does not count as auto-reviewed
  * @param EditPage $editPage
  * @return bool
  */
 protected function editWillBeAutoreviewed(EditPage $editPage)
 {
     $title = $this->article->getTitle();
     // convenience
     if (!$this->article->isReviewable()) {
         return false;
     }
     if ($title->quickUserCan('autoreview')) {
         if (FlaggedRevs::autoReviewNewPages() && !$this->article->exists()) {
             return true;
             // edit will be autoreviewed
         }
         if (!isset($editPage->fr_baseFRev)) {
             $baseRevId = self::getBaseRevId($editPage, $this->getRequest());
             $editPage->fr_baseFRev = FlaggedRevision::newFromTitle($title, $baseRevId);
         }
         if ($editPage->fr_baseFRev) {
             return true;
             // edit will be autoreviewed
         }
     }
     return false;
     // edit won't be autoreviewed
 }
コード例 #3
0
 /**
  * Validate and clean up parameters (e.g. from POST request).
  * @return mixed (true on success, error string on failure)
  */
 protected function doCheckParameters()
 {
     $action = $this->getAction();
     if ($action === null) {
         return 'review_param_missing';
         // no action specified (approve, reject, de-approve)
     } elseif (!$this->oldid) {
         return 'review_no_oldid';
         // no revision target
     }
     # Get the revision's current flags (if any)
     $this->oldFrev = FlaggedRevision::newFromTitle($this->page, $this->oldid, FR_MASTER);
     $this->oldFlags = $this->oldFrev ? $this->oldFrev->getTags() : FlaggedRevision::expandRevisionTags('');
     // default
     # Set initial value for newLastChangeTime (if unchanged on submit)
     $this->newLastChangeTime = $this->lastChangeTime;
     # Fill in implicit tag data for binary flag case
     $iDims = $this->implicitDims();
     if ($iDims) {
         $this->dims = $iDims;
         // binary flag case
     }
     if ($action === 'approve') {
         # We must at least rate each category as 1, the minimum
         if (in_array(0, $this->dims, true)) {
             return 'review_too_low';
         }
         # Special token to discourage fiddling with templates/files...
         if (!$this->skipValidationKey) {
             $k = self::validationKey($this->templateParams, $this->imageParams, $this->fileVersion, $this->oldid, $this->sessionKey);
             if ($this->validatedParams !== $k) {
                 return 'review_bad_key';
             }
         }
         # Sanity check tags
         if (!FlaggedRevs::flagsAreValid($this->dims)) {
             return 'review_bad_tags';
         }
         # Check permissions with tags
         if (!FlaggedRevs::userCanSetFlags($this->user, $this->dims, $this->oldFlags)) {
             return 'review_denied';
         }
     } elseif ($action === 'unapprove') {
         # Check permissions with old tags
         if (!FlaggedRevs::userCanSetFlags($this->user, $this->oldFlags)) {
             return 'review_denied';
         }
     }
     return true;
 }
コード例 #4
0
 /**
  * Get the stable revision
  * @return mixed (FlaggedRevision/null)
  */
 public function getStableRev()
 {
     if (!FlaggedRevs::inReviewNamespace($this->mTitle)) {
         return null;
         // short-circuit
     }
     if (!$this->mDataLoaded) {
         $this->loadPageData();
     }
     # Stable rev deferred even after page data load
     if ($this->stableRev === null) {
         $srev = FlaggedRevision::newFromTitle($this->mTitle, $this->stable);
         $this->stableRev = $srev ? $srev : false;
         // cache negative hits too
     }
     return $this->stableRev ? $this->stableRev : null;
     // false => null
 }
コード例 #5
0
 /**
  * Get the HTML output of a revision based on $text.
  * @param Title $title
  * @param string $text
  * @param int $id Source revision Id
  * @param ParserOptions $pOpts
  * @return ParserOutput
  */
 public static function parseStableText(Title $title, $text, $id, ParserOptions $pOpts)
 {
     global $wgParser;
     # Notify Parser if includes should be stabilized
     $resetManager = false;
     $incManager = FRInclusionManager::singleton();
     if ($id && self::inclusionSetting() != FR_INCLUDES_CURRENT) {
         # Use FRInclusionManager to do the template/file version query
         # up front unless the versions are already specified there...
         if (!$incManager->parserOutputIsStabilized()) {
             $frev = FlaggedRevision::newFromTitle($title, $id);
             if ($frev) {
                 $incManager->stabilizeParserOutput($frev);
                 $resetManager = true;
                 // need to reset when done
             }
         }
     }
     # Parse the new body, wikitext -> html
     $parserOut = $wgParser->parse($text, $title, $pOpts, true, true, $id);
     # Stable parse done!
     if ($resetManager) {
         $incManager->clear();
         // reset the FRInclusionManager as needed
     }
     return $parserOut;
 }
コード例 #6
0
 /**
  * Generates a brief review form for a page
  * @return array (html string, error string or true)
  */
 public function getHtml()
 {
     global $wgLang;
     $revId = $this->rev->getId();
     if ($this->rev->isDeleted(Revision::DELETED_TEXT)) {
         return array('', 'review_bad_oldid');
         # The revision must be valid and public
     }
     $article = $this->article;
     // convenience
     $srev = $article->getStableRev();
     # See if the version being displayed is flagged...
     if ($revId == $article->getStable()) {
         $frev = $srev;
         // avoid query
     } else {
         $frev = FlaggedRevision::newFromTitle($article->getTitle(), $revId);
     }
     $oldFlags = $frev ? $frev->getTags() : FlaggedRevs::quickTags(FR_CHECKED);
     // basic tags
     $reviewTime = $frev ? $frev->getTimestamp() : '';
     // last review of rev
     $priorRevId = $this->refRev ? $this->refRev->getId() : 0;
     # If we are reviewing updates to a page, start off with the stable revision's
     # flags. Otherwise, we just fill them in with the selected revision's flags.
     # @TODO: do we want to carry over info for other diffs?
     if ($srev && $srev->getRevId() == $priorRevId) {
         // diff-to-stable
         $flags = $srev->getTags();
         # Check if user is allowed to renew the stable version.
         # If not, then get the flags for the new revision itself.
         if (!FlaggedRevs::userCanSetFlags($this->user, $oldFlags)) {
             $flags = $oldFlags;
         }
         # Re-review button is need for template/file only review case
         $reviewIncludes = $srev->getRevId() == $revId && !$article->stableVersionIsSynced();
     } else {
         // views
         $flags = $oldFlags;
         $reviewIncludes = false;
         // re-review button not needed
     }
     # Disable form for unprivileged users
     $disabled = array();
     if (!$article->getTitle()->quickUserCan('review') || !FlaggedRevs::userCanSetFlags($this->user, $flags)) {
         $disabled = array('disabled' => 'disabled');
     }
     # Begin form...
     $reviewTitle = SpecialPage::getTitleFor('RevisionReview');
     $action = $reviewTitle->getLocalUrl('action=submit');
     $params = array('method' => 'post', 'action' => $action, 'id' => 'mw-fr-reviewform');
     $form = Xml::openElement('form', $params) . "\n";
     $form .= Xml::openElement('fieldset', array('class' => 'flaggedrevs_reviewform noprint')) . "\n";
     # Add appropriate legend text
     $legendMsg = $frev ? 'revreview-reflag' : 'revreview-flag';
     $form .= Xml::openElement('legend', array('id' => 'mw-fr-reviewformlegend'));
     $form .= "<strong>" . wfMessage($legendMsg)->escaped() . "</strong>";
     $form .= Xml::closeElement('legend') . "\n";
     # Show explanatory text
     $form .= $this->topNotice;
     # Check if anyone is reviewing this already and
     # show a conflict warning message as needed...
     if ($priorRevId) {
         list($u, $ts) = FRUserActivity::getUserReviewingDiff($priorRevId, $this->rev->getId());
     } else {
         list($u, $ts) = FRUserActivity::getUserReviewingPage($this->rev->getPage());
     }
     $form .= Xml::openElement('p');
     // Page under review (and not by this user)...
     if ($u !== null && $u != $this->user->getName()) {
         $form .= '<span class="fr-under-review">';
         $msg = $priorRevId ? 'revreview-poss-conflict-c' : 'revreview-poss-conflict-p';
         $form .= wfMessage($msg, $u, $wgLang->date($ts, true), $wgLang->time($ts, true))->parse();
         $form .= "</span>";
         // Page not under review or under review by this user...
     } elseif (!$frev) {
         // rev not already reviewed
         $form .= '<span id="mw-fr-reviewing-status" style="display:none;"></span>';
         // JS widget
     }
     $form .= Xml::closeElement('p') . "\n";
     # Start rating controls
     $css = $disabled ? 'fr-rating-controls-disabled' : 'fr-rating-controls';
     $form .= Xml::openElement('p', array('class' => $css, 'id' => 'fr-rating-controls')) . "\n";
     # Add main checkboxes/selects
     $form .= Xml::openElement('span', array('id' => 'mw-fr-ratingselects', 'class' => 'fr-rating-options')) . "\n";
     $form .= self::ratingInputs($this->user, $flags, (bool) $disabled, (bool) $frev) . "\n";
     $form .= Xml::closeElement('span') . "\n";
     # Don't put buttons & comment field on the same line as tag inputs.
     if (!$disabled && !FlaggedRevs::binaryFlagging()) {
         // $disabled => no comment/buttons
         $form .= "<br />";
     }
     # Start comment & buttons
     $form .= Xml::openElement('span', array('id' => 'mw-fr-confirmreview')) . "\n";
     # Hide comment input if needed
     if (!$disabled) {
         $form .= Xml::inputLabel(wfMessage('revreview-log')->text(), 'wpReason', 'mw-fr-commentbox', 40, '', array('maxlength' => 255, 'class' => 'fr-comment-box'));
     }
     # Add the submit buttons...
     $rejectId = $this->rejectRefRevId();
     // determine if there will be reject button
     $form .= self::submitButtons($rejectId, $frev, (bool) $disabled, $reviewIncludes);
     # Show stability log if there is anything interesting...
     if ($article->isPageLocked()) {
         $form .= ' ' . FlaggedRevsXML::logToggle('revreview-log-toggle-show');
     }
     # End comment & buttons
     $form .= Xml::closeElement('span') . "\n";
     # ..add the actual stability log body here
     if ($article->isPageLocked()) {
         $form .= FlaggedRevsXML::stabilityLogExcerpt($article);
     }
     # End rating controls
     $form .= Xml::closeElement('p') . "\n";
     # Show explanatory text
     $form .= $this->bottomNotice;
     # Get the file version used for File: pages as needed
     $fileKey = $this->getFileVersion();
     # Get template/file version info as needed
     list($templateIDs, $imageSHA1Keys) = $this->getIncludeVersions();
     # Convert these into flat string params
     list($templateParams, $imageParams, $fileVersion) = RevisionReviewForm::getIncludeParams($templateIDs, $imageSHA1Keys, $fileKey);
     # Hidden params
     $form .= Html::hidden('title', $reviewTitle->getPrefixedText()) . "\n";
     $form .= Html::hidden('target', $article->getTitle()->getPrefixedDBKey()) . "\n";
     $form .= Html::hidden('refid', $priorRevId, array('id' => 'mw-fr-input-refid')) . "\n";
     $form .= Html::hidden('oldid', $revId, array('id' => 'mw-fr-input-oldid')) . "\n";
     $form .= Html::hidden('wpEditToken', $this->user->getEditToken()) . "\n";
     $form .= Html::hidden('changetime', $reviewTime, array('id' => 'mw-fr-input-changetime')) . "\n";
     // id for JS
     $form .= Html::hidden('userreviewing', (int) ($u === $this->user->getName()), array('id' => 'mw-fr-user-reviewing')) . "\n";
     // id for JS
     # Add review parameters
     $form .= Html::hidden('templateParams', $templateParams) . "\n";
     $form .= Html::hidden('imageParams', $imageParams) . "\n";
     $form .= Html::hidden('fileVersion', $fileVersion) . "\n";
     # Special token to discourage fiddling...
     $key = $this->request->getSessionData('wsFlaggedRevsKey');
     $checkCode = RevisionReviewForm::validationKey($templateParams, $imageParams, $fileVersion, $revId, $key);
     $form .= Html::hidden('validatedParams', $checkCode) . "\n";
     $form .= Xml::closeElement('fieldset') . "\n";
     $form .= Xml::closeElement('form') . "\n";
     return array($form, true);
 }
コード例 #7
0
 /**
  * Mark auto-reviewed edits as patrolled
  */
 public static function autoMarkPatrolled(RecentChange &$rc)
 {
     if (empty($rc->mAttribs['rc_this_oldid'])) {
         return true;
     }
     $fa = FlaggableWikiPage::getTitleInstance($rc->getTitle());
     $fa->loadPageData('fromdbmaster');
     // Is the page reviewable?
     if ($fa->isReviewable()) {
         $revId = $rc->mAttribs['rc_this_oldid'];
         // If the edit we just made was reviewed, then it's the stable rev
         $frev = FlaggedRevision::newFromTitle($rc->getTitle(), $revId, FR_MASTER);
         // Reviewed => patrolled
         if ($frev) {
             RevisionReviewForm::updateRecentChanges($rc, 'patrol', $frev);
             $rc->mAttribs['rc_patrolled'] = 1;
             // make sure irc/email notifs know status
         }
         return true;
     }
     return true;
 }
コード例 #8
0
 /**
  * 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 'stablize_denied';
     }
     # Parse and cleanup the expiry time given...
     $expiry = $this->getExpiry();
     if ($expiry === false) {
         return 'stabilize_expiry_invalid';
     } elseif ($expiry !== Block::infinity() && $expiry < wfTimestampNow()) {
         return 'stabilize_expiry_old';
     }
     # Update the DB row with the new config...
     $changed = FRPageConfig::setStabilitySettings($this->page, $this->getNewConfig());
     # Log if this actually changed anything...
     if ($changed) {
         $article = new FlaggableWikiPage($this->page);
         if (FlaggedRevs::useOnlyIfProtected()) {
             # Config may have changed to allow stable versions, so refresh
             # the tracking table to account for any hidden reviewed versions...
             $frev = FlaggedRevision::determineStable($this->page, FR_MASTER);
             if ($frev) {
                 $article->updateStableVersion($frev);
             } else {
                 $article->clearStableVersion();
             }
         }
         # Update logs and make a null edit
         $nullRev = $this->updateLogsAndHistory($article);
         # Null edit may have been auto-reviewed already
         $frev = FlaggedRevision::newFromTitle($this->page, $nullRev->getId(), FR_MASTER);
         $updatesDone = (bool) $frev;
         // stableVersionUpdates() already called?
         # Check if this null edit is to be reviewed...
         if ($this->reviewThis && !$frev) {
             $flags = null;
             # Review this revision of the page...
             $ok = FlaggedRevs::autoReviewEdit($article, $this->user, $nullRev, $flags, true);
             if ($ok) {
                 FlaggedRevs::markRevisionPatrolled($nullRev);
                 // reviewed -> patrolled
                 $updatesDone = true;
                 // stableVersionUpdates() already called
             }
         }
         # Update page and tracking tables and clear cache.
         if (!$updatesDone) {
             FlaggedRevs::stableVersionUpdates($this->page);
         }
     }
     # Apply watchlist checkbox value (may be NULL)
     $this->updateWatchlist();
     # Take this opportunity to purge out expired configurations
     FRPageConfig::purgeExpiredConfigurations();
     return true;
 }
コード例 #9
0
 /**
  * When an user makes a null-edit we sometimes want to review it...
  * (a) Null undo or rollback
  * (b) Null edit with review box checked
  * Note: called after edit ops are finished
  */
 public static function maybeNullEditReview(Page $article, $user, $text, $s, $m, $a, $b, $flags, $rev, &$status, $baseId)
 {
     global $wgRequest;
     # Revision must *be* null (null edit). We also need the user who made the edit.
     if (!$user || $rev !== null) {
         return true;
     }
     # Rollback/undo or box checked
     $reviewEdit = $wgRequest->getCheck('wpReviewEdit');
     if (!$baseId && !$reviewEdit) {
         return true;
         // short-circuit
     }
     $fa = FlaggableWikiPage::getTitleInstance($article->getTitle());
     $fa->loadPageData('fromdbmaster');
     if (!$fa->isReviewable()) {
         return true;
         // page is not reviewable
     }
     $title = $article->getTitle();
     // convenience
     # Get the current revision ID
     $rev = Revision::newFromTitle($title);
     if (!$rev) {
         return true;
         // wtf?
     }
     $flags = null;
     # Is this a rollback/undo that didn't change anything?
     if ($baseId > 0) {
         $frev = FlaggedRevision::newFromTitle($title, $baseId);
         // base rev of null edit
         $pRev = Revision::newFromId($rev->getParentId());
         // current rev parent
         $revIsNull = $pRev && $pRev->getTextId() == $rev->getTextId();
         # Was the edit that we tried to revert to reviewed?
         # We avoid auto-reviewing null edits to avoid confusion (bug 28476).
         if ($frev && !$revIsNull) {
             # Review this revision of the page...
             $ok = FlaggedRevs::autoReviewEdit($article, $user, $rev, $flags);
             if ($ok) {
                 FlaggedRevs::markRevisionPatrolled($rev);
                 // reviewed -> patrolled
                 FlaggedRevs::extraHTMLCacheUpdate($title);
                 return true;
             }
         }
     }
     # Get edit timestamp, it must exist.
     $editTimestamp = $wgRequest->getVal('wpEdittime');
     # Is the page checked off to be reviewed?
     if ($editTimestamp && $reviewEdit && $title->userCan('review')) {
         # Check wpEdittime against current revision's time.
         # If an edit was auto-merged in between, review only up to what
         # was the current rev when this user started editing the page.
         if ($rev->getTimestamp() != $editTimestamp) {
             $dbw = wfGetDB(DB_MASTER);
             $rev = Revision::loadFromTimestamp($dbw, $title, $editTimestamp);
             if (!$rev) {
                 return true;
                 // deleted?
             }
         }
         # Review this revision of the page...
         $ok = FlaggedRevs::autoReviewEdit($article, $user, $rev, $flags, false);
         if ($ok) {
             FlaggedRevs::markRevisionPatrolled($rev);
             // reviewed -> patrolled
             FlaggedRevs::extraHTMLCacheUpdate($title);
         }
     }
     return true;
 }