public function execute()
 {
     global $wgContLang;
     $pageSet = $this->getPageSet();
     $pageids = array_keys($pageSet->getGoodTitles());
     if (!$pageids) {
         return true;
     }
     // Construct SQL Query
     $this->addTables('flaggedpages');
     $this->addFields(array('fp_page_id', 'fp_stable', 'fp_quality', 'fp_pending_since'));
     $this->addWhereFld('fp_page_id', $pageids);
     $res = $this->select(__METHOD__);
     $result = $this->getResult();
     foreach ($res as $row) {
         $data = array('stable_revid' => intval($row->fp_stable), 'level' => intval($row->fp_quality), 'level_text' => FlaggedRevs::getQualityLevelText($row->fp_quality));
         if ($row->fp_pending_since) {
             $data['pending_since'] = wfTimestamp(TS_ISO_8601, $row->fp_pending_since);
         }
         $result->addValue(array('query', 'pages', $row->fp_page_id), 'flagged', $data);
     }
     $this->resetQueryParams();
     $this->addTables('flaggedpage_config');
     $this->addFields(array('fpc_page_id', 'fpc_level', 'fpc_expiry'));
     $this->addWhereFld('fpc_page_id', $pageids);
     foreach ($this->select(__METHOD__) as $row) {
         $result->addValue(array('query', 'pages', $row->fpc_page_id, 'flagged'), 'protection_level', $row->fpc_level);
         $result->addValue(array('query', 'pages', $row->fpc_page_id, 'flagged'), 'protection_expiry', $wgContLang->formatExpiry($row->fpc_expiry, TS_ISO_8601));
     }
     return true;
 }
 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");
 }
 public static function addApiRevisionData(&$module)
 {
     if (!$module instanceof ApiQueryRevisions) {
         return true;
     }
     $params = $module->extractRequestParams(false);
     if (empty($params['prop']) || !in_array('flagged', $params['prop'])) {
         return true;
     }
     if (!in_array('ids', $params['prop'])) {
         $module->dieUsage('if rvprop=flagged is set, you must also set rvprop=ids', 'missingparam');
     }
     // Get all requested pageids/revids in a mapping:
     // pageid => revid => array_index of the revision
     // we will need this later to add data to the result array
     $result = $module->getResult();
     $data = $result->getData();
     if (!isset($data['query']) || !isset($data['query']['pages'])) {
         return true;
     }
     foreach ($data['query']['pages'] as $pageid => $page) {
         if (array_key_exists('revisions', (array) $page)) {
             foreach ($page['revisions'] as $index => $rev) {
                 if (array_key_exists('revid', (array) $rev)) {
                     $pageids[$pageid][$rev['revid']] = $index;
                 }
             }
         }
     }
     if (empty($pageids)) {
         return true;
     }
     // Construct SQL Query
     $db = $module->getDB();
     $module->resetQueryParams();
     $module->addTables(array('flaggedrevs', 'user'));
     $module->addFields(array('fr_page_id', 'fr_rev_id', 'fr_timestamp', 'fr_quality', 'fr_tags', 'user_name'));
     $module->addWhere('fr_user=user_id');
     $where = array();
     // Construct WHERE-clause to avoid multiplying the number of scanned rows
     // as flaggedrevs table has composite primary key (fr_page_id,fr_rev_id)
     foreach ($pageids as $pageid => $revids) {
         $where[] = $db->makeList(array('fr_page_id' => $pageid, 'fr_rev_id' => array_keys($revids)), LIST_AND);
     }
     $module->addWhere($db->makeList($where, LIST_OR));
     //$module->addOption( 'USE INDEX', array( 'flaggedrevs' => 'page_rev' ) );
     $res = $module->select(__METHOD__);
     // Add flagging data to result array
     foreach ($res as $row) {
         $index = $pageids[$row->fr_page_id][$row->fr_rev_id];
         $data = array('user' => $row->user_name, 'timestamp' => wfTimestamp(TS_ISO_8601, $row->fr_timestamp), 'level' => intval($row->fr_quality), 'level_text' => FlaggedRevs::getQualityLevelText($row->fr_quality), 'tags' => FlaggedRevision::expandRevisionTags($row->fr_tags));
         $result->addValue(array('query', 'pages', $row->fr_page_id, 'revisions', $index), 'flagged', $data);
     }
     return true;
 }
 public function execute()
 {
     $this->getMain()->setCacheMode('public');
     $minQLTags = FlaggedRevs::quickTags(FR_QUALITY);
     $minPLTags = FlaggedRevs::quickTags(FR_PRISTINE);
     $data = array();
     foreach (FlaggedRevs::getDimensions() as $tag => $levels) {
         $data[] = array('name' => $tag, 'levels' => count($levels) - 1, 'tier1' => 1, 'tier2' => $minQLTags[$tag], 'tier3' => $minPLTags[$tag]);
     }
     $result = $this->getResult();
     $result->setIndexedTagName($data, 'tag');
     $result->addValue(null, $this->getModuleName(), $data);
 }
 protected function showStableList()
 {
     $out = $this->getOutput();
     # Must be a content page
     if (!FlaggedRevs::inReviewNamespace($this->page)) {
         $out->addWikiMsg('reviewedversions-none', $this->page->getPrefixedText());
         return;
     }
     $pager = new ReviewedVersionsPager($this, array(), $this->page);
     $num = $pager->getNumRows();
     if ($num) {
         $out->addWikiMsg('reviewedversions-list', $this->page->getPrefixedText(), $this->getLang()->formatNum($num));
         $out->addHTML($pager->getNavigationBar());
         $out->addHTML("<ul>" . $pager->getBody() . "</ul>");
         $out->addHTML($pager->getNavigationBar());
     } else {
         $out->addHTML(wfMsgExt('reviewedversions-none', array('parse'), $this->page->getPrefixedText()));
     }
 }
 /**
  * (a) Stabilize inclusions in Parser output
  * (b) Load all of the "review time" versions of template/files from $frev
  * (c) Load their stable version counterparts (avoids DB hits)
  * Note: Used when calling FlaggedRevs::parseStableText().
  * @param FlaggedRevision $frev
  * @return void
  */
 public function stabilizeParserOutput(FlaggedRevision $frev)
 {
     $tStbVersions = $fStbVersions = array();
     // stable versions
     $tRevVersions = $frev->getTemplateVersions();
     $fRevVersions = $frev->getFileVersions();
     # We can preload *most* of the stable version IDs the parser will need...
     if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE) {
         $tStbVersions = $frev->getStableTemplateVersions();
         $fStbVersions = $frev->getStableFileVersions();
     }
     $this->setReviewedVersions($tRevVersions, $fRevVersions);
     $this->setStableVersionCache($tStbVersions, $fStbVersions);
 }
