diff --git a/js/src/modules/functions.ts b/js/src/modules/functions.ts index 86b8e54fbd..9f6f62a960 100644 --- a/js/src/modules/functions.ts +++ b/js/src/modules/functions.ts @@ -1095,9 +1095,9 @@ function onloadSqlQueryEditEvents () { return false; } - var $form = $(this).prev('form'); + var $form = $('.result_query form'); var sqlQuery = ($form.find('input[name=\'sql_query\']').val() as string).trim(); - var $innerSql = $(this).parent().prev().find('code.sql'); + var $innerSql = $('.result_query').find('code.sql'); var newContent = '\n'; newContent += Functions.getForeignKeyCheckboxLoader(); diff --git a/libraries/classes/Html/Generator.php b/libraries/classes/Html/Generator.php index dbf524a098..5d27b213d6 100644 --- a/libraries/classes/Html/Generator.php +++ b/libraries/classes/Html/Generator.php @@ -13,7 +13,6 @@ use PhpMyAdmin\Profiling; use PhpMyAdmin\Providers\ServerVariables\ServerVariablesProvider; use PhpMyAdmin\Query\Compatibility; use PhpMyAdmin\ResponseRenderer; -use PhpMyAdmin\Sanitize; use PhpMyAdmin\SqlParser\Lexer; use PhpMyAdmin\SqlParser\Parser; use PhpMyAdmin\SqlParser\Utils\Error as ParserError; @@ -453,218 +452,231 @@ class Generator unset($GLOBALS['using_bookmark_message']); } - if ($renderSql) { - $retval .= '
' . "\n"; - } - - if ($message instanceof Message) { - if (isset($GLOBALS['special_message'])) { - $message->addText($GLOBALS['special_message']); - unset($GLOBALS['special_message']); - } - - $retval .= $message->getDisplay(); - } else { - $context = 'primary'; + if (is_string($message)) { + $context = Message::NOTICE; if ($type === 'error') { - $context = 'danger'; + $context = Message::ERROR; } elseif ($type === 'success') { - $context = 'success'; + $context = Message::SUCCESS; } - $retval .= ''; + $message = new Message($message, $context); } - if ($renderSql) { - $queryTooBig = false; + if (isset($GLOBALS['special_message'])) { + $message->addText($GLOBALS['special_message']); + unset($GLOBALS['special_message']); + } - $queryLength = mb_strlen($sqlQuery); - if ($queryLength > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { - // when the query is large (for example an INSERT of binary - // data), the parser chokes; so avoid parsing the query - $queryTooBig = true; - $queryBase = mb_substr($sqlQuery, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]'; + $retval .= $message->getDisplay(); + + if (! $renderSql) { + return $retval; + } + + $retval .= '
' . "\n"; + + $queryTooBig = false; + + $queryLength = mb_strlen($sqlQuery); + if ($queryLength > $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) { + // when the query is large (for example an INSERT of binary + // data), the parser chokes; so avoid parsing the query + $queryTooBig = true; + $queryBase = mb_substr($sqlQuery, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]'; + } else { + $queryBase = $sqlQuery; + } + + // Html format the query to be displayed + // If we want to show some sql code it is easiest to create it here + /* SQL-Parser-Analyzer */ + + if (! empty($GLOBALS['show_as_php'])) { + $newLine = '\\n"
' . "\n" . '    . "'; + $queryBase = htmlspecialchars(addslashes($queryBase)); + $queryBase = preg_replace('/((\015\012)|(\015)|(\012))/', $newLine, $queryBase); + $queryBase = '
' . "\n"
+                . '$sql = "' . $queryBase . '";' . "\n"
+                . '
'; + } elseif ($queryTooBig) { + $queryBase = '
' . "\n"
+                . htmlspecialchars($queryBase, ENT_COMPAT) . '
'; + } else { + $queryBase = self::formatSql($queryBase); + } + + // Prepares links that may be displayed to edit/explain the query + // (don't go to default pages, we must go to the page + // where the query box is available) + + // Basic url query part + $urlParams = []; + if (! isset($GLOBALS['db'])) { + $GLOBALS['db'] = ''; + } + + if (strlen($GLOBALS['db']) > 0) { + $urlParams['db'] = $GLOBALS['db']; + if (strlen($GLOBALS['table']) > 0) { + $urlParams['table'] = $GLOBALS['table']; + $editLinkRoute = '/table/sql'; } else { - $queryBase = $sqlQuery; + $editLinkRoute = '/database/sql'; } + } else { + $editLinkRoute = '/server/sql'; + } - // Html format the query to be displayed - // If we want to show some sql code it is easiest to create it here - /* SQL-Parser-Analyzer */ - - if (! empty($GLOBALS['show_as_php'])) { - $newLine = '\\n"
' . "\n" . '    . "'; - $queryBase = htmlspecialchars(addslashes($queryBase)); - $queryBase = preg_replace('/((\015\012)|(\015)|(\012))/', $newLine, $queryBase); - $queryBase = '
' . "\n"
-                    . '$sql = "' . $queryBase . '";' . "\n"
-                    . '
'; - } elseif ($queryTooBig) { - $queryBase = '
' . "\n"
-                    . htmlspecialchars($queryBase, ENT_COMPAT) . '
'; - } else { - $queryBase = self::formatSql($queryBase); - } - - // Prepares links that may be displayed to edit/explain the query - // (don't go to default pages, we must go to the page - // where the query box is available) - - // Basic url query part - $urlParams = []; - if (! isset($GLOBALS['db'])) { - $GLOBALS['db'] = ''; - } - - if (strlen($GLOBALS['db']) > 0) { - $urlParams['db'] = $GLOBALS['db']; - if (strlen($GLOBALS['table']) > 0) { - $urlParams['table'] = $GLOBALS['table']; - $editLinkRoute = '/table/sql'; - } else { - $editLinkRoute = '/database/sql'; - } - } else { - $editLinkRoute = '/server/sql'; - } - - // Want to have the query explained - // but only explain a SELECT (that has not been explained) - /* SQL-Parser-Analyzer */ - $explainLink = ''; - $isSelect = preg_match('@^SELECT[[:space:]]+@i', $sqlQuery); - if (! empty($GLOBALS['cfg']['SQLQuery']['Explain']) && ! $queryTooBig) { - $explainParams = $urlParams; - if ($isSelect) { - $explainParams['sql_query'] = 'EXPLAIN ' . $sqlQuery; - $explainLink = ' [ ' - . self::linkOrButton( - Url::getFromRoute('/import', $explainParams), - null, - __('Explain SQL'), - ) . ' ]'; - } elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sqlQuery)) { - $explainParams['sql_query'] = mb_substr($sqlQuery, 8); - $explainLink = ' [ ' - . self::linkOrButton( - Url::getFromRoute('/import', $explainParams), - null, - __('Skip Explain SQL'), - ) . ']'; - } - } - - $urlParams['sql_query'] = $sqlQuery; - $urlParams['show_query'] = 1; - - // even if the query is big and was truncated, offer the chance - // to edit it (unless it's enormous, see linkOrButton() ) - if (! empty($GLOBALS['cfg']['SQLQuery']['Edit']) && empty($GLOBALS['show_as_php'])) { - $editLink = ' [ ' - . self::linkOrButton(Url::getFromRoute($editLinkRoute, $urlParams), null, __('Edit')) - . ' ]'; - } else { - $editLink = ''; - } - - // Also we would like to get the SQL formed in some nice - // php-code - if (! empty($GLOBALS['cfg']['SQLQuery']['ShowAsPHP']) && ! $queryTooBig) { - if (! empty($GLOBALS['show_as_php'])) { - $phpLink = ' [ ' - . self::linkOrButton( - Url::getFromRoute('/import', $urlParams), - null, - __('Without PHP code'), - ) - . ' ]'; - - $phpLink .= ' [ ' - . self::linkOrButton( - Url::getFromRoute('/import', $urlParams), - null, - __('Submit query'), - ) - . ' ]'; - } else { - $phpParams = $urlParams; - $phpParams['show_as_php'] = 1; - $phpLink = ' [ ' - . self::linkOrButton( - Url::getFromRoute('/import', $phpParams), - null, - __('Create PHP code'), - ) - . ' ]'; - } - } else { - $phpLink = ''; - } - - // Refresh query - if ( - ! empty($GLOBALS['cfg']['SQLQuery']['Refresh']) - && ! isset($GLOBALS['show_as_php']) // 'Submit query' does the same - && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $sqlQuery) - ) { - $refreshLink = Url::getFromRoute('/sql', $urlParams); - $refreshLink = ' [ ' - . self::linkOrButton($refreshLink, null, __('Refresh')) . ' ]'; - } else { - $refreshLink = ''; - } - - $retval .= '
'; - $retval .= $queryBase; - $retval .= '
'; - - $retval .= '
'; - $retval .= '
'; - $retval .= Url::getHiddenInputs($GLOBALS['db'], $GLOBALS['table']); - $retval .= ''; - - // avoid displaying a Profiling checkbox that could - // be checked, which would re-execute an INSERT, for example - if ($refreshLink !== '' && Profiling::isSupported($GLOBALS['dbi'])) { - $retval .= ''; - $retval .= ''; - } - - $retval .= '
'; - - /** - * TODO: Should we have $cfg['SQLQuery']['InlineEdit']? - */ - if (! empty($GLOBALS['cfg']['SQLQuery']['Edit']) && ! $queryTooBig && empty($GLOBALS['show_as_php'])) { - $inlineEditLink = ' [ ' + // Want to have the query explained + // but only explain a SELECT (that has not been explained) + /* SQL-Parser-Analyzer */ + $explainLink = ''; + $isSelect = preg_match('@^SELECT[[:space:]]+@i', $sqlQuery); + if (! empty($GLOBALS['cfg']['SQLQuery']['Explain']) && ! $queryTooBig) { + $explainParams = $urlParams; + if ($isSelect) { + $explainParams['sql_query'] = 'EXPLAIN ' . $sqlQuery; + $explainLink = '
' . self::linkOrButton( - '#', + Url::getFromRoute('/import', $explainParams), null, - _pgettext('Inline edit query', 'Edit inline'), - ['class' => 'inline_edit_sql'], - ) - . ' ]'; - } else { - $inlineEditLink = ''; + __('Explain SQL'), + ['class' => 'btn btn-link'], + ) . '
' . "\n"; + } elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sqlQuery)) { + $explainParams['sql_query'] = mb_substr($sqlQuery, 8); + $explainLink = '
' + . self::linkOrButton( + Url::getFromRoute('/import', $explainParams), + null, + __('Skip Explain SQL'), + ['class' => 'btn btn-link'], + ) . '
' . "\n"; } - - $retval .= $inlineEditLink . $editLink . $explainLink . $phpLink - . $refreshLink; - $retval .= '
'; - - $retval .= '
'; } + $urlParams['sql_query'] = $sqlQuery; + $urlParams['show_query'] = 1; + + // even if the query is big and was truncated, offer the chance + // to edit it (unless it's enormous, see linkOrButton() ) + if (! empty($GLOBALS['cfg']['SQLQuery']['Edit']) && empty($GLOBALS['show_as_php'])) { + $editLink = '
' + . self::linkOrButton( + Url::getFromRoute($editLinkRoute, $urlParams), + null, + __('Edit'), + ['class' => 'btn btn-link'], + ) + . '
' . "\n"; + } else { + $editLink = ''; + } + + // Also we would like to get the SQL formed in some nice + // php-code + if (! empty($GLOBALS['cfg']['SQLQuery']['ShowAsPHP']) && ! $queryTooBig) { + if (! empty($GLOBALS['show_as_php'])) { + $phpLink = '
' + . self::linkOrButton( + Url::getFromRoute('/import', $urlParams), + null, + __('Without PHP code'), + ['class' => 'btn btn-link'], + ) + . '
' . "\n"; + + $phpLink .= '
' + . self::linkOrButton( + Url::getFromRoute('/import', $urlParams), + null, + __('Submit query'), + ['class' => 'btn btn-link'], + ) + . '
' . "\n"; + } else { + $phpParams = $urlParams; + $phpParams['show_as_php'] = 1; + $phpLink = '
' + . self::linkOrButton( + Url::getFromRoute('/import', $phpParams), + null, + __('Create PHP code'), + ['class' => 'btn btn-link'], + ) + . '
' . "\n"; + } + } else { + $phpLink = ''; + } + + // Refresh query + if ( + ! empty($GLOBALS['cfg']['SQLQuery']['Refresh']) + && ! isset($GLOBALS['show_as_php']) // 'Submit query' does the same + && preg_match('@^(SELECT|SHOW)[[:space:]]+@i', $sqlQuery) + ) { + $refreshLink = Url::getFromRoute('/sql', $urlParams); + $refreshLink = '
' + . self::linkOrButton( + $refreshLink, + null, + __('Refresh'), + ['class' => 'btn btn-link'], + ) . '
' . "\n"; + } else { + $refreshLink = ''; + } + + $retval .= '
'; + $retval .= $queryBase; + $retval .= '
' . "\n"; + + $retval .= ''; + + $retval .= '
'; + return $retval; } @@ -1105,7 +1117,7 @@ class Generator $sqlQuery = mb_substr($sqlQuery, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]'; } - return '
' . "\n"
+        return '
' . "\n"
             . htmlspecialchars($sqlQuery, ENT_COMPAT) . "\n"
             . '
'; } diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 6769c60382..b44b33871a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -7399,7 +7399,6 @@ - @@ -7407,7 +7406,6 @@ - $alt $defaultFunction diff --git a/public/themes/bootstrap/scss/_common.scss b/public/themes/bootstrap/scss/_common.scss index 4234bb6d01..3c8b568279 100644 --- a/public/themes/bootstrap/scss/_common.scss +++ b/public/themes/bootstrap/scss/_common.scss @@ -71,23 +71,6 @@ textarea { text-shadow: 0 1px 0 $black; } -div.tools { - padding: 0.2em; - - a { - color: #3a7ead !important; - } - - margin-top: 0; - margin-bottom: 0.5em; - // avoid a thick line since this should be used under another fieldset - border-top: 0; - text-align: right; - float: none; - clear: both; - border-radius: 0 0 4px 4px; -} - .pma-fieldset.tblFooters { margin-top: 0; margin-bottom: 0.5em; @@ -267,7 +250,6 @@ td .icon { background: #d3dce3; } -div.tools, .tblFooters { font-weight: normal; color: $black; @@ -282,14 +264,6 @@ div.tools, } } -div.tools a { - &:link, - &:visited, - &:active { - color: #00f; - } -} - .tblFooters a { &:link, &:active, @@ -299,7 +273,6 @@ div.tools a { } .tblHeaders a:hover, -div.tools a:hover, .tblFooters a:hover { color: #f00; } @@ -829,30 +802,6 @@ textarea { float: left; } -code { - font-size: 1em; - - &.php { - display: block; - padding-left: 1em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } - - &.sql { - display: block; - padding: 1em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } -} - div.sqlvalidate { display: block; padding: 1em; @@ -863,13 +812,6 @@ div.sqlvalidate { direction: ltr; } -.result_query { - div.sqlOuter { - background: #e5e5e5; - text-align: left; - } -} - #PMA_slidingMessage code.sql, div.sqlvalidate { background: #e5e5e5; @@ -2715,10 +2657,6 @@ body .ui-dialog { // Extra large devices (large desktops, 1200px and up) @include media-breakpoint-up(xl) { - div.tools { - text-align: left; - } - .pma-fieldset.tblFooters, .tblFooters { text-align: left; diff --git a/public/themes/bootstrap/scss/_print.scss b/public/themes/bootstrap/scss/_print.scss index a2b47f33e7..c03129ef8c 100644 --- a/public/themes/bootstrap/scss/_print.scss +++ b/public/themes/bootstrap/scss/_print.scss @@ -63,11 +63,6 @@ float: none; } - .sqlOuter { - color: black; - background-color: #000; - } - // For hiding 'Open a New phpMyAdmin Window' button // Hide extra menu on /table/structure .cDrop, diff --git a/public/themes/metro/scss/_common.scss b/public/themes/metro/scss/_common.scss index 5fbe0de820..05fdfc6c78 100644 --- a/public/themes/metro/scss/_common.scss +++ b/public/themes/metro/scss/_common.scss @@ -382,20 +382,6 @@ select { margin-bottom: 20px; } -div.tools { - padding: 10px; - text-align: right; - - span { - float: right; - margin: 6px 2px; - } - - a { - color: var(--blue-header) !important; - } -} - .pma-fieldset.tblFooters { margin-top: -1px; border-top: 0; @@ -589,7 +575,6 @@ img.lightbulb { font-weight: normal; } -div.tools, .tblFooters { font-weight: normal; color: $th-color; @@ -597,7 +582,6 @@ div.tools, } .tblHeaders, -div.tools, .tblFooters { a { &:link, @@ -1089,7 +1073,6 @@ code { } } -.sqlOuter code.sql, div.sqlvalidate, #inline_editor_outer { display: block; @@ -2869,10 +2852,6 @@ body { // Extra large devices (large desktops, 1200px and up) @include media-breakpoint-up(xl) { - div.tools { - text-align: left; - } - .pma-fieldset.tblFooters, .tblFooters { text-align: left; diff --git a/public/themes/original/scss/_common.scss b/public/themes/original/scss/_common.scss index d0e01cd292..485ed2bd8c 100644 --- a/public/themes/original/scss/_common.scss +++ b/public/themes/original/scss/_common.scss @@ -101,19 +101,6 @@ button { padding-top: 1em; } -div.tools { - border: 1px solid #000; - padding: 0.2em; - margin-top: 0; - margin-bottom: 0.5em; - - /* avoid a thick line since this should be used under another fieldset */ - border-top: 0; - text-align: right; - float: none; - clear: both; -} - .pma-fieldset.tblFooters { margin-top: 0; margin-bottom: 0.5em; @@ -297,7 +284,6 @@ label.error { background: $th-background; } -div.tools, .tblFooters { font-weight: normal; color: $th-color; @@ -316,18 +302,6 @@ div.tools, } } -div.tools a { - &:link, - &:visited, - &:active { - color: #00f; - } - - &:hover { - color: #f00; - } -} - .tblFooters a { &:link, &:active, @@ -821,31 +795,6 @@ kbd { box-shadow: none; } -code { - font-size: 1em; - color: $main-color; - - &.php { - display: block; - padding-left: 0.3em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } - - &.sql { - display: block; - padding: 0.3em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } -} - div.sqlvalidate { display: block; padding: 0.3em; @@ -864,10 +813,6 @@ div.sqlvalidate { background: $bg-one; } -.result_query div.sqlOuter { - text-align: left; -} - #PMA_slidingMessage code.sql { border: $main-color solid 1px; border-top: 0; @@ -2715,10 +2660,6 @@ body { // Extra large devices (large desktops, 1200px and up) @include media-breakpoint-up(xl) { - div.tools { - text-align: left; - } - .pma-fieldset.tblFooters, .tblFooters { text-align: left; diff --git a/public/themes/pmahomme/scss/_common.scss b/public/themes/pmahomme/scss/_common.scss index 65b030bf04..2805dba570 100644 --- a/public/themes/pmahomme/scss/_common.scss +++ b/public/themes/pmahomme/scss/_common.scss @@ -278,23 +278,6 @@ select { text-shadow: 0 1px 0 #000; } -div.tools { - padding: 0.2em; - - a { - color: #3a7ead !important; - } - - margin-top: 0; - margin-bottom: 0.5em; - // avoid a thick line since this should be used under another fieldset - border-top: 0; - text-align: right; - float: none; - clear: both; - border-radius: 0 0 4px 4px; -} - .pma-fieldset.tblFooters { margin-top: 0; margin-bottom: 0.5em; @@ -475,7 +458,6 @@ img.lightbulb { background: $th-background; } -div.tools, .tblFooters { font-weight: normal; color: $th-color; @@ -490,14 +472,6 @@ div.tools, } } -div.tools a { - &:link, - &:visited, - &:active { - color: #00f; - } -} - .tblFooters a { &:link, &:active, @@ -507,7 +481,6 @@ div.tools a { } .tblHeaders a:hover, -div.tools a:hover, .tblFooters a:hover { color: #f00; } @@ -1015,31 +988,6 @@ kbd { box-shadow: none; } -code { - font-size: 1em; - color: $main-color; - - &.php { - display: block; - padding-left: 1em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } - - &.sql { - display: block; - padding: 1em; - margin-top: 0; - margin-bottom: 0; - max-height: 10em; - overflow: auto; - direction: ltr; - } -} - div.sqlvalidate { display: block; padding: 1em; @@ -2843,10 +2791,6 @@ body .ui-dialog { // Extra large devices (large desktops, 1200px and up) @include media-breakpoint-up(xl) { - div.tools { - text-align: left; - } - .pma-fieldset.tblFooters, .tblFooters { text-align: left; diff --git a/test/classes/Controllers/Table/DeleteRowsControllerTest.php b/test/classes/Controllers/Table/DeleteRowsControllerTest.php index 91b15284f8..490b67e604 100644 --- a/test/classes/Controllers/Table/DeleteRowsControllerTest.php +++ b/test/classes/Controllers/Table/DeleteRowsControllerTest.php @@ -59,7 +59,10 @@ class DeleteRowsControllerTest extends AbstractTestCase (new DeleteRowsController($response, new Template(), $dbi))($request); $actual = $response->getHTMLResult(); $this->assertStringContainsString( - '', + '', $actual, ); $this->assertStringContainsString('DELETE FROM `test_table` WHERE `test_table`.`id` = 3 LIMIT 1;', $actual); diff --git a/test/classes/Html/GeneratorTest.php b/test/classes/Html/GeneratorTest.php index e60da79126..fc15da0b21 100644 --- a/test/classes/Html/GeneratorTest.php +++ b/test/classes/Html/GeneratorTest.php @@ -277,7 +277,7 @@ class GeneratorTest extends AbstractTestCase public function testFormatSql(): void { $this->assertEquals( - '
' . "\n"
+            '
' . "\n"
             . 'SELECT 1 < 2' . "\n"
             . '
