Skip to content

Commit ba5af3f

Browse files
committed
[TASK] Avoid json encoding of ParameterType
Doctrine DBAL 4 transform the `ParameterType` from class to a native enum, which is a non baked enum which prevents serialization of the enum, for example using `json_encode()`. The `DatabaseAccessor` used for the function test `withSnapshot()` feature encodes column information of the snapshotted data as json, badly breaking down with `Doctrine DBAL 4`. `TYPO3\CMS\Core\Database\Connection` has been modified to determine the parameter types for `insert()`, `update()` and similar methods based on the database structure if the types are not passed. This change modifes the column preparation to avoid the enum type and instead save the doctrine type name as string. This is only done, if `ParameterType` is a real enum and therefore only with `Doctrine DBAL 4`. The adjustment on the `Connection` is added to the `Doctrine DBAL 4 Upgrade` change and is therefore a tight coupled bridge. [1] https://github.com/doctrine/dbal/blob/4.0.x/UPGRADE.md#bc-break-converted-enum-like-classes-to-enums [2] https://review.typo3.org/c/Packages/TYPO3.CMS/+/76553 Releases: main
1 parent 4f927cc commit ba5af3f

File tree

1 file changed

+16
-3
lines changed

1 file changed

+16
-3
lines changed

Classes/Core/Functional/Framework/DataHandling/Snapshot/DatabaseAccessor.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717

1818
namespace TYPO3\TestingFramework\Core\Functional\Framework\DataHandling\Snapshot;
1919

20+
use Doctrine\DBAL\ParameterType;
2021
use Doctrine\DBAL\Schema\Table;
22+
use Doctrine\DBAL\Types\Type;
23+
use Doctrine\DBAL\Types\Types;
2124
use TYPO3\CMS\Core\Database\Connection;
2225
use TYPO3\CMS\Core\Database\Query\QueryBuilder as TYPO3QueryBuilder;
2326
use TYPO3\TestingFramework\Core\Testbase;
@@ -116,9 +119,19 @@ private function prepareColumns(array $columnNames, Table $table): array
116119
{
117120
$columnTypes = array_map(
118121
function (string $columnName) use ($table) {
119-
return $table->getColumn($columnName)
120-
->getType()
121-
->getBindingType();
122+
// Doctrine DBAL v4 converted the `*ParameterType` to an enum, and therefore returning this enum instead
123+
// of the string value like before. As this is a non-baked enum, it cannot be serialized or json_encoded,
124+
// and breaking the snapshot export badly. Due to the requirement to support Doctrine DBAL v3 and v4 it
125+
// is necessary to detect the enum end return the doctrine type name instead. The `Connection->insert()`
126+
// adjustment is adjusted to transform the provided types during import to the correct ParameterType
127+
// again.
128+
// @see https://github.com/doctrine/dbal/blob/4.0.x/UPGRADE.md#bc-break-converted-enum-like-classes-to-enums
129+
// @todo Simplify this after Doctine DBAL v3 support can be dropped.
130+
$type = $table->getColumn($columnName)->getType();
131+
$bindingType = $type->getBindingType();
132+
return (enum_exists(ParameterType::class))
133+
? Type::lookupName($type)
134+
: $type->getBindingType();
122135
},
123136
$columnNames
124137
);

0 commit comments

Comments
 (0)