Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 53
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
AttachLatest
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 2
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 45
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2/**
3 * Corrects wrong values in the `page_latest` field in the database.
4 *
5 * Copyright © 2005 Brooke Vibber <bvibber@wikimedia.org>
6 * https://www.mediawiki.org/
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 * http://www.gnu.org/copyleft/gpl.html
22 *
23 * @file
24 * @ingroup Maintenance
25 */
26
27use MediaWiki\Title\Title;
28
29require_once __DIR__ . '/Maintenance.php';
30
31/**
32 * Maintenance script to correct wrong values in the `page_latest` field
33 * in the database.
34 *
35 * @ingroup Maintenance
36 */
37class AttachLatest extends Maintenance {
38    public function __construct() {
39        parent::__construct();
40        $this->addOption( "fix", "Actually fix the entries, will dry run otherwise" );
41        $this->addOption( "regenerate-all",
42            "Regenerate the page_latest field for all records in table page" );
43        $this->addDescription( 'Fix page_latest entries in the page table' );
44    }
45
46    public function execute() {
47        $this->output( "Looking for pages with page_latest set to 0...\n" );
48        $dbw = $this->getPrimaryDB();
49        $conds = [ 'page_latest' => 0 ];
50        if ( $this->hasOption( 'regenerate-all' ) ) {
51            $conds = '';
52        }
53        $result = $dbw->newSelectQueryBuilder()
54            ->select( [ 'page_id', 'page_namespace', 'page_title' ] )
55            ->from( 'page' )
56            ->where( $conds )
57            ->caller( __METHOD__ )
58            ->fetchResultSet();
59
60        $services = $this->getServiceContainer();
61        $dbDomain = $services->getDBLoadBalancerFactory()->getLocalDomainID();
62        $wikiPageFactory = $services->getWikiPageFactory();
63        $revisionLookup = $services->getRevisionLookup();
64
65        $n = 0;
66        foreach ( $result as $row ) {
67            $pageId = intval( $row->page_id );
68            $title = Title::makeTitle( $row->page_namespace, $row->page_title );
69            $name = $title->getPrefixedText();
70            $latestTime = $dbw->newSelectQueryBuilder()
71                ->select( 'MAX(rev_timestamp)' )
72                ->from( 'revision' )
73                ->where( [ 'rev_page' => $pageId ] )
74                ->caller( __METHOD__ )
75                ->fetchField();
76            if ( !$latestTime ) {
77                $this->output( "$dbDomain $pageId [[$name]] can't find latest rev time?!\n" );
78                continue;
79            }
80
81            $revRecord = $revisionLookup->getRevisionByTimestamp( $title, $latestTime, IDBAccessObject::READ_LATEST );
82            if ( $revRecord === null ) {
83                $this->output(
84                    "$dbDomain $pageId [[$name]] latest time $latestTime, can't find revision id\n"
85                );
86                continue;
87            }
88
89            $id = $revRecord->getId();
90            $this->output( "$dbDomain $pageId [[$name]] latest time $latestTime, rev id $id\n" );
91            if ( $this->hasOption( 'fix' ) ) {
92                $page = $wikiPageFactory->newFromTitle( $title );
93                $page->updateRevisionOn( $dbw, $revRecord );
94                $this->waitForReplication();
95            }
96            $n++;
97        }
98        $this->output( "Done! Processed $n pages.\n" );
99        if ( !$this->hasOption( 'fix' ) ) {
100            $this->output( "This was a dry run; rerun with --fix to update page_latest.\n" );
101        }
102    }
103}
104
105$maintClass = AttachLatest::class;
106require_once RUN_MAINTENANCE_IF_MAIN;