Esempio n. 7
0
 public function getParamDescription()
 {
     $desc = array('revid' => 'The revision ID for which to set the flags', 'token' => 'An edit token retrieved through prop=info', 'comment' => 'Comment for the review (optional)', 'unapprove' => 'If set, revision will be unapproved rather than approved.');
     if (!FlaggedRevs::binaryFlagging()) {
         foreach (FlaggedRevs::getTags() as $flagname) {
             $desc['flag_' . $flagname] = "Set the flag ''{$flagname}'' to the specified value";
         }
     }
     return $desc;
 }
 /**
  * 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
 }
 /**
  * Generates review form submit buttons
  * @param int $rejectId left rev ID for "reject" on diffs
  * @param FlaggedRevision $frev, the flagged revision, if any
  * @param bool $disabled, is the form disabled?
  * @param bool $reviewIncludes, force the review button to be usable?
  * @return string
  */
 protected static function submitButtons($rejectId, $frev, $disabled, $reviewIncludes = false)
 {
     $disAttrib = array('disabled' => 'disabled');
     # ACCEPT BUTTON: accept a revision
     # We may want to re-review to change:
     # (a) notes (b) tags (c) pending template/file changes
     if (FlaggedRevs::binaryFlagging()) {
         // just the buttons
         $applicable = !$frev || $reviewIncludes;
         // no tags/notes
         $needsChange = false;
         // no state change possible
     } else {
         // buttons + ratings
         $applicable = true;
         // tags might change
         $needsChange = $frev && !$reviewIncludes;
     }
     $s = Xml::submitButton(wfMessage('revreview-submit-review')->escaped(), array('name' => 'wpApprove', 'id' => 'mw-fr-submit-accept', 'accesskey' => wfMessage('revreview-ak-review')->text(), 'title' => wfMessage('revreview-tt-flag')->text() . ' [' . wfMessage('revreview-ak-review')->text() . ']') + ($disabled || !$applicable ? $disAttrib : array()));
     # REJECT BUTTON: revert from a pending revision to the stable
     if ($rejectId) {
         $s .= ' ';
         $s .= Xml::submitButton(wfMessage('revreview-submit-reject')->escaped(), array('name' => 'wpReject', 'id' => 'mw-fr-submit-reject', 'title' => wfMessage('revreview-tt-reject')->text()) + ($disabled ? $disAttrib : array()));
     }
     # UNACCEPT BUTTON: revoke a revisions acceptance
     # Hide if revision is not flagged
     $s .= ' ';
     $s .= Xml::submitButton(wfMessage('revreview-submit-unreview')->escaped(), array('name' => 'wpUnapprove', 'id' => 'mw-fr-submit-unaccept', 'title' => wfMessage('revreview-tt-unflag')->text(), 'style' => $frev ? '' : 'display:none') + ($disabled ? $disAttrib : array())) . "\n";
     // Disable buttons unless state changes in some cases (non-JS compatible)
     $s .= '<script type="text/javascript">var jsReviewNeedsChange = ' . (int) $needsChange . "</script>\n";
     return $s;
 }
 /**
  * Updates the flaggedpage_pending table
  * @param int $pageId Page ID
  * @abstract int $latest Latest revision
  * @return void
  */
 protected static function updatePendingList($pageId, $latest)
 {
     $data = array();
     # Get the highest tier used on this wiki
     $level = FlaggedRevs::highestReviewTier();
     $dbw = wfGetDB(DB_MASTER);
     # Update pending times for each level, going from highest to lowest
     $higherLevelId = 0;
     $higherLevelTS = '';
     while ($level >= 0) {
         # Get the latest revision of this level...
         # Any revision of one tier is also a revision of lower tiers.
         # Instead of doing fr_quality > X queries we do exact comparisons
         # for better INDEX usage. However, in order to treat a rev as the
         # latest tier X rev, we make sure it is newer than all tier (X+1) revs.
         $row = $dbw->selectRow(array('flaggedrevs', 'revision'), array('fr_rev_id', 'rev_timestamp'), array('fr_page_id' => $pageId, 'fr_quality' => $level, 'fr_rev_timestamp > ' . $dbw->addQuotes($higherLevelTS), 'rev_id = fr_rev_id', 'rev_page = fr_page_id', 'rev_deleted & ' . Revision::DELETED_TEXT => 0), __METHOD__, array('ORDER BY' => 'fr_rev_timestamp DESC', 'LIMIT' => 1));
         # If there is a revision of this level, track it...
         # Revisions accepted to one tier count as accepted
         # at the lower tiers (i.e. quality -> checked).
         if ($row) {
             $id = $row->fr_rev_id;
             $ts = $row->rev_timestamp;
         } else {
             // use previous rev of higher tier (if any)
             $id = $higherLevelId;
             $ts = $higherLevelTS;
         }
         # Get edits that actually are pending...
         if ($id && $latest > $id) {
             # Get the timestamp of the edit after this version (if any)
             $nextTimestamp = $dbw->selectField('revision', 'rev_timestamp', array('rev_page' => $pageId, "rev_timestamp > " . $dbw->addQuotes($ts)), __METHOD__, array('ORDER BY' => 'rev_timestamp ASC', 'LIMIT' => 1));
             $data[] = array('fpp_page_id' => $pageId, 'fpp_quality' => $level, 'fpp_rev_id' => $id, 'fpp_pending_since' => $nextTimestamp);
             $higherLevelId = $id;
             $higherLevelTS = $ts;
         }
         $level--;
     }
     # Clear any old junk, and insert new rows
     $dbw->delete('flaggedpage_pending', array('fpp_page_id' => $pageId), __METHOD__);
     $dbw->insert('flaggedpage_pending', $data, __METHOD__);
 }
 /**
  * Automatically review an revision and add a log entry in the review log.
  *
  * This is called during edit operations after the new revision is added
  * and the page tables updated, but before LinksUpdate is called.
  *
  * $auto is here for revisions checked off to be reviewed. Auto-review
  * triggers on edit, but we don't want those to count as just automatic.
  * This also makes it so the user's name shows up in the page history.
  *
  * If $flags is given, then they will be the review tags. If not, the one
  * from the stable version will be used or minimal tags if that's not possible.
  * If no appropriate tags can be found, then the review will abort.
  */
 public static function autoReviewEdit(Page $article, $user, Revision $rev, array $flags = null, $auto = true)
 {
     wfProfileIn(__METHOD__);
     $title = $article->getTitle();
     // convenience
     # Get current stable version ID (for logging)
     $oldSv = FlaggedRevision::newFromStable($title, FR_MASTER);
     $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
     # Set the auto-review tags from the prior stable version.
     # Normally, this should already be done and given here...
     if (!is_array($flags)) {
         if ($oldSv) {
             # Use the last stable version if $flags not given
             if ($user->isAllowed('bot')) {
                 $flags = $oldSv->getTags();
                 // no change for bot edits
             } else {
                 # Account for perms/tags...
                 $flags = self::getAutoReviewTags($user, $oldSv->getTags());
             }
         } else {
             // new page?
             $flags = self::quickTags(FR_CHECKED);
             // use minimal level
         }
         if (!is_array($flags)) {
             wfProfileOut(__METHOD__);
             return false;
             // can't auto-review this revision
         }
     }
     # Get review property flags
     $propFlags = $auto ? array('auto') : array();
     # Rev ID is not put into parser on edit, so do the same here.
     # Also, a second parse would be triggered otherwise.
     $editInfo = $article->prepareTextForEdit($rev->getText());
     $poutput = $editInfo->output;
     // revision HTML output
     # If this is an image page, store corresponding file info
     $fileData = array('name' => null, 'timestamp' => null, 'sha1' => null);
     if ($title->getNamespace() == NS_FILE) {
         # We must use WikiFilePage process cache on upload or get bitten by slave lag
         $file = $article instanceof WikiFilePage || $article instanceof ImagePage ? $article->getFile() : wfFindFile($title, array('bypassCache' => true));
         // skip cache; bug 31056
         if (is_object($file) && $file->exists()) {
             $fileData['name'] = $title->getDBkey();
             $fileData['timestamp'] = $file->getTimestamp();
             $fileData['sha1'] = $file->getSha1();
         }
     }
     # Our review entry
     $flaggedRevision = new FlaggedRevision(array('rev' => $rev, 'user_id' => $user->getId(), 'timestamp' => $rev->getTimestamp(), 'quality' => FlaggedRevs::getQualityTier($flags, 0), 'tags' => FlaggedRevision::flattenRevisionTags($flags), 'img_name' => $fileData['name'], 'img_timestamp' => $fileData['timestamp'], 'img_sha1' => $fileData['sha1'], 'templateVersions' => $poutput->getTemplateIds(), 'fileVersions' => $poutput->getFileSearchOptions(), 'flags' => implode(',', $propFlags)));
     $flaggedRevision->insert();
     # Update the article review log
     FlaggedRevsLog::updateReviewLog($title, $flags, array(), '', $rev->getId(), $oldSvId, true, $auto);
     # Update page and tracking tables and clear cache
     FlaggedRevs::stableVersionUpdates($title);
     wfProfileOut(__METHOD__);
     return true;
 }
 function __construct($form, $namespace, $level = -1, $category = '', $size = null, $watched = false, $stable = false)
 {
     $this->mForm = $form;
     # Must be a content page...
     $vnamespaces = FlaggedRevs::getReviewNamespaces();
     if (is_null($namespace)) {
         $namespace = $vnamespaces;
     } else {
         $namespace = intval($namespace);
     }
     # Sanity check
     if (!in_array($namespace, $vnamespaces)) {
         $namespace = $vnamespaces;
     }
     $this->namespace = $namespace;
     # Sanity check level: 0 = checked; 1 = quality; 2 = pristine
     $this->level = $level >= 0 && $level <= 2 ? $level : -1;
     $this->category = $category ? str_replace(' ', '_', $category) : null;
     $this->size = $size !== null ? intval($size) : null;
     $this->watched = (bool) $watched;
     $this->stable = $stable && !FlaggedRevs::isStableShownByDefault() && !FlaggedRevs::useOnlyIfProtected();
     parent::__construct();
     # Don't get too expensive
     $this->mLimitsShown = array(20, 50, 100);
     $this->setLimit($this->mLimit);
     // apply max limit
 }
 /**
  * @param int $namespace (null for "all")
  * @param string $autoreview ('' for "all", 'none' for no restriction)
  */
 function __construct($form, $conds = array(), $namespace, $autoreview, $indef)
 {
     $this->mForm = $form;
     $this->mConds = $conds;
     $this->indef = $indef;
     // Must be content pages...
     $validNS = FlaggedRevs::getReviewNamespaces();
     if (is_integer($namespace)) {
         if (!in_array($namespace, $validNS)) {
             $namespace = $validNS;
             // fallback to "all"
         }
     } else {
         $namespace = $validNS;
         // "all"
     }
     $this->namespace = $namespace;
     if ($autoreview === 'none') {
         $autoreview = '';
         // 'none' => ''
     } elseif ($autoreview === '') {
         $autoreview = null;
         // '' => null
     }
     $this->autoreview = $autoreview;
     parent::__construct();
 }
 function __construct($form, $live, $namespace, $redirs = false, $category = null, $level = 0)
 {
     $this->mForm = $form;
     $this->live = (bool) $live;
     # Must be a content page...
     if (!is_null($namespace)) {
         $namespace = (int) $namespace;
     }
     $vnamespaces = FlaggedRevs::getReviewNamespaces();
     # Must be a single NS for perfomance reasons
     if (is_null($namespace) || !in_array($namespace, $vnamespaces)) {
         $namespace = !$vnamespaces ? -1 : $vnamespaces[0];
     }
     $this->namespace = $namespace;
     $this->category = $category ? str_replace(' ', '_', $category) : null;
     $this->level = intval($level);
     $this->showredirs = (bool) $redirs;
     parent::__construct();
     // Don't get too expensive
     $this->mLimitsShown = array(20, 50);
     $this->setLimit($this->mLimit);
     // apply max limit
 }
