Merge pull request #20022 from MauricioFauth/sql-request

Replace request globals with ServerRequest object in Sql and Display\Results classes
This commit is contained in:
Maurício Meneghini Fauth 2026-01-15 15:55:52 -03:00 committed by GitHub
commit 547e4d87dc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 133 additions and 145 deletions

View File

@ -12231,13 +12231,13 @@ parameters:
-
message: '#^Cannot cast mixed to int\.$#'
identifier: cast.int
count: 1
count: 3
path: src/Sql.php
-
message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#'
identifier: empty.notAllowed
count: 10
count: 4
path: src/Sql.php
-
@ -12264,12 +12264,6 @@ parameters:
count: 1
path: src/Sql.php
-
message: '#^Only booleans are allowed in &&, mixed given on the right side\.$#'
identifier: booleanAnd.rightNotBoolean
count: 3
path: src/Sql.php
-
message: '#^Only booleans are allowed in &&, string given on the left side\.$#'
identifier: booleanAnd.leftNotBoolean
@ -12295,14 +12289,14 @@ parameters:
path: src/Sql.php
-
message: '#^Only booleans are allowed in a negated boolean, mixed given\.$#'
identifier: booleanNot.exprNotBoolean
message: '#^Only booleans are allowed in an if condition, PhpMyAdmin\\Dbal\\ResultInterface\|false given\.$#'
identifier: if.condNotBoolean
count: 1
path: src/Sql.php
-
message: '#^Only booleans are allowed in an if condition, PhpMyAdmin\\Dbal\\ResultInterface\|false given\.$#'
identifier: if.condNotBoolean
message: '#^Parameter \#1 \$label of method PhpMyAdmin\\Sql\:\:getBookmarkCreatedMessage\(\) expects string\|null, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Sql.php
@ -12348,24 +12342,12 @@ parameters:
count: 2
path: src/Sql.php
-
message: '#^Parameter \#3 \$column of method PhpMyAdmin\\Sql\:\:cleanupRelations\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Sql.php
-
message: '#^Parameter \#3 \$subject of function str_replace expects array\<string\>\|string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Sql.php
-
message: '#^Parameter \#4 \$bookmarkLabel of method PhpMyAdmin\\Sql\:\:storeTheQueryAsBookmark\(\) expects string, mixed given\.$#'
identifier: argument.type
count: 1
path: src/Sql.php
-
message: '''
#^Call to deprecated method getInstance\(\) of class PhpMyAdmin\\Config\:

View File

@ -3848,13 +3848,18 @@
<code><![CDATA[$expr]]></code>
<code><![CDATA[$expr]]></code>
<code><![CDATA[$field]]></code>
<code><![CDATA[$geoOption]]></code>
<code><![CDATA[$hiddenFields['session_max_rows']]]></code>
<code><![CDATA[$i]]></code>
<code><![CDATA[$i]]></code>
<code><![CDATA[$identifier]]></code>
<code><![CDATA[$meta->name]]></code>
<code><![CDATA[$pftext]]></code>
<code><![CDATA[$pos]]></code>
<code><![CDATA[$query]]></code>
<code><![CDATA[$relationalDisplay]]></code>
<code><![CDATA[$relationalDisplay]]></code>
<code><![CDATA[$sessionMaxRows]]></code>
<code><![CDATA[$value]]></code>
</MixedAssignment>
<MixedOperand>
@ -8004,6 +8009,7 @@
</InvalidNullableReturnType>
<MixedArgument>
<code><![CDATA[$numberOfLine / $maxRows]]></code>
<code><![CDATA[$request->getQueryParam('label')]]></code>
<code><![CDATA[$sortCol]]></code>
</MixedArgument>
<MixedArrayAccess>
@ -8046,17 +8052,11 @@
<code><![CDATA[$row[$column]]]></code>
</NullableReturnStatement>
<PossiblyInvalidArgument>
<code><![CDATA[$_POST['bkm_label']]]></code>
<code><![CDATA[$_POST['dropped_column'] ?? '']]></code>
<code><![CDATA[$numRows]]></code>
<code><![CDATA[$numRows]]></code>
<code><![CDATA[$numRows]]></code>
<code><![CDATA[$numRows]]></code>
</PossiblyInvalidArgument>
<PossiblyInvalidCast>
<code><![CDATA[$_POST['bkm_label']]]></code>
<code><![CDATA[$_POST['dropped_column'] ?? '']]></code>
</PossiblyInvalidCast>
<PossiblyInvalidOperand>
<code><![CDATA[$numRows]]></code>
<code><![CDATA[$sortCol]]></code>
@ -8081,16 +8081,7 @@
</RedundantCondition>
<RiskyTruthyFalsyComparison>
<code><![CDATA[! $index->isUnique()]]></code>
<code><![CDATA[$_POST['grid_edit']]]></code>
<code><![CDATA[$_POST['printview']]]></code>
<code><![CDATA[$_POST['printview']]]></code>
<code><![CDATA[$table]]></code>
<code><![CDATA[empty($_GET['id_bookmark'])]]></code>
<code><![CDATA[empty($_GET['id_bookmark'])]]></code>
<code><![CDATA[empty($_POST['bkm_label'])]]></code>
<code><![CDATA[empty($_POST['is_browse_distinct'])]]></code>
<code><![CDATA[empty($_POST['purge'])]]></code>
<code><![CDATA[empty($_REQUEST['ajax_page_request'])]]></code>
<code><![CDATA[empty($statement->altered[0]->field->column)]]></code>
</RiskyTruthyFalsyComparison>
</file>
@ -10185,7 +10176,6 @@
<code><![CDATA[testSetConfigParamsForDisplayTable]]></code>
<code><![CDATA[testSetConfigParamsForDisplayTable]]></code>
<code><![CDATA[testSetConfigParamsForDisplayTable]]></code>
<code><![CDATA[testSetConfigParamsForDisplayTable]]></code>
</PossiblyInvalidArgument>
<PropertyTypeCoercion>
<code><![CDATA[$config->settings]]></code>

View File

@ -32,6 +32,7 @@ final class QueryController implements InvocableController
$goto = Url::getFromRoute('/database/multi-table-query');
$this->response->addHTML($this->sql->executeQueryAndSendQueryResponse(
$request,
null,
false, // is_gotofile
$db, // db

View File

@ -632,6 +632,7 @@ final readonly class ImportController implements InvocableController
}
$htmlOutput .= $this->sql->executeQueryAndGetQueryResponse(
$request,
$statementInfo,
false, // is_gotofile
Current::$database, // db
@ -656,6 +657,7 @@ final readonly class ImportController implements InvocableController
$request->getParsedBodyParamAsString('sql_query'),
$request->getParsedBodyParamAsString('bkm_label'),
$request->hasBodyParam('bkm_replace'),
$request->hasBodyParam('bkm_all_users'),
);
}
@ -683,6 +685,7 @@ final readonly class ImportController implements InvocableController
$request->getParsedBodyParamAsString('sql_query'),
$request->getParsedBodyParamAsString('bkm_label'),
$request->hasBodyParam('bkm_replace'),
$request->hasBodyParam('bkm_all_users'),
);
}

View File

@ -29,10 +29,11 @@ final class RelationalValuesController implements InvocableController
$column = $request->getParsedBodyParamAsString('column', '');
$relationKeyOrDisplayColumn = $request->getParsedBodyParamAsStringOrNull('relation_key_or_display_column');
$currentValueParam = $request->getParsedBodyParamAsString('curr_value', '');
if ($_SESSION['tmpval']['relational_display'] === 'D' && $relationKeyOrDisplayColumn !== null) {
$currValue = $relationKeyOrDisplayColumn;
} else {
$currValue = $request->getParsedBodyParamAsString('curr_value', '');
$currValue = $currentValueParam;
}
$dropdown = $this->sql->getHtmlForRelationalColumnDropdown(
@ -40,6 +41,7 @@ final class RelationalValuesController implements InvocableController
Current::$table,
$column,
$currValue,
$currentValueParam,
);
$this->response->addJSON('dropdown', $dropdown);

View File

@ -164,6 +164,7 @@ readonly class SqlController implements InvocableController
Current::$messageToShow = $request->getParsedBodyParamAsString('message_to_show', '');
$this->response->addHTML($this->sql->executeQueryAndSendQueryResponse(
$request,
$statementInfo,
$isGotofile,
Current::$database,

View File

@ -66,6 +66,7 @@ final readonly class DeleteRowsController implements InvocableController
}
$this->response->addHTML($this->sql->executeQueryAndSendQueryResponse(
$request,
null,
false,
Current::$database,

View File

@ -211,7 +211,7 @@ final class SearchController implements InvocableController
if (! isset($_POST['columnsToDisplay']) && ! isset($_POST['displayAllColumns'])) {
$this->displaySelectionFormAction();
} else {
$this->doSelectionAction();
$this->doSelectionAction($request);
}
return $this->response->response();
@ -220,7 +220,7 @@ final class SearchController implements InvocableController
/**
* Do selection action
*/
private function doSelectionAction(): void
private function doSelectionAction(ServerRequest $request): void
{
/**
* Selection criteria have been submitted -> do the work
@ -231,6 +231,7 @@ final class SearchController implements InvocableController
* Add this to ensure following procedures included running correctly.
*/
$this->response->addHTML($this->sql->executeQueryAndSendQueryResponse(
$request,
null,
false, // is_gotofile
Current::$database, // db

View File

@ -35,7 +35,7 @@ final class BrowseController implements InvocableController
return $this->response->response();
}
$this->displayTableBrowseForSelectedColumns(UrlParams::$goto);
$this->displayTableBrowseForSelectedColumns($request, UrlParams::$goto);
return $this->response->response();
}
@ -45,7 +45,7 @@ final class BrowseController implements InvocableController
*
* @param string $goto goto page url
*/
private function displayTableBrowseForSelectedColumns(string $goto): void
private function displayTableBrowseForSelectedColumns(ServerRequest $request, string $goto): void
{
$fields = [];
foreach ($_POST['selected_fld'] as $sval) {
@ -64,6 +64,7 @@ final class BrowseController implements InvocableController
$this->response->addHTML(
$this->sql->executeQueryAndGetQueryResponse(
$request,
$statementInfo,
false, // is_gotofile
Current::$database, // db

View File

@ -14,6 +14,7 @@ use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Dbal\ResultInterface;
use PhpMyAdmin\FieldMetadata;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Indexes\Index;
use PhpMyAdmin\Indexes\IndexColumn;
use PhpMyAdmin\Message;
@ -2789,7 +2790,7 @@ class Results
* @todo currently this is called twice unnecessary
* @todo ignore LIMIT and ORDER in query!?
*/
public function setConfigParamsForDisplayTable(StatementInfo $statementInfo): void
public function setConfigParamsForDisplayTable(ServerRequest $request, StatementInfo $statementInfo): void
{
$sqlMd5 = md5($this->server . $this->db . $this->sqlQuery);
$query = $_SESSION['tmpval']['query'][$sqlMd5] ?? [];
@ -2801,21 +2802,19 @@ class Results
}
// The value can also be from _GET as described on issue #16146 when sorting results
$sessionMaxRows = $_GET['session_max_rows'] ?? $_POST['session_max_rows'] ?? '';
$sessionMaxRows = $request->getParam('session_max_rows');
if (is_numeric($sessionMaxRows)) {
$query['max_rows'] = (int) $sessionMaxRows;
unset($_GET['session_max_rows'], $_POST['session_max_rows']);
} elseif ($sessionMaxRows === self::ALL_ROWS) {
$query['max_rows'] = self::ALL_ROWS;
unset($_GET['session_max_rows'], $_POST['session_max_rows']);
} elseif (empty($query['max_rows'])) {
$query['max_rows'] = $this->config->config->maxRows;
}
if (isset($_REQUEST['pos']) && is_numeric($_REQUEST['pos'])) {
$query['pos'] = (int) $_REQUEST['pos'];
unset($_REQUEST['pos']);
$pos = $request->getParam('pos');
if (is_numeric($pos)) {
$query['pos'] = (int) $pos;
} elseif (empty($query['pos'])) {
$query['pos'] = 0;
}
@ -2823,30 +2822,18 @@ class Results
// Full text is needed in case of explain statements, if not specified.
$fullText = $statementInfo->flags->queryType === StatementType::Explain;
if (
isset($_REQUEST['pftext']) && in_array(
$_REQUEST['pftext'],
[self::DISPLAY_PARTIAL_TEXT, self::DISPLAY_FULL_TEXT],
true,
)
) {
$query['pftext'] = $_REQUEST['pftext'];
unset($_REQUEST['pftext']);
$pftext = $request->getParam('pftext');
if (in_array($pftext, [self::DISPLAY_PARTIAL_TEXT, self::DISPLAY_FULL_TEXT], true)) {
$query['pftext'] = $pftext;
} elseif ($fullText) {
$query['pftext'] = self::DISPLAY_FULL_TEXT;
} elseif (empty($query['pftext'])) {
$query['pftext'] = self::DISPLAY_PARTIAL_TEXT;
}
if (
isset($_REQUEST['relational_display']) && in_array(
$_REQUEST['relational_display'],
[self::RELATIONAL_KEY, self::RELATIONAL_DISPLAY_COLUMN],
true,
)
) {
$query['relational_display'] = $_REQUEST['relational_display'];
unset($_REQUEST['relational_display']);
$relationalDisplay = $request->getParam('relational_display');
if (in_array($relationalDisplay, [self::RELATIONAL_KEY, self::RELATIONAL_DISPLAY_COLUMN], true)) {
$query['relational_display'] = $relationalDisplay;
} elseif (empty($query['relational_display'])) {
// The current session value has priority over a
// change via Settings; this change will be apparent
@ -2854,44 +2841,35 @@ class Results
$query['relational_display'] = $this->config->settings['RelationalDisplay'];
}
if (
isset($_REQUEST['geoOption']) && in_array(
$_REQUEST['geoOption'],
[self::GEOMETRY_DISP_WKT, self::GEOMETRY_DISP_WKB, self::GEOMETRY_DISP_GEOM],
true,
)
) {
$query['geoOption'] = $_REQUEST['geoOption'];
unset($_REQUEST['geoOption']);
$geoOption = $request->getParam('geoOption');
if (in_array($geoOption, [self::GEOMETRY_DISP_WKT, self::GEOMETRY_DISP_WKB, self::GEOMETRY_DISP_GEOM], true)) {
$query['geoOption'] = $geoOption;
} elseif (empty($query['geoOption'])) {
$query['geoOption'] = self::GEOMETRY_DISP_GEOM;
}
if (isset($_REQUEST['display_binary'])) {
if ($request->has('display_binary')) {
$query['display_binary'] = true;
unset($_REQUEST['display_binary']);
} elseif (isset($_REQUEST['display_options_form'])) {
} elseif ($request->has('display_options_form')) {
// we know that the checkbox was unchecked
unset($query['display_binary']);
} elseif (! isset($_REQUEST['full_text_button'])) {
} elseif (! $request->has('full_text_button')) {
// selected by default because some operations like OPTIMIZE TABLE
// and all queries involving functions return "binary" contents,
// according to low-level field flags
$query['display_binary'] = true;
}
if (isset($_REQUEST['display_blob'])) {
if ($request->has('display_blob')) {
$query['display_blob'] = true;
unset($_REQUEST['display_blob']);
} elseif (isset($_REQUEST['display_options_form'])) {
} elseif ($request->has('display_options_form')) {
// we know that the checkbox was unchecked
unset($query['display_blob']);
}
if (isset($_REQUEST['hide_transformation'])) {
if ($request->has('hide_transformation')) {
$query['hide_transformation'] = true;
unset($_REQUEST['hide_transformation']);
} elseif (isset($_REQUEST['display_options_form'])) {
} elseif ($request->has('display_options_form')) {
// we know that the checkbox was unchecked
unset($query['hide_transformation']);
}

View File

@ -14,6 +14,7 @@ use PhpMyAdmin\Display\DisplayParts;
use PhpMyAdmin\Display\Results as DisplayResults;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Html\MySQLDocumentation;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Identifiers\DatabaseName;
use PhpMyAdmin\Indexes\Index;
use PhpMyAdmin\Query\Utilities;
@ -235,6 +236,7 @@ class Sql
string $table,
string $column,
string $currentValue,
string $currentValueParam,
): string {
$foreignData = $this->relation->getForeignData(
$this->relation->getForeigners($db, $table, $column),
@ -250,7 +252,7 @@ class Sql
$urlParams = ['db' => $db, 'table' => $table, 'field' => $column];
return $this->template->render('sql/relational_column_dropdown', [
'current_value' => $_POST['curr_value'],
'current_value' => $currentValueParam,
'params' => $urlParams,
]);
}
@ -511,6 +513,7 @@ class Sql
string $sqlQueryForBookmark,
string $bookmarkLabel,
bool $bookmarkReplace,
bool $hasBookmarkAllUsers,
): void {
if ($bookmarkReplace) {
$bookmarks = $this->bookmarkRepository->getList($this->config->selectedServer['user'], $db);
@ -528,7 +531,7 @@ class Sql
$bookmarkLabel,
$bookmarkUser,
$db,
isset($_POST['bkm_all_users']),
$hasBookmarkAllUsers,
);
if ($bookmark === false) {
@ -737,6 +740,7 @@ class Sql
* }
*/
private function executeTheQuery(
ServerRequest $request,
StatementInfo $statementInfo,
string $fullSqlQuery,
bool $isGotoFile,
@ -774,13 +778,15 @@ class Sql
// If there are no errors and bookmarklabel was given,
// store the query as a bookmark
if (! empty($_POST['bkm_label']) && $sqlQueryForBookmark) {
$bookmarkLabel = $request->getParsedBodyParamAsString('bkm_label', '');
if ($bookmarkLabel !== '' && $sqlQueryForBookmark) {
$this->storeTheQueryAsBookmark(
$db,
$this->config->selectedServer['user'],
$sqlQueryForBookmark,
$_POST['bkm_label'],
isset($_POST['bkm_replace']),
$bookmarkLabel,
$request->hasBodyParam('bkm_replace'),
$request->hasBodyParam('bkm_all_users'),
);
}
@ -795,7 +801,12 @@ class Sql
$unlimNumRows = $this->countQueryResults($numRows, $justBrowsing, $db, $table, $statementInfo);
$this->cleanupRelations($db, $table, $_POST['dropped_column'] ?? '', ! empty($_POST['purge']));
$this->cleanupRelations(
$db,
$table,
$request->getParsedBodyParamAsString('dropped_column', ''),
$request->hasBodyParam('purge'),
);
return [$result, $numRows, $unlimNumRows, $profilingResults, $errorMessage];
}
@ -836,6 +847,7 @@ class Sql
string $messageToShow,
StatementInfo $statementInfo,
int|string $numRows,
bool $hasRollbackQuery,
): Message {
if ($statementInfo->flags->queryType === StatementType::Delete) {
$message = Message::getMessageForDeletedRows($numRows);
@ -892,7 +904,7 @@ class Sql
}
// In case of ROLLBACK, notify the user.
if (isset($_POST['rollback_query'])) {
if ($hasRollbackQuery) {
$message->addText(__('[ROLLBACK occurred.]'));
}
@ -916,6 +928,7 @@ class Sql
* @return string html
*/
private function getQueryResponseForNoResultsReturned(
ServerRequest $request,
StatementInfo $statementInfo,
string $db,
string|null $table,
@ -935,7 +948,12 @@ class Sql
if ($errorMessage !== '') {
$message = Message::rawError($errorMessage);
} else {
$message = $this->getMessageForNoRowsReturned($messageToShow, $statementInfo, $numRows);
$message = $this->getMessageForNoRowsReturned(
$messageToShow,
$statementInfo,
$numRows,
$request->hasBodyParam('rollback_query'),
);
}
$queryMessage = Generator::getMessage($message, $sqlQuery, MessageType::Success);
@ -951,7 +969,7 @@ class Sql
}
// For ajax requests add message and sql_query as JSON
if (empty($_REQUEST['ajax_page_request'])) {
if (! $request->has('ajax_page_request')) {
$extraData['message'] = $message;
if ($this->config->settings['ShowSQL']) {
$extraData['sql_query'] = $queryMessage;
@ -959,7 +977,7 @@ class Sql
}
if (
isset($_POST['dropped_column'])
$request->hasBodyParam('dropped_column')
&& $db !== '' && $table !== null && $table !== ''
) {
// to refresh the list of indexes (Ajax mode)
@ -988,6 +1006,7 @@ class Sql
]);
$sqlQueryResultsTable = $this->getHtmlForSqlQueryResultsTable(
$request,
$displayResultsObject,
$displayParts,
false,
@ -1004,7 +1023,7 @@ class Sql
$bookmarkFeature = $this->relation->getRelationParameters()->bookmarkFeature;
if (
$bookmarkFeature !== null
&& empty($_GET['id_bookmark'])
&& (int) $request->getQueryParam('id_bookmark') <= 0
&& $sqlQuery
) {
$bookmark = $this->template->render('sql/bookmark', [
@ -1055,14 +1074,14 @@ class Sql
* Returns a message for successful creation of a bookmark or null if a bookmark
* was not created
*/
private function getBookmarkCreatedMessage(): string
private function getBookmarkCreatedMessage(string|null $label): string
{
$output = '';
if (isset($_GET['label'])) {
if ($label !== null && $label !== '') {
$message = Message::success(
__('Bookmark %s has been created.'),
);
$message->addParam($_GET['label']);
$message->addParam($label);
$output = $message->getDisplay();
}
@ -1082,6 +1101,7 @@ class Sql
* @psalm-param int|numeric-string $numRows
*/
private function getHtmlForSqlQueryResultsTable(
ServerRequest $request,
DisplayResults $displayResultsObject,
DisplayParts $displayParts,
bool $editable,
@ -1091,8 +1111,8 @@ class Sql
StatementInfo $statementInfo,
bool $isLimitedDisplay = false,
): string {
$printView = isset($_POST['printview']) && $_POST['printview'];
$isBrowseDistinct = ! empty($_POST['is_browse_distinct']);
$printView = $request->hasBodyParam('printview');
$isBrowseDistinct = (bool) $request->getParsedBodyParamAsStringOrNull('is_browse_distinct');
if ($statementInfo->flags->isProcedure) {
return $this->getHtmlForStoredProcedureResults(
@ -1257,6 +1277,7 @@ class Sql
* @return string html
*/
private function getQueryResponseForResultsReturned(
ServerRequest $request,
ResultInterface $result,
StatementInfo $statementInfo,
string $db,
@ -1272,7 +1293,7 @@ class Sql
): string {
// If we are retrieving the full value of a truncated field or the original
// value of a transformed field, show it here
if (isset($_POST['grid_edit']) && $_POST['grid_edit']) {
if ($request->hasBodyParam('grid_edit')) {
$this->getResponseForGridEdit($result);
ResponseRenderer::getInstance()->callExit();
}
@ -1342,7 +1363,7 @@ class Sql
]);
}
if (isset($_POST['printview']) && $_POST['printview']) {
if ($request->hasBodyParam('printview')) {
$displayParts = DisplayParts::fromArray([
'hasEditLink' => false,
'deleteLink' => DeleteLinkEnum::NO_DELETE,
@ -1352,9 +1373,7 @@ class Sql
'hasTextButton' => false,
'hasPrintLink' => false,
]);
}
if (! isset($_POST['printview']) || ! $_POST['printview']) {
} else {
$scripts->addFile('makegrid.js');
$scripts->addFile('sql.js');
Current::$message = null;
@ -1372,9 +1391,10 @@ class Sql
? $this->getMessageIfMissingColumnIndex($db, $editable, $hasUnique)
: '';
$bookmarkCreatedMessage = $this->getBookmarkCreatedMessage();
$bookmarkCreatedMessage = $this->getBookmarkCreatedMessage($request->getQueryParam('label'));
$tableHtml = $this->getHtmlForSqlQueryResultsTable(
$request,
$displayResultsObject,
$displayParts,
$editable,
@ -1389,7 +1409,7 @@ class Sql
if (
$bookmarkFeature !== null
&& $displayParts->hasBookmarkForm
&& empty($_GET['id_bookmark'])
&& (int) $request->getQueryParam('id_bookmark') <= 0
&& $sqlQuery
) {
$bookmarkSupportHtml = $this->template->render('sql/bookmark', [
@ -1430,6 +1450,7 @@ class Sql
* @param string $completeQuery complete query
*/
public function executeQueryAndSendQueryResponse(
ServerRequest $request,
StatementInfo|null $statementInfo,
bool $isGotoFile,
string $db,
@ -1450,6 +1471,7 @@ class Sql
}
return $this->executeQueryAndGetQueryResponse(
$request,
$statementInfo,
$isGotoFile, // is_gotofile
$db, // db
@ -1481,6 +1503,7 @@ class Sql
* @return string html
*/
public function executeQueryAndGetQueryResponse(
ServerRequest $request,
StatementInfo $statementInfo,
bool $isGotoFile,
string $db,
@ -1501,7 +1524,7 @@ class Sql
if (
$this->isRememberSortingOrder($statementInfo)
&& ! $statementInfo->flags->union
&& ! isset($_POST['sort_by_key'])
&& ! $request->hasBodyParam('sort_by_key')
) {
if (! isset($_SESSION['sql_from_query_box'])) {
$statementInfo = $this->handleSortOrder($db, $table ?? '', $statementInfo, $sqlQuery);
@ -1519,7 +1542,7 @@ class Sql
$goto,
$sqlQuery,
);
$displayResultsObject->setConfigParamsForDisplayTable($statementInfo);
$displayResultsObject->setConfigParamsForDisplayTable($request, $statementInfo);
// assign default full_sql_query
$fullSqlQuery = $sqlQuery;
@ -1540,7 +1563,12 @@ class Sql
$this->deleteTransformationInfo($db, $table ?? '', $statementInfo);
}
$message = $this->getMessageForNoRowsReturned($messageToShow, $statementInfo, 0);
$message = $this->getMessageForNoRowsReturned(
$messageToShow,
$statementInfo,
0,
$request->hasBodyParam('rollback_query'),
);
return Generator::getMessage($message, Current::$sqlQuery, MessageType::Success);
}
@ -1549,6 +1577,7 @@ class Sql
$defaultFkCheck = ForeignKey::handleDisableCheckInit();
[$result, $numRows, $unlimNumRows, $profilingResults, $errorMessage] = $this->executeTheQuery(
$request,
$statementInfo,
$fullSqlQuery,
$isGotoFile,
@ -1562,6 +1591,7 @@ class Sql
// No rows returned -> move back to the calling page
if (($numRows === 0 && $unlimNumRows === 0) || $statementInfo->flags->isAffected || $result === false) {
$htmlOutput = $this->getQueryResponseForNoResultsReturned(
$request,
$statementInfo,
$db,
$table,
@ -1577,6 +1607,7 @@ class Sql
} else {
// At least one row is returned -> displays a table with results
$htmlOutput = $this->getQueryResponseForResultsReturned(
$request,
$result,
$statementInfo,
$db,

View File

@ -11,7 +11,7 @@ use PhpMyAdmin\ConfigStorage\RelationCleanup;
use PhpMyAdmin\Controllers\Import\ImportController;
use PhpMyAdmin\Current;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Http\ServerRequest;
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
use PhpMyAdmin\Import\Import;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Template;
@ -52,19 +52,12 @@ class ImportControllerTest extends AbstractTestCase
. 'FROM table1 A' . "\n"
. 'WHERE A.nomEtablissement = :nomEta AND foo = :1 AND `:a` IS NULL';
$request = self::createStub(ServerRequest::class);
$request->method('getParsedBodyParam')->willReturnMap([
['db', null, Current::$database],
['table', null, Current::$table],
['parameters', null, [':nomEta' => 'Saint-Louis - Châteaulin', ':1' => '4']],
['sql_query', null, Current::$sqlQuery],
]);
$request->method('hasBodyParam')->willReturnMap([
['parameterized', true],
['rollback_query', false],
['allow_interrupt', false],
['skip', false],
['show_as_php', false],
$request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com')->withParsedBody([
'db' => Current::$database,
'table' => Current::$table,
'parameters' => [':nomEta' => 'Saint-Louis - Châteaulin', ':1' => '4'],
'sql_query' => Current::$sqlQuery,
'parameterized' => '1',
]);
$this->dummyDbi->addResult(

View File

@ -15,6 +15,7 @@ use PhpMyAdmin\Display\Results as DisplayResults;
use PhpMyAdmin\Display\SortExpression;
use PhpMyAdmin\FieldMetadata;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
use PhpMyAdmin\Message;
use PhpMyAdmin\MessageType;
use PhpMyAdmin\ParseAnalyze;
@ -876,8 +877,10 @@ class ResultsTest extends AbstractTestCase
$query = 'ANALYZE FORMAT=JSON SELECT * FROM test_table';
[$statementInfo] = ParseAnalyze::sqlQuery($query, $db);
$request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com');
$object = new DisplayResults($this->dbi, $config, $db, $table, 2, '', $query);
$object->setConfigParamsForDisplayTable($statementInfo);
$object->setConfigParamsForDisplayTable($request, $statementInfo);
self::assertSame('F', $_SESSION['tmpval']['pftext']);
@ -885,38 +888,37 @@ class ResultsTest extends AbstractTestCase
[$statementInfo] = ParseAnalyze::sqlQuery($query, $db);
$object = new DisplayResults($this->dbi, $config, $db, $table, 2, '', $query);
$object->setConfigParamsForDisplayTable($statementInfo);
$object->setConfigParamsForDisplayTable($request, $statementInfo);
self::assertSame('P', $_SESSION['tmpval']['pftext']);
}
/**
* @param array<string, array<string, array<string, array<string, bool|int|string>>>|string> $session
* @param array<string, string> $get
* @param array<string, string> $post
* @param array<string, string> $request
* @param array<string, string> $queryParams
* @param array<string, string> $parsedBody
* @param array<string, bool|array<string, array<string, bool|int|string>>|string|int> $expected
*/
#[DataProvider('providerSetConfigParamsForDisplayTable')]
public function testSetConfigParamsForDisplayTable(
array $session,
array $get,
array $post,
array $request,
array $queryParams,
array $parsedBody,
array $expected,
): void {
$_SESSION = $session;
$_GET = $get;
$_POST = $post;
$_REQUEST = $request;
$db = 'test_db';
$table = 'test_table';
$query = 'SELECT * FROM `test_db`.`test_table`;';
[$statementInfo] = ParseAnalyze::sqlQuery($query, $db);
$request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com')
->withQueryParams($queryParams)
->withParsedBody($parsedBody);
$object = new DisplayResults($this->dbi, Config::getInstance(), $db, $table, 2, '', $query);
$object->setConfigParamsForDisplayTable($statementInfo);
$object->setConfigParamsForDisplayTable($request, $statementInfo);
self::assertArrayHasKey('tmpval', $_SESSION);
self::assertIsArray($_SESSION['tmpval']);
@ -933,7 +935,6 @@ class ResultsTest extends AbstractTestCase
[' PMA_token ' => 'token'],
[],
[],
[],
[
'query' => [
'2b7b3faf4b48255e47876f6d5bd2da35' => [
@ -988,7 +989,6 @@ class ResultsTest extends AbstractTestCase
],
[],
[],
[],
[
'query' => [
'b' => [],
@ -1024,9 +1024,9 @@ class ResultsTest extends AbstractTestCase
],
'default and request values' => [
[' PMA_token ' => 'token'],
['session_max_rows' => '27'],
['session_max_rows' => '28'],
[
'session_max_rows' => '27',
'pos' => '2',
'pftext' => DisplayResults::DISPLAY_FULL_TEXT,
'relational_display' => DisplayResults::RELATIONAL_DISPLAY_COLUMN,
@ -1088,7 +1088,6 @@ class ResultsTest extends AbstractTestCase
],
' PMA_token ' => 'token',
],
[],
['session_max_rows' => DisplayResults::ALL_ROWS],
[
'pos' => 'NaN',

View File

@ -10,6 +10,7 @@ use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\ConfigStorage\RelationCleanup;
use PhpMyAdmin\Current;
use PhpMyAdmin\Dbal\DatabaseInterface;
use PhpMyAdmin\Http\Factory\ServerRequestFactory;
use PhpMyAdmin\ParseAnalyze;
use PhpMyAdmin\Sql;
use PhpMyAdmin\Template;
@ -620,7 +621,11 @@ class SqlTest extends AbstractTestCase
$config = Config::getInstance();
$config->selectedServer['DisableIS'] = true;
$config->selectedServer['user'] = 'user';
$request = ServerRequestFactory::create()->createServerRequest('POST', 'https://example.com');
$actual = $this->sql->executeQueryAndSendQueryResponse(
$request,
null,
false,
'sakila',