Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 78
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 / 78
0.00% covered (danger)
0.00%
0 / 4
380
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 / 61
0.00% covered (danger)
0.00%
0 / 1
156
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\Html\Html;
11
12class SpecialDeleteCargoTable extends UnlistedSpecialPage {
13
14    public function __construct() {
15        parent::__construct( 'DeleteCargoTable' );
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( __METHOD__ );
33            foreach ( $fieldTables as $fieldTable ) {
34                $cdb->dropTable( $fieldTable, __METHOD__ );
35            }
36            if ( is_array( $fieldHelperTables ) ) {
37                foreach ( $fieldHelperTables as $fieldHelperTable ) {
38                    $cdb->dropTable( $fieldHelperTable, __METHOD__ );
39                }
40            }
41            $cdb->dropTable( $mainTable, __METHOD__ );
42            $cdb->commit( __METHOD__ );
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 ], __METHOD__ );
50        $dbw->delete( 'cargo_pages', [ 'table_name' => $mainTable ], __METHOD__ );
51    }
52
53    public function execute( $subpage = false ) {
54        // Check permissions.
55        if ( !$this->getUser()->isAllowed( 'deletecargodata' ) ) {
56            $this->displayRestrictionError();
57        }
58
59        $out = $this->getOutput();
60        $req = $this->getRequest();
61        $csrfTokenSet = $this->getContext()->getCsrfTokenSet();
62
63        $out->enableOOUI();
64
65        $this->setHeaders();
66        if ( $subpage == '' ) {
67            CargoUtils::displayErrorMessage( $out, $this->msg( "cargo-notable" ) );
68            return true;
69        }
70
71        $replacementTable = $req->getCheck( '_replacement' );
72        $origTableName = $subpage;
73        if ( $replacementTable ) {
74            $tableName = $subpage . '__NEXT';
75        } else {
76            $tableName = $subpage;
77        }
78
79        // Make sure that this table exists.
80        $dbr = CargoUtils::getMainDBForRead();
81        $res = $dbr->select( 'cargo_tables', [ 'main_table', 'field_tables', 'field_helper_tables' ],
82            [ 'main_table' => $tableName ], __METHOD__ );
83        if ( $res->numRows() == 0 ) {
84            CargoUtils::displayErrorMessage( $out, $this->msg( "cargo-unknowntable", $tableName ) );
85            return true;
86        }
87
88        $ctPage = CargoUtils::getSpecialPage( 'CargoTables' );
89        $row = $res->fetchRow();
90        $fieldTables = unserialize( $row['field_tables'] );
91        $fieldHelperTables = unserialize( $row['field_helper_tables'] );
92
93        if ( $req->wasPosted() && $req->getCheck( 'delete' ) && $csrfTokenSet->matchToken( $req->getText( 'wpEditToken' ) ) ) {
94            self::deleteTable( $tableName, $fieldTables, $fieldHelperTables );
95            $text = Html::rawElement( 'p', [], $this->msg( 'cargo-deletetable-success', $tableName )->escaped() ) . "\n";
96            $tablesLink = CargoUtils::makeLink( $this->getLinkRenderer(),
97                $ctPage->getPageTitle(),
98                htmlspecialchars( $ctPage->getDescription() ) );
99            $text .= Html::rawElement( 'p', [], $this->msg( 'returnto' )->rawParams( $tablesLink )->escaped() );
100            $out->addHTML( $text );
101            if ( !$replacementTable ) {
102                CargoUtils::logTableAction( 'deletetable', $tableName, $this->getUser() );
103            }
104            return true;
105        }
106
107        $ctURL = $ctPage->getPageTitle()->getFullURL();
108        $tableLink = "[$ctURL/$origTableName $origTableName]";
109
110        if ( $replacementTable ) {
111            $replacementTableURL = "$ctURL/$origTableName";
112            $replacementTableURL .= ( strpos( $replacementTableURL, '?' ) ) ? '&' : '?';
113            $replacementTableURL .= '_replacement';
114            $text = Html::rawElement( 'p',
115                [ 'class' => 'plainlinks' ],
116                $this->msg( 'cargo-deletetable-replacementconfirm', $replacementTableURL, $tableLink )->parse()
117            );
118        } else {
119            $text = Html::rawElement( 'p',
120                [ 'class' => 'plainlinks' ],
121                $this->msg( 'cargo-deletetable-confirm', $tableLink )->parse()
122            );
123        }
124        $out->addHTML( $text );
125
126        $htmlForm = HTMLForm::factory( 'ooui', [], $this->getContext() );
127
128        if ( $replacementTable ) {
129            $htmlForm = $htmlForm->addHiddenField( '_replacement', '' );
130        }
131
132        $htmlForm
133            ->setSubmitName( 'delete' )
134            ->setSubmitTextMsg( 'delete' )
135            ->setSubmitDestructive()
136            ->prepareForm()
137            ->displayForm( false );
138
139        return true;
140    }
141}