Bug #105004
closedPHP Warning: Array to string conversion when persisting JSON data (persists "Array" if warnings are silenced)
100%
Description
Version: 13.3.0
Steps to reproduce:
composer create-project typo3/cms-base-distribution project-name ^13
Install via vendor/bin/typo3 setup
Database: sqlite
Module: Webhooks > Create new record
Select trigger "typo3/file-added"
Add name: foobar,
URL: http://127.0.0.1/
Secret: press dice-button
Press Save
Exception/Warning:
PHP Warning: Array to string conversion in […]/vendor/doctrine/dbal/src/Driver/PDO/Statement.php line 26
(1/1) #1476107295 TYPO3\CMS\Core\Error\Exception PHP Warning: Array to string conversion in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Driver/PDO/Statement.php line 26 in /home/ben/src/test-13-3/vendor/typo3/cms-core/Classes/Error/ErrorHandler.php line 138 } $message = self::ERROR_LEVEL_LABELS[$errorLevel] . ': ' . $errorMessage . ' in ' . $errorFile . ' line ' . $errorLine; if ($errorLevel & $this->exceptionalErrors) { throw new Exception($message, 1476107295); } $message = $this->getFormattedLogMessage($message); at TYPO3\CMS\Core\Error\ErrorHandler->handleError() at PDOStatement->bindValue() in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Driver/PDO/Statement.php line 26 { $pdoType = $this->convertParamType($type); try { $this->stmt->bindValue($param, $value, $pdoType); } catch (PDOException $exception) { throw Exception::new($exception); } } at Doctrine\DBAL\Driver\PDO\Statement->bindValue() in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Driver/Middleware/AbstractStatementMiddleware.php line 19 } public function bindValue(int|string $param, mixed $value, ParameterType $type): void { $this->wrappedStatement->bindValue($param, $value, $type); } public function execute(): Result { at Doctrine\DBAL\Driver\Middleware\AbstractStatementMiddleware->bindValue() in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Connection.php line 1243 } else { $bindingType = ParameterType::STRING; } $stmt->bindValue($bindIndex, $value, $bindingType); ++$bindIndex; } } else { at Doctrine\DBAL\Connection->bindParameters() in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Connection.php line 865 [$sql, $params, $types] = $this->expandArrayParameters($sql, $params, $types); $stmt = $connection->prepare($sql); $this->bindParameters($stmt, $params, $types); return $stmt->execute() ->rowCount(); } at Doctrine\DBAL\Connection->executeStatement() in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Connection.php line 510 $values[] = $value; $set[] = '?'; } return $this->executeStatement( 'INSERT INTO ' . $table . ' (' . implode(', ', $columns) . ')' . ' VALUES (' . implode(', ', $set) . ')', $values, is_string(key($types)) ? $this->extractTypeValues($columns, $types) : $types, at Doctrine\DBAL\Connection->insert() in /home/ben/src/test-13-3/vendor/typo3/cms-core/Classes/Database/Connection.php line 192 */ public function insert(string $tableName, array $data, array $types = []): int { $this->ensureDatabaseValueTypes($tableName, $data, $types); return parent::insert( $this->quoteIdentifier($tableName), $this->quoteColumnValuePairs($data), $this->quoteColumnTypes($types) ); at TYPO3\CMS\Core\Database\Connection->insert() in /home/ben/src/test-13-3/vendor/typo3/cms-core/Classes/DataHandling/DataHandler.php line 7721 $connection = $this->connectionPool->getConnectionForTable($table); $insertErrorMessage = ''; try { // Execute the INSERT query: $connection->insert($table, $fieldArray); } catch (DBALException $e) { $insertErrorMessage = $e->getPrevious()->getMessage(); } // If succees, do...: at TYPO3\CMS\Core\DataHandling\DataHandler->insertDB() in /home/ben/src/test-13-3/vendor/typo3/cms-core/Classes/DataHandling/DataHandler.php line 1080 $this->insertDB($table, $id, $fieldArray, true, (int)($incomingFieldArray['uid'] ?? 0)); // Hold auto-versionized ids of placeholders $this->autoVersionIdMap[$table][$this->substNEWwithIDs[$id]] = $this->substNEWwithIDs[$id]; } else { $this->insertDB($table, $id, $fieldArray, false, (int)($incomingFieldArray['uid'] ?? 0)); } } else { if ($table === 'pages') { // Only a certain number of fields needs to be checked for updates, at TYPO3\CMS\Core\DataHandling\DataHandler->process_datamap() in /home/ben/src/test-13-3/vendor/typo3/cms-backend/Classes/Controller/EditDocumentController.php line 554 } // Perform the saving operation with DataHandler: if ($this->doSave === true) { $tce->process_datamap(); $tce->process_cmdmap(); // Update the module menu for the current backend user, as they updated their UI language $currentUserId = $beUser->getUserId();
Files
Updated by Benjamin Franzke 2 months ago
Note that sqlite schema differs between v12 and v13:
v12:
.schema sys_webhook CREATE TABLE sys_webhook ( "uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "pid" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "updatedon" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "createdon" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "deleted" SMALLINT UNSIGNED DEFAULT 0 NOT NULL, "disabled" SMALLINT UNSIGNED DEFAULT 0 NOT NULL, "starttime" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "endtime" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "description" CLOB DEFAULT NULL, "name" VARCHAR(100) DEFAULT '' NOT NULL, "url" VARCHAR(2048) DEFAULT '' NOT NULL, "method" VARCHAR(10) DEFAULT '' NOT NULL, "secret" VARCHAR(255) DEFAULT '' NOT NULL, "webhook_type" VARCHAR(255) DEFAULT '' NOT NULL, "verify_ssl" INTEGER DEFAULT 1 NOT NULL, "additional_headers" CLOB DEFAULT NULL --(DC2Type:json), "identifier" VARCHAR(36) DEFAULT '' NOT NULL )
v13:
.schema sys_webhook CREATE TABLE IF NOT EXISTS "sys_webhook" ( "uid" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "pid" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "updatedon" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "createdon" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "deleted" SMALLINT UNSIGNED DEFAULT 0 NOT NULL, "disabled" SMALLINT UNSIGNED DEFAULT 0 NOT NULL, "starttime" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "endtime" INTEGER UNSIGNED DEFAULT 0 NOT NULL, "description" CLOB DEFAULT NULL COLLATE "BINARY", "webhook_type" VARCHAR(255) DEFAULT '' NOT NULL COLLATE "BINARY", "name" VARCHAR(100) DEFAULT '' NOT NULL COLLATE "BINARY", "identifier" VARCHAR(36) DEFAULT '' NOT NULL COLLATE "BINARY", "secret" VARCHAR DEFAULT '' NOT NULL COLLATE "BINARY", "url" CLOB DEFAULT '' NOT NULL COLLATE "BINARY", "method" VARCHAR(10) DEFAULT '' NOT NULL COLLATE "BINARY", "verify_ssl" SMALLINT UNSIGNED DEFAULT 1 NOT NULL, "additional_headers" CLOB DEFAULT NULL COLLATE "BINARY" );
While v12 has "additional_headers" CLOB DEFAULT NULL --(DC2Type:json),
it is just "additional_headers" CLOB DEFAULT NULL COLLATE "BINARY"
in v13.
That means: Introspection that uses connection->createSchemaManager()->introspectSchema
to obtain target types will detect the column as a string-type and thus won't json_encode array`s to strings before sending binding them via bindValue()
Updated by Benjamin Franzke 2 months ago
- Subject changed from PHP Warning: Array to string conversion in /home/ben/src/test-13-3/vendor/doctrine/dbal/src/Driver/PDO/Statement.php line 26 to PHP Warning: Array to string conversion when persisting JSON data (persists "Array" if warnings are silenced)
Updated by Benjamin Franzke 2 months ago
I guess this happended because doctrine removed type comments in doctrine/dbal 4.0:
https://github.com/doctrine/dbal/pull/5107
That means: We must not longer introspect the schema to obtain target types – we should rather use our own schema.
Updated by Stefan Bürk about 2 months ago
- Related to Task #105208: Ensure correct type resolving in `AbstractSchemaManager` added
Updated by Gerrit Code Review about 2 months ago
- Status changed from New to Under Review
Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 2 months ago
Patch set 2 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 2 months ago
Patch set 3 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 2 months ago
Patch set 4 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 2 months ago
Patch set 5 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 1 month ago
Patch set 6 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 1 month ago
Patch set 7 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 1 month ago
Patch set 8 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 1 month ago
Patch set 9 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Gerrit Code Review about 1 month ago
Patch set 10 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/86436
Updated by Stefan Bürk about 1 month ago
- Status changed from Under Review to Resolved
- % Done changed from 0 to 100
Applied in changeset 07e8935a886eeb9b37927268ea6f82a8f43ba2d9.