Passed
Push — master ( a7be49...5129e4 )
by Maurício
08:55
created

libraries/classes/Common.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpMyAdmin;
6
7
use PhpMyAdmin\Query\Utilities;
8
use function explode;
9
use function strlen;
10
use function strpos;
11
12
/**
13
 * Shared code for server, database and table level pages.
14
 */
15
final class Common
16
{
17 64
    public static function server(): void
18
    {
19 64
        global $db, $table, $url_query, $viewing_mode, $err_url, $is_grantuser, $is_createuser, $dbi;
20
21
        /**
22
         * Handles some variables that may have been sent by the calling script
23
         * Note: this can be called also from the db panel to get the privileges of
24
         *       a db, in which case we want to keep displaying the tabs of
25
         *       the Database panel
26
         */
27 64
        if (empty($viewing_mode)) {
28 64
            $db = '';
29 64
            $table = '';
30
        }
31
32
        /**
33
         * Set parameters for links
34
         */
35 64
        $url_query = Url::getCommon();
36
37
        /**
38
         * Defines the urls to return to in case of error in a sql statement
39
         */
40 64
        $err_url = Url::getFromRoute('/');
41
42 64
        $is_grantuser = $dbi->isUserType('grant');
43 64
        $is_createuser = $dbi->isUserType('create');
44
45
        // now, select the mysql db
46 64
        if (! $dbi->isSuperuser()) {
47 20
            return;
48
        }
49
50 44
        $dbi->selectDb('mysql');
51 44
    }
52
53 4
    public static function database(): void
54
    {
55 4
        global $cfg, $db, $is_show_stats, $db_is_system_schema, $err_url;
56 4
        global $message, $dbi, $url_query, $errno, $is_db, $err_url_0;
57
58 4
        Util::checkParameters(['db']);
59
60 4
        $response = Response::getInstance();
61 4
        $is_show_stats = $cfg['ShowStats'];
62
63 4
        $db_is_system_schema = Utilities::isSystemSchema($db);
64 4
        if ($db_is_system_schema) {
65
            $is_show_stats = false;
66
        }
67
68 4
        $relation = new Relation($dbi);
69 4
        $operations = new Operations($dbi, $relation);
70
71
        /**
72
         * Defines the urls to return to in case of error in a sql statement
73
         */
74 4
        $err_url_0 = Url::getFromRoute('/');
75
76 4
        $err_url = Util::getScriptNameForOption(
77 4
            $cfg['DefaultTabDatabase'],
78 4
            'database'
79
        );
80 4
        $err_url .= Url::getCommon(['db' => $db], strpos($err_url, '?') === false ? '?' : '&');
81
82
        /**
83
         * Ensures the database exists (else move to the "parent" script) and displays
84
         * headers
85
         */
86 4
        if (! isset($is_db) || ! $is_db) {
87
            if (strlen($db) > 0) {
88
                $is_db = $dbi->selectDb($db);
89
                // This "Command out of sync" 2014 error may happen, for example
90
                // after calling a MySQL procedure; at this point we can't select
91
                // the db but it's not necessarily wrong
92
                if ($dbi->getError() && $errno == 2014) {
93
                    $is_db = true;
94
                    unset($errno);
95
                }
96
            } else {
97
                $is_db = false;
98
            }
99
            // Not a valid db name -> back to the welcome page
100
            $params = ['reload' => '1'];
101
            if (isset($message)) {
102
                $params['message'] = $message;
103
            }
104
            $uri = './index.php?route=/' . Url::getCommonRaw($params, '&');
105
            if (strlen($db) === 0 || ! $is_db) {
106
                if ($response->isAjax()) {
107
                    $response->setRequestStatus(false);
108
                    $response->addJSON(
109
                        'message',
110
                        Message::error(__('No databases selected.'))
111
                    );
112
                } else {
113
                    Core::sendHeaderLocation($uri);
114
                }
115
                exit;
116
            }
117
        } // end if (ensures db exists)
118
119
        /**
120
         * Changes database charset if requested by the user
121
         */
122 4
        if (isset($_POST['submitcollation'], $_POST['db_collation']) && ! empty($_POST['db_collation'])) {
123
            [$db_charset] = explode('_', $_POST['db_collation']);
124
            $sql_query = 'ALTER DATABASE ' . Util::backquote($db)
125
                . ' DEFAULT' . Util::getCharsetQueryPart($_POST['db_collation'] ?? '');
126
            $dbi->query($sql_query);
127
            $message = Message::success();
128
129
            /**
130
             * Changes tables charset if requested by the user
131
             */
132
            if (isset($_POST['change_all_tables_collations']) &&
133
                $_POST['change_all_tables_collations'] === 'on'
134
            ) {
135
                [$tables] = Util::getDbInfo($db, null);
136
                foreach ($tables as $tableName => $data) {
137
                    if ($dbi->getTable($db, $tableName)->isView()) {
138
                        // Skip views, we can not change the collation of a view.
139
                        // issue #15283
140
                        continue;
141
                    }
142
                    $sql_query = 'ALTER TABLE '
143
                        . Util::backquote($db)
144
                        . '.'
145
                        . Util::backquote($tableName)
0 ignored issues
show
Are you sure PhpMyAdmin\Util::backquote($tableName) of type array|mixed|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

145
                        . /** @scrutinizer ignore-type */ Util::backquote($tableName)
Loading history...
146
                        . ' DEFAULT '
147
                        . Util::getCharsetQueryPart($_POST['db_collation'] ?? '');
148
                    $dbi->query($sql_query);
149
150
                    /**
151
                     * Changes columns charset if requested by the user
152
                     */
153
                    if (! isset($_POST['change_all_tables_columns_collations']) ||
154
                        $_POST['change_all_tables_columns_collations'] !== 'on'
155
                    ) {
156
                        continue;
157
                    }
158
159
                    $operations->changeAllColumnsCollation($db, $tableName, $_POST['db_collation']);
160
                }
161
            }
162
            unset($db_charset);
163
164
            /**
165
             * If we are in an Ajax request, let us stop the execution here. Necessary for
166
             * db charset change action on /database/operations. If this causes a bug on
167
             * other pages, we might have to move this to a different location.
168
             */
169
            if ($response->isAjax()) {
170
                $response->setRequestStatus($message->isSuccess());
171
                $response->addJSON('message', $message);
172
                exit;
173
            }
174 4
        } elseif (isset($_POST['submitcollation'], $_POST['db_collation']) && empty($_POST['db_collation'])) {
175
            if ($response->isAjax()) {
176
                $response->setRequestStatus(false);
177
                $response->addJSON(
178
                    'message',
179
                    Message::error(__('No collation provided.'))
180
                );
181
            }
182
        }
183
184
        /**
185
         * Set parameters for links
186
         */
187 4
        $url_query = Url::getCommon(['db' => $db]);
188 4
    }
189
190
    public static function table(): void
191
    {
192
        global $db, $table, $db_is_system_schema, $url_query, $url_params, $cfg, $dbi, $err_url, $err_url_0, $route;
193
194
        Util::checkParameters(['db', 'table']);
195
196
        $db_is_system_schema = Utilities::isSystemSchema($db);
197
198
        /**
199
         * Set parameters for links
200
         *
201
         * @deprecated
202
         */
203
        $url_query = Url::getCommon(['db' => $db, 'table' => $table]);
204
205
        /**
206
         * Set parameters for links
207
         */
208
        $url_params = [];
209
        $url_params['db']    = $db;
210
        $url_params['table'] = $table;
211
212
        /**
213
         * Defines the urls to return to in case of error in a sql statement
214
         */
215
        $err_url_0 = Util::getScriptNameForOption(
216
            $cfg['DefaultTabDatabase'],
217
            'database'
218
        );
219
        $err_url_0 .= Url::getCommon(['db' => $db], strpos($err_url_0, '?') === false ? '?' : '&');
220
221
        $err_url = Util::getScriptNameForOption(
222
            $cfg['DefaultTabTable'],
223
            'table'
224
        );
225
        $err_url .= Url::getCommon($url_params, strpos($err_url, '?') === false ? '?' : '&');
226
227
        /**
228
         * Skip test if we are exporting as we can't tell whether a table name is an alias (which would fail the test).
229
         */
230
        if ($route !== '/table/export') {
231
            return;
232
        }
233
234
        DbTableExists::check();
235
    }
236
}
237