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; }
/** * 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; }
protected function update_flaggedrevs($start = null) { $this->output("Populating and correcting flaggedrevs columns\n"); $BATCH_SIZE = 1000; $db = wfGetDB(DB_MASTER); if ($start === null) { $start = $db->selectField('revision', 'MIN(rev_id)', false, __METHOD__); } $end = $db->selectField('revision', 'MAX(rev_id)', false, __METHOD__); if (is_null($start) || is_null($end)) { $this->output("...revision table seems to be empty.\n"); return; } # Do remaining chunk $end += $BATCH_SIZE - 1; $blockStart = $start; $blockEnd = $start + $BATCH_SIZE - 1; $count = 0; $changed = 0; while ($blockEnd <= $end) { $this->output("...doing fr_rev_id from {$blockStart} to {$blockEnd}\n"); $cond = "rev_id BETWEEN {$blockStart} AND {$blockEnd} \n\t\t\t\tAND fr_rev_id = rev_id AND page_id = rev_page"; $res = $db->select(array('revision', 'flaggedrevs', 'page'), array('fr_rev_id', 'fr_tags', 'fr_quality', 'page_namespace', 'page_title', 'fr_img_name', 'fr_img_timestamp', 'fr_img_sha1', 'rev_page'), $cond, __METHOD__); $db->begin(); # Go through and clean up missing items, as well as correct fr_quality... foreach ($res as $row) { $tags = FlaggedRevision::expandRevisionTags($row->fr_tags); # Quality rating levels may have changed due to config tweaks... $quality = FlaggedRevs::getQualityTier($tags, 0); $file = $row->fr_img_name; $fileTime = $row->fr_img_timestamp; $fileSha1 = $row->fr_img_sha1; # Check for file version to see if it's stored the old way... if ($row->page_namespace == NS_FILE && !$file) { $irow = $db->selectRow('flaggedimages', array('fi_img_timestamp', 'fi_img_sha1'), array('fi_rev_id' => $row->fr_rev_id, 'fi_name' => $row->page_title), __METHOD__); $fileTime = $irow ? $irow->fi_img_timestamp : null; $fileSha1 = $irow ? $irow->fi_img_sha1 : null; $file = $irow ? $row->page_title : null; # Fill in from current if broken if (!$irow) { $crow = $db->selectRow('image', array('img_timestamp', 'img_sha1'), array('img_name' => $row->page_title), __METHOD__); $fileTime = $crow ? $crow->img_timestamp : null; $fileSha1 = $crow ? $crow->img_sha1 : null; $file = $crow ? $row->page_title : null; } } # Check if anything needs updating if ($quality != $row->fr_quality || $file != $row->fr_img_name || $fileSha1 != $row->fr_img_sha1 || $fileTime != $row->fr_img_timestamp) { # Update the row... $db->update('flaggedrevs', array('fr_quality' => $quality, 'fr_img_name' => $file, 'fr_img_sha1' => $fileSha1, 'fr_img_timestamp' => $fileTime), array('fr_rev_id' => $row->fr_rev_id), __METHOD__); $changed++; } $count++; } $db->commit(); $db->freeResult($res); $blockStart += $BATCH_SIZE; $blockEnd += $BATCH_SIZE; wfWaitForSlaves(5); } $this->output("fr_quality and fr_img_* columns update complete ..." . " {$count} rows [{$changed} changed]\n"); }