Merge pull request #18439 from MauricioFauth/stmt-message-box

Redesign the SQL message card
This commit is contained in:
Maurício Meneghini Fauth 2023-05-18 18:04:42 -03:00 committed by GitHub
commit 15ab473ec6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 258 additions and 416 deletions

View File

@ -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 = '<textarea name="sql_query_edit" id="sql_query_edit">' + escapeHtml(sqlQuery) + '</textarea>\n';
newContent += Functions.getForeignKeyCheckboxLoader();

View File

@ -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 .= '<div class="result_query">' . "\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 .= '<div class="alert alert-' . $context . '" role="alert">';
$retval .= Sanitize::sanitizeMessage($message);
if (isset($GLOBALS['special_message'])) {
$retval .= Sanitize::sanitizeMessage($GLOBALS['special_message']);
unset($GLOBALS['special_message']);
}
$retval .= '</div>';
$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 .= '<div class="card result_query">' . "\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"<br>' . "\n" . '&nbsp;&nbsp;&nbsp;&nbsp;. "';
$queryBase = htmlspecialchars(addslashes($queryBase));
$queryBase = preg_replace('/((\015\012)|(\015)|(\012))/', $newLine, $queryBase);
$queryBase = '<code class="php" dir="ltr"><pre>' . "\n"
. '$sql = "' . $queryBase . '";' . "\n"
. '</pre></code>';
} elseif ($queryTooBig) {
$queryBase = '<code class="sql" dir="ltr"><pre>' . "\n"
. htmlspecialchars($queryBase, ENT_COMPAT) . '</pre></code>';
} 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"<br>' . "\n" . '&nbsp;&nbsp;&nbsp;&nbsp;. "';
$queryBase = htmlspecialchars(addslashes($queryBase));
$queryBase = preg_replace('/((\015\012)|(\015)|(\012))/', $newLine, $queryBase);
$queryBase = '<code class="php"><pre>' . "\n"
. '$sql = "' . $queryBase . '";' . "\n"
. '</pre></code>';
} elseif ($queryTooBig) {
$queryBase = '<code class="sql"><pre>' . "\n"
. htmlspecialchars($queryBase, ENT_COMPAT) . '</pre></code>';
} 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 = ' [&nbsp;'
. self::linkOrButton(
Url::getFromRoute('/import', $explainParams),
null,
__('Explain SQL'),
) . '&nbsp;]';
} elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sqlQuery)) {
$explainParams['sql_query'] = mb_substr($sqlQuery, 8);
$explainLink = ' [&nbsp;'
. 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 = ' [&nbsp;'
. self::linkOrButton(Url::getFromRoute($editLinkRoute, $urlParams), null, __('Edit'))
. '&nbsp;]';
} 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 = ' [&nbsp;'
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Without PHP code'),
)
. '&nbsp;]';
$phpLink .= ' [&nbsp;'
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Submit query'),
)
. '&nbsp;]';
} else {
$phpParams = $urlParams;
$phpParams['show_as_php'] = 1;
$phpLink = ' [&nbsp;'
. self::linkOrButton(
Url::getFromRoute('/import', $phpParams),
null,
__('Create PHP code'),
)
. '&nbsp;]';
}
} 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 = ' [&nbsp;'
. self::linkOrButton($refreshLink, null, __('Refresh')) . '&nbsp;]';
} else {
$refreshLink = '';
}
$retval .= '<div class="sqlOuter">';
$retval .= $queryBase;
$retval .= '</div>';
$retval .= '<div class="tools d-print-none">';
$retval .= '<form action="' . Url::getFromRoute('/sql') . '" method="post">';
$retval .= Url::getHiddenInputs($GLOBALS['db'], $GLOBALS['table']);
$retval .= '<input type="hidden" name="sql_query" value="'
. htmlspecialchars($sqlQuery) . '">';
// avoid displaying a Profiling checkbox that could
// be checked, which would re-execute an INSERT, for example
if ($refreshLink !== '' && Profiling::isSupported($GLOBALS['dbi'])) {
$retval .= '<input type="hidden" name="profiling_form" value="1">';
$retval .= '<input type="checkbox" name="profiling" id="profilingCheckbox" class="autosubmit"';
$retval .= isset($_SESSION['profiling']) ? ' checked' : '';
$retval .= '> <label for="profilingCheckbox">' . __('Profiling') . '</label>';
}
$retval .= '</form>';
/**
* TODO: Should we have $cfg['SQLQuery']['InlineEdit']?
*/
if (! empty($GLOBALS['cfg']['SQLQuery']['Edit']) && ! $queryTooBig && empty($GLOBALS['show_as_php'])) {
$inlineEditLink = ' [&nbsp;'
// 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 = '<div class="col-auto">'
. self::linkOrButton(
'#',
Url::getFromRoute('/import', $explainParams),
null,
_pgettext('Inline edit query', 'Edit inline'),
['class' => 'inline_edit_sql'],
)
. '&nbsp;]';
} else {
$inlineEditLink = '';
__('Explain SQL'),
['class' => 'btn btn-link'],
) . '</div>' . "\n";
} elseif (preg_match('@^EXPLAIN[[:space:]]+SELECT[[:space:]]+@i', $sqlQuery)) {
$explainParams['sql_query'] = mb_substr($sqlQuery, 8);
$explainLink = '<div class="col-auto">'
. self::linkOrButton(
Url::getFromRoute('/import', $explainParams),
null,
__('Skip Explain SQL'),
['class' => 'btn btn-link'],
) . '</div>' . "\n";
}
$retval .= $inlineEditLink . $editLink . $explainLink . $phpLink
. $refreshLink;
$retval .= '</div>';
$retval .= '</div>';
}
$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 = '<div class="col-auto">'
. self::linkOrButton(
Url::getFromRoute($editLinkRoute, $urlParams),
null,
__('Edit'),
['class' => 'btn btn-link'],
)
. '</div>' . "\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 = '<div class="col-auto">'
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Without PHP code'),
['class' => 'btn btn-link'],
)
. '</div>' . "\n";
$phpLink .= '<div class="col-auto">'
. self::linkOrButton(
Url::getFromRoute('/import', $urlParams),
null,
__('Submit query'),
['class' => 'btn btn-link'],
)
. '</div>' . "\n";
} else {
$phpParams = $urlParams;
$phpParams['show_as_php'] = 1;
$phpLink = '<div class="col-auto">'
. self::linkOrButton(
Url::getFromRoute('/import', $phpParams),
null,
__('Create PHP code'),
['class' => 'btn btn-link'],
)
. '</div>' . "\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 = '<div class="col-auto">'
. self::linkOrButton(
$refreshLink,
null,
__('Refresh'),
['class' => 'btn btn-link'],
) . '</div>' . "\n";
} else {
$refreshLink = '';
}
$retval .= '<div class="card-body sqlOuter">';
$retval .= $queryBase;
$retval .= '</div>' . "\n";
$retval .= '<div class="card-footer tools d-print-none">' . "\n";
$retval .= '<div class="row align-items-center">' . "\n";
$retval .= '<div class="col-auto">' . "\n";
$retval .= '<form action="' . Url::getFromRoute('/sql') . '" method="post">' . "\n";
$retval .= Url::getHiddenInputs($GLOBALS['db'], $GLOBALS['table']) . "\n";
$retval .= '<input type="hidden" name="sql_query" value="'
. htmlspecialchars($sqlQuery) . '">' . "\n";
// avoid displaying a Profiling checkbox that could
// be checked, which would re-execute an INSERT, for example
if ($refreshLink !== '' && Profiling::isSupported($GLOBALS['dbi'])) {
$retval .= '<input type="hidden" name="profiling_form" value="1">' . "\n";
$retval .= '<div class="form-check form-switch">' . "\n";
$retval .= '<input type="checkbox" name="profiling" id="profilingCheckbox" role="switch"';
$retval .= ' class="form-check-input autosubmit"';
$retval .= isset($_SESSION['profiling']) ? ' checked>' . "\n" : '>' . "\n";
$retval .= '<label class="form-check-label" for="profilingCheckbox">' . __('Profiling') . '</label>' . "\n";
$retval .= '</div>' . "\n";
}
$retval .= '</form></div>' . "\n";
/**
* TODO: Should we have $cfg['SQLQuery']['InlineEdit']?
*/
if (! empty($GLOBALS['cfg']['SQLQuery']['Edit']) && ! $queryTooBig && empty($GLOBALS['show_as_php'])) {
$inlineEditLink = '<div class="col-auto">'
. self::linkOrButton(
'#',
null,
_pgettext('Inline edit query', 'Edit inline'),
['class' => 'btn btn-link inline_edit_sql'],
)
. '</div>' . "\n";
} else {
$inlineEditLink = '';
}
$retval .= $inlineEditLink . $editLink . $explainLink . $phpLink
. $refreshLink;
$retval .= '</div></div>';
$retval .= '</div>';
return $retval;
}
@ -1105,7 +1117,7 @@ class Generator
$sqlQuery = mb_substr($sqlQuery, 0, $GLOBALS['cfg']['MaxCharactersInDisplayedSQL']) . '[...]';
}
return '<code class="sql"><pre>' . "\n"
return '<code class="sql" dir="ltr"><pre>' . "\n"
. htmlspecialchars($sqlQuery, ENT_COMPAT) . "\n"
. '</pre></code>';
}