Esempio n. 15
0
 /**
  * Same as pendingEditNotice(), but returns a Message object.
  */
 public static function pendingEditNoticeMessage($flaggedArticle, $frev, $revsSince)
 {
     global $wgLang;
     $flags = $frev->getTags();
     $time = $wgLang->date($frev->getTimestamp(), true);
     # Add message text for pending edits
     $msg = FlaggedRevs::isQuality($flags) ? 'revreview-pending-quality' : 'revreview-pending-basic';
     return wfMessage($msg, $frev->getRevId(), $time)->numParams($revsSince);
 }
 function __construct($form, $level = -1, $category = '', $tag = '')
 {
     $this->mForm = $form;
     # Must be a content page...
     $this->namespace = FlaggedRevs::getReviewNamespaces();
     # Sanity check level: 0 = checked; 1 = quality; 2 = pristine
     $this->level = $level >= 0 && $level <= 2 ? $level : -1;
     $this->tag = $tag;
     $this->category = $category ? str_replace(' ', '_', $category) : null;
     parent::__construct();
     // Don't get to expensive
     $this->mLimitsShown = array(20, 50, 100);
     $this->setLimit($this->mLimit);
     // apply max limit
 }
 /**
  * Purge expired restrictions from the flaggedpage_config table.
  * The stable version of pages may change and invalidation may be required.
  */
 public static function purgeExpiredConfigurations()
 {
     if (wfReadOnly()) {
         return;
     }
     $dbw = wfGetDB(DB_MASTER);
     # Find pages with expired configs...
     $config = self::getDefaultVisibilitySettings();
     // config is to be reset
     $encCutoff = $dbw->addQuotes($dbw->timestamp());
     $ret = $dbw->select(array('flaggedpage_config', 'page'), array('fpc_page_id', 'page_namespace', 'page_title'), array('page_id = fpc_page_id', 'fpc_expiry < ' . $encCutoff), __METHOD__);
     # Figured out to do with each page...
     $pagesClearConfig = array();
     $pagesClearTracking = $titlesClearTracking = array();
     foreach ($ret as $row) {
         # If FlaggedRevs got "turned off" (in protection config)
         # for this page, then clear it from the tracking tables...
         if (FlaggedRevs::useOnlyIfProtected() && !$config['override']) {
             $pagesClearTracking[] = $row->fpc_page_id;
             // no stable version
             $titlesClearTracking[] = Title::newFromRow($row);
             // no stable version
         }
         $pagesClearConfig[] = $row->fpc_page_id;
         // page with expired config
     }
     # Clear the expired config for these pages...
     if (count($pagesClearConfig)) {
         $dbw->delete('flaggedpage_config', array('fpc_page_id' => $pagesClearConfig, 'fpc_expiry < ' . $encCutoff), __METHOD__);
     }
     # Clear the tracking rows and update page_touched for the
     # pages in $pagesClearConfig that do now have a stable version...
     if (count($pagesClearTracking)) {
         FlaggedRevs::clearTrackingRows($pagesClearTracking);
         $dbw->update('page', array('page_touched' => $dbw->timestamp()), array('page_id' => $pagesClearTracking), __METHOD__);
     }
     # Also, clear their squid caches and purge other pages that use this page.
     # NOTE: all of these updates are deferred via $wgDeferredUpdateList.
     foreach ($titlesClearTracking as $title) {
         FlaggedRevs::purgeSquid($title);
         if (FlaggedRevs::inclusionSetting() == FR_INCLUDES_STABLE) {
             FlaggedRevs::HTMLCacheUpdates($title);
             // purge pages that use this page
         }
     }
 }
 /**
  * @param FlaggedRevision $frev
  * Removes flagged revision data for this page/id set
  * @return bool
  */
 private function unapproveRevision(FlaggedRevision $frev)
 {
     wfProfileIn(__METHOD__);
     # Get current stable version ID (for logging)
     $oldSv = FlaggedRevision::newFromStable($this->page, FR_MASTER);
     # Delete from flaggedrevs table
     $frev->delete();
     # Update the article review log
     $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
     FlaggedRevsLog::updateReviewLog($this->page, $this->dims, $this->oldFlags, $this->comment, $this->oldid, $oldSvId, false);
     # Get the new stable version as of now
     $sv = FlaggedRevision::determineStable($this->page, FR_MASTER);
     # Update recent changes
     self::updateRecentChanges($frev->getRevision(), 'unpatrol', $sv);
     # Update page and tracking tables and clear cache
     $changed = FlaggedRevs::stableVersionUpdates($this->page, $sv, $oldSv);
     if ($changed) {
         FlaggedRevs::HTMLCacheUpdates($this->page);
         // purge pages that use this page
     }
     # Caller may want to get the change time
     $this->newLastChangeTime = '';
     wfProfileOut(__METHOD__);
     return true;
 }
 public static function AjaxReview()
 {
     global $wgUser, $wgOut, $wgRequest;
     $args = func_get_args();
     if (wfReadOnly()) {
         return '<err#>' . wfMsgExt('revreview-failed', 'parseinline') . wfMsgExt('revreview-submission-invalid', 'parseinline');
     }
     $tags = FlaggedRevs::getTags();
     // Make review interface object
     $form = new RevisionReviewForm($wgUser);
     $title = null;
     // target page
     $editToken = '';
     // edit token
     // Each ajax url argument is of the form param|val.
     // This means that there is no ugly order dependance.
     foreach ($args as $arg) {
         $set = explode('|', $arg, 2);
         if (count($set) != 2) {
             return '<err#>' . wfMsgExt('revreview-failed', 'parseinline') . wfMsgExt('revreview-submission-invalid', 'parseinline');
         }
         list($par, $val) = $set;
         switch ($par) {
             case "target":
                 $title = Title::newFromURL($val);
                 break;
             case "oldid":
                 $form->setOldId($val);
                 break;
             case "refid":
                 $form->setRefId($val);
                 break;
             case "validatedParams":
                 $form->setValidatedParams($val);
                 break;
             case "templateParams":
                 $form->setTemplateParams($val);
                 break;
             case "imageParams":
                 $form->setFileParams($val);
                 break;
             case "fileVersion":
                 $form->setFileVersion($val);
                 break;
             case "wpApprove":
                 $form->setApprove($val);
                 break;
             case "wpUnapprove":
                 $form->setUnapprove($val);
                 break;
             case "wpReject":
                 $form->setReject($val);
                 break;
             case "wpReason":
                 $form->setComment($val);
                 break;
             case "changetime":
                 $form->setLastChangeTime($val);
                 break;
             case "wpEditToken":
                 $editToken = $val;
                 break;
             default:
                 $p = preg_replace('/^wp/', '', $par);
                 // kill any "wp" prefix
                 if (in_array($p, $tags)) {
                     $form->setDim($p, $val);
                 }
                 break;
         }
     }
     # Valid target title?
     if (!$title) {
         return '<err#>' . wfMsgExt('notargettext', 'parseinline');
     }
     $form->setPage($title);
     $form->setSessionKey($wgRequest->getSessionData('wsFlaggedRevsKey'));
     $status = $form->ready();
     // all params loaded
     # Check session via user token
     if (!$wgUser->matchEditToken($editToken)) {
         return '<err#>' . wfMsgExt('sessionfailure', 'parseinline');
     }
     # Basic permission checks...
     $permErrors = $title->getUserPermissionsErrors('review', $wgUser, false);
     if (!$permErrors) {
         $permErrors = $title->getUserPermissionsErrors('edit', $wgUser, false);
     }
     if ($permErrors) {
         return '<err#>' . $wgOut->parse($wgOut->formatPermissionsErrorMessage($permErrors, 'review'));
     }
     # Try submission...
     $status = $form->submit();
     # Success...
     if ($status === true) {
         # Sent new lastChangeTime TS to client for later submissions...
         $changeTime = $form->getNewLastChangeTime();
         if ($form->getAction() === 'approve') {
             // approve
             return "<suc#><lct#{$changeTime}>";
         } elseif ($form->getAction() === 'unapprove') {
             // de-approve
             return "<suc#><lct#{$changeTime}>";
         } elseif ($form->getAction() === 'reject') {
             // revert
             return "<suc#><lct#{$changeTime}>";
         }
         # Failure...
     } else {
         return '<err#>' . wfMsgExt('revreview-failed', 'parse') . '<p>' . wfMsgHtml($status) . '</p>';
     }
 }
 /**
  * Create revision, diff, and history links for log line entry
  */
 public static function reviewLogLinks($action, $title, $params)
 {
     global $wgLang;
     $links = '';
     # Show link to page with oldid=x as well as the diff to the former stable rev.
     # Param format is <rev id, last stable id, rev timestamp>.
     if (isset($params[0])) {
         $revId = (int) $params[0];
         // the revision reviewed
         $oldStable = isset($params[1]) ? (int) $params[1] : 0;
         # Show diff to changes since the prior stable version
         if ($oldStable && $revId > $oldStable) {
             $msg = FlaggedRevsLog::isReviewDeapproval($action) ? 'review-logentry-diff2' : 'review-logentry-diff';
             // reviewed
             $links .= '(';
             $links .= Linker::linkKnown($title, wfMessage($msg)->escaped(), array(), array('oldid' => $oldStable, 'diff' => $revId));
             $links .= ')';
         }
         # Show a diff link to this revision
         $ts = empty($params[2]) ? Revision::getTimestampFromId($title, $revId) : $params[2];
         $time = $wgLang->timeanddate($ts, true);
         $links .= ' (';
         $links .= Linker::linkKnown($title, wfMessage('review-logentry-id', $revId, $time)->escaped(), array(), array('oldid' => $revId, 'diff' => 'prev') + FlaggedRevs::diffOnlyCGI());
         $links .= ')';
     }
     return $links;
 }
 /**
  * Get flags for a revision
  * @param array $tags
  * @return string
  */
 public static function flattenRevisionTags(array $tags)
 {
     $flags = '';
     foreach ($tags as $tag => $value) {
         # Add only currently recognized ones
         if (FlaggedRevs::getTagLevels($tag)) {
             $flags .= $tag . ':' . intval($value) . "\n";
         }
     }
     return $flags;
 }
 /**
  * Set template and image versions from parsing a revision
  * @param Title $title
  * @param int $revId
  * @param ParserOutput $rev
  * @return void
  */
 public static function setRevIncludes(Title $title, $revId, ParserOutput $pOut)
 {
     global $wgMemc;
     $key = self::getCacheKey($title, $revId);
     # Get the template/file versions used...
     $versions = array($pOut->getTemplateIds(), $pOut->getFileSearchOptions());
     # Save to cache (check cache expiry for dynamic elements)...
     $data = FlaggedRevs::makeMemcObj($versions);
     $wgMemc->set($key, $data, $pOut->getCacheExpiry());
 }
 private function showForm()
 {
     global $wgScript;
     $this->getOutput()->addHTML(Xml::openElement('form', array('name' => 'qualityoversight', 'action' => $wgScript, 'method' => 'get')) . '<fieldset><legend>' . $this->msg('qualityoversight-legend')->escaped() . '</legend><p>' . Html::hidden('title', $this->getPageTitle()->getPrefixedDBKey()) . FlaggedRevsXML::getNamespaceMenu($this->namespace) . '&#160;' . (FlaggedRevs::qualityVersions() ? FlaggedRevsXML::getLevelMenu($this->level, 'revreview-filter-all', 1) . '&#160;' : "") . Xml::inputLabel($this->msg('specialloguserlabel')->text(), 'user', 'user', 20, $this->user) . '<br />' . FlaggedRevsXML::getStatusFilterMenu($this->status) . '&#160;' . FlaggedRevsXML::getAutoFilterMenu($this->automatic) . '&#160;' . Xml::submitButton($this->msg('go')->text()) . '</p></fieldset>' . Xml::closeElement('form'));
 }
 function __construct($form, $conds = array(), $type = 0, $namespace = 0, $hideRedirs = 1)
 {
     $this->mForm = $form;
     $this->mConds = $conds;
     $this->type = $type;
     # Must be a content page...
     if (!is_null($namespace)) {
         $namespace = intval($namespace);
     }
     $vnamespaces = FlaggedRevs::getReviewNamespaces();
     if (is_null($namespace) || !in_array($namespace, $vnamespaces)) {
         $namespace = !$vnamespaces ? -1 : $vnamespaces[0];
     }
     $this->namespace = $namespace;
     $this->hideRedirs = $hideRedirs;
     parent::__construct();
 }
 public function getAllowedParams()
 {
     $namespaces = FlaggedRevs::getReviewNamespaces();
     // Replace '' with more readable 'none' in autoreview restiction levels
     $autoreviewLevels = FlaggedRevs::getRestrictionLevels();
     $autoreviewLevels[] = 'none';
     return array('start' => array(ApiBase::PARAM_TYPE => 'integer'), 'end' => array(ApiBase::PARAM_TYPE => 'integer'), 'dir' => array(ApiBase::PARAM_DFLT => 'newer', ApiBase::PARAM_TYPE => array('newer', 'older')), 'namespace' => array(ApiBase::PARAM_DFLT => null, ApiBase::PARAM_TYPE => 'namespace', ApiBase::PARAM_ISMULTI => true), 'default' => array(ApiBase::PARAM_DFLT => null, ApiBase::PARAM_TYPE => array('latest', 'stable')), 'autoreview' => array(ApiBase::PARAM_DFLT => null, ApiBase::PARAM_TYPE => $autoreviewLevels), 'limit' => array(ApiBase::PARAM_DFLT => 10, ApiBase::PARAM_TYPE => 'limit', ApiBase::PARAM_MIN => 1, ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2));
 }