', Generator::formatSql('SELECT 1 < 2'), @@ -286,7 +286,7 @@ class GeneratorTest extends AbstractTestCase $GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 6; $this->assertEquals( - '
' . "\n"
+            '
' . "\n"
             . 'SELECT[...]' . "\n"
             . '
', Generator::formatSql('SELECT 1 < 2', true), @@ -457,10 +457,31 @@ class GeneratorTest extends AbstractTestCase -
-
+
+
+
 SELECT 1;
-
Edit inline ] [ Edit ] [ Explain SQL ] [ Create PHP code ] [ Refresh ]
+
+
HTML; // phpcs:enable @@ -488,13 +509,24 @@ HTML; // phpcs:disable Generic.Files.LineLength.TooLong $expected = <<<'HTML' -
-
+
+
 $sql = "EXPLAIN SELECT 1;";
-
+
+
HTML; // phpcs:enable diff --git a/test/classes/Plugins/Transformations/TransformationPluginsTest.php b/test/classes/Plugins/Transformations/TransformationPluginsTest.php index de4e25b86f..361ba5150f 100644 --- a/test/classes/Plugins/Transformations/TransformationPluginsTest.php +++ b/test/classes/Plugins/Transformations/TransformationPluginsTest.php @@ -523,7 +523,7 @@ class TransformationPluginsTest extends AbstractTestCase [ new Text_Plain_Sql(), ['select *', ['option1', 'option2']], - '
' . "\n"
+                '
' . "\n"
                 . 'select *' . "\n"
                 . '
', ],