diff --git a/Sources/Db/APIs/MySQL.php b/Sources/Db/APIs/MySQL.php index 625e43d520..389b2c6027 100644 --- a/Sources/Db/APIs/MySQL.php +++ b/Sources/Db/APIs/MySQL.php @@ -361,9 +361,21 @@ public function insert(string $method, string $table, array $columns, array $dat } } - // Inserting data as a single row can be done as a single array. - if (!is_array($data[array_rand($data)])) { - $data = [$data]; + // Ensure that $data is a multidimensional array. + if (array_filter($data, fn($dataRow) => is_array($dataRow)) !== $data) { + // If backward compatibility mode is enabled, quietly clean up after + // old mods that did the wrong thing. Otherwise, trigger an error. + if (!empty(Config::$backward_compatibility)) { + $data = [$data]; + } else { + $this->error_backtrace( + 'Invalid data structure sent to the database.', + '', + E_USER_ERROR, + __FILE__, + __LINE__, + ); + } } // Create the mold for a single row insert. diff --git a/Sources/Db/APIs/PostgreSQL.php b/Sources/Db/APIs/PostgreSQL.php index c9420bc34d..1aef375f1f 100644 --- a/Sources/Db/APIs/PostgreSQL.php +++ b/Sources/Db/APIs/PostgreSQL.php @@ -387,8 +387,21 @@ public function insert(string $method, string $table, array $columns, array $dat // Force method to lower case $method = strtolower($method); - if (!is_array($data[array_rand($data)])) { - $data = [$data]; + // Ensure that $data is a multidimensional array. + if (array_filter($data, fn($dataRow) => is_array($dataRow)) !== $data) { + // If backward compatibility mode is enabled, quietly clean up after + // old mods that did the wrong thing. Otherwise, trigger an error. + if (!empty(Config::$backward_compatibility)) { + $data = [$data]; + } else { + $this->error_backtrace( + 'Invalid data structure sent to the database.', + '', + E_USER_ERROR, + __FILE__, + __LINE__, + ); + } } // Replace the prefix holder with the actual prefix. diff --git a/Sources/Db/DatabaseApiInterface.php b/Sources/Db/DatabaseApiInterface.php index 821e25c801..fc40a8b5e0 100644 --- a/Sources/Db/DatabaseApiInterface.php +++ b/Sources/Db/DatabaseApiInterface.php @@ -71,16 +71,23 @@ public function fetch_all(object $request): array; public function free_result(object $result): bool; /** - * Gets the ID of the most recently inserted row. + * Inserts one or more rows of data into a database table and optionally + * returns the resulting IDs. * * @param string $method INSERT or REPLACE. * @param string $table The table (only used for Postgres). - * @param array $columns An array of the columns we're inserting the data into. Should contain 'column' => 'datatype' pairs. - * @param array $data The data to insert. - * @param array $keys The keys for the table, needs to be not empty on replace mode. - * @param object $connection = null The connection (if null, $db_connection is used). - * @param int returnmode 0 = nothing(default), 1 = last row id, 2 = all rows id as array. - * @return int The ID of the most recently inserted row. + * @param array $columns Array of the columns we're inserting the data into. + * Should contain 'column' => 'datatype' pairs. + * @param array $data Rows of data to insert. Each element of $data must + * be an array of values corresponding to $columns. + * @param array $keys The keys for the table. Must not empty in replace mode. + * @param int $returnmode 0 = nothing, 1 = last row ID, 2 = all row IDs. + * Default: 0. + * @param object $connection The connection to use. + * If null, $db_connection is used. + * @return int|array|null Null if $returnmode is 0, the ID of the most + * recently inserted row if $returnmode is 1, or the IDS of all the + * inserted rows if $returnmode is 2. */ public function insert(string $method, string $table, array $columns, array $data, array $keys, int $returnmode = 0, ?object $connection = null): int|array|null;