Esempio n. 26
0
 /**
  * Get log params (associate array) from a stability config
  * @param array $config
  * @return array (associative)
  */
 public static function stabilityLogParams(array $config)
 {
     $params = $config;
     if (!FlaggedRevs::useOnlyIfProtected()) {
         $params['precedence'] = 1;
         // b/c hack for presenting log params...
     }
     return $params;
 }
Esempio n. 27
0
 public function getAllowedParams()
 {
     $namespaces = FlaggedRevs::getReviewNamespaces();
     return array('start' => array(ApiBase::PARAM_TYPE => 'integer'), 'end' => array(ApiBase::PARAM_TYPE => 'integer'), 'dir' => array(ApiBase::PARAM_DFLT => 'newer', ApiBase::PARAM_TYPE => array('newer', 'older')), 'namespace' => array(ApiBase::PARAM_DFLT => !$namespaces ? NS_MAIN : $namespaces[0], ApiBase::PARAM_TYPE => 'namespace', ApiBase::PARAM_ISMULTI => true), 'filterredir' => array(ApiBase::PARAM_DFLT => 'all', ApiBase::PARAM_TYPE => array('redirects', 'nonredirects', 'all')), 'filterlevel' => array(ApiBase::PARAM_DFLT => null, ApiBase::PARAM_TYPE => 'integer', ApiBase::PARAM_MIN => 0, ApiBase::PARAM_MAX => 2), 'limit' => array(ApiBase::PARAM_DFLT => 10, ApiBase::PARAM_TYPE => 'limit', ApiBase::PARAM_MIN => 1, ApiBase::PARAM_MAX => ApiBase::LIMIT_BIG1, ApiBase::PARAM_MAX2 => ApiBase::LIMIT_BIG2));
 }
 public static function pendingEditNotice($flaggedArticle, $frev, $revsSince)
 {
     global $wgLang;
     $flags = $frev->getTags();
     $time = $wgLang->date($frev->getTimestamp(), true);
     # Add message text for pending edits
     $msg = FlaggedRevs::isQuality($flags) ? 'revreview-pending-quality' : 'revreview-pending-basic';
     $tag = wfMsgExt($msg, 'parseinline', $frev->getRevId(), $time, $revsSince);
     return $tag;
 }
 public function getAllowedParams()
 {
     // Replace '' with more readable 'none' in autoreview restiction levels
     $autoreviewLevels = FlaggedRevs::getRestrictionLevels();
     $autoreviewLevels[] = 'none';
     return array('protectlevel' => array(ApiBase::PARAM_TYPE => $autoreviewLevels, ApiBase::PARAM_DFLT => 'none'), 'expiry' => 'infinite', 'reason' => '', 'watch' => null, 'token' => null, 'title' => null);
 }
 /**
  * Automatically review an revision and add a log entry in the review log.
  *
  * This is called during edit operations after the new revision is added
  * and the page tables updated, but before LinksUpdate is called.
  *
  * $auto is here for revisions checked off to be reviewed. Auto-review
  * triggers on edit, but we don't want those to count as just automatic.
  * This also makes it so the user's name shows up in the page history.
  *
  * If $flags is given, then they will be the review tags. If not, the one
  * from the stable version will be used or minimal tags if that's not possible.
  * If no appropriate tags can be found, then the review will abort.
  */
 public static function autoReviewEdit(WikiPage $article, $user, Revision $rev, array $flags = null, $auto = true)
 {
     wfProfileIn(__METHOD__);
     $title = $article->getTitle();
     // convenience
     # Get current stable version ID (for logging)
     $oldSv = FlaggedRevision::newFromStable($title, FR_MASTER);
     $oldSvId = $oldSv ? $oldSv->getRevId() : 0;
     # Set the auto-review tags from the prior stable version.
     # Normally, this should already be done and given here...
     if (!is_array($flags)) {
         if ($oldSv) {
             # Use the last stable version if $flags not given
             if ($user->isAllowed('bot')) {
                 $flags = $oldSv->getTags();
                 // no change for bot edits
             } else {
                 # Account for perms/tags...
                 $flags = self::getAutoReviewTags($user, $oldSv->getTags());
             }
         } else {
             // new page?
             $flags = self::quickTags(FR_CHECKED);
             // use minimal level
         }
         if (!is_array($flags)) {
             wfProfileOut(__METHOD__);
             return false;
             // can't auto-review this revision
         }
     }
     # Get review property flags
     $propFlags = $auto ? array('auto') : array();
     # Note: this needs to match the prepareContentForEdit() call WikiPage::doEditContent.
     # This is for consistency and also to avoid triggering a second parse otherwise.
     $editInfo = $article->prepareContentForEdit($rev->getContent(), null, $user, $rev->getContentFormat());
     $poutput = $editInfo->output;
     // revision HTML output
     # Get the "review time" versions of templates and files.
     # This tries to make sure each template/file version either came from the stable
     # version of that template/file or was a "review time" version used in the stable
     # version of this page. If a pending version of a template/file is currently vandalism,
     # we try to avoid storing its ID as the "review time" version so it won't show up when
     # someone views the page. If not possible, this stores the current template/file.
     if (FlaggedRevs::inclusionSetting() === FR_INCLUDES_CURRENT) {
         $tVersions = $poutput->getTemplateIds();
         $fVersions = $poutput->getFileSearchOptions();
     } else {
         $tVersions = $oldSv ? $oldSv->getTemplateVersions() : array();
         $fVersions = $oldSv ? $oldSv->getFileVersions() : array();
         foreach ($poutput->getTemplateIds() as $ns => $pages) {
             foreach ($pages as $dbKey => $revId) {
                 if (!isset($tVersions[$ns][$dbKey])) {
                     $srev = FlaggedRevision::newFromStable(Title::makeTitle($ns, $dbKey));
                     if ($srev) {
                         // use stable
                         $tVersions[$ns][$dbKey] = $srev->getRevId();
                     } else {
                         // use current
                         $tVersions[$ns][$dbKey] = $revId;
                     }
                 }
             }
         }
         foreach ($poutput->getFileSearchOptions() as $dbKey => $info) {
             if (!isset($fVersions[$dbKey])) {
                 $srev = FlaggedRevision::newFromStable(Title::makeTitle(NS_FILE, $dbKey));
                 if ($srev && $srev->getFileTimestamp()) {
                     // use stable
                     $fVersions[$dbKey]['time'] = $srev->getFileTimestamp();
                     $fVersions[$dbKey]['sha1'] = $srev->getFileSha1();
                 } else {
                     // use current
                     $fVersions[$dbKey]['time'] = $info['time'];
                     $fVersions[$dbKey]['sha1'] = $info['sha1'];
                 }
             }
         }
     }
     # If this is an image page, get the corresponding file version info...
     $fileData = array('name' => null, 'timestamp' => null, 'sha1' => null);
     if ($title->getNamespace() == NS_FILE) {
         # We must use WikiFilePage process cache on upload or get bitten by slave lag
         $file = $article instanceof WikiFilePage || $article instanceof ImagePage ? $article->getFile() : wfFindFile($title, array('bypassCache' => true));
         // skip cache; bug 31056
         if (is_object($file) && $file->exists()) {
             $fileData['name'] = $title->getDBkey();
             $fileData['timestamp'] = $file->getTimestamp();
             $fileData['sha1'] = $file->getSha1();
         }
     }
     # Our review entry
     $flaggedRevision = new FlaggedRevision(array('rev' => $rev, 'user_id' => $user->getId(), 'timestamp' => $rev->getTimestamp(), 'quality' => FlaggedRevs::getQualityTier($flags, 0), 'tags' => FlaggedRevision::flattenRevisionTags($flags), 'img_name' => $fileData['name'], 'img_timestamp' => $fileData['timestamp'], 'img_sha1' => $fileData['sha1'], 'templateVersions' => $tVersions, 'fileVersions' => $fVersions, 'flags' => implode(',', $propFlags)));
     $flaggedRevision->insert();
     # Update the article review log
     FlaggedRevsLog::updateReviewLog($title, $flags, array(), '', $rev->getId(), $oldSvId, true, $auto);
     # Update page and tracking tables and clear cache
     FlaggedRevs::stableVersionUpdates($article);
     wfProfileOut(__METHOD__);
     return true;
 }