Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 108 |
UpdateFRTracking | |
0.00% |
0 / 1 |
|
0.00% |
0 / 3 |
240 | |
0.00% |
0 / 100 |
__construct | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 5 |
|||
execute | |
0.00% |
0 / 1 |
2 | |
0.00% |
0 / 3 |
|||
updateFlaggedPages | |
0.00% |
0 / 1 |
182 | |
0.00% |
0 / 92 |
<?php | |
/** | |
* @ingroup Maintenance | |
*/ | |
use MediaWiki\MediaWikiServices; | |
use MediaWiki\Revision\RevisionStore; | |
if ( getenv( 'MW_INSTALL_PATH' ) ) { | |
$IP = getenv( 'MW_INSTALL_PATH' ); | |
} else { | |
$IP = __DIR__ . '/../../..'; | |
} | |
require_once "$IP/maintenance/Maintenance.php"; | |
class UpdateFRTracking extends Maintenance { | |
public function __construct() { | |
parent::__construct(); | |
$this->addDescription( "Correct the page data in the flaggedrevs tracking tables. " ); | |
$this->addOption( 'startpage', 'Page ID to start on', false, true ); | |
$this->requireExtension( 'FlaggedRevs' ); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
public function execute() { | |
$startPage = $this->getOption( 'startpage' ); | |
$this->updateFlaggedPages( $startPage ); | |
} | |
/** | |
* @param int|null $start Page ID | |
*/ | |
private function updateFlaggedPages( $start = null ) { | |
$this->output( "Populating and correcting flaggedpages/flaggedpage_config columns\n" ); | |
$BATCH_SIZE = 300; | |
$db = $this->getDB( DB_PRIMARY ); | |
$revisionStore = MediaWikiServices::getInstance()->getRevisionStore(); | |
if ( $start === null ) { | |
$start = $db->selectField( 'page', 'MIN(page_id)', '', __METHOD__ ); | |
} | |
$end = $db->selectField( 'page', 'MAX(page_id)', '', __METHOD__ ); | |
if ( $start === null || $end === null ) { | |
$this->output( "...flaggedpages table seems to be empty.\n" ); | |
return; | |
} | |
# Do remaining chunk | |
$end += $BATCH_SIZE - 1; | |
$blockStart = (int)$start; | |
$blockEnd = (int)$start + $BATCH_SIZE - 1; | |
$count = 0; | |
$deleted = 0; | |
$fixed = 0; | |
while ( $blockEnd <= $end ) { | |
$this->output( "...doing page_id from $blockStart to $blockEnd\n" ); | |
$cond = "page_id BETWEEN $blockStart AND $blockEnd"; | |
$this->beginTransaction( $db, __METHOD__ ); | |
$res = $db->select( 'page', | |
[ 'page_id', 'page_namespace', 'page_title', 'page_latest' ], | |
$cond, __METHOD__ ); | |
# Go through and update the de-normalized references... | |
foreach ( $res as $row ) { | |
$title = Title::newFromRow( $row ); | |
$article = FlaggableWikiPage::newInstance( $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 { | |
$changed = (bool)$oldFrev; | |
$deleted += (int)$changed; | |
} | |
# Get the latest revision | |
$queryInfo = $revisionStore->getQueryInfo(); | |
$revRow = $db->selectRow( | |
$queryInfo['tables'], | |
$queryInfo['fields'], | |
[ 'rev_page' => $row->page_id ], | |
__METHOD__, | |
[ 'ORDER BY' => 'rev_timestamp DESC' ], | |
$queryInfo['joins'] | |
); | |
# Correct page_latest if needed (import/files made plenty of bad rows) | |
if ( $revRow ) { | |
$latestRevId = $article->getLatest(); | |
if ( $latestRevId ) { | |
// If not found (false), cast to 0 so that the | |
// page is updated, just to be on the safe side, | |
// even though it should always be found | |
$latestTimestamp = (int)$revisionStore->getTimestampFromId( | |
$latestRevId, | |
RevisionStore::READ_LATEST | |
); | |
} else { | |
$latestTimestamp = 0; | |
} | |
if ( $revRow->rev_timestamp > $latestTimestamp ) { | |
// Most recent revision, based on timestamp, is | |
// newer than the page_latest | |
// update page_latest accordingly | |
$revRecord = $revisionStore->newRevisionFromRow( | |
$revRow, | |
RevisionStore::READ_LATEST, | |
$title | |
); | |
if ( $article->updateRevisionOn( | |
$db, | |
$revRecord, | |
$latestRevId | |
) ) { | |
$fixed++; | |
} | |
} | |
} | |
if ( $changed ) { | |
# Lazily rebuild dependencies on next parse (we invalidate below) | |
FlaggedRevs::clearStableOnlyDeps( $title->getArticleID() ); | |
$title->invalidateCache(); | |
} | |
$count++; | |
} | |
# Remove manual config settings that simply restate the site defaults | |
$db->delete( 'flaggedpage_config', | |
[ "fpc_page_id BETWEEN $blockStart AND $blockEnd", | |
'fpc_override' => intval( FlaggedRevs::isStableShownByDefault() ), | |
'fpc_level' => '' | |
], | |
__METHOD__ | |
); | |
$deleted += $db->affectedRows(); | |
$this->commitTransaction( $db, __METHOD__ ); | |
$blockStart += $BATCH_SIZE; | |
$blockEnd += $BATCH_SIZE; | |
} | |
$this->output( "flaggedpage columns update complete ..." . | |
" {$count} rows [{$fixed} fixed] [{$deleted} deleted]\n" ); | |
} | |
} | |
$maintClass = UpdateFRTracking::class; | |
require_once RUN_MAINTENANCE_IF_MAIN; |