View File

@ -7399,7 +7399,6 @@
<code><![CDATA[$GLOBALS['cfg']['SQLQuery']]]></code>
<code><![CDATA[$GLOBALS['show_as_php']]]></code>
<code><![CDATA[$GLOBALS['special_message']]]></code>
<code><![CDATA[$GLOBALS['special_message']]]></code>
<code><![CDATA[$GLOBALS['using_bookmark_message']]]></code>
<code><![CDATA[$server['socket']]]></code>
<code><![CDATA[$server['ssl']]]></code>
@ -7407,7 +7406,6 @@
<code><![CDATA[$server['ssl_verify']]]></code>
</InvalidArrayOffset>
<MixedArgument>
<code><![CDATA[$GLOBALS['special_message']]]></code>
<code><![CDATA[$GLOBALS['special_message']]]></code>
<code>$alt</code>
<code>$defaultFunction</code>

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -59,7 +59,10 @@ class DeleteRowsControllerTest extends AbstractTestCase
(new DeleteRowsController($response, new Template(), $dbi))($request);
$actual = $response->getHTMLResult();
$this->assertStringContainsString(
'<div class="alert alert-success" role="alert">Your SQL query has been executed successfully.</div>',
'<div class="alert alert-success" role="alert">' . "\n"
. ' <img src="themes/dot.gif" title="" alt="" class="icon ic_s_success">'
. ' Your SQL query has been executed successfully.' . "\n"
. '</div>',
$actual,
);
$this->assertStringContainsString('DELETE FROM `test_table` WHERE `test_table`.`id` = 3 LIMIT 1;', $actual);

