public function testPageDataFromTitle()
 {
     $title = Title::makeTitle(NS_MAIN, "somePage");
     $article = new FlaggableWikiPage($title);
     $user = $this->user;
     $article->doEdit("Some text to insert", "creating a page", EDIT_NEW, false, $user);
     $data = (array) $article->pageDataFromTitle(wfGetDB(DB_SLAVE), $title);
     $this->assertEquals(true, array_key_exists('fpc_override', $data), "data->fpc_override field exists");
     $this->assertEquals(true, array_key_exists('fp_stable', $data), "data->fp_stable field exists");
     $this->assertEquals(true, array_key_exists('fp_pending_since', $data), "data->fp_pending_since field exists");
     $this->assertEquals(true, array_key_exists('fp_reviewed', $data), "data->fp_reviewed field exists");
 }
 /**
  * This function does essentially the same as RevisionReview::AjaxReview,
  * except that it generates the template and image parameters itself.
  */
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     // Check basic permissions
     if (!$wgUser->isAllowed('review')) {
         $this->dieUsage("You don't have the right to review revisions.", 'permissiondenied');
     } elseif ($wgUser->isBlocked(false)) {
         $this->dieUsageMsg(array('blockedtext'));
     }
     $newRev = Revision::newFromId($params['oldid']);
     if (!$newRev || !$newRev->getTitle()) {
         $this->dieUsage("Cannot find a revision with the specified ID.", 'notarget');
     }
     $title = $newRev->getTitle();
     $fa = FlaggableWikiPage::getTitleInstance($title);
     if (!$fa->isReviewable()) {
         $this->dieUsage("Provided page is not reviewable.", 'notreviewable');
     }
     $status = false;
     if ($params['previd']) {
         // changes
         $oldRev = Revision::newFromId($params['previd']);
         if (!$oldRev || $oldRev->getPage() != $newRev->getPage()) {
             $this->dieUsage("Revisions do not belong to the same page.", 'notarget');
         }
         // Mark as reviewing...
         if ($params['reviewing']) {
             $status = FRUserActivity::setUserReviewingDiff($wgUser, $params['previd'], $params['oldid']);
             // Unmark as reviewing...
         } else {
             $status = FRUserActivity::clearUserReviewingDiff($wgUser, $params['previd'], $params['oldid']);
         }
     } else {
         // Mark as reviewing...
         if ($params['reviewing']) {
             $status = FRUserActivity::setUserReviewingPage($wgUser, $newRev->getPage());
             // Unmark as reviewing...
         } else {
             $status = FRUserActivity::clearUserReviewingPage($wgUser, $newRev->getPage());
         }
     }
     # Success in setting flag...
     if ($status === true) {
         $this->getResult()->addValue(null, $this->getModuleName(), array('result' => 'Success'));
         # Failure...
     } else {
         $this->getResult()->addValue(null, $this->getModuleName(), array('result' => 'Failure'));
     }
 }
 protected function list_reviewable_pages($fileHandle)
 {
     global $wgFlaggedRevsNamespaces, $wgUseSquid, $wgUseFileCache;
     $this->output("Building list of all reviewable pages to purge ...\n");
     if (!$wgUseSquid && !$wgUseFileCache) {
         $this->output("Squid/file cache not enabled ... nothing to purge.\n");
         return;
     } elseif (empty($wgFlaggedRevsNamespaces)) {
         $this->output("There are no reviewable namespaces ... nothing to purge.\n");
         return;
     }
     $db = wfGetDB(DB_MASTER);
     $start = $db->selectField('page', 'MIN(page_id)', false, __FUNCTION__);
     $end = $db->selectField('page', 'MAX(page_id)', false, __FUNCTION__);
     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;
     while ($blockEnd <= $end) {
         $this->output("... doing page_id from {$blockStart} to {$blockEnd}\n");
         $res = $db->select('page', '*', array("page_id BETWEEN {$blockStart} AND {$blockEnd}", 'page_namespace' => $wgFlaggedRevsNamespaces), __FUNCTION__);
         # Go through and append each purgeable page...
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             $fa = FlaggableWikiPage::getTitleInstance($title);
             if ($fa->isReviewable()) {
                 # Need to purge this page - add to list
                 fwrite($fileHandle, $title->getPrefixedDBKey() . "\n");
                 $count++;
             }
         }
         $db->freeResult($res);
         $blockStart += $this->mBatchSize - 1;
         $blockEnd += $this->mBatchSize - 1;
         wfWaitForSlaves(5);
         // not really needed
     }
     $this->output("List of reviewable pages to purge complete ... {$count} pages\n");
 }
