|
7 | 7 | use PhpMyAdmin\Config\ConfigFile; |
8 | 8 | use PhpMyAdmin\Config\Forms\User\UserFormList; |
9 | 9 | use PhpMyAdmin\ConfigStorage\Relation; |
| 10 | +use PhpMyAdmin\Dbal\DatabaseName; |
10 | 11 |
|
11 | 12 | use function __; |
12 | 13 | use function array_flip; |
13 | 14 | use function array_merge; |
14 | 15 | use function basename; |
| 16 | +use function htmlspecialchars; |
15 | 17 | use function http_build_query; |
16 | 18 | use function is_array; |
17 | 19 | use function json_decode; |
@@ -120,7 +122,11 @@ public function save(array $config_array) |
120 | 122 | $relationParameters = $this->relation->getRelationParameters(); |
121 | 123 | $server = $GLOBALS['server'] ?? $GLOBALS['cfg']['ServerDefault']; |
122 | 124 | $cache_key = 'server_' . $server; |
123 | | - if ($relationParameters->userPreferencesFeature === null || $relationParameters->user === null) { |
| 125 | + if ( |
| 126 | + $relationParameters->userPreferencesFeature === null |
| 127 | + || $relationParameters->user === null |
| 128 | + || $relationParameters->db === null |
| 129 | + ) { |
124 | 130 | // no pmadb table, use session storage |
125 | 131 | $_SESSION['userconfig'] = [ |
126 | 132 | 'db' => $config_array, |
@@ -165,17 +171,37 @@ public function save(array $config_array) |
165 | 171 |
|
166 | 172 | if (! $dbi->tryQuery($query, DatabaseInterface::CONNECT_CONTROL)) { |
167 | 173 | $message = Message::error(__('Could not save configuration')); |
168 | | - $message->addMessage( |
169 | | - Message::rawError($dbi->getError(DatabaseInterface::CONNECT_CONTROL)), |
170 | | - '<br><br>' |
171 | | - ); |
| 174 | + $message->addMessage(Message::error($dbi->getError(DatabaseInterface::CONNECT_CONTROL)), '<br><br>'); |
| 175 | + if (! $this->hasAccessToDatabase($relationParameters->db)) { |
| 176 | + /** |
| 177 | + * When phpMyAdmin cached the configuration storage parameters, it checked if the database can be |
| 178 | + * accessed, so if it could not be accessed anymore, then the cache must be cleared as it's out of date. |
| 179 | + * |
| 180 | + * @psalm-suppress MixedArrayAssignment |
| 181 | + */ |
| 182 | + $_SESSION['relation'][$GLOBALS['server']] = []; |
| 183 | + $message->addMessage(Message::error(htmlspecialchars( |
| 184 | + __('The phpMyAdmin configuration storage database could not be accessed.') |
| 185 | + )), '<br><br>'); |
| 186 | + } |
172 | 187 |
|
173 | 188 | return $message; |
174 | 189 | } |
175 | 190 |
|
176 | 191 | return true; |
177 | 192 | } |
178 | 193 |
|
| 194 | + private function hasAccessToDatabase(DatabaseName $database): bool |
| 195 | + { |
| 196 | + $escapedDb = $GLOBALS['dbi']->escapeString($database->getName()); |
| 197 | + $query = 'SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = \'' . $escapedDb . '\';'; |
| 198 | + if ($GLOBALS['cfg']['Server']['DisableIS']) { |
| 199 | + $query = 'SHOW DATABASES LIKE \'' . Util::escapeMysqlWildcards($escapedDb) . '\';'; |
| 200 | + } |
| 201 | + |
| 202 | + return (bool) $GLOBALS['dbi']->fetchSingleRow($query, 'ASSOC', DatabaseInterface::CONNECT_CONTROL); |
| 203 | + } |
| 204 | + |
179 | 205 | /** |
180 | 206 | * Returns a user preferences array filtered by $cfg['UserprefsDisallow'] |
181 | 207 | * (exclude list) and keys from user preferences form (allow list) |
|
0 commit comments