Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/phpmyadmin/phpmyadmin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKamil Tekiela <tekiela246@gmail.com>2022-08-23 04:39:53 +0300
committerGitHub <noreply@github.com>2022-08-23 04:39:53 +0300
commitf7f8722e1f013afbb0332cd9d03999ef54c293fa (patch)
treeb5d74d3b0b7d473bb9aceaee4509b73604a41bbd
parent6ed03b3f00832f6186ef8a0ed0fdda0cd3315b87 (diff)
Refactor insert edit (#17684)
This is a major redesign of the code that handles these four actions: in-place edit(AJAX), edit of multiple rows, copying of rows, and insertion of new rows. The goal is to make the code easier to read and more understandable. I introduced a new DTO for better readability. Some of the methods were made private to the model The controller has access to two methods for getting the value for INSERT and for UPDATE Unfortunately, I have introduced method envy on EditField, but I do not want to move the functionality away from InsertEdit.php Unit tests have not improved in readability but I added helpful comments explaining what we are testing. There's probably a way to improve it too. I will probably merge all commits once I decide it's ready for review. Signed-off-by: Kamil Tekiela <tekiela246@gmail.com>
-rw-r--r--libraries/classes/Controllers/Table/ReplaceController.php120
-rw-r--r--libraries/classes/EditField.php56
-rw-r--r--libraries/classes/InsertEdit.php309
-rw-r--r--phpstan-baseline.neon70
-rw-r--r--psalm-baseline.xml79
-rw-r--r--test/classes/InsertEditTest.php896
-rw-r--r--test/classes/Stubs/DbiDummy.php6
7 files changed, 725 insertions, 811 deletions
diff --git a/libraries/classes/Controllers/Table/ReplaceController.php b/libraries/classes/Controllers/Table/ReplaceController.php
index e393026f07..ed49fc32df 100644
--- a/libraries/classes/Controllers/Table/ReplaceController.php
+++ b/libraries/classes/Controllers/Table/ReplaceController.php
@@ -11,6 +11,7 @@ use PhpMyAdmin\Controllers\Sql\SqlController;
use PhpMyAdmin\Controllers\Table\SqlController as TableSqlController;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
+use PhpMyAdmin\EditField;
use PhpMyAdmin\File;
use PhpMyAdmin\Html\Generator;
use PhpMyAdmin\Http\ServerRequest;
@@ -24,10 +25,8 @@ use PhpMyAdmin\Transformations;
use PhpMyAdmin\Util;
use function __;
-use function array_keys;
use function array_values;
use function class_exists;
-use function count;
use function implode;
use function in_array;
use function is_array;
@@ -145,6 +144,7 @@ final class ReplaceController extends AbstractController
$insertErrors = [];
$rowSkipped = false;
$GLOBALS['unsaved_values'] = [];
+ /** @var string|int $where_clause */
foreach ($loopArray as $rownumber => $where_clause) {
// skip fields to be ignored
if (! $usingKey && isset($_POST['insert_ignore_' . $where_clause])) {
@@ -157,33 +157,28 @@ final class ReplaceController extends AbstractController
// Map multi-edit keys to single-level arrays, dependent on how we got the fields
$multi_edit_columns = $_POST['fields']['multi_edit'][$rownumber] ?? [];
$multi_edit_columns_name = $_POST['fields_name']['multi_edit'][$rownumber] ?? [];
- $multi_edit_columns_prev = $_POST['fields_prev']['multi_edit'][$rownumber] ?? null;
- $multi_edit_funcs = $_POST['funcs']['multi_edit'][$rownumber] ?? null;
- $multi_edit_salt = $_POST['salt']['multi_edit'][$rownumber] ?? null;
- $multi_edit_columns_type = $_POST['fields_type']['multi_edit'][$rownumber] ?? null;
- $multi_edit_columns_null = $_POST['fields_null']['multi_edit'][$rownumber] ?? null;
- $multi_edit_columns_null_prev = $_POST['fields_null_prev']['multi_edit'][$rownumber] ?? null;
- $multi_edit_auto_increment = $_POST['auto_increment']['multi_edit'][$rownumber] ?? null;
- $multi_edit_virtual = $_POST['virtual']['multi_edit'][$rownumber] ?? null;
-
- // When a select field is nullified, it's not present in $_POST
- // so initialize it; this way, the foreach($multi_edit_columns) will process it
- foreach (array_keys($multi_edit_columns_name) as $key) {
- if (isset($multi_edit_columns[$key])) {
- continue;
- }
-
- $multi_edit_columns[$key] = '';
- }
+ $multi_edit_columns_prev = $_POST['fields_prev']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_funcs = $_POST['funcs']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_salt = $_POST['salt']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_columns_type = $_POST['fields_type']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_columns_null = $_POST['fields_null']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_columns_null_prev = $_POST['fields_null_prev']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_auto_increment = $_POST['auto_increment']['multi_edit'][$rownumber] ?? [];
+ $multi_edit_virtual = $_POST['virtual']['multi_edit'][$rownumber] ?? [];
// Iterate in the order of $multi_edit_columns_name,
// not $multi_edit_columns, to avoid problems
// when inserting multiple entries
$insert_fail = false;
+ /** @var int|string $key */
foreach ($multi_edit_columns_name as $key => $column_name) {
// Note: $key is an md5 of the fieldname. The actual fieldname is
// available in $multi_edit_columns_name[$key]
+ // When a select field is nullified, it's not present in $_POST so initialize it
+ $multi_edit_columns[$key] = $multi_edit_columns[$key] ?? '';
+
+ /** @var string[]|string $current_value */
$current_value = $multi_edit_columns[$key];
if (is_array($current_value)) {
// Some column types accept comma-separated values e.g. set
@@ -243,54 +238,43 @@ final class ReplaceController extends AbstractController
// delete $file_to_insert temporary variable
$file_to_insert->cleanUp();
- if (empty($multi_edit_funcs[$key])) {
- $current_value_as_an_array = $this->insertEdit->getCurrentValueForDifferentTypes(
- $possibly_uploaded_val,
- $key,
- $multi_edit_columns_type,
- $current_value,
- $multi_edit_auto_increment,
- $multi_edit_columns_name,
- $multi_edit_columns_null,
- $multi_edit_columns_null_prev,
- $isInsert,
- $usingKey,
- $where_clause,
- $GLOBALS['table']
- );
- } else {
- $current_value_as_an_array = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_funcs[$key],
- $multi_edit_salt[$key] ?? null,
- $current_value
- );
- }
+ $editField = new EditField(
+ $column_name,
+ $current_value,
+ $multi_edit_columns_type[$key] ?? '',
+ isset($multi_edit_auto_increment[$key]),
+ ! empty($multi_edit_columns_null[$key]),
+ ! empty($multi_edit_columns_null_prev[$key]),
+ $multi_edit_funcs[$key] ?? '',
+ $multi_edit_salt[$key] ?? null,
+ $multi_edit_columns_prev[$key] ?? null,
+ $possibly_uploaded_val !== false
+ );
+
+ if (! isset($multi_edit_virtual[$key])) {
+ if ($isInsert) {
+ $queryPart = $this->insertEdit->getQueryValueForInsert(
+ $editField,
+ $usingKey,
+ $where_clause
+ );
+ if ($queryPart !== '' && $valueSets === []) {
+ // first inserted row so prepare the list of fields
+ $queryFields[] = Util::backquote($editField->columnName);
+ }
+ } else {
+ $queryPart = $this->insertEdit->getQueryValueForUpdate($editField);
+ }
- if (! isset($multi_edit_virtual, $multi_edit_virtual[$key])) {
- [
- $queryValues,
- $queryFields,
- ] = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- $multi_edit_columns_null,
- $current_value,
- $multi_edit_columns_prev,
- $multi_edit_funcs,
- $isInsert,
- $queryValues,
- $queryFields,
- $current_value_as_an_array,
- $valueSets,
- $key,
- $multi_edit_columns_null_prev
- );
+ if ($queryPart !== '') {
+ $queryValues[] = $queryPart;
+ }
}
- if (! isset($multi_edit_columns_null[$key])) {
- continue;
+ // phpcs:ignore SlevomatCodingStandard.ControlStructures.EarlyExit.EarlyExitNotUsed
+ if ($editField->isNull) {
+ $multi_edit_columns[$key] = null;
}
-
- $multi_edit_columns[$key] = null;
}
// temporarily store rows not inserted
@@ -299,7 +283,7 @@ final class ReplaceController extends AbstractController
$GLOBALS['unsaved_values'][$rownumber] = $multi_edit_columns;
}
- if ($insert_fail || count($queryValues) <= 0) {
+ if ($insert_fail || $queryValues === []) {
continue;
}
@@ -322,12 +306,12 @@ final class ReplaceController extends AbstractController
$multi_edit_columns_type,
$multi_edit_columns_null,
$multi_edit_auto_increment,
- $current_value_as_an_array,
$key,
$current_value,
$where_clause,
$multi_edit_columns_null_prev,
- $insert_fail
+ $insert_fail,
+ $multi_edit_columns
);
// Builds the sql query
@@ -348,8 +332,6 @@ final class ReplaceController extends AbstractController
return;
}
- unset($multi_edit_columns);
-
// If there is a request for SQL previewing.
if (isset($_POST['preview_sql'])) {
Core::previewSQL($GLOBALS['query']);
diff --git a/libraries/classes/EditField.php b/libraries/classes/EditField.php
new file mode 100644
index 0000000000..26ded0dd5a
--- /dev/null
+++ b/libraries/classes/EditField.php
@@ -0,0 +1,56 @@
+<?php
+
+declare(strict_types=1);
+
+namespace PhpMyAdmin;
+
+/**
+ * @psalm-immutable
+ */
+final class EditField
+{
+ /** @var string $columnName */
+ public $columnName;
+ /** @var string $value */
+ public $value;
+ /** @var string $type */
+ public $type;
+ /** @var bool $autoIncrement */
+ public $autoIncrement;
+ /** @var bool $isNull */
+ public $isNull;
+ /** @var bool $wasPreviouslyNull */
+ public $wasPreviouslyNull;
+ /** @var string $function */
+ public $function;
+ /** @var string|null $salt */
+ public $salt;
+ /** @var string|null $previousValue */
+ public $previousValue;
+ /** @var bool $isUploaded */
+ public $isUploaded;
+
+ public function __construct(
+ string $columnName,
+ string $value,
+ string $type,
+ bool $autoIncrement,
+ bool $isNull,
+ bool $wasPreviouslyNull,
+ string $function,
+ ?string $salt,
+ ?string $previousValue,
+ bool $isUploaded
+ ) {
+ $this->columnName = $columnName;
+ $this->value = $value;
+ $this->type = $type;
+ $this->autoIncrement = $autoIncrement;
+ $this->isNull = $isNull;
+ $this->wasPreviouslyNull = $wasPreviouslyNull;
+ $this->function = $function;
+ $this->salt = $salt;
+ $this->previousValue = $previousValue;
+ $this->isUploaded = $isUploaded;
+ }
+}
diff --git a/libraries/classes/InsertEdit.php b/libraries/classes/InsertEdit.php
index f73d022612..fc8107c023 100644
--- a/libraries/classes/InsertEdit.php
+++ b/libraries/classes/InsertEdit.php
@@ -1550,29 +1550,23 @@ class InsertEdit
}
/**
- * Get current value in multi edit mode
- *
- * @param string $multiEditFunction multiple edit functions array
- * @param ?string $multiEditSalt multiple edit array with encryption salt
- * @param string $currentValue current value in the column
+ * Get value part if a function was specified
*/
- public function getCurrentValueAsAnArrayForMultipleEdit(
- string $multiEditFunction,
- ?string $multiEditSalt,
- string $currentValue
+ private function formatAsSqlFunction(
+ EditField $editField
): string {
- if ($multiEditFunction === 'PHP_PASSWORD_HASH') {
+ if ($editField->function === 'PHP_PASSWORD_HASH') {
/**
* @see https://github.com/vimeo/psalm/issues/3350
*
* @psalm-suppress InvalidArgument
*/
- $hash = password_hash($currentValue, PASSWORD_DEFAULT);
+ $hash = password_hash($editField->value, PASSWORD_DEFAULT);
return "'" . $this->dbi->escapeString($hash) . "'";
}
- if ($multiEditFunction === 'UUID') {
+ if ($editField->function === 'UUID') {
/* This way user will know what UUID new row has */
$uuid = (string) $this->dbi->fetchValue('SELECT UUID()');
@@ -1580,170 +1574,123 @@ class InsertEdit
}
if (
- in_array($multiEditFunction, $this->getGisFromTextFunctions())
- || in_array($multiEditFunction, $this->getGisFromWKBFunctions())
+ in_array($editField->function, $this->getGisFromTextFunctions())
+ || in_array($editField->function, $this->getGisFromWKBFunctions())
) {
- return $multiEditFunction . "('" . $this->dbi->escapeString($currentValue) . "')";
+ return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "')";
}
if (
- ! in_array($multiEditFunction, self::FUNC_NO_PARAM)
- || ($currentValue !== ''
- && in_array($multiEditFunction, self::FUNC_OPTIONAL_PARAM))
+ ! in_array($editField->function, self::FUNC_NO_PARAM)
+ || ($editField->value !== '' && in_array($editField->function, self::FUNC_OPTIONAL_PARAM))
) {
if (
- (isset($multiEditSalt)
- && ($multiEditFunction === 'AES_ENCRYPT'
- || $multiEditFunction === 'AES_DECRYPT'))
- || (! empty($multiEditSalt)
- && ($multiEditFunction === 'DES_ENCRYPT'
- || $multiEditFunction === 'DES_DECRYPT'
- || $multiEditFunction === 'ENCRYPT'))
+ ($editField->salt !== null
+ && ($editField->function === 'AES_ENCRYPT'
+ || $editField->function === 'AES_DECRYPT'))
+ || ($editField->salt
+ && ($editField->function === 'DES_ENCRYPT'
+ || $editField->function === 'DES_DECRYPT'
+ || $editField->function === 'ENCRYPT'))
) {
- return $multiEditFunction . "('" . $this->dbi->escapeString($currentValue) . "','"
- . $this->dbi->escapeString($multiEditSalt) . "')";
+ return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "','"
+ . $this->dbi->escapeString($editField->salt) . "')";
}
- return $multiEditFunction . "('" . $this->dbi->escapeString($currentValue) . "')";
+ return $editField->function . "('" . $this->dbi->escapeString($editField->value) . "')";
}
- return $multiEditFunction . '()';
+ return $editField->function . '()';
}
/**
- * Get query values array and query fields array for insert and update in multi edit
- *
- * @param array $multiEditColumnsName multiple edit columns name array
- * @param array $multiEditColumnsNull multiple edit columns null array
- * @param string $currentValue current value in the column in loop
- * @param array $multiEditColumnsPrev multiple edit previous columns array
- * @param array $multiEditFuncs multiple edit functions array
- * @param bool $isInsert boolean value whether insert or not
- * @param array $queryValues SET part of the sql query
- * @param array $queryFields array of query fields
- * @param string $currentValueAsAnArray current value in the column
- * as an array
- * @param array $valueSets array of valu sets
- * @param string $key an md5 of the column name
- * @param array $multiEditColumnsNullPrev array of multiple edit columns
- * null previous
- *
- * @return array[] ($query_values, $query_fields)
+ * Get the field value formatted for use in a SQL statement.
+ * Used in both INSERT and UPDATE statements.
*/
- public function getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multiEditColumnsName,
- $multiEditColumnsNull,
- $currentValue,
- $multiEditColumnsPrev,
- $multiEditFuncs,
- $isInsert,
- $queryValues,
- $queryFields,
- $currentValueAsAnArray,
- $valueSets,
- $key,
- $multiEditColumnsNullPrev
- ) {
- // i n s e r t
- if ($isInsert) {
- // no need to add column into the valuelist
- if (strlen($currentValueAsAnArray) > 0) {
- $queryValues[] = $currentValueAsAnArray;
- // first inserted row so prepare the list of fields
- if (empty($valueSets)) {
- $queryFields[] = Util::backquote($multiEditColumnsName[$key]);
- }
- }
- } elseif (! empty($multiEditColumnsNullPrev[$key]) && ! isset($multiEditColumnsNull[$key])) {
- // u p d a t e
+ private function getValueFormattedAsSql(
+ EditField $editField,
+ string $protectedValue = ''
+ ): string {
+ if ($editField->isUploaded) {
+ return $editField->value;
+ }
- // field had the null checkbox before the update
- // field no longer has the null checkbox
- $queryValues[] = Util::backquote($multiEditColumnsName[$key])
- . ' = ' . $currentValueAsAnArray;
- } elseif (
- ! (empty($multiEditFuncs[$key])
- && empty($multiEditColumnsNull[$key])
- && isset($multiEditColumnsPrev[$key])
- && $currentValue === $multiEditColumnsPrev[$key])
- && $currentValueAsAnArray !== ''
- ) {
- // avoid setting a field to NULL when it's already NULL
- // (field had the null checkbox before the update
- // field still has the null checkbox)
- if (empty($multiEditColumnsNullPrev[$key]) || empty($multiEditColumnsNull[$key])) {
- $queryValues[] = Util::backquote($multiEditColumnsName[$key])
- . ' = ' . $currentValueAsAnArray;
- }
+ if ($editField->function !== '') {
+ return $this->formatAsSqlFunction($editField);
}
- return [
- $queryValues,
- $queryFields,
- ];
+ return $this->formatAsSqlValueBasedOnType(
+ $editField,
+ $protectedValue
+ );
}
/**
- * Get the current column value in the form for different data types
+ * Get query values array and query fields array for insert and update in multi edit
*
- * @param string|false $possiblyUploadedVal uploaded file content
- * @param string $key an md5 of the column name
- * @param array|null $multiEditColumnsType array of multi edit column types
- * @param string $currentValue current column value in the form
- * @param array|null $multiEditAutoIncrement multi edit auto increment
- * @param array $multiEditColumnsName multi edit column names array
- * @param array $multiEditColumnsNull multi edit columns null array
- * @param array $multiEditColumnsNullPrev multi edit columns previous null
- * @param bool $isInsert whether insert or not
- * @param bool $usingKey whether editing or new row
- * @param string $whereClause where clause
- * @param string $table table name
- *
- * @return string current column value in the form
+ * @param string|int $whereClause Either a positional index or string representing selected row
*/
- public function getCurrentValueForDifferentTypes(
- $possiblyUploadedVal,
- $key,
- ?array $multiEditColumnsType,
- string $currentValue,
- ?array $multiEditAutoIncrement,
- $multiEditColumnsName,
- $multiEditColumnsNull,
- $multiEditColumnsNullPrev,
- $isInsert,
- $usingKey,
- $whereClause,
- $table
+ public function getQueryValueForInsert(
+ EditField $editField,
+ bool $usingKey,
+ $whereClause
): string {
- if ($possiblyUploadedVal !== false) {
- return $possiblyUploadedVal;
+ $protectedValue = '';
+ if ($editField->type === 'protected' && $usingKey && $whereClause !== '') {
+ // Fetch the current values of a row to use in case we have a protected field
+ $protectedValue = $this->dbi->fetchValue(
+ 'SELECT ' . Util::backquote($editField->columnName)
+ . ' FROM ' . Util::backquote($GLOBALS['table'])
+ . ' WHERE ' . $whereClause
+ ) ?: '';
}
- // c o l u m n v a l u e i n t h e f o r m
- $type = $multiEditColumnsType[$key] ?? '';
+ return $this->getValueFormattedAsSql($editField, $protectedValue);
+ }
- if ($type !== 'protected' && $type !== 'set' && strlen($currentValue) === 0) {
- // best way to avoid problems in strict mode
- // (works also in non-strict mode)
- $currentValue = "''";
- if (isset($multiEditAutoIncrement, $multiEditAutoIncrement[$key])) {
- $currentValue = 'NULL';
- }
- } elseif ($type === 'set') {
- $currentValue = "'" . $this->dbi->escapeString($currentValue) . "'";
- } elseif ($type === 'protected') {
- // Fetch the current values of a row to use in case we have a protected field
- if (
- $isInsert
- && $usingKey
- && is_array($multiEditColumnsType) && $whereClause
- ) {
- $protectedRow = $this->dbi->fetchSingleRow(
- 'SELECT * FROM ' . Util::backquote($table)
- . ' WHERE ' . $whereClause . ';'
- );
- }
+ /**
+ * Get field-value pairs for update SQL.
+ * During update, we build the SQL only with the fields that should be updated.
+ */
+ public function getQueryValueForUpdate(EditField $editField): string
+ {
+ $currentValueFormattedAsSql = $this->getValueFormattedAsSql($editField);
+
+ // avoid setting a field to NULL when it's already NULL
+ // (field had the null checkbox before the update; field still has the null checkbox)
+ if ($editField->wasPreviouslyNull && $editField->isNull) {
+ return '';
+ }
+
+ // A blob field that hasn't been changed will have no value
+ if ($currentValueFormattedAsSql === '') {
+ return '';
+ }
+
+ if (
+ // Field had the null checkbox before the update; field no longer has the null checkbox
+ $editField->wasPreviouslyNull ||
+ // Field was marked as NULL (the value will be unchanged if it was an empty string)
+ $editField->isNull ||
+ // A function was applied to the field
+ $editField->function !== '' ||
+ // The value was changed
+ $editField->value !== $editField->previousValue
+ ) {
+ return Util::backquote($editField->columnName) . ' = ' . $currentValueFormattedAsSql;
+ }
+ return '';
+ }
+
+ /**
+ * Get the current column value in the form for different data types
+ */
+ private function formatAsSqlValueBasedOnType(
+ EditField $editField,
+ string $protectedValue
+ ): string {
+ if ($editField->type === 'protected') {
// here we are in protected mode (asked in the config)
// so tbl_change has put this special value in the
// columns array, so we do not change the column value
@@ -1752,44 +1699,54 @@ class InsertEdit
// when in UPDATE mode, do not alter field's contents. When in INSERT
// mode, insert empty field because no values were submitted.
// If protected blobs where set, insert original fields content.
- $currentValue = '';
- if (! empty($protectedRow[$multiEditColumnsName[$key]])) {
- $currentValue = '0x'
- . bin2hex($protectedRow[$multiEditColumnsName[$key]]);
+ if ($protectedValue !== '') {
+ return '0x' . bin2hex($protectedValue);
}
- } elseif ($type === 'hex') {
- if (substr($currentValue, 0, 2) != '0x') {
- $currentValue = '0x' . $currentValue;
+
+ if ($editField->isNull) {
+ return 'NULL';
}
- } elseif ($type === 'bit') {
- $currentValue = (string) preg_replace('/[^01]/', '0', $currentValue);
- $currentValue = "b'" . $this->dbi->escapeString($currentValue) . "'";
- } elseif (
- ! ($type === 'datetime' || $type === 'timestamp' || $type === 'date')
- || ($currentValue !== 'CURRENT_TIMESTAMP'
- && $currentValue !== 'current_timestamp()')
- ) {
- $currentValue = "'" . $this->dbi->escapeString($currentValue)
- . "'";
+
+ // The Null checkbox was unchecked for this field
+ if ($editField->wasPreviouslyNull) {
+ return "''";
+ }
+
+ return '';
}
- // Was the Null checkbox checked for this field?
- // (if there is a value, we ignore the Null checkbox: this could
- // be possible if Javascript is disabled in the browser)
- if (! empty($multiEditColumnsNull[$key]) && ($currentValue == "''" || $currentValue == '')) {
- $currentValue = 'NULL';
+ if ($editField->value === '') {
+ // When the field is autoIncrement, the best way to avoid problems
+ // in strict mode is to set the value to null (works also in non-strict mode)
+
+ // If the value is empty and the null checkbox is checked, set it to null
+ return $editField->autoIncrement || $editField->isNull ? 'NULL' : "''";
+ }
+
+ if ($editField->type === 'hex') {
+ if (substr($editField->value, 0, 2) != '0x') {
+ return '0x' . $editField->value;
+ }
+
+ return $editField->value;
+ }
+
+ if ($editField->type === 'bit') {
+ $currentValue = (string) preg_replace('/[^01]/', '0', $editField->value);
+
+ return "b'" . $this->dbi->escapeString($currentValue) . "'";
}
- // The Null checkbox was unchecked for this field
if (
- empty($currentValue)
- && ! empty($multiEditColumnsNullPrev[$key])
- && ! isset($multiEditColumnsNull[$key])
+ ($editField->type !== 'datetime' && $editField->type !== 'timestamp' && $editField->type !== 'date')
+ || ($editField->value !== 'CURRENT_TIMESTAMP' && $editField->value !== 'current_timestamp()')
) {
- $currentValue = "''";
+ return "'" . $this->dbi->escapeString($editField->value) . "'";
}
- return $currentValue;
+ // If there is a value, we ignore the Null checkbox;
+ // this could be possible if Javascript is disabled in the browser
+ return $editField->value;
}
/**
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
index 371bfa983e..e3b70bbe39 100644
--- a/phpstan-baseline.neon
+++ b/phpstan-baseline.neon
@@ -4351,31 +4351,6 @@ parameters:
path: libraries/classes/InsertEdit.php
-
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getCurrentValueForDifferentTypes\\(\\) has parameter \\$multiEditAutoIncrement with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getCurrentValueForDifferentTypes\\(\\) has parameter \\$multiEditColumnsName with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getCurrentValueForDifferentTypes\\(\\) has parameter \\$multiEditColumnsNull with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getCurrentValueForDifferentTypes\\(\\) has parameter \\$multiEditColumnsNullPrev with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getCurrentValueForDifferentTypes\\(\\) has parameter \\$multiEditColumnsType with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getDisplayValueForForeignTableColumn\\(\\) has parameter \\$map with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/InsertEdit.php
@@ -4501,51 +4476,6 @@ parameters:
path: libraries/classes/InsertEdit.php
-
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$multiEditColumnsName with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$multiEditColumnsNull with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$multiEditColumnsNullPrev with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$multiEditColumnsPrev with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$multiEditFuncs with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$queryFields with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$queryValues with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) has parameter \\$valueSets with no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
- message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getQueryValuesForInsertAndUpdateInMultipleEdit\\(\\) return type has no value type specified in iterable type array\\.$#"
- count: 1
- path: libraries/classes/InsertEdit.php
-
- -
message: "#^Method PhpMyAdmin\\\\InsertEdit\\:\\:getSpecialCharsAndBackupFieldForExistingRow\\(\\) has parameter \\$column with no value type specified in iterable type array\\.$#"
count: 1
path: libraries/classes/InsertEdit.php
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index 5cf4c590a0..8840207287 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -3651,29 +3651,20 @@
<InvalidArgument occurrences="1">
<code>$insertErrors</code>
</InvalidArgument>
- <MixedArgument occurrences="31">
+ <MixedArgument occurrences="21">
<code>$_POST['db']</code>
<code>$_POST['rel_fields_list']</code>
<code>$_POST['table']</code>
<code>$_POST['transform_fields_list']</code>
<code>$column_name</code>
<code>$column_name</code>
- <code>$current_value</code>
- <code>$current_value</code>
- <code>$current_value</code>
+ <code>$column_name</code>
<code>$errorMessages</code>
<code>$extra_data</code>
<code>$lastMessages</code>
- <code>$multi_edit_auto_increment</code>
- <code>$multi_edit_columns_name</code>
- <code>$multi_edit_columns_null</code>
- <code>$multi_edit_columns_null</code>
- <code>$multi_edit_columns_null_prev</code>
- <code>$multi_edit_columns_null_prev</code>
- <code>$multi_edit_columns_prev</code>
- <code>$multi_edit_columns_type</code>
- <code>$multi_edit_funcs</code>
- <code>$multi_edit_funcs[$key]</code>
+ <code>$multi_edit_columns_prev[$key] ?? null</code>
+ <code>$multi_edit_columns_type[$key] ?? ''</code>
+ <code>$multi_edit_funcs[$key] ?? ''</code>
<code>$multi_edit_salt[$key] ?? null</code>
<code>$one_where_clause</code>
<code>$relation_field</code>
@@ -3682,19 +3673,14 @@
<code>$totalAffectedRows</code>
<code>$totalAffectedRows</code>
<code>$warningMessages</code>
- <code>$where_clause</code>
</MixedArgument>
- <MixedArgumentTypeCoercion occurrences="5">
- <code>$current_value</code>
- <code>$key</code>
- <code>$key</code>
- <code>$queryValues</code>
- <code>$queryValues</code>
- </MixedArgumentTypeCoercion>
- <MixedArrayAccess occurrences="4">
+ <MixedArrayAccess occurrences="7">
<code>$_POST['fields_name']['multi_edit']</code>
<code>$extra_data['relations']</code>
<code>$multi_edit_columns[$key]</code>
+ <code>$multi_edit_columns_prev[$key]</code>
+ <code>$multi_edit_columns_type[$key]</code>
+ <code>$multi_edit_funcs[$key]</code>
<code>$multi_edit_salt[$key]</code>
</MixedArrayAccess>
<MixedArrayAssignment occurrences="4">
@@ -3706,7 +3692,7 @@
<MixedArrayOffset occurrences="1">
<code>$mimeMap[$column_name]</code>
</MixedArrayOffset>
- <MixedAssignment occurrences="32">
+ <MixedAssignment occurrences="31">
<code>$GLOBALS['active_page']</code>
<code>$GLOBALS['cfg']['InsertRows']</code>
<code>$GLOBALS['disp_message']</code>
@@ -3722,11 +3708,11 @@
<code>$column_name</code>
<code>$column_name</code>
<code>$curr_rel_field</code>
- <code>$current_value</code>
<code>$extra_data['row_count']</code>
<code>$insertRows</code>
<code>$multi_edit_auto_increment</code>
<code>$multi_edit_columns</code>
+ <code>$multi_edit_columns[$key]</code>
<code>$multi_edit_columns_name</code>
<code>$multi_edit_columns_null</code>
<code>$multi_edit_columns_null_prev</code>
@@ -3738,32 +3724,17 @@
<code>$one_where_clause</code>
<code>$relation_field</code>
<code>$relation_field_value</code>
- <code>$where_clause</code>
</MixedAssignment>
<MixedMethodCall occurrences="1">
<code>new $classname()</code>
</MixedMethodCall>
- <MixedOperand occurrences="3">
+ <MixedOperand occurrences="1">
<code>$relation_field_value</code>
- <code>$where_clause</code>
- <code>$where_clause</code>
</MixedOperand>
- <PossiblyNullArgument occurrences="11">
+ <PossiblyNullArgument occurrences="2">
<code>$GLOBALS['urlParams']</code>
<code>$GLOBALS['urlParams']</code>
- <code>$current_value</code>
- <code>$current_value</code>
- <code>$current_value</code>
- <code>$multi_edit_columns_null</code>
- <code>$multi_edit_columns_null</code>
- <code>$multi_edit_columns_null_prev</code>
- <code>$multi_edit_columns_null_prev</code>
- <code>$multi_edit_columns_prev</code>
- <code>$multi_edit_funcs</code>
</PossiblyNullArgument>
- <PossiblyNullArrayAccess occurrences="1">
- <code>$multi_edit_salt[$key]</code>
- </PossiblyNullArrayAccess>
<PossiblyNullReference occurrences="1">
<code>get</code>
</PossiblyNullReference>
@@ -7895,7 +7866,7 @@
</file>
<file src="libraries/classes/InsertEdit.php">
<LessSpecificReturnStatement occurrences="1"/>
- <MixedArgument occurrences="76">
+ <MixedArgument occurrences="72">
<code>$_POST['fields']['multi_edit']</code>
<code>$backupField</code>
<code>$columnMime['input_transformation_options']</code>
@@ -7952,10 +7923,6 @@
<code>$foreigner['foreign_table']</code>
<code>$foreigner['foreign_table']</code>
<code>$foreigner['foreign_table']</code>
- <code>$multiEditColumnsName[$key]</code>
- <code>$multiEditColumnsName[$key]</code>
- <code>$multiEditColumnsName[$key]</code>
- <code>$protectedRow[$multiEditColumnsName[$key]]</code>
<code>$rows[$keyId]</code>
<code>$singleQuery</code>
<code>$singleQuery</code>
@@ -7983,7 +7950,7 @@
<code>$urlParams</code>
<code>$valueSets</code>
</MixedArgumentTypeCoercion>
- <MixedArrayAccess occurrences="8">
+ <MixedArrayAccess occurrences="7">
<code>$_POST['fields']['multi_edit']</code>
<code>$_POST['where_clause'][0]</code>
<code>$_SESSION['tmpval']['relational_display']</code>
@@ -7991,13 +7958,12 @@
<code>$enumValue['plain']</code>
<code>$enumValue['plain']</code>
<code>$enumValue['plain']</code>
- <code>$protectedRow[$multiEditColumnsName[$key]]</code>
</MixedArrayAccess>
<MixedArrayAssignment occurrences="2">
<code>$editedValues[$cellIndex][$columnName]</code>
<code>$extraData['transformations'][$cellIndex]</code>
</MixedArrayAssignment>
- <MixedArrayOffset occurrences="28">
+ <MixedArrayOffset occurrences="27">
<code>$commentsMap[$column['Field']]</code>
<code>$commentsMap[$column['Field']]</code>
<code>$currentRow[$column['Field']]</code>
@@ -8025,9 +7991,8 @@
<code>$currentRow[$column['Field']]</code>
<code>$mimeMap[$tableColumn['Field']]</code>
<code>$mimeMap[$tableColumn['Field']]</code>
- <code>$protectedRow[$multiEditColumnsName[$key]]</code>
</MixedArrayOffset>
- <MixedAssignment occurrences="36">
+ <MixedAssignment occurrences="35">
<code>$GLOBALS['cfg']['ShowFieldTypesInDataEditView']</code>
<code>$GLOBALS['cfg']['ShowFunctionFields']</code>
<code>$_SESSION['edit_next']</code>
@@ -8056,7 +8021,6 @@
<code>$tmp['Default']</code>
<code>$transformedHtml</code>
<code>$trueType</code>
- <code>$type</code>
<code>$urlParams['sql_query']</code>
<code>$whereClause</code>
<code>$whereClause</code>
@@ -8088,13 +8052,10 @@
</MixedReturnTypeCoercion>
<MoreSpecificReturnType occurrences="1"/>
<PossiblyNullArgument occurrences="3">
- <code>$multiEditSalt</code>
+ <code>$editField-&gt;salt</code>
<code>$newValue</code>
<code>$newValue</code>
</PossiblyNullArgument>
- <PossiblyUndefinedVariable occurrences="1">
- <code>$protectedRow</code>
- </PossiblyUndefinedVariable>
<RedundantCast occurrences="1">
<code>(int) $GLOBALS['cfg']['InsertRows']</code>
</RedundantCast>
@@ -15233,9 +15194,7 @@
<code>$result['pma_type']</code>
<code>$result['wrap']</code>
</MixedArrayAccess>
- <MixedArrayAssignment occurrences="5">
- <code>$_POST['fields']['multi_edit']</code>
- <code>$_POST['fields']['multi_edit']</code>
+ <MixedArrayAssignment occurrences="3">
<code>$_POST['fields']['multi_edit']</code>
<code>$_SESSION['tmpval']['relational_display']</code>
<code>$_SESSION['tmpval']['relational_display']</code>
diff --git a/test/classes/InsertEditTest.php b/test/classes/InsertEditTest.php
index 06049ad39a..03bd69bc97 100644
--- a/test/classes/InsertEditTest.php
+++ b/test/classes/InsertEditTest.php
@@ -8,6 +8,7 @@ use PhpMyAdmin\ConfigStorage\Relation;
use PhpMyAdmin\Core;
use PhpMyAdmin\DatabaseInterface;
use PhpMyAdmin\Dbal\Warning;
+use PhpMyAdmin\EditField;
use PhpMyAdmin\FieldMetadata;
use PhpMyAdmin\FileListing;
use PhpMyAdmin\InsertEdit;
@@ -1988,523 +1989,552 @@ class InsertEditTest extends AbstractTestCase
}
/**
- * Test for getQueryValuesForInsertAndUpdateInMultipleEdit
+ * Test for getQueryValuesForInsert
*/
- public function testGetQueryValuesForInsertAndUpdateInMultipleEdit(): void
+ public function testGetQueryValuesForInsert(): void
{
- $multi_edit_columns_name = ['0' => 'fld'];
-
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- [],
- '',
- [],
- [],
- true,
- [1],
- [2],
- 'foo',
- [],
- '0',
- []
- );
-
- $this->assertEquals(
- [
- [
- 1,
- 'foo',
- ],
- [
- 2,
- '`fld`',
- ],
- ],
- $result
- );
-
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- [],
- '',
- [],
- [],
+ // Simple insert
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ 'fld',
+ 'foo',
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
false,
- [1],
- [2],
- 'foo',
- [],
- '0',
- ['a']
+ ''
);
-
$this->assertEquals(
- [
- [
- 1,
- '`fld` = foo',
- ],
- [2],
- ],
+ "'foo'",
$result
);
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- ['b'],
- "'`c`'",
- ['c'],
- [],
+ // Test for file upload
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '0x123',
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ true
+ ),
false,
- [1],
- [2],
- 'foo',
- [],
- '0',
- ['a']
+ ''
);
- $this->assertEquals(
+ $this->assertEquals('0x123', $result);
+
+ // Test functions
+ $this->dummyDbi->addResult(
+ 'SELECT UUID()',
[
- [1],
- [2],
- ],
- $result
+ ['uuid1234'],// Minimal working setup for 2FA
+ ]
);
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- ['b'],
- "'`c`'",
- ['c'],
- [3],
+ // case 1
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ '',
+ false,
+ false,
+ false,
+ 'UUID',
+ null,
+ null,
+ false
+ ),
false,
- [1],
- [2],
- 'foo',
- [],
- '0',
- []
+ ''
);
- $this->assertEquals(
- [
- [
- 1,
- '`fld` = foo',
- ],
- [2],
- ],
- $result
- );
+ $this->assertEquals("'uuid1234'", $result);
- // Test to see if a zero-string is not ignored
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- [],
- '0',
- [],
- [],
+ // case 2
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ "'",
+ '',
+ false,
+ false,
+ false,
+ 'AES_ENCRYPT',
+ '',
+ null,
+ false
+ ),
false,
- [],
- [],
- "'0'",
- [],
- '0',
- []
- );
-
- $this->assertEquals(
- [
- ["`fld` = '0'"],
- [],
- ],
- $result
+ ''
);
+ $this->assertEquals("AES_ENCRYPT('\\'','')", $result);
- // Can only happen when table contains blob field that was left unchanged during edit
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- [],
- '',
- [],
- [],
+ // case 3
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ "'",
+ '',
+ false,
+ false,
+ false,
+ 'ABS',
+ null,
+ null,
+ false
+ ),
false,
- [],
- [],
- '',
- [],
- '0',
- []
+ ''
);
+ $this->assertEquals("ABS('\\'')", $result);
- $this->assertEquals(
- [
- [],
- [],
- ],
- $result
+ // case 4
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ '',
+ false,
+ false,
+ false,
+ 'RAND',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals('RAND()', $result);
- // Test to see if a field will be set to null when it wasn't null previously
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- ['on'],
- '',
- [],
- [],
+ // case 5
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ "a'c",
+ '',
+ false,
+ false,
+ false,
+ 'PHP_PASSWORD_HASH',
+ null,
+ null,
+ false
+ ),
false,
- [],
- [],
- 'NULL',
- [],
- '0',
- []
+ ''
);
+ $this->assertTrue(password_verify("a'c", mb_substr($result, 1, -1)));
- $this->assertEquals(
- [
- ['`fld` = NULL'],
- [],
- ],
- $result
- );
+ // Test different data types
- // Test to see if a field will be ignored if it was null previously
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- ['on'],
- '',
- [],
- [],
- false,
- [],
- [],
- 'NULL',
- [],
- '0',
- ['on']
+ // Datatype: protected copied from the databse
+ $GLOBALS['table'] = 'test_table';
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ 'name',
+ '',
+ 'protected',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ true,
+ '`id` = 4'
);
+ $this->assertEquals('0x313031', $result);
- $this->assertEquals(
- [
- [],
- [],
- ],
- $result
+ // An empty value for auto increment column should be converted to NULL
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '', // empty for null
+ '',
+ true,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals('NULL', $result);
- // Test to see if a field will be ignored if it the value is unchanged
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- [],
- "a'b",
- ["a'b"],
- [],
+ // Simple empty value
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
false,
- [],
- [],
- "'a\'b'",
- [],
- '0',
- []
+ ''
);
+ $this->assertEquals("''", $result);
- $this->assertEquals(
- [
- [],
- [],
- ],
- $result
+ // Datatype: set
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '', // doesn't matter what the value is
+ 'set',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals("''", $result);
- // Test to see if a field can be set to NULL
- $result = $this->insertEdit->getQueryValuesForInsertAndUpdateInMultipleEdit(
- $multi_edit_columns_name,
- ['on'],
- '',
- [''],
- [],
+ // Datatype: protected with no value should produce an empty string
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ 'protected',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
false,
- [],
- [],
- 'NULL',
- [],
- '0',
- []
+ ''
);
+ $this->assertEquals('', $result);
- $this->assertEquals(
- [
- ['`fld` = NULL'],
- [],
- ],
- $result
+ // Datatype: protected with null flag set
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ 'protected',
+ false,
+ true,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
- }
-
- /**
- * Test for getCurrentValueAsAnArrayForMultipleEdit
- */
- public function testGetCurrentValueAsAnArrayForMultipleEdit(): void
- {
- // case 2
- $multi_edit_function = 'UUID';
+ $this->assertEquals('NULL', $result);
- $this->dummyDbi->addResult(
- 'SELECT UUID()',
- [
- ['uuid1234'],// Minimal working setup for 2FA
- ]
+ // Datatype: bit
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '20\'12',
+ 'bit',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals("b'00010'", $result);
- $this->insertEdit = new InsertEdit(
- $GLOBALS['dbi'],
- new Relation($GLOBALS['dbi']),
- new Transformations(),
- new FileListing(),
- new Template()
+ // Datatype: date
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '20\'12',
+ 'date',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals("'20\\'12'", $result);
- $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_function,
- null,
- 'currVal'
+ // A NULL checkbox
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ 'set',
+ false,
+ true,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
+ $this->assertEquals('NULL', $result);
- $this->assertEquals("'uuid1234'", $result);
-
- // case 3
- $multi_edit_function = 'AES_ENCRYPT';
- $multi_edit_salt = '';
- $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_function,
- $multi_edit_salt,
- "'"
+ // Datatype: protected but NULL checkbox was unchecked without uploading a file
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '',
+ 'protected',
+ false,
+ false,
+ true, // was previously NULL
+ '',
+ null,
+ null,
+ false // no upload
+ ),
+ false,
+ ''
);
- $this->assertEquals("AES_ENCRYPT('\\'','')", $result);
+ $this->assertEquals("''", $result);
- // case 4
- $multi_edit_function = 'ABS';
- $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_function,
- null,
- "'"
+ // Datatype: date with default value
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ 'current_timestamp()',
+ 'date',
+ false,
+ false,
+ true, // NULL should be ignored
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
- $this->assertEquals("ABS('\\'')", $result);
+ $this->assertEquals('current_timestamp()', $result);
- // case 5
- $multi_edit_function = 'RAND';
- $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_function,
- null,
+ // Datatype: hex without 0x
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '222aaafff',
+ 'hex',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
''
);
- $this->assertEquals('RAND()', $result);
+ $this->assertEquals('0x222aaafff', $result);
- // case 6
- $multi_edit_function = 'PHP_PASSWORD_HASH';
- $result = $this->insertEdit->getCurrentValueAsAnArrayForMultipleEdit(
- $multi_edit_function,
- null,
- "a'c"
+ // Datatype: hex with 0x
+ $result = $this->insertEdit->getQueryValueForInsert(
+ new EditField(
+ '',
+ '0x222aaafff',
+ 'hex',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ ),
+ false,
+ ''
);
- $this->assertTrue(password_verify("a'c", mb_substr($result, 1, -1)));
+ $this->assertEquals('0x222aaafff', $result);
}
/**
- * Test for getCurrentValueForDifferentTypes
+ * Test for getQueryValuesForUpdate
*/
- public function testGetCurrentValueForDifferentTypes(): void
+ public function testGetQueryValuesForUpdate(): void
{
- $this->insertEdit = new InsertEdit(
- $GLOBALS['dbi'],
- new Relation($GLOBALS['dbi']),
- new Transformations(),
- new FileListing(),
- new Template()
+ // Simple update
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ 'foo',
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ )
);
-
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- '123',
- '0',
- [],
- '',
- [],
- [],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ $this->assertEquals(
+ "`fld` = 'foo'",
+ $result
);
- $this->assertEquals('123', $result);
-
- // case 2
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['test'],
- '',
- [1],
- [],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ // Update of null when it was null previously
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ '', // null fields will have no value
+ '',
+ false,
+ true,
+ true,
+ '',
+ null,
+ null,
+ false
+ )
);
-
- $this->assertEquals('NULL', $result);
-
- // case 3
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['test'],
- '',
- [],
- [],
- [],
- [],
- true,
- true,
+ $this->assertEquals(
'',
- 'test_table'
+ $result
);
- $this->assertEquals("''", $result);
-
- // case 4
- $_POST['fields']['multi_edit'][0][0] = [];
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['set'],
- '',
- [],
- [],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ // Update of null when it was NOT null previously
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ '', // null fields will have no value
+ '',
+ false,
+ true,
+ false,
+ '',
+ null,
+ '', // in edit mode the previous value will be empty string
+ false
+ )
);
-
- $this->assertEquals("''", $result);
-
- // case 5
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['protected'],
- '',
- [],
- ['name'],
- [],
- [],
- true,
- true,
- '`id` = 4',
- 'test_table'
+ $this->assertEquals(
+ '`fld` = NULL',
+ $result
);
- $this->assertEquals('0x313031', $result);
-
- // case 6
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['protected'],
- '',
- [],
- ['a'],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ // Update to NOT null when it was null previously
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ "ab'c",
+ '',
+ false,
+ false,
+ true,
+ '',
+ null,
+ null,
+ false
+ )
);
-
- $this->assertEquals('', $result);
-
- // case 7
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['bit'],
- '20\'12',
- [],
- ['a'],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ $this->assertEquals(
+ "`fld` = 'ab\'c'",
+ $result
);
- $this->assertEquals("b'00010'", $result);
-
- // case 7
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['date'],
- '20\'12',
- [],
- ['a'],
- [],
- [],
- true,
- true,
- '',
- 'test_table'
+ // Test to see if a zero-string is not ignored
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ '0', // zero-string provided as value
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ )
+ );
+ $this->assertEquals(
+ "`fld` = '0'",
+ $result
);
- $this->assertEquals("'20\\'12'", $result);
-
- // case 8
- $_POST['fields']['multi_edit'][0][0] = [];
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['set'],
- '',
- [],
- [],
- [1],
- [],
- true,
- true,
+ // Test to check if blob field that was left unchanged during edit will be ignored
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ '', // no value
+ 'protected',
+ false,
+ false,
+ false,
+ '',
+ null,
+ null,
+ false
+ )
+ );
+ $this->assertEquals(
'',
- 'test_table'
+ $result
);
- $this->assertEquals('NULL', $result);
+ // Test to see if a field will be ignored if it the value is unchanged
+ $result = $this->insertEdit->getQueryValueForUpdate(
+ new EditField(
+ 'fld',
+ "a'b",
+ '',
+ false,
+ false,
+ false,
+ '',
+ null,
+ "a'b",
+ false
+ )
+ );
- // case 9
- $result = $this->insertEdit->getCurrentValueForDifferentTypes(
- false,
- '0',
- ['protected'],
- '',
- [],
- ['a'],
- [],
- [1],
- true,
- true,
+ $this->assertEquals(
'',
- 'test_table'
+ $result
);
-
- $this->assertEquals("''", $result);
}
/**
diff --git a/test/classes/Stubs/DbiDummy.php b/test/classes/Stubs/DbiDummy.php
index ed32b12e08..6ea0e1777c 100644
--- a/test/classes/Stubs/DbiDummy.php
+++ b/test/classes/Stubs/DbiDummy.php
@@ -2762,9 +2762,9 @@ class DbiDummy implements DbiExtension
],
],
[
- 'query' => 'SELECT * FROM `test_table` WHERE `id` = 4;',
- 'columns' => ['id', 'name', 'datetimefield'],
- 'result' => [['4', '101', '2013-01-20 02:00:02']],
+ 'query' => 'SELECT `name` FROM `test_table` WHERE `id` = 4',
+ 'columns' => ['name'],
+ 'result' => [['101']],
],
[
'query' => 'SELECT * FROM `mysql`.`user` WHERE `User` = \'username\' AND `Host` = \'hostname\';',