Ejemplo n.º 4
0
 /**
  * This function does essentially the same as RevisionReview::AjaxReview,
  * except that it generates the template and image parameters itself.
  */
 public function execute()
 {
     global $wgUser;
     $params = $this->extractRequestParams();
     // Check basic permissions
     if (!$wgUser->isAllowed('review')) {
         $this->dieUsage("You don't have the right to review revisions.", 'permissiondenied');
     } elseif ($wgUser->isBlocked(false)) {
         $this->dieUsageMsg(array('blockedtext'));
     }
     // Get target rev and title
     $revid = (int) $params['revid'];
     $rev = Revision::newFromId($revid);
     if (!$rev) {
         $this->dieUsage("Cannot find a revision with the specified ID.", 'notarget');
     }
     $title = $rev->getTitle();
     // Construct submit form...
     $form = new RevisionReviewForm($wgUser);
     $form->setPage($title);
     $form->setOldId($revid);
     $form->setApprove(empty($params['unapprove']));
     $form->setUnapprove(!empty($params['unapprove']));
     if (isset($params['comment'])) {
         $form->setComment($params['comment']);
     }
     // The flagging parameters have the form 'flag_$name'.
     // Extract them and put the values into $form->dims
     foreach (FlaggedRevs::getTags() as $tag) {
         $form->setDim($tag, (int) $params['flag_' . $tag]);
     }
     if ($form->getAction() === 'approve') {
         $article = new FlaggableWikiPage($title);
         // Get the file version used for File: pages
         $file = $article->getFile();
         if ($file) {
             $fileVer = array('time' => $file->getTimestamp(), 'sha1' => $file->getSha1());
         } else {
             $fileVer = null;
         }
         // Now get the template and image parameters needed
         list($templateIds, $fileTimeKeys) = FRInclusionCache::getRevIncludes($article, $rev, $wgUser);
         // Get version parameters for review submission (flat strings)
         list($templateParams, $imageParams, $fileParam) = RevisionReviewForm::getIncludeParams($templateIds, $fileTimeKeys, $fileVer);
         // Set the version parameters...
         $form->setTemplateParams($templateParams);
         $form->setFileParams($imageParams);
         $form->setFileVersion($fileParam);
         $form->bypassValidationKey();
         // always OK; uses current templates/files
     }
     $status = $form->ready();
     // all params set
     # Try to do the actual review
     $status = $form->submit();
     # Approve/de-approve success
     if ($status === true) {
         $this->getResult()->addValue(null, $this->getModuleName(), array('result' => 'Success'));
         # Approve-specific failures
     } elseif ($form->getAction() === 'approve') {
         if ($status === 'review_denied') {
             $this->dieUsage("You don't have the necessary rights to set the specified flags.", 'permissiondenied');
         } elseif ($status === 'review_too_low') {
             $this->dieUsage("Either all or none of the flags have to be set to zero.", 'mixedapproval');
         } elseif ($status === 'review_bad_key') {
             $this->dieUsage("You don't have the necessary rights to set the specified flags.", 'permissiondenied');
         } elseif ($status === 'review_bad_tags') {
             $this->dieUsage("The specified flags are not valid.", 'invalidtags');
         } elseif ($status === 'review_bad_oldid') {
             $this->dieUsage("No revision with the specified ID.", 'notarget');
         } else {
             // FIXME: review_param_missing? better msg?
             $this->dieUsageMsg(array('unknownerror', ''));
         }
         # De-approve specific failure
     } elseif ($form->getAction() === 'unapprove') {
         if ($status === 'review_denied') {
             $this->dieUsage("You don't have the necessary rights to remove the flags.", 'permissiondenied');
         } elseif ($status === 'review_not_flagged') {
             $this->dieUsage("No flagged revision with the specified ID.", 'notarget');
         } else {
             // FIXME: review_param_missing? better msg?
             $this->dieUsageMsg(array('unknownerror', ''));
         }
         # Generic failures
     } else {
         if ($status === 'review_page_unreviewable') {
             $this->dieUsage("Provided page is not reviewable.", 'notreviewable');
         } elseif ($status === 'review_page_notexists') {
             $this->dieUsage("Provided page does not exist.", 'notarget');
         }
     }
 }
 /**
  * Add [checked version] and such to left and right side of diff
  */
 protected static function diffReviewMarkers(FlaggableWikiPage $article, $oldRev, $newRev)
 {
     $table = '';
     $srev = $article->getStableRev();
     # Diff between two revisions
     if ($oldRev && $newRev) {
         list($msg, $class) = self::getDiffRevMsgAndClass($oldRev, $srev);
         $table .= "<table class='fr-diff-ratings'><tr>";
         $table .= "<td width='50%' align='center'>";
         $table .= "<span class='{$class}'>[" . wfMsgHtml($msg) . "]</span>";
         list($msg, $class) = self::getDiffRevMsgAndClass($newRev, $srev);
         $table .= "</td><td width='50%' align='center'>";
         $table .= "<span class='{$class}'>[" . wfMsgHtml($msg) . "]</span>";
         $table .= "</td></tr></table>\n";
         # New page "diffs" - just one rev
     } elseif ($newRev) {
         list($msg, $class) = self::getDiffRevMsgAndClass($newRev, $srev);
         $table .= "<table class='fr-diff-ratings'>";
         $table .= "<tr><td align='center'><span class='{$class}'>";
         $table .= '[' . wfMsgHtml($msg) . ']';
         $table .= "</span></td></tr></table>\n";
     }
     return $table;
 }
 /**
  * Load any objects after ready() called
  * @return mixed (true on success, error string on failure)
  */
 protected function doBuildOnReady()
 {
     $this->article = FlaggableWikiPage::getTitleInstance($this->page);
     return true;
 }
 /**
  * Update the page tables with a new stable version.
  * @param WikiPage|Title $page
  * @param FlaggedRevision|null $sv, the new stable version (optional)
  * @param FlaggedRevision|null $oldSv, the old stable version (optional)
  * @param Object editInfo Article edit info about the current revision (optional)
  * @return bool stable version text/file changed and FR_INCLUDES_STABLE
  */
 public static function stableVersionUpdates($page, $sv = null, $oldSv = null, $editInfo = null)
 {
     if ($page instanceof FlaggableWikiPage) {
         $article = $page;
     } elseif ($page instanceof WikiPage) {
         $article = FlaggableWikiPage::getTitleInstance($page->getTitle());
     } elseif ($page instanceof Title) {
         $article = FlaggableWikiPage::getTitleInstance($page);
     } else {
         throw new MWException("First argument must be a Title or WikiPage.");
     }
     $title = $article->getTitle();
     $changed = false;
     if ($oldSv === null) {
         // optional
         $oldSv = FlaggedRevision::newFromStable($title, FR_MASTER);
     }
     if ($sv === null) {
         // optional
         $sv = FlaggedRevision::determineStable($title, FR_MASTER);
     }
     if (!$sv) {
         # Empty flaggedrevs data for this page if there is no stable version
         $article->clearStableVersion();
         # Check if pages using this need to be refreshed...
         if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE) {
             $changed = (bool) $oldSv;
         }
     } else {
         # Update flagged page related fields
         $article->updateStableVersion($sv, $editInfo ? $editInfo->revid : null);
         # Check if pages using this need to be invalidated/purged...
         if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE) {
             $changed = !$oldSv || $sv->getRevId() != $oldSv->getRevId() || $sv->getFileTimestamp() != $oldSv->getFileTimestamp() || $sv->getFileSha1() != $oldSv->getFileSha1();
         }
         # Update template/file version cache...
         if ($editInfo && $sv->getRevId() != $editInfo->revid) {
             FRInclusionCache::setRevIncludes($title, $editInfo->revid, $editInfo->output);
         }
     }
     # Lazily rebuild dependancies on next parse (we invalidate below)
     FlaggedRevs::clearStableOnlyDeps($title->getArticleID());
     # Clear page cache
     $title->invalidateCache();
     self::purgeSquid($title);
     return $changed;
 }
 /**
  * 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;
 }
 protected function updateLogsAndHistory(FlaggableWikiPage $article)
 {
     global $wgContLang;
     $newConfig = $this->getNewConfig();
     $oldConfig = $this->getOldConfig();
     $reason = $this->getReason();
     # Insert stability log entry...
     FlaggedRevsLog::updateStabilityLog($this->page, $newConfig, $oldConfig, $reason);
     # Build null-edit comment...<action: reason [settings] (expiry)>
     if (FRPageConfig::configIsReset($newConfig)) {
         $type = "stable-logentry-reset";
         $settings = '';
         // no level, expiry info
     } else {
         $type = "stable-logentry-config";
         // Settings message in text form (e.g. [x=a,y=b,z])
         $params = FlaggedRevsLog::stabilityLogParams($newConfig);
         $settings = FlaggedRevsLogView::stabilitySettings($params, true);
     }
     $comment = $wgContLang->ucfirst(wfMsgForContent($type, $this->page->getPrefixedText()));
     // action
     if ($reason != '') {
         $comment .= wfMsgForContent('colon-separator') . $reason;
         // add reason
     }
     if ($settings != '') {
         $comment .= " {$settings}";
         // add settings
     }
     # Insert a null revision...
     $dbw = wfGetDB(DB_MASTER);
     $nullRev = Revision::newNullRevision($dbw, $article->getId(), $comment, true);
     $nullRev->insertOn($dbw);
     # Update page record and touch page
     $oldLatest = $nullRev->getParentId();
     $article->updateRevisionOn($dbw, $nullRev, $oldLatest);
     wfRunHooks('NewRevisionFromEditComplete', array($article, $nullRev, $oldLatest, $this->user));
     # Return null Revision object for autoreview check
     return $nullRev;
 }
Ejemplo n.º 10
0
 protected function update_flaggedpages($start = null)
 {
     $this->output("Populating and correcting flaggedpages/flaggedpage_config columns\n");
     $BATCH_SIZE = 300;
     $db = wfGetDB(DB_MASTER);
     if ($start === null) {
         $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("...flaggedpages table seems to be empty.\n");
         return;
     }
     # Do remaining chunk
     $end += $BATCH_SIZE - 1;
     $blockStart = $start;
     $blockEnd = $start + $BATCH_SIZE - 1;
     $count = $deleted = $fixed = 0;
     while ($blockEnd <= $end) {
         $this->output("...doing page_id from {$blockStart} to {$blockEnd}\n");
         $cond = "page_id BETWEEN {$blockStart} AND {$blockEnd}";
         $res = $db->select('page', array('page_id', 'page_namespace', 'page_title', 'page_latest'), $cond, __METHOD__);
         # Go through and update the de-normalized references...
         $db->begin();
         foreach ($res as $row) {
             $title = Title::newFromRow($row);
             $article = new FlaggableWikiPage($title);
             $oldFrev = FlaggedRevision::newFromStable($title, FR_MASTER);
             $frev = FlaggedRevision::determineStable($title, FR_MASTER);
             # Update fp_stable, fp_quality, and fp_reviewed
             if ($frev) {
                 $article->updateStableVersion($frev, $row->page_latest);
                 $changed = !$oldFrev || $oldFrev->getRevId() != $frev->getRevId();
                 # Somethings broke? Delete the row...
             } else {
                 $article->clearStableVersion();
                 if ($db->affectedRows() > 0) {
                     $deleted++;
                 }
                 $changed = (bool) $oldFrev;
             }
             # Get the latest revision
             $revRow = $db->selectRow('revision', '*', array('rev_page' => $row->page_id), __METHOD__, array('ORDER BY' => 'rev_timestamp DESC'));
             # Correct page_latest if needed (import/files made plenty of bad rows)
             if ($revRow) {
                 $revision = new Revision($revRow);
                 if ($article->updateIfNewerOn($db, $revision)) {
                     $fixed++;
                 }
             }
             if ($changed) {
                 # Lazily rebuild dependancies on next parse (we invalidate below)
                 FlaggedRevs::clearStableOnlyDeps($title);
                 $title->invalidateCache();
             }
             $count++;
         }
         $db->freeResult($res);
         # Remove manual config settings that simply restate the site defaults
         $db->delete('flaggedpage_config', array("fpc_page_id BETWEEN {$blockStart} AND {$blockEnd}", 'fpc_override' => intval(FlaggedRevs::isStableShownByDefault()), 'fpc_level' => ''), __METHOD__);
         $deleted = $deleted + $db->affectedRows();
         $db->commit();
         $blockStart += $BATCH_SIZE;
         $blockEnd += $BATCH_SIZE;
         wfWaitForSlaves(5);
     }
     $this->output("flaggedpage columns update complete ..." . " {$count} rows [{$fixed} fixed] [{$deleted} deleted]\n");
 }
 public static function addToHistLine(HistoryPager $history, $row, &$s, &$liClasses)
 {
     $fa = FlaggableWikiPage::getTitleInstance($history->getTitle());
     if (!$fa->isReviewable()) {
         return true;
         // nothing to do here
     }
     # Fetch and process cache the stable revision
     if (!isset($history->fr_stableRevId)) {
         $srev = $fa->getStableRev();
         $history->fr_stableRevId = $srev ? $srev->getRevId() : null;
         $history->fr_stableRevUTS = $srev ? wfTimestamp(TS_UNIX, $srev->getRevTimestamp()) : null;
         $history->fr_pendingRevs = false;
     }
     if (!$history->fr_stableRevId) {
         return true;
         // nothing to do here
     }
     $title = $history->getTitle();
     $revId = (int) $row->rev_id;
     // Pending revision: highlight and add diff link
     $link = $class = '';
     if (wfTimestamp(TS_UNIX, $row->rev_timestamp) > $history->fr_stableRevUTS) {
         $class = 'flaggedrevs-pending';
         $link = wfMsgExt('revreview-hist-pending-difflink', 'parseinline', $title->getPrefixedText(), $history->fr_stableRevId, $revId);
         $link = '<span class="plainlinks mw-fr-hist-difflink">' . $link . '</span>';
         $history->fr_pendingRevs = true;
         // pending rev shown above stable
         // Reviewed revision: highlight and add link
     } elseif (isset($row->fr_quality)) {
         if (!($row->rev_deleted & Revision::DELETED_TEXT)) {
             # Add link to stable version of *this* rev, if any
             list($link, $class) = self::markHistoryRow($title, $row);
             # Space out and demark the stable revision
             if ($revId == $history->fr_stableRevId && $history->fr_pendingRevs) {
                 $liClasses[] = 'fr-hist-stable-margin';
             }
         }
     }
     # Style the row as needed
     if ($class) {
         $s = "<span class='{$class}'>{$s}</span>";
     }
     # Add stable old version link
     if ($link) {
         $s .= " {$link}";
     }
     return true;
 }
 /**
  * When an edit is made to a page:
  * (a) If the page is reviewable, silently mark the edit patrolled if it was auto-reviewed
  * (b) If the page can be patrolled, auto-patrol the edit patrolled as normal
  * (c) If the page is new and $wgUseNPPatrol is on, auto-patrol the edit patrolled as normal
  * (d) If the edit is neither reviewable nor patrolleable, silently mark it 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'];
         $quality = FlaggedRevision::getRevQuality($revId, FR_MASTER);
         // Reviewed => patrolled
         if ($quality !== false && $quality >= FR_CHECKED) {
             RevisionReviewForm::updateRecentChanges($rc, 'patrol', $fa->getStableRev());
             $rc->mAttribs['rc_patrolled'] = 1;
             // make sure irc/email notifs know status
         }
         return true;
     }
     return true;
 }