From 971bb92a8c4ef46cc518c100d3a9c0ecf880521d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Mon, 10 Jun 2024 21:11:11 +0200 Subject: [PATCH] Fixed error caused by ArrayType fields which is required by the webauthn bundle but was removed in doctrine/orm 4.0 We simple forward port the ArrayType class from orm 3.8 to fix this error --- config/packages/doctrine.yaml | 4 ++ src/Doctrine/Types/ArrayType.php | 116 +++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 src/Doctrine/Types/ArrayType.php diff --git a/config/packages/doctrine.yaml b/config/packages/doctrine.yaml index 3a160030..8dac4552 100644 --- a/config/packages/doctrine.yaml +++ b/config/packages/doctrine.yaml @@ -17,6 +17,10 @@ doctrine: class: App\Doctrine\Types\BigDecimalType tinyint: class: App\Doctrine\Types\TinyIntType + + # This was removed in doctrine/orm 4.0 but we need it for the WebauthnKey entity + array: + class: App\Doctrine\Types\ArrayType schema_filter: ~^(?!internal)~ # Only enable this when needed diff --git a/src/Doctrine/Types/ArrayType.php b/src/Doctrine/Types/ArrayType.php new file mode 100644 index 00000000..daab9b75 --- /dev/null +++ b/src/Doctrine/Types/ArrayType.php @@ -0,0 +1,116 @@ +. + */ + +declare(strict_types=1); + +namespace App\Doctrine\Types; + +use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Types\Exception\SerializationFailed; +use Doctrine\DBAL\Types\Type; +use Doctrine\Deprecations\Deprecation; + +use function is_resource; +use function restore_error_handler; +use function serialize; +use function set_error_handler; +use function stream_get_contents; +use function unserialize; + +use const E_DEPRECATED; +use const E_USER_DEPRECATED; + +/** + * This class is taken from doctrine ORM 3.8. https://github.com/doctrine/dbal/blob/3.8.x/src/Types/ArrayType.php + * + * It was removed in doctrine ORM 4.0. However, we require it for backward compatibility with WebauthnKey. + * Therefore, we manually added it here as a custom type as a forward compatibility layer. + */ +class ArrayType extends Type +{ + /** + * {@inheritDoc} + */ + public function getSQLDeclaration(array $column, AbstractPlatform $platform): string + { + return $platform->getClobTypeDeclarationSQL($column); + } + + /** + * {@inheritDoc} + */ + public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): string + { + return serialize($value); + } + + /** + * {@inheritDoc} + */ + public function convertToPHPValue(mixed $value, AbstractPlatform $platform): mixed + { + if ($value === null) { + return null; + } + + $value = is_resource($value) ? stream_get_contents($value) : $value; + + set_error_handler(function (int $code, string $message): bool { + if ($code === E_DEPRECATED || $code === E_USER_DEPRECATED) { + return false; + } + + //Change to original code. Use SerializationFailed instead of ConversionException. + throw new SerializationFailed("Serialization failed (Code $code): " . $message); + }); + + try { + //Change to original code. Use false for allowed_classes, to avoid unsafe unserialization of objects. + return unserialize($value, ['allowed_classes' => false]); + } finally { + restore_error_handler(); + } + } + + /** + * {@inheritDoc} + */ + public function getName(): string + { + return "array"; + } + + /** + * {@inheritDoc} + * + * @deprecated + */ + public function requiresSQLCommentHint(AbstractPlatform $platform): bool + { + Deprecation::triggerIfCalledFromOutside( + 'doctrine/dbal', + 'https://github.com/doctrine/dbal/pull/5509', + '%s is deprecated.', + __METHOD__, + ); + + return true; + } +} \ No newline at end of file