diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b6a57d4c67..1f878ceb41 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2308,7 +2308,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 9 + count: 8 path: src/Controllers/Import/ImportController.php - @@ -2358,7 +2358,7 @@ parameters: - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, mixed given\\.$#" - count: 5 + count: 4 path: src/Controllers/Import/ImportController.php - @@ -2381,11 +2381,6 @@ parameters: count: 1 path: src/Controllers/Import/ImportController.php - - - message: "#^Parameter \\#8 \\$goto of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndGetQueryResponse\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Import/ImportController.php - - message: "#^Result of \\|\\| is always true\\.$#" count: 1 @@ -3165,7 +3160,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 3 + count: 2 path: src/Controllers/Sql/SqlController.php - @@ -3173,11 +3168,6 @@ parameters: count: 1 path: src/Controllers/Sql/SqlController.php - - - message: "#^Parameter \\#1 \\$goto of method PhpMyAdmin\\\\Controllers\\\\Sql\\\\SqlController\\:\\:addBookmark\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Sql/SqlController.php - - message: "#^Parameter \\#1 \\$haystack of function str_contains expects string, mixed given\\.$#" count: 1 @@ -3228,11 +3218,6 @@ parameters: count: 1 path: src/Controllers/Sql/SqlController.php - - - message: "#^Parameter \\#8 \\$goto of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndSendQueryResponse\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Sql/SqlController.php - - message: "#^Parameter \\#9 \\$dispQuery of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndSendQueryResponse\\(\\) expects string\\|null, mixed given\\.$#" count: 1 @@ -3300,7 +3285,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 3 + count: 2 path: src/Controllers/Table/ChangeController.php - @@ -3308,16 +3293,6 @@ parameters: count: 1 path: src/Controllers/Table/ChangeController.php - - - message: "#^Parameter \\#1 \\$haystack of function str_contains expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/ChangeController.php - - - - message: "#^Parameter \\#1 \\$haystack of function str_starts_with expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/ChangeController.php - - message: "#^Parameter \\#1 \\$message of static method PhpMyAdmin\\\\Html\\\\Generator\\:\\:getMessage\\(\\) expects PhpMyAdmin\\\\Message\\|string, mixed given\\.$#" count: 1 @@ -3522,11 +3497,6 @@ parameters: count: 1 path: src/Controllers/Table/DeleteRowsController.php - - - message: "#^Parameter \\#8 \\$goto of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndSendQueryResponse\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/DeleteRowsController.php - - message: "#^Parameter \\#9 \\$dispQuery of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndSendQueryResponse\\(\\) expects string\\|null, mixed given\\.$#" count: 1 @@ -3600,11 +3570,6 @@ parameters: count: 1 path: src/Controllers/Table/ExportController.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 1 - path: src/Controllers/Table/ExportRowsController.php - - message: """ #^Call to deprecated method getInstance\\(\\) of class PhpMyAdmin\\\\Config\\: @@ -4139,11 +4104,6 @@ parameters: count: 1 path: src/Controllers/Table/SearchController.php - - - message: "#^Parameter \\#8 \\$goto of method PhpMyAdmin\\\\Sql\\:\\:executeQueryAndSendQueryResponse\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/SearchController.php - - message: """ #^Call to deprecated method getInstance\\(\\) of class PhpMyAdmin\\\\Config\\: @@ -4167,11 +4127,6 @@ parameters: count: 1 path: src/Controllers/Table/Structure/BrowseController.php - - - message: "#^Parameter \\#1 \\$goto of method PhpMyAdmin\\\\Controllers\\\\Table\\\\Structure\\\\BrowseController\\:\\:displayTableBrowseForSelectedColumns\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/Structure/BrowseController.php - - message: "#^Parameter \\#1 \\$identifier of static method PhpMyAdmin\\\\Util\\:\\:backquote\\(\\) expects string\\|Stringable\\|null, mixed given\\.$#" count: 1 @@ -4615,11 +4570,6 @@ parameters: count: 1 path: src/Controllers/Table/ZoomSearchController.php - - - message: "#^Parameter \\#2 \\$goto of method PhpMyAdmin\\\\Controllers\\\\Table\\\\ZoomSearchController\\:\\:zoomSubmitAction\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/Controllers/Table/ZoomSearchController.php - - message: "#^Parameter \\#2 \\$signature of static method PhpMyAdmin\\\\Core\\:\\:checkSqlQuerySignature\\(\\) expects string, mixed given\\.$#" count: 1 @@ -7838,7 +7788,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 3 + count: 2 path: src/InsertEdit.php - @@ -7866,11 +7816,6 @@ parameters: count: 1 path: src/InsertEdit.php - - - message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getGotoInclude\\(\\) should return string but returns mixed\\.$#" - count: 1 - path: src/InsertEdit.php - - message: "#^Offset 2 does not exist on array\\{0\\?\\: string, 1\\?\\: string, 2\\?\\: string, 3\\?\\: numeric\\-string\\}\\.$#" count: 1 @@ -7896,6 +7841,11 @@ parameters: count: 2 path: src/InsertEdit.php + - + message: "#^Only booleans are allowed in a negated boolean, string\\|false given\\.$#" + count: 1 + path: src/InsertEdit.php + - message: "#^Parameter \\#1 \\$buffer of method PhpMyAdmin\\\\Plugins\\\\TransformationsInterface\\:\\:applyTransformation\\(\\) expects string, mixed given\\.$#" count: 1 @@ -7918,7 +7868,7 @@ parameters: - message: "#^Parameter \\#1 \\$haystack of function str_contains expects string, mixed given\\.$#" - count: 2 + count: 1 path: src/InsertEdit.php - @@ -8011,11 +7961,6 @@ parameters: count: 1 path: src/InsertEdit.php - - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, mixed given\\.$#" - count: 1 - path: src/InsertEdit.php - - message: "#^Parameter \\#2 \\$table of method PhpMyAdmin\\\\ConfigStorage\\\\Relation\\:\\:getDisplayField\\(\\) expects string, mixed given\\.$#" count: 1 @@ -12709,7 +12654,7 @@ parameters: - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 5 + count: 2 path: src/SqlQueryForm.php - @@ -17104,16 +17049,6 @@ parameters: count: 1 path: tests/unit/SqlQueryFormTest.php - - - message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#" - count: 1 - path: tests/unit/SqlQueryFormTest.php - - - - message: "#^Parameter \\#1 \\$string of function htmlspecialchars expects string, mixed given\\.$#" - count: 1 - path: tests/unit/SqlQueryFormTest.php - - message: "#^Property PhpMyAdmin\\\\Config\\:\\:\\$settings \\(array\\{PmaAbsoluteUri\\: string, AuthLog\\: string, AuthLogSuccess\\: bool, PmaNoRelation_DisableWarning\\: bool, SuhosinDisableWarning\\: bool, LoginCookieValidityDisableWarning\\: bool, ReservedWordDisableWarning\\: bool, TranslationWarningThreshold\\: int, \\.\\.\\.\\}\\) does not accept array\\{PmaAbsoluteUri\\: string, AuthLog\\: string, AuthLogSuccess\\: bool, PmaNoRelation_DisableWarning\\: bool, SuhosinDisableWarning\\: bool, LoginCookieValidityDisableWarning\\: bool, ReservedWordDisableWarning\\: bool, TranslationWarningThreshold\\: int, \\.\\.\\.\\}\\.$#" count: 1 diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 8f503aab4a..3de85cabe2 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1877,7 +1877,6 @@ getParsedBodyParamAsString('import_type', '')]]> - settings['MemoryLimit'])]]> @@ -2841,7 +2840,6 @@ - @@ -2920,16 +2918,11 @@ - - - - - @@ -3133,9 +3126,6 @@ - - - @@ -6414,7 +6404,6 @@ salt]]> - config->settings['UploadDir'])]]> @@ -7100,6 +7089,9 @@ + + + @@ -7114,9 +7106,6 @@ - - - @@ -10341,9 +10330,6 @@ - - - config->settings['Servers'][Current::$server]['verbose'])]]> @@ -14156,9 +14142,6 @@ settings]]> settings]]> - - - diff --git a/psalm.xml b/psalm.xml index 3a6da9f241..c75172017a 100644 --- a/psalm.xml +++ b/psalm.xml @@ -62,7 +62,6 @@ file_handle: resource|null, finished: bool, from_cookie: bool, - goto: string, hostname: string, import_file: string, import_file_name: string, diff --git a/src/Controllers/Database/SqlController.php b/src/Controllers/Database/SqlController.php index 459ee8d7b6..3862c1a240 100644 --- a/src/Controllers/Database/SqlController.php +++ b/src/Controllers/Database/SqlController.php @@ -16,6 +16,7 @@ use PhpMyAdmin\Message; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\SqlQueryForm; use PhpMyAdmin\Url; +use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use function __; @@ -36,7 +37,6 @@ class SqlController implements InvocableController public function __invoke(ServerRequest $request): Response { - $GLOBALS['goto'] ??= null; $GLOBALS['back'] ??= null; $GLOBALS['errorUrl'] ??= null; @@ -74,8 +74,8 @@ class SqlController implements InvocableController * After a syntax error, we return to this script * with the typed query in the textarea. */ - $GLOBALS['goto'] = Url::getFromRoute('/database/sql'); - $GLOBALS['back'] = $GLOBALS['goto']; + UrlParams::$goto = Url::getFromRoute('/database/sql'); + $GLOBALS['back'] = UrlParams::$goto; $delimiter = $request->getParsedBodyParamAsString('delimiter', ';'); $this->response->addHTML($this->sqlQueryForm->getHtml( diff --git a/src/Controllers/Import/ImportController.php b/src/Controllers/Import/ImportController.php index 70063b6469..ab7ebb99db 100644 --- a/src/Controllers/Import/ImportController.php +++ b/src/Controllers/Import/ImportController.php @@ -61,7 +61,6 @@ final class ImportController implements InvocableController public function __invoke(ServerRequest $request): Response { - $GLOBALS['goto'] ??= null; $GLOBALS['display_query'] ??= null; $GLOBALS['ajax_reload'] ??= null; $GLOBALS['import_text'] ??= null; @@ -174,7 +173,7 @@ final class ImportController implements InvocableController // so we can obtain the message $_SESSION['Import_message']['message'] = $GLOBALS['message']->getDisplay(); - $_SESSION['Import_message']['go_back_url'] = $GLOBALS['goto']; + $_SESSION['Import_message']['go_back_url'] = UrlParams::$goto; $this->response->setRequestStatus(false); $this->response->addJSON('message', $GLOBALS['message']); @@ -206,22 +205,22 @@ final class ImportController implements InvocableController // Create error and goto url if (ImportSettings::$importType === 'table') { - $GLOBALS['goto'] = Url::getFromRoute('/table/import'); + UrlParams::$goto = Url::getFromRoute('/table/import'); } elseif (ImportSettings::$importType === 'database') { - $GLOBALS['goto'] = Url::getFromRoute('/database/import'); + UrlParams::$goto = Url::getFromRoute('/database/import'); } elseif (ImportSettings::$importType === 'server') { - $GLOBALS['goto'] = Url::getFromRoute('/server/import'); - } elseif (empty($GLOBALS['goto']) || preg_match('@^index\.php$@i', $GLOBALS['goto']) !== 1) { + UrlParams::$goto = Url::getFromRoute('/server/import'); + } elseif (UrlParams::$goto === '' || preg_match('@^index\.php$@i', UrlParams::$goto) !== 1) { if (Current::$table !== '' && Current::$database !== '') { - $GLOBALS['goto'] = Url::getFromRoute('/table/structure'); + UrlParams::$goto = Url::getFromRoute('/table/structure'); } elseif (Current::$database !== '') { - $GLOBALS['goto'] = Url::getFromRoute('/database/structure'); + UrlParams::$goto = Url::getFromRoute('/database/structure'); } else { - $GLOBALS['goto'] = Url::getFromRoute('/server/sql'); + UrlParams::$goto = Url::getFromRoute('/server/sql'); } } - $GLOBALS['errorUrl'] = $GLOBALS['goto'] . Url::getCommon(UrlParams::$params, '&'); + $GLOBALS['errorUrl'] = UrlParams::$goto . Url::getCommon(UrlParams::$params, '&'); $_SESSION['Import_message']['go_back_url'] = $GLOBALS['errorUrl']; if (Current::$database !== '') { @@ -559,7 +558,7 @@ final class ImportController implements InvocableController UrlParams::$params['local_import_file'] = ImportSettings::$localImportFile; } - $importUrl = $GLOBALS['errorUrl'] = $GLOBALS['goto'] . Url::getCommon(UrlParams::$params, '&'); + $importUrl = $GLOBALS['errorUrl'] = UrlParams::$goto . Url::getCommon(UrlParams::$params, '&'); $GLOBALS['message'] = Message::error( __( @@ -655,7 +654,7 @@ final class ImportController implements InvocableController null, // sql_query_for_bookmark - see below null, // message_to_show null, // sql_data - $GLOBALS['goto'], // goto + UrlParams::$goto, // goto null, // disp_query null, // disp_message $GLOBALS['sql_query'], // sql_query @@ -718,7 +717,7 @@ final class ImportController implements InvocableController $this->response->addJSON('message', Message::error(ImportSettings::$message)); } else { /** @psalm-suppress UnresolvableInclude */ - include ROOT_PATH . $GLOBALS['goto']; + include ROOT_PATH . UrlParams::$goto; } return $this->response->response(); diff --git a/src/Controllers/Sql/SqlController.php b/src/Controllers/Sql/SqlController.php index 08f44584a2..6f4cf193e8 100644 --- a/src/Controllers/Sql/SqlController.php +++ b/src/Controllers/Sql/SqlController.php @@ -19,6 +19,7 @@ use PhpMyAdmin\ParseAnalyze; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Sql; use PhpMyAdmin\Url; +use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use function __; @@ -41,7 +42,6 @@ class SqlController implements InvocableController { $GLOBALS['display_query'] ??= null; $GLOBALS['ajax_reload'] ??= null; - $GLOBALS['goto'] ??= null; $GLOBALS['errorUrl'] ??= null; $GLOBALS['unlim_num_rows'] ??= null; $GLOBALS['import_text'] ??= null; @@ -74,16 +74,16 @@ class SqlController implements InvocableController */ $isGotofile = true; $config = Config::getInstance(); - if (empty($GLOBALS['goto'])) { + if (UrlParams::$goto === '') { if (Current::$table === '') { - $GLOBALS['goto'] = Util::getScriptNameForOption($config->settings['DefaultTabDatabase'], 'database'); + UrlParams::$goto = Util::getScriptNameForOption($config->settings['DefaultTabDatabase'], 'database'); } else { - $GLOBALS['goto'] = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); + UrlParams::$goto = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); } } if (! isset($GLOBALS['errorUrl'])) { - $GLOBALS['errorUrl'] = ! empty($GLOBALS['back']) ? $GLOBALS['back'] : $GLOBALS['goto']; + $GLOBALS['errorUrl'] = ! empty($GLOBALS['back']) ? $GLOBALS['back'] : UrlParams::$goto; $GLOBALS['errorUrl'] .= Url::getCommon( ['db' => Current::$database], ! str_contains($GLOBALS['errorUrl'], '?') ? '?' : '&', @@ -124,7 +124,7 @@ class SqlController implements InvocableController $GLOBALS['sql_query'] = $this->sql->getDefaultSqlQueryForBrowse(Current::$database, Current::$table); // set $goto to what will be displayed if query returns 0 rows - $GLOBALS['goto'] = ''; + UrlParams::$goto = ''; } elseif (! $this->response->checkParameters(['sql_query'])) { return $this->response->response(); } @@ -169,7 +169,7 @@ class SqlController implements InvocableController $storeBkm = $request->hasBodyParam('store_bkm'); $bkmAllUsers = $request->getParsedBodyParam('bkm_all_users'); // Should this be hasBodyParam? if ($storeBkm && $bkmFields !== null) { - $this->addBookmark($GLOBALS['goto'], $bkmFields, (bool) $bkmAllUsers); + $this->addBookmark(UrlParams::$goto, $bkmFields, (bool) $bkmAllUsers); return $this->response->response(); } @@ -177,9 +177,9 @@ class SqlController implements InvocableController /** * Sets or modifies the $goto variable if required */ - if ($GLOBALS['goto'] === Url::getFromRoute('/sql')) { + if (UrlParams::$goto === Url::getFromRoute('/sql')) { $isGotofile = false; - $GLOBALS['goto'] = Url::getFromRoute('/sql', [ + UrlParams::$goto = Url::getFromRoute('/sql', [ 'db' => Current::$database, 'table' => Current::$table, 'sql_query' => $GLOBALS['sql_query'], @@ -194,7 +194,7 @@ class SqlController implements InvocableController $GLOBALS['import_text'] ?? null, $GLOBALS['message_to_show'] ?? null, null, - $GLOBALS['goto'], + UrlParams::$goto, isset($GLOBALS['disp_query']) ? $GLOBALS['display_query'] : null, $GLOBALS['disp_message'] ?? null, $GLOBALS['sql_query'], diff --git a/src/Controllers/Table/ChangeController.php b/src/Controllers/Table/ChangeController.php index 3277790086..e4c39c8bdf 100644 --- a/src/Controllers/Table/ChangeController.php +++ b/src/Controllers/Table/ChangeController.php @@ -122,14 +122,14 @@ class ChangeController implements InvocableController /** * Defines the url to return to in case of error in a sql statement - * (at this point, $GLOBALS['goto'] will be set but could be empty) + * (at this point, UrlParams::$goto will be set but could be empty) */ - if (empty($GLOBALS['goto'])) { + if (UrlParams::$goto === '') { if (Current::$table !== '') { // avoid a problem (see bug #2202709) - $GLOBALS['goto'] = Url::getFromRoute('/table/sql'); + UrlParams::$goto = Url::getFromRoute('/table/sql'); } else { - $GLOBALS['goto'] = Url::getFromRoute('/database/sql'); + UrlParams::$goto = Url::getFromRoute('/database/sql'); } } @@ -137,13 +137,13 @@ class ChangeController implements InvocableController $sqlQuery = $request->getParsedBodyParam('sql_query'); UrlParams::$params = ['db' => Current::$database, 'sql_query' => is_string($sqlQuery) ? $sqlQuery : '']; - if (str_starts_with($GLOBALS['goto'] ?? '', 'index.php?route=/table')) { + if (str_starts_with(UrlParams::$goto, 'index.php?route=/table')) { UrlParams::$params['table'] = Current::$table; } - $GLOBALS['errorUrl'] = $GLOBALS['goto'] . Url::getCommon( + $GLOBALS['errorUrl'] = UrlParams::$goto . Url::getCommon( UrlParams::$params, - ! str_contains($GLOBALS['goto'], '?') ? '?' : '&', + ! str_contains(UrlParams::$goto, '?') ? '?' : '&', ); UrlParams::$params = []; diff --git a/src/Controllers/Table/DeleteRowsController.php b/src/Controllers/Table/DeleteRowsController.php index 5826cc533d..670fd55f4e 100644 --- a/src/Controllers/Table/DeleteRowsController.php +++ b/src/Controllers/Table/DeleteRowsController.php @@ -17,6 +17,7 @@ use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Sql; use PhpMyAdmin\Template; use PhpMyAdmin\Transformations; +use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use PhpMyAdmin\Utils\ForeignKey; @@ -34,7 +35,6 @@ final class DeleteRowsController implements InvocableController public function __invoke(ServerRequest $request): Response { - $GLOBALS['goto'] ??= null; $GLOBALS['disp_message'] ??= null; $GLOBALS['disp_query'] ??= null; @@ -90,7 +90,7 @@ final class DeleteRowsController implements InvocableController null, null, null, - $GLOBALS['goto'] ?? '', + UrlParams::$goto, $GLOBALS['disp_query'] ?? null, $GLOBALS['disp_message'] ?? null, $GLOBALS['sql_query'], diff --git a/src/Controllers/Table/ExportRowsController.php b/src/Controllers/Table/ExportRowsController.php index 9572633961..4492c378e6 100644 --- a/src/Controllers/Table/ExportRowsController.php +++ b/src/Controllers/Table/ExportRowsController.php @@ -8,6 +8,7 @@ use PhpMyAdmin\Controllers\InvocableController; use PhpMyAdmin\Http\Response; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\ResponseRenderer; +use PhpMyAdmin\UrlParams; use function __; use function array_values; @@ -26,7 +27,7 @@ final class ExportRowsController implements InvocableController $GLOBALS['single_table'] ??= null; $GLOBALS['where_clause'] ??= null; - if (! empty($GLOBALS['goto']) && (! isset($_POST['rows_to_delete']) || ! is_array($_POST['rows_to_delete']))) { + if (UrlParams::$goto !== '' && (! isset($_POST['rows_to_delete']) || ! is_array($_POST['rows_to_delete']))) { $this->response->setRequestStatus(false); $this->response->addJSON('message', __('No row selected.')); diff --git a/src/Controllers/Table/FindReplaceController.php b/src/Controllers/Table/FindReplaceController.php index 694fd167ec..799fed668b 100644 --- a/src/Controllers/Table/FindReplaceController.php +++ b/src/Controllers/Table/FindReplaceController.php @@ -171,8 +171,8 @@ final class FindReplaceController implements InvocableController */ private function displaySelectionFormAction(): void { - if (! isset($GLOBALS['goto'])) { - $GLOBALS['goto'] = Util::getScriptNameForOption( + if (UrlParams::$goto === '') { + UrlParams::$goto = Util::getScriptNameForOption( Config::getInstance()->settings['DefaultTabTable'], 'table', ); @@ -186,7 +186,7 @@ final class FindReplaceController implements InvocableController $this->response->render('table/find_replace/index', [ 'db' => Current::$database, 'table' => Current::$table, - 'goto' => $GLOBALS['goto'], + 'goto' => UrlParams::$goto, 'column_names' => $this->columnNames, 'types' => $types, 'sql_types' => $this->dbi->types, diff --git a/src/Controllers/Table/SearchController.php b/src/Controllers/Table/SearchController.php index e052400f00..486068ba7e 100644 --- a/src/Controllers/Table/SearchController.php +++ b/src/Controllers/Table/SearchController.php @@ -255,7 +255,7 @@ final class SearchController implements InvocableController null, // sql_query_for_bookmark null, // message_to_show null, // sql_data - $GLOBALS['goto'], // goto + UrlParams::$goto, // goto null, // disp_query null, // disp_message $sqlQuery, // sql_query @@ -269,8 +269,8 @@ final class SearchController implements InvocableController private function displaySelectionFormAction(): void { $config = Config::getInstance(); - if (! isset($GLOBALS['goto'])) { - $GLOBALS['goto'] = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); + if (UrlParams::$goto === '') { + UrlParams::$goto = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); } $properties = []; @@ -281,7 +281,7 @@ final class SearchController implements InvocableController $this->response->render('table/search/index', [ 'db' => Current::$database, 'table' => Current::$table, - 'goto' => $GLOBALS['goto'], + 'goto' => UrlParams::$goto, 'properties' => $properties, 'geom_column_flag' => $this->geomColumnFlag, 'column_names' => $this->columnNames, diff --git a/src/Controllers/Table/SqlController.php b/src/Controllers/Table/SqlController.php index 06aaefa08a..8eb3c81e0c 100644 --- a/src/Controllers/Table/SqlController.php +++ b/src/Controllers/Table/SqlController.php @@ -17,6 +17,7 @@ use PhpMyAdmin\Message; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\SqlQueryForm; use PhpMyAdmin\Url; +use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use function __; @@ -38,7 +39,6 @@ class SqlController implements InvocableController public function __invoke(ServerRequest $request): Response { $GLOBALS['errorUrl'] ??= null; - $GLOBALS['goto'] ??= null; $GLOBALS['back'] ??= null; $this->response->addScriptFiles(['makegrid.js', 'vendor/jquery/jquery.uitablefilter.js', 'sql.js']); @@ -90,7 +90,7 @@ class SqlController implements InvocableController * After a syntax error, we return to this script * with the typed query in the textarea. */ - $GLOBALS['goto'] = Url::getFromRoute('/table/sql'); + UrlParams::$goto = Url::getFromRoute('/table/sql'); $GLOBALS['back'] = Url::getFromRoute('/table/sql'); $delimiter = $request->getParsedBodyParamAsString('delimiter', ';'); diff --git a/src/Controllers/Table/Structure/BrowseController.php b/src/Controllers/Table/Structure/BrowseController.php index 2f3f1a33cc..e117b8a63d 100644 --- a/src/Controllers/Table/Structure/BrowseController.php +++ b/src/Controllers/Table/Structure/BrowseController.php @@ -11,6 +11,7 @@ use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\ParseAnalyze; use PhpMyAdmin\ResponseRenderer; use PhpMyAdmin\Sql; +use PhpMyAdmin\UrlParams; use PhpMyAdmin\Util; use function __; @@ -32,7 +33,7 @@ final class BrowseController implements InvocableController return $this->response->response(); } - $this->displayTableBrowseForSelectedColumns($GLOBALS['goto']); + $this->displayTableBrowseForSelectedColumns(UrlParams::$goto); return $this->response->response(); } diff --git a/src/Controllers/Table/ZoomSearchController.php b/src/Controllers/Table/ZoomSearchController.php index 98227f5bf8..fa94eecee7 100644 --- a/src/Controllers/Table/ZoomSearchController.php +++ b/src/Controllers/Table/ZoomSearchController.php @@ -82,7 +82,6 @@ final class ZoomSearchController implements InvocableController public function __invoke(ServerRequest $request): Response { - $GLOBALS['goto'] ??= null; $GLOBALS['errorUrl'] ??= null; if (! $this->response->checkParameters(['db', 'table'])) { return $this->response->response(); @@ -177,11 +176,11 @@ final class ZoomSearchController implements InvocableController return $this->response->response(); } - if (! isset($GLOBALS['goto'])) { - $GLOBALS['goto'] = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); + if (UrlParams::$goto === '') { + UrlParams::$goto = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); } - $this->zoomSubmitAction($dataLabel, $GLOBALS['goto']); + $this->zoomSubmitAction($dataLabel, UrlParams::$goto); return $this->response->response(); } @@ -245,8 +244,8 @@ final class ZoomSearchController implements InvocableController private function displaySelectionFormAction(string $dataLabel): void { $config = Config::getInstance(); - if (! isset($GLOBALS['goto'])) { - $GLOBALS['goto'] = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); + if (UrlParams::$goto === '') { + UrlParams::$goto = Util::getScriptNameForOption($config->settings['DefaultTabTable'], 'table'); } $criteriaColumnNames = $_POST['criteriaColumnNames'] ?? null; @@ -270,7 +269,7 @@ final class ZoomSearchController implements InvocableController $this->response->render('table/zoom_search/index', [ 'db' => Current::$database, 'table' => Current::$table, - 'goto' => $GLOBALS['goto'], + 'goto' => UrlParams::$goto, 'properties' => $properties, 'geom_column_flag' => $this->geomColumnFlag, 'column_names' => $this->columnNames, diff --git a/src/Http/Middleware/UrlParamsSetting.php b/src/Http/Middleware/UrlParamsSetting.php index dc8e4d5c20..1e7144cbf7 100644 --- a/src/Http/Middleware/UrlParamsSetting.php +++ b/src/Http/Middleware/UrlParamsSetting.php @@ -31,13 +31,13 @@ final class UrlParamsSetting implements MiddlewareInterface private function setGotoAndBackGlobals(ServerRequestInterface $request): void { // Holds page that should be displayed. - $GLOBALS['goto'] = ''; + UrlParams::$goto = ''; $goto = $request->getQueryParams()['goto'] ?? $request->getParsedBody()['goto'] ?? null; Assert::nullOrString($goto); if ($goto !== null && Core::checkPageValidity($goto)) { - $GLOBALS['goto'] = $goto; + UrlParams::$goto = $goto; UrlParams::$params['goto'] = $goto; } else { if ($this->config->issetCookie('goto')) { diff --git a/src/InsertEdit.php b/src/InsertEdit.php index 2801e27648..b6ddb80006 100644 --- a/src/InsertEdit.php +++ b/src/InsertEdit.php @@ -105,7 +105,7 @@ class InsertEdit $formParams = [ 'db' => $db, 'table' => $table, - 'goto' => $GLOBALS['goto'], + 'goto' => UrlParams::$goto, 'err_url' => $errorUrl, 'sql_query' => $_POST['sql_query'] ?? '', ]; @@ -646,7 +646,7 @@ class InsertEdit 'table' => $table, 'where_clause_array' => $whereClauseArray, 'err_url' => $errorUrl, - 'goto' => $GLOBALS['goto'], + 'goto' => UrlParams::$goto, 'sql_query' => $_POST['sql_query'] ?? null, 'has_where_clause' => isset($_POST['where_clause']), 'insert_rows_default' => $this->config->settings['InsertRows'], @@ -855,7 +855,7 @@ class InsertEdit /** * set $goto_include variable for different cases and retrieve like, - * if $GLOBALS['goto'] empty, if $goto_include previously not defined + * if UrlParams::$goto empty, if $goto_include previously not defined * and new_insert, same_insert, edit_next * * @param string|false $gotoInclude store some script for include, otherwise it is @@ -868,16 +868,16 @@ class InsertEdit return '/table/change'; } - if (! empty($GLOBALS['goto'])) { - if (preg_match('@^[a-z_]+\.php$@', $GLOBALS['goto']) !== 1) { + if (UrlParams::$goto !== '') { + if (preg_match('@^[a-z_]+\.php$@', UrlParams::$goto) !== 1) { // this should NOT happen - //$GLOBALS['goto'] = false; - $gotoInclude = str_contains($GLOBALS['goto'], 'index.php?route=/sql') ? '/sql' : false; + //UrlParams::$goto = false; + $gotoInclude = str_contains(UrlParams::$goto, 'index.php?route=/sql') ? '/sql' : false; } else { - $gotoInclude = $GLOBALS['goto']; + $gotoInclude = UrlParams::$goto; } - if ($GLOBALS['goto'] === 'index.php?route=/database/sql' && Current::$table !== '') { + if (UrlParams::$goto === 'index.php?route=/database/sql' && Current::$table !== '') { Current::$table = ''; } } diff --git a/src/ResponseRenderer.php b/src/ResponseRenderer.php index daa7d552a1..4c79638f50 100644 --- a/src/ResponseRenderer.php +++ b/src/ResponseRenderer.php @@ -472,6 +472,10 @@ class ResponseRenderer continue; } + if (! $request && $param === 'goto' && UrlParams::$goto !== '') { + continue; + } + $errorMessage .= __('Missing parameter:') . ' ' . $param diff --git a/src/SqlQueryForm.php b/src/SqlQueryForm.php index 9ee5c3c323..341119b4fe 100644 --- a/src/SqlQueryForm.php +++ b/src/SqlQueryForm.php @@ -75,12 +75,12 @@ class SqlQueryForm if ($db === '') { // prepare for server related - $goto = empty($GLOBALS['goto']) ? Url::getFromRoute('/server/sql') : $GLOBALS['goto']; + $goto = UrlParams::$goto === '' ? Url::getFromRoute('/server/sql') : UrlParams::$goto; } elseif ($table === '') { // prepare for db related - $goto = empty($GLOBALS['goto']) ? Url::getFromRoute('/database/sql') : $GLOBALS['goto']; + $goto = UrlParams::$goto === '' ? Url::getFromRoute('/database/sql') : UrlParams::$goto; } else { - $goto = empty($GLOBALS['goto']) ? Url::getFromRoute('/table/sql') : $GLOBALS['goto']; + $goto = UrlParams::$goto === '' ? Url::getFromRoute('/table/sql') : UrlParams::$goto; } if ($displayTab === 'full' || $displayTab === 'sql') { diff --git a/src/UrlParams.php b/src/UrlParams.php index fd411b794d..460b79de38 100644 --- a/src/UrlParams.php +++ b/src/UrlParams.php @@ -11,4 +11,5 @@ class UrlParams { /** @var array $params */ public static array $params = []; + public static string $goto = ''; } diff --git a/tests/unit/Controllers/Table/DeleteRowsControllerTest.php b/tests/unit/Controllers/Table/DeleteRowsControllerTest.php index 3b3b329a05..a9142fb70d 100644 --- a/tests/unit/Controllers/Table/DeleteRowsControllerTest.php +++ b/tests/unit/Controllers/Table/DeleteRowsControllerTest.php @@ -20,7 +20,7 @@ class DeleteRowsControllerTest extends AbstractTestCase { public function testDeleteRowsController(): void { - $GLOBALS['goto'] = null; + UrlParams::$goto = ''; Current::$database = 'test_db'; Current::$table = 'test_table'; UrlParams::$params = []; diff --git a/tests/unit/Controllers/Table/ExportRowsControllerTest.php b/tests/unit/Controllers/Table/ExportRowsControllerTest.php index 96669bd240..3198d94c1f 100644 --- a/tests/unit/Controllers/Table/ExportRowsControllerTest.php +++ b/tests/unit/Controllers/Table/ExportRowsControllerTest.php @@ -12,6 +12,7 @@ use PhpMyAdmin\Http\Factory\ResponseFactory; use PhpMyAdmin\Http\ServerRequest; use PhpMyAdmin\Tests\AbstractTestCase; use PhpMyAdmin\Tests\Stubs\ResponseRenderer; +use PhpMyAdmin\UrlParams; use PHPUnit\Framework\Attributes\CoversClass; #[CoversClass(ExportRowsController::class)] @@ -31,6 +32,7 @@ class ExportRowsControllerTest extends AbstractTestCase public function testExportRowsController(): void { $_POST['rows_to_delete'] = 'row'; + UrlParams::$goto = ''; $controller = $this->createMock(ExportController::class); $controller->expects(self::once())->method('__invoke') @@ -49,7 +51,7 @@ class ExportRowsControllerTest extends AbstractTestCase public function testWithoutRowsToDelete(): void { - $GLOBALS['goto'] = 'goto'; + UrlParams::$goto = 'goto'; $controller = $this->createMock(ExportController::class); $controller->expects(self::never())->method('__invoke'); @@ -67,7 +69,7 @@ class ExportRowsControllerTest extends AbstractTestCase public function testWithRowsToDelete(): void { - $GLOBALS['goto'] = 'goto'; + UrlParams::$goto = 'goto'; $_POST['rows_to_delete'] = ['key1' => 'row1', 'key2' => 'row2']; $controller = $this->createMock(ExportController::class); diff --git a/tests/unit/Controllers/Table/ReplaceControllerTest.php b/tests/unit/Controllers/Table/ReplaceControllerTest.php index e082b91b23..2b763ca637 100644 --- a/tests/unit/Controllers/Table/ReplaceControllerTest.php +++ b/tests/unit/Controllers/Table/ReplaceControllerTest.php @@ -129,7 +129,7 @@ class ReplaceControllerTest extends AbstractTestCase self::createStub(TableSqlController::class), ); - $GLOBALS['goto'] = 'index.php?route=/sql'; + UrlParams::$goto = 'index.php?route=/sql'; $dummyDbi->addSelectDb('my_db'); $dummyDbi->addSelectDb('my_db'); $dummyDbi->addResult( diff --git a/tests/unit/Http/Middleware/UrlParamsSettingTest.php b/tests/unit/Http/Middleware/UrlParamsSettingTest.php index a3ca7a799a..0d4bf9a8a1 100644 --- a/tests/unit/Http/Middleware/UrlParamsSettingTest.php +++ b/tests/unit/Http/Middleware/UrlParamsSettingTest.php @@ -19,7 +19,7 @@ final class UrlParamsSettingTest extends AbstractTestCase public function testProcess(): void { UrlParams::$params = []; - $GLOBALS['goto'] = null; + UrlParams::$goto = ''; $GLOBALS['back'] = null; $request = ServerRequestFactory::create()->createServerRequest('POST', 'http://example.com/') @@ -32,13 +32,13 @@ final class UrlParamsSettingTest extends AbstractTestCase $urlParamsSetting = new UrlParamsSetting(self::createStub(Config::class)); self::assertSame($response, $urlParamsSetting->process($request, $handler)); /** @psalm-suppress TypeDoesNotContainType */ - self::assertSame('index.php?route=/', $GLOBALS['goto']); + self::assertSame('index.php?route=/', UrlParams::$goto); /** @psalm-suppress TypeDoesNotContainType */ self::assertSame('index.php?route=/', $GLOBALS['back']); /** @psalm-suppress TypeDoesNotContainType */ self::assertSame(['goto' => 'index.php?route=/'], UrlParams::$params); - $GLOBALS['goto'] = null; + UrlParams::$goto = ''; $GLOBALS['back'] = null; } } diff --git a/tests/unit/InsertEditTest.php b/tests/unit/InsertEditTest.php index cdef634810..e139257d11 100644 --- a/tests/unit/InsertEditTest.php +++ b/tests/unit/InsertEditTest.php @@ -22,6 +22,7 @@ use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Tests\Stubs\DummyResult; use PhpMyAdmin\Transformations; use PhpMyAdmin\Url; +use PhpMyAdmin\UrlParams; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Medium; @@ -127,7 +128,7 @@ class InsertEditTest extends AbstractTestCase $whereClause = ['foo' => 'bar ', '1' => ' test']; $_POST['clause_is_unique'] = false; $_POST['sql_query'] = 'SELECT a'; - $GLOBALS['goto'] = 'index.php'; + UrlParams::$goto = 'index.php'; $result = $this->insertEdit->getFormParametersForInsertForm( 'dbname', @@ -161,7 +162,7 @@ class InsertEditTest extends AbstractTestCase $_GET['clause_is_unique'] = false; $_GET['sql_query'] = 'SELECT a'; $_GET['sql_signature'] = Core::signSqlQuery($_GET['sql_query']); - $GLOBALS['goto'] = 'index.php'; + UrlParams::$goto = 'index.php'; $result = $this->insertEdit->getFormParametersForInsertForm( 'dbname', @@ -971,7 +972,7 @@ class InsertEditTest extends AbstractTestCase $config = Config::getInstance(); $config->settings['InsertRows'] = 1; $config->settings['ServerDefault'] = 1; - $GLOBALS['goto'] = 'index.php'; + UrlParams::$goto = 'index.php'; $_POST['where_clause'] = true; $_POST['sql_query'] = 'SELECT 1'; @@ -1346,7 +1347,7 @@ class InsertEditTest extends AbstractTestCase */ public function testGetGotoInclude(): void { - $GLOBALS['goto'] = '123.php'; + UrlParams::$goto = '123.php'; Current::$table = ''; self::assertSame( @@ -1360,7 +1361,7 @@ class InsertEditTest extends AbstractTestCase $this->insertEdit->getGotoInclude('index'), ); - $GLOBALS['goto'] = 'index.php?route=/database/sql'; + UrlParams::$goto = 'index.php?route=/database/sql'; self::assertSame( '/database/sql', @@ -1369,7 +1370,7 @@ class InsertEditTest extends AbstractTestCase self::assertSame('', Current::$table); - $GLOBALS['goto'] = 'index.php?route=/sql&server=2'; + UrlParams::$goto = 'index.php?route=/sql&server=2'; self::assertSame( '/sql', diff --git a/tests/unit/SqlQueryFormTest.php b/tests/unit/SqlQueryFormTest.php index 8c9c5ffa65..90119c5a6e 100644 --- a/tests/unit/SqlQueryFormTest.php +++ b/tests/unit/SqlQueryFormTest.php @@ -16,6 +16,7 @@ use PhpMyAdmin\SqlQueryForm; use PhpMyAdmin\Template; use PhpMyAdmin\Tests\Stubs\DbiDummy; use PhpMyAdmin\Url; +use PhpMyAdmin\UrlParams; use PHPUnit\Framework\Attributes\CoversClass; use ReflectionProperty; @@ -163,7 +164,7 @@ class SqlQueryFormTest extends AbstractTestCase ); //validate 5: $goto - $goto = empty($GLOBALS['goto']) ? Url::getFromRoute('/table/sql') : $GLOBALS['goto']; + $goto = UrlParams::$goto === '' ? Url::getFromRoute('/table/sql') : UrlParams::$goto; self::assertStringContainsString( htmlspecialchars($goto), $html,