31 require_once __DIR__ .
'/Maintenance.php';
44 parent::__construct();
45 $this->
addDescription(
"Look for 'orphan' revisions hooked to pages which don't exist\n" .
46 "and 'childless' pages with no revisions\n" .
47 "Then, kill the poor widows and orphans\n" .
48 "Man this is depressing"
50 $this->
addOption(
'fix',
'Actually fix broken entries' );
64 $tbls = [
'page',
'revision',
'redirect' ];
66 $tbls = array_merge( $tbls, $extraTable );
68 $db->lockTables( [], $tbls, __METHOD__ );
83 $commentQuery = $commentStore->getJoin(
'rev_comment' );
86 $this->
output(
"Checking for orphan revision table entries... "
87 .
"(this may take a while on a large wiki)\n" );
88 $result = $dbw->select(
89 [
'revision',
'page' ] + $commentQuery[
'tables'] + $actorQuery[
'tables'],
90 [
'rev_id',
'rev_page',
'rev_timestamp' ] + $commentQuery[
'fields'] + $actorQuery[
'fields'],
91 [
'page_id' =>
null ],
94 [
'page' => [
'LEFT JOIN', [
'rev_page=page_id' ] ] ] + $commentQuery[
'joins']
95 + $actorQuery[
'joins']
97 $orphans = $result->numRows();
99 $this->
output(
"$orphans orphan revisions...\n" );
101 "%10s %10s %14s %20s %s\n",
102 'rev_id',
'rev_page',
'rev_timestamp',
'rev_user_text',
'rev_comment'
105 $contLang = MediaWikiServices::getInstance()->getContentLanguage();
106 foreach ( $result as $row ) {
107 $comment = $commentStore->getComment(
'rev_comment', $row )->text;
108 if ( $comment !==
'' ) {
109 $comment =
'(' . $contLang->truncateForVisual( $comment, 40 ) .
')';
111 $rev_user_text = $contLang->truncateForVisual( $row->rev_user_text, 20 );
112 # pad $rev_user_text to 20 characters. Note that this may
113 # yield poor results if $rev_user_text contains combining
114 # or half-width characters. Alas.
115 if ( mb_strlen( $rev_user_text ) < 20 ) {
116 $rev_user_text = str_repeat(
' ', 20 - mb_strlen( $rev_user_text ) );
118 $this->
output( sprintf(
"%10d %10d %14s %s %s\n",
125 $dbw->delete(
'revision', [
'rev_id' => $row->rev_id ] );
129 $this->
output(
"Run again with --fix to remove these entries automatically.\n" );
132 $this->
output(
"No orphans! Yay!\n" );
136 $dbw->unlockTables( __METHOD__ );
146 $page = $dbw->tableName(
'page' );
147 $revision = $dbw->tableName(
'revision' );
150 $this->
lockTables( $dbw, [
'user',
'text' ] );
153 $this->
output(
"\nChecking for pages whose page_latest links are incorrect... "
154 .
"(this may take a while on a large wiki)\n" );
155 $result = $dbw->query(
"
157 FROM $page LEFT JOIN $revision ON page_latest=rev_id
160 foreach ( $result as $row ) {
161 $result2 = $dbw->query(
"
162 SELECT MAX(rev_timestamp) as max_timestamp
164 WHERE rev_page=" . (
int)( $row->page_id )
166 $row2 = $dbw->fetchObject( $result2 );
168 if ( $row->rev_timestamp != $row2->max_timestamp ) {
170 $this->
output( sprintf(
"%10s %10s %14s %14s\n",
171 'page_id',
'rev_id',
'timestamp',
'max timestamp' ) );
174 $this->
output( sprintf(
"%10d %10d %14s %14s\n",
178 $row2->max_timestamp ) );
181 $maxId = $dbw->selectField(
185 'rev_page' => $row->page_id,
186 'rev_timestamp' => $row2->max_timestamp ] );
187 $this->
output(
"... updating to revision $maxId\n" );
191 $article->updateRevisionOn( $dbw, $maxRev );
200 $this->
output(
"Found $found pages with incorrect latest revision.\n" );
202 $this->
output(
"No pages with incorrect latest revision. Yay!\n" );
204 if ( !$fix && $found > 0 ) {
205 $this->
output(
"Run again with --fix to remove these entries automatically.\n" );
209 $dbw->unlockTables( __METHOD__ );