diff options
-rw-r--r-- | libraries/classes/Controllers/Table/ReplaceController.php | 120 | ||||
-rw-r--r-- | libraries/classes/EditField.php | 56 | ||||
-rw-r--r-- | libraries/classes/InsertEdit.php | 309 | ||||
-rw-r--r-- | phpstan-baseline.neon | 70 | ||||
-rw-r--r-- | psalm-baseline.xml | 79 | ||||
-rw-r--r-- | test/classes/InsertEditTest.php | 896 | ||||
-rw-r--r-- | test/classes/Stubs/DbiDummy.php | 6 |
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->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\';', |