1<?php
2
3declare(strict_types=1);
4
5namespace PhpMyAdmin;
6
7use PhpMyAdmin\Controllers\Database\SqlController;
8use function defined;
9use function strlen;
10
11final class DbTableExists
12{
13    /**
14     * Ensure the database and the table exist (else move to the "parent" script)
15     * and display headers
16     */
17    public static function check(): void
18    {
19        self::checkDatabase();
20        self::checkTable();
21    }
22
23    private static function checkDatabase(): void
24    {
25        global $db, $dbi, $is_db, $message, $show_as_php, $sql_query;
26
27        if (! empty($is_db)) {
28            return;
29        }
30
31        $is_db = false;
32        if (strlen($db) > 0) {
33            $is_db = @$dbi->selectDb($db);
34        }
35
36        if ($is_db || defined('IS_TRANSFORMATION_WRAPPER')) {
37            return;
38        }
39
40        $response = Response::getInstance();
41        if ($response->isAjax()) {
42            $response->setRequestStatus(false);
43            $response->addJSON(
44                'message',
45                Message::error(__('No databases selected.'))
46            );
47
48            exit;
49        }
50
51        $url_params = ['reload' => 1];
52
53        if (isset($message)) {
54            $url_params['message'] = $message;
55        }
56
57        if (! empty($sql_query)) {
58            $url_params['sql_query'] = $sql_query;
59        }
60
61        if (isset($show_as_php)) {
62            $url_params['show_as_php'] = $show_as_php;
63        }
64
65        Core::sendHeaderLocation('./index.php?route=/' . Url::getCommonRaw($url_params, '&'));
66
67        exit;
68    }
69
70    private static function checkTable(): void
71    {
72        global $containerBuilder, $db, $table, $dbi, $is_table;
73
74        if (! empty($is_table)
75            || defined('PMA_SUBMIT_MULT')
76            || defined('TABLE_MAY_BE_ABSENT')
77        ) {
78            return;
79        }
80
81        $is_table = false;
82        if (strlen($table) > 0) {
83            $is_table = $dbi->getCache()->getCachedTableContent([$db, $table], false);
84            if ($is_table) {
85                return;
86            }
87
88            $_result = $dbi->tryQuery(
89                'SHOW TABLES LIKE \'' . $dbi->escapeString($table) . '\';',
90                DatabaseInterface::CONNECT_USER,
91                DatabaseInterface::QUERY_STORE
92            );
93            $is_table = @$dbi->numRows($_result);
94            $dbi->freeResult($_result);
95        }
96
97        if ($is_table) {
98            return;
99        }
100
101        if (defined('IS_TRANSFORMATION_WRAPPER')) {
102            exit;
103        }
104
105        if (strlen($table) > 0) {
106            /**
107             * SHOW TABLES doesn't show temporary tables, so try select
108             * (as it can happen just in case temporary table, it should be fast):
109             */
110            $_result = $dbi->tryQuery(
111                'SELECT COUNT(*) FROM ' . Util::backquote($table) . ';',
112                DatabaseInterface::CONNECT_USER,
113                DatabaseInterface::QUERY_STORE
114            );
115            $is_table = ($_result && @$dbi->numRows($_result));
116            $dbi->freeResult($_result);
117        }
118
119        if ($is_table) {
120            return;
121        }
122
123        /** @var SqlController $controller */
124        $controller = $containerBuilder->get(SqlController::class);
125        $controller->index();
126
127        exit;
128    }
129}
130