View File

@ -277,7 +277,7 @@ class GeneratorTest extends AbstractTestCase
public function testFormatSql(): void
{
$this->assertEquals(
'<code class="sql"><pre>' . "\n"
'<code class="sql" dir="ltr"><pre>' . "\n"
. 'SELECT 1 &lt; 2' . "\n"
. '</pre></code>',
Generator::formatSql('SELECT 1 < 2'),
@ -286,7 +286,7 @@ class GeneratorTest extends AbstractTestCase
$GLOBALS['cfg']['MaxCharactersInDisplayedSQL'] = 6;
$this->assertEquals(
'<code class="sql"><pre>' . "\n"
'<code class="sql" dir="ltr"><pre>' . "\n"
. 'SELECT[...]' . "\n"
. '</pre></code>',
Generator::formatSql('SELECT 1 < 2', true),
@ -457,10 +457,31 @@ class GeneratorTest extends AbstractTestCase
<div class="alert alert-primary" role="alert">
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_notice"> Bookmark message
</div>
<div class="result_query">
<div class="alert alert-primary" role="alert">Message <em>one</em>.Message <em>two</em>.</div><div class="sqlOuter"><code class="sql"><pre>
<div class="alert alert-primary" role="alert">
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_notice"> Message <em>one</em>. Message <em>two</em>.
</div>
<div class="card result_query">
<div class="card-body sqlOuter"><code class="sql" dir="ltr"><pre>
SELECT 1;
</pre></code></div><div class="tools d-print-none"><form action="index.php?route=/sql&server=2&lang=en" method="post"><input type="hidden" name="db" value="test_db"><input type="hidden" name="table" value="test_table"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token"><input type="hidden" name="sql_query" value="SELECT 1;"><input type="hidden" name="profiling_form" value="1"><input type="checkbox" name="profiling" id="profilingCheckbox" class="autosubmit"> <label for="profilingCheckbox">Profiling</label></form> [&nbsp;<a href="#" class="inline_edit_sql">Edit inline</a>&nbsp;] [&nbsp;<a href="index.php" data-post="route=/table/sql&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&server=2&lang=en">Edit</a>&nbsp;] [&nbsp;<a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&server=2&lang=en">Explain SQL</a>&nbsp;] [&nbsp;<a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&show_as_php=1&server=2&lang=en">Create PHP code</a>&nbsp;] [&nbsp;<a href="index.php" data-post="route=/sql&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&server=2&lang=en">Refresh</a>&nbsp;]</div></div>
</pre></code></div>
<div class="card-footer tools d-print-none">
<div class="row align-items-center">
<div class="col-auto">
<form action="index.php?route=/sql&server=2&lang=en" method="post">
<input type="hidden" name="db" value="test_db"><input type="hidden" name="table" value="test_table"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token">
<input type="hidden" name="sql_query" value="SELECT 1;">
<input type="hidden" name="profiling_form" value="1">
<div class="form-check form-switch">
<input type="checkbox" name="profiling" id="profilingCheckbox" role="switch" class="form-check-input autosubmit">
<label class="form-check-label" for="profilingCheckbox">Profiling</label>
</div>
</form></div>
<div class="col-auto"><a href="#" class="btn btn-link inline_edit_sql">Edit inline</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/table/sql&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&server=2&lang=en" class="btn btn-link">Edit</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&server=2&lang=en" class="btn btn-link">Explain SQL</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&show_as_php=1&server=2&lang=en" class="btn btn-link">Create PHP code</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/sql&db=test_db&table=test_table&sql_query=SELECT+1%3B&show_query=1&server=2&lang=en" class="btn btn-link">Refresh</a></div>
</div></div></div>
HTML;
// phpcs:enable
@ -488,13 +509,24 @@ HTML;
// phpcs:disable Generic.Files.LineLength.TooLong
$expected = <<<'HTML'
<div class="result_query">
<div class="alert alert-success" role="alert">
<img src="themes/dot.gif" title="" alt="" class="icon ic_s_success"> Message <em>one</em>. Message <em>two</em>.
</div>
<div class="sqlOuter"><code class="php"><pre>
<div class="card result_query">
<div class="card-body sqlOuter"><code class="php" dir="ltr"><pre>
$sql = "EXPLAIN SELECT 1;";
</pre></code></div><div class="tools d-print-none"><form action="index.php?route=/sql&server=2&lang=en" method="post"><input type="hidden" name="db" value="test_db"><input type="hidden" name="table" value="test_table"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token"><input type="hidden" name="sql_query" value="EXPLAIN SELECT 1;"></form> [&nbsp;<a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=SELECT+1%3B&server=2&lang=en">Skip Explain SQL</a>] [&nbsp;<a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&show_query=1&server=2&lang=en">Without PHP code</a>&nbsp;] [&nbsp;<a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&show_query=1&server=2&lang=en">Submit query</a>&nbsp;]</div></div>
</pre></code></div>
<div class="card-footer tools d-print-none">
<div class="row align-items-center">
<div class="col-auto">
<form action="index.php?route=/sql&server=2&lang=en" method="post">
<input type="hidden" name="db" value="test_db"><input type="hidden" name="table" value="test_table"><input type="hidden" name="server" value="2"><input type="hidden" name="lang" value="en"><input type="hidden" name="token" value="token">
<input type="hidden" name="sql_query" value="EXPLAIN SELECT 1;">
</form></div>
<div class="col-auto"><a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=SELECT+1%3B&server=2&lang=en" class="btn btn-link">Skip Explain SQL</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&show_query=1&server=2&lang=en" class="btn btn-link">Without PHP code</a></div>
<div class="col-auto"><a href="index.php" data-post="route=/import&db=test_db&table=test_table&sql_query=EXPLAIN+SELECT+1%3B&show_query=1&server=2&lang=en" class="btn btn-link">Submit query</a></div>
</div></div></div>
HTML;
// phpcs:enable

View File

@ -523,7 +523,7 @@ class TransformationPluginsTest extends AbstractTestCase
[
new Text_Plain_Sql(),
['select *', ['option1', 'option2']],
'<code class="sql"><pre>' . "\n"
'<code class="sql" dir="ltr"><pre>' . "\n"
. 'select *' . "\n"
. '</pre></code>',
],