Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialDeleteCargoTable
0.00% covered (danger)
0.00%
0 / 77
0.00% covered (danger)
0.00%
0 / 4
272
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 deleteTable
0.00% covered (danger)
0.00%
0 / 15
0.00% covered (danger)
0.00%
0 / 1
30
 execute
0.00% covered (danger)
0.00%
0 / 60
0.00% covered (danger)
0.00%
0 / 1
90
1<?php
2/**
3 * An interface to delete a "Cargo table", which can be one or more real
4 * database tables.
5 *
6 * @author Yaron Koren
7 * @ingroup Cargo
8 */
9
10use MediaWiki\MediaWikiServices;
11
12class SpecialDeleteCargoTable extends UnlistedSpecialPage {
13
14    public function __construct() {
15        parent::__construct( 'DeleteCargoTable', 'deletecargodata' );
16    }
17
18    public function doesWrites() {
19        return true;
20    }
21
22    /**
23     * The table being deleted here is a Cargo table, not a DB table per
24     * se - a Cargo table corresponds to a main DB table, plus
25     * potentially one or more helper tables; all need to be deleted.
26     * Also, records need to be removed from the cargo_tables and
27     * cargo_pages tables.
28     */
29    public static function deleteTable( $mainTable, $fieldTables, $fieldHelperTables ) {
30        $cdb = CargoUtils::getDB();
31        try {
32            $cdb->begin();
33            foreach ( $fieldTables as $fieldTable ) {
34                $cdb->dropTable( $fieldTable );
35            }
36            if ( is_array( $fieldHelperTables ) ) {
37                foreach ( $fieldHelperTables as $fieldHelperTable ) {
38                    $cdb->dropTable( $fieldHelperTable );
39                }
40            }
41            $cdb->dropTable( $mainTable );
42            $cdb->commit();
43        } catch ( Exception $e ) {
44            throw new MWException( "Caught exception ($e) while trying to drop Cargo table. "
45            . "Please make sure that your database user account has the DROP permission." );
46        }
47
48        $dbw = CargoUtils::getMainDBForWrite();
49        $dbw->delete( 'cargo_tables', [ 'main_table' => $mainTable ] );
50        $dbw->delete( 'cargo_pages', [ 'table_name' => $mainTable ] );
51    }
52
53    public function execute( $subpage = false ) {
54        $this->checkPermissions();
55
56        $out = $this->getOutput();
57        $req = $this->getRequest();
58
59        $out->enableOOUI();
60
61        $this->setHeaders();
62        if ( $subpage == '' ) {
63            CargoUtils::displayErrorMessage( $out, $this->msg( "cargo-notable" ) );
64            return true;
65        }
66
67        $replacementTable = $req->getCheck( '_replacement' );
68        $origTableName = $subpage;
69        if ( $replacementTable ) {
70            $tableName = $subpage . '__NEXT';
71        } else {
72            $tableName = $subpage;
73        }
74
75        // Make sure that this table exists.
76        $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
77        $dbr = $lb->getConnectionRef( DB_REPLICA );
78        $res = $dbr->select( 'cargo_tables', [ 'main_table', 'field_tables', 'field_helper_tables' ],
79            [ 'main_table' => $tableName ] );
80        if ( $res->numRows() == 0 ) {
81            CargoUtils::displayErrorMessage( $out, $this->msg( "cargo-unknowntable", $tableName ) );
82            return true;
83        }
84
85        $ctPage = CargoUtils::getSpecialPage( 'CargoTables' );
86        $row = $res->fetchRow();
87        $fieldTables = unserialize( $row['field_tables'] );
88        $fieldHelperTables = unserialize( $row['field_helper_tables'] );
89
90        if ( $this->getRequest()->getCheck( 'delete' ) ) {
91            self::deleteTable( $tableName, $fieldTables, $fieldHelperTables );
92            $text = Html::element( 'p', null, $this->msg( 'cargo-deletetable-success', $tableName )->parse() ) . "\n";
93            $tablesLink = CargoUtils::makeLink( $this->getLinkRenderer(),
94                $ctPage->getPageTitle(),
95                htmlspecialchars( $ctPage->getDescription() ) );
96            $text .= Html::rawElement( 'p', null, $this->msg( 'returnto', $tablesLink )->text() );
97            $out->addHTML( $text );
98            if ( !$replacementTable ) {
99                CargoUtils::logTableAction( 'deletetable', $tableName, $this->getUser() );
100            }
101            return true;
102        }
103
104        $ctURL = $ctPage->getPageTitle()->getFullURL();
105        $tableLink = "[$ctURL/$origTableName $origTableName]";
106
107        if ( $replacementTable ) {
108            $replacementTableURL = "$ctURL/$origTableName";
109            $replacementTableURL .= ( strpos( $replacementTableURL, '?' ) ) ? '&' : '?';
110            $replacementTableURL .= '_replacement';
111            $text = Html::rawElement( 'p',
112                [ 'class' => 'plainlinks' ],
113                $this->msg( 'cargo-deletetable-replacementconfirm', $replacementTableURL, $tableLink )->parse()
114            );
115        } else {
116            $text = Html::rawElement( 'p',
117                [ 'class' => 'plainlinks' ],
118                $this->msg( 'cargo-deletetable-confirm', $tableLink )->parse()
119            );
120        }
121        $out->addHTML( $text );
122
123        $htmlForm = HTMLForm::factory( 'ooui', [], $this->getContext() );
124
125        if ( $replacementTable ) {
126            $htmlForm = $htmlForm->addHiddenField( '_replacement', '' );
127        }
128
129        $htmlForm
130            ->setSubmitName( 'delete' )
131            ->setSubmitTextMsg( 'delete' )
132            ->setSubmitDestructive()
133            ->prepareForm()
134            ->displayForm( false );
135
136        return true;
137    }
138}