Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 64
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
NukePage
0.00% covered (danger)
0.00%
0 / 61
0.00% covered (danger)
0.00%
0 / 3
90
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 1
56
 deleteRevisions
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Erase a page record from the database
4 * Irreversible (can't use standard undelete) and does not update link tables
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 * http://www.gnu.org/copyleft/gpl.html
20 *
21 * @file
22 * @ingroup Maintenance
23 * @author Rob Church <robchur@gmail.com>
24 */
25
26require_once __DIR__ . '/Maintenance.php';
27
28use MediaWiki\Deferred\SiteStatsUpdate;
29use MediaWiki\Title\Title;
30
31/**
32 * Maintenance script that erases a page record from the database.
33 *
34 * @ingroup Maintenance
35 */
36class NukePage extends Maintenance {
37    public function __construct() {
38        parent::__construct();
39        $this->addDescription( 'Remove a page record from the database' );
40        $this->addOption( 'delete', "Actually delete the page" );
41        $this->addArg( 'title', 'Title to delete' );
42    }
43
44    public function execute() {
45        $name = $this->getArg( 0 );
46        $delete = $this->hasOption( 'delete' );
47
48        $dbw = $this->getPrimaryDB();
49        $this->beginTransaction( $dbw, __METHOD__ );
50
51        # Get page ID
52        $this->output( "Searching for \"$name\"..." );
53        $title = Title::newFromText( $name );
54        if ( $title ) {
55            $id = $title->getArticleID();
56            $real = $title->getPrefixedText();
57            $isGoodArticle = $title->isContentPage();
58            $this->output( "found \"$real\" with ID $id.\n" );
59
60            # Get corresponding revisions
61            $this->output( "Searching for revisions..." );
62
63            $revs = $dbw->newSelectQueryBuilder()
64                ->select( 'rev_id' )
65                ->from( 'revision' )
66                ->where( [ 'rev_page' => $id ] )
67                ->caller( __METHOD__ )->fetchFieldValues();
68            $count = count( $revs );
69            $this->output( "found $count.\n" );
70
71            # Delete the page record and associated recent changes entries
72            if ( $delete ) {
73                $this->output( "Deleting page record..." );
74                $dbw->newDeleteQueryBuilder()
75                    ->deleteFrom( 'page' )
76                    ->where( [ 'page_id' => $id ] )
77                    ->caller( __METHOD__ )->execute();
78                $this->output( "done.\n" );
79                $this->output( "Cleaning up recent changes..." );
80                $dbw->newDeleteQueryBuilder()
81                    ->deleteFrom( 'recentchanges' )
82                    ->where( [ 'rc_cur_id' => $id ] )
83                    ->caller( __METHOD__ )->execute();
84                $this->output( "done.\n" );
85            }
86
87            $this->commitTransaction( $dbw, __METHOD__ );
88
89            # Delete revisions as appropriate
90            if ( $delete && $count ) {
91                $this->output( "Deleting revisions..." );
92                $this->deleteRevisions( $revs );
93                $this->output( "done.\n" );
94                $this->purgeRedundantText( true );
95            }
96
97            # Update stats as appropriate
98            if ( $delete ) {
99                $this->output( "Updating site stats..." );
100                // if it was good, decrement that too
101                $ga = $isGoodArticle ? -1 : 0;
102                $stats = SiteStatsUpdate::factory( [
103                    'edits' => -$count,
104                    'articles' => $ga,
105                    'pages' => -1
106                ] );
107                $stats->doUpdate();
108                $this->output( "done.\n" );
109            }
110        } else {
111            $this->output( "not found in database.\n" );
112            $this->commitTransaction( $dbw, __METHOD__ );
113        }
114    }
115
116    public function deleteRevisions( $ids ) {
117        $dbw = $this->getPrimaryDB();
118        $this->beginTransaction( $dbw, __METHOD__ );
119
120        $dbw->newDeleteQueryBuilder()
121            ->deleteFrom( 'revision' )
122            ->where( [ 'rev_id' => $ids ] )
123            ->caller( __METHOD__ )->execute();
124
125        $this->commitTransaction( $dbw, __METHOD__ );
126    }
127}
128
129$maintClass = NukePage::class;
130require_once RUN_MAINTENANCE_IF_MAIN;