requireExtension( 'DiscussionTools' ); $this->addDescription( 'Persist thread item information for the given pages/revisions' ); $this->addOption( 'rev', 'Revision ID to process', false, true, false, true ); $this->addOption( 'page', 'Page title to process', false, true, false, true ); $this->addOption( 'all', 'Process the whole wiki', false, false, false, false ); $this->addOption( 'current', 'Process current revisions only', false, false, false, false ); } public function execute() { $services = MediaWikiServices::getInstance(); $this->itemStore = $services->getService( 'DiscussionTools.ThreadItemStore' ); $this->revStore = $services->getRevisionStore(); if ( $this->getOption( 'all' ) ) { $conds = []; } elseif ( $this->getOption( 'page' ) ) { $linkBatch = $services->getLinkBatchFactory()->newLinkBatch(); foreach ( $this->getOption( 'page' ) as $page ) { $linkBatch->addObj( Title::newFromText( $page ) ); } $pageIds = array_map( static function ( $page ) { return $page->getId(); }, $linkBatch->getPageIdentities() ); $conds = [ 'rev_page' => $pageIds ]; } elseif ( $this->getOption( 'rev' ) ) { $conds = [ 'rev_id' => $this->getOption( 'rev' ) ]; } else { $this->error( "One of 'all', 'page', or 'rev' required" ); $this->maybeHelp( true ); return; } if ( $this->getOption( 'current' ) ) { // runTable() doesn't provide a way to do a JOIN. This is equivalent, but it might have // different performance characteristics. It should be good enough for a maintenance script. $conds[] = 'rev_id IN ( SELECT page_latest FROM page )'; } $this->runTable( [ 'table' => 'revision', 'conds' => $conds, 'index' => [ 'rev_page', 'rev_timestamp', 'rev_id' ], 'callback' => 'processRow', ] ); } /** * @param stdClass $row Database table row */ protected function processRow( stdClass $row ) { $changed = false; try { // HACK (because we don't query the table this data ordinarily comes from, // and we don't care about edit summaries here) $row->rev_comment_text = ''; $row->rev_comment_data = null; $row->rev_comment_cid = null; $rev = $this->revStore->newRevisionFromRow( $row ); $title = Title::newFromLinkTarget( $rev->getPageAsLinkTarget() ); if ( HookUtils::isAvailableForTitle( $title ) ) { $threadItemSet = HookUtils::parseRevisionParsoidHtml( $rev ); if ( !$this->dryrun ) { // Store permalink data $changed = $this->itemStore->insertThreadItems( $rev, $threadItemSet ); } } } catch ( Throwable $e ) { $this->output( "Error while processing revid=$row->rev_id, pageid=$row->rev_page\n" ); MWExceptionRenderer::output( $e, MWExceptionRenderer::AS_RAW ); } $this->progress( (int)$changed ); } } $maintClass = PersistRevisionThreadItems::class; require_once RUN_MAINTENANCE_IF_MAIN;