From 9f45cda2e601fd4638491aadd3d43f80ff4b3830 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Mon, 1 Dec 2025 12:16:36 +0100 Subject: [PATCH 1/2] test with php 8.4 and 8.5 --- .github/workflows/ci.yml | 2 +- CHANGELOG.md | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 86ca135..fb66165 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,7 +14,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.0', '8.1', '8.2', '8.3'] + php-version: ['8.0', '8.1', '8.2', '8.3', '8.4', '8.5'] include: - php-version: '8.0' composer-flags: '--prefer-stable --prefer-lowest' diff --git a/CHANGELOG.md b/CHANGELOG.md index 2e04409..b79fac4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# 2.6.2 + +* Test with PHP 8.4 and 8.5. + # 2.6.1 * Fixed: Dates with a getter/setter where incorrectly handled in the refactoring for 2.6.0. From ec9b770585b6efd4fa555b3c5ea0d1f679d94a05 Mon Sep 17 00:00:00 2001 From: David Buchmann Date: Mon, 1 Dec 2025 12:18:02 +0100 Subject: [PATCH 2/2] apply latest php-cs-fixer --- src/Compiler.php | 2 +- src/Configuration/ClassToGenerate.php | 2 +- src/Configuration/GroupCombination.php | 2 +- src/DeserializerGenerator.php | 24 +++++++++++----------- src/Exception/UnsupportedTypeException.php | 4 ++-- src/Path/ArrayEntry.php | 2 +- src/Path/ModelEntry.php | 2 +- src/Path/Root.php | 2 +- src/Recursion.php | 2 +- src/Serializer.php | 10 ++++----- src/SerializerGenerator.php | 16 +++++++-------- tests/Fixtures/AccessorOrder.php | 2 +- tests/Fixtures/NonEmptyConstructor.php | 2 +- 13 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/Compiler.php b/src/Compiler.php index 7afe5c8..2d3d4a7 100644 --- a/src/Compiler.php +++ b/src/Compiler.php @@ -11,7 +11,7 @@ final class Compiler public function __construct( private Builder $metadataBuilder, private DeserializerGenerator $deserializerGenerator, - private SerializerGenerator $serializerGenerator + private SerializerGenerator $serializerGenerator, ) { } diff --git a/src/Configuration/ClassToGenerate.php b/src/Configuration/ClassToGenerate.php index b9d7e87..9ea5c6d 100644 --- a/src/Configuration/ClassToGenerate.php +++ b/src/Configuration/ClassToGenerate.php @@ -34,7 +34,7 @@ class ClassToGenerate implements \IteratorAggregate public function __construct( private GeneratorConfiguration $configuration, private string $className, - ?array $defaultVersions = null + ?array $defaultVersions = null, ) { $this->defaultVersions = null === $defaultVersions ? null : array_map('strval', $defaultVersions); } diff --git a/src/Configuration/GroupCombination.php b/src/Configuration/GroupCombination.php index e9decba..bd7d8fe 100644 --- a/src/Configuration/GroupCombination.php +++ b/src/Configuration/GroupCombination.php @@ -27,7 +27,7 @@ public function __construct( * If not specified, this falls back to the class default. * If the array is not null, it must have a length > 0. */ - private ?array $versions = null + private ?array $versions = null, ) { sort($this->groups); diff --git a/src/DeserializerGenerator.php b/src/DeserializerGenerator.php index a75de37..69debe3 100644 --- a/src/DeserializerGenerator.php +++ b/src/DeserializerGenerator.php @@ -35,7 +35,7 @@ public function __construct( private Deserialization $templating, array $classesToGenerate, private string $cacheDirectory, - ?GeneratorConfiguration $configuration = null + ?GeneratorConfiguration $configuration = null, ) { $this->filesystem = new Filesystem(); $this->configuration = $this->createGeneratorConfiguration($configuration, $classesToGenerate); @@ -64,7 +64,7 @@ public function generate(Builder $metadataBuilder): void private function writeFile(ClassMetadata $classMetadata): void { if (\count($classMetadata->getConstructorParameters())) { - throw new \Exception(sprintf('We currently do not support deserializing when the root class has a non-empty constructor. Class %s', $classMetadata->getClassName())); + throw new \Exception(\sprintf('We currently do not support deserializing when the root class has a non-empty constructor. Class %s', $classMetadata->getClassName())); } $functionName = self::buildDeserializerFunctionName($classMetadata->getClassName()); @@ -77,7 +77,7 @@ private function writeFile(ClassMetadata $classMetadata): void $this->generateCodeForClass($classMetadata, $arrayPath, new ModelPath('model')) ); - $this->filesystem->dumpFile(sprintf('%s/%s.php', $this->cacheDirectory, $functionName), $code); + $this->filesystem->dumpFile(\sprintf('%s/%s.php', $this->cacheDirectory, $functionName), $code); } /** @@ -87,7 +87,7 @@ private function generateCodeForClass( ClassMetadata $classMetadata, ArrayPath $arrayPath, ModelPath $modelPath, - array $stack = [] + array $stack = [], ): string { $stack[$classMetadata->getClassName()] = ($stack[$classMetadata->getClassName()] ?? 0) + 1; @@ -128,9 +128,9 @@ private function generateCodeForClass( continue; } if ($definition->isRequired()) { - $msg = sprintf('Unknown constructor argument "%s". Class %s only has properties that tell how to handle %s.', $definition->getName(), $classMetadata->getClassName(), implode(', ', array_keys($constructorArgumentNames))); + $msg = \sprintf('Unknown constructor argument "%s". Class %s only has properties that tell how to handle %s.', $definition->getName(), $classMetadata->getClassName(), implode(', ', array_keys($constructorArgumentNames))); if ($overwrittenNames) { - $msg .= sprintf(' Multiple definitions for fields %s seen - the last one overwrites previous ones.', implode(', ', array_keys($overwrittenNames))); + $msg .= \sprintf(' Multiple definitions for fields %s seen - the last one overwrites previous ones.', implode(', ', array_keys($overwrittenNames))); } throw new \Exception($msg); } @@ -150,7 +150,7 @@ private function generateCodeForProperty( PropertyMetadata $propertyMetadata, ArrayPath $arrayPath, ModelPath $modelPath, - array $stack + array $stack, ): string { if ($propertyMetadata->isReadOnly()) { return ''; @@ -184,7 +184,7 @@ private function generateCodeForField( PropertyMetadata $propertyMetadata, ArrayPath $arrayPath, ModelPath $modelPath, - array $stack + array $stack, ): string { return $this->templating->renderConditional( (string) $arrayPath, @@ -199,7 +199,7 @@ private function generateInnerCodeForFieldType( PropertyMetadata $propertyMetadata, ArrayPath $arrayPath, ModelPath $modelPropertyPath, - array $stack + array $stack, ): string { $type = $propertyMetadata->getType(); @@ -241,7 +241,7 @@ private function generateCodeForArray( PropertyTypeArray $type, ArrayPath $arrayPath, ModelPath $modelPath, - array $stack + array $stack, ): string { if ($type->getSubType() instanceof PropertyTypePrimitive) { // for arrays of scalars, copy the field even when its an empty array @@ -287,7 +287,7 @@ private function generateCodeForArrayCollection( PropertyTypeArray $type, ArrayPath $arrayPath, ModelPath $modelPath, - array $stack + array $stack, ): string { $tmpVariable = ModelPath::tempVariable([(string) $modelPath, $propertyMetadata->getName()]); $innerCode = $this->generateCodeForArray($type, $arrayPath, $tmpVariable, $stack); @@ -304,7 +304,7 @@ private function generateCodeForArrayCollection( */ private function createGeneratorConfiguration( ?GeneratorConfiguration $configuration, - array $classesToGenerate + array $classesToGenerate, ): GeneratorConfiguration { if (null === $configuration) { $configuration = new GeneratorConfiguration([], []); diff --git a/src/Exception/UnsupportedTypeException.php b/src/Exception/UnsupportedTypeException.php index d115818..a008613 100644 --- a/src/Exception/UnsupportedTypeException.php +++ b/src/Exception/UnsupportedTypeException.php @@ -18,7 +18,7 @@ final class UnsupportedTypeException extends Exception public static function typeUnsupportedDeserialization(string $type): self { - return new self(sprintf(self::UNSUPPORTED_TYPE_DESERIALIZATION, $type)); + return new self(\sprintf(self::UNSUPPORTED_TYPE_DESERIALIZATION, $type)); } /** @@ -29,6 +29,6 @@ public static function typeUnsupportedSerialization(string $type, ?string $versi $versionInfo = $version ?: '[no version]'; $groupInfo = \count($groups) ? implode(', ', $groups) : '[no groups]'; - return new self(sprintf(self::UNSUPPORTED_TYPE_SERIALIZATION, $type, $versionInfo, $groupInfo)); + return new self(\sprintf(self::UNSUPPORTED_TYPE_SERIALIZATION, $type, $versionInfo, $groupInfo)); } } diff --git a/src/Path/ArrayEntry.php b/src/Path/ArrayEntry.php index caffe21..a97941d 100644 --- a/src/Path/ArrayEntry.php +++ b/src/Path/ArrayEntry.php @@ -4,7 +4,7 @@ namespace Liip\Serializer\Path; -final class ArrayEntry extends AbstractEntry +final class ArrayEntry extends AbstractEntry implements \Stringable { public function __toString(): string { diff --git a/src/Path/ModelEntry.php b/src/Path/ModelEntry.php index d5f532f..df9de5f 100644 --- a/src/Path/ModelEntry.php +++ b/src/Path/ModelEntry.php @@ -4,7 +4,7 @@ namespace Liip\Serializer\Path; -final class ModelEntry extends AbstractEntry +final class ModelEntry extends AbstractEntry implements \Stringable { public function __toString(): string { diff --git a/src/Path/Root.php b/src/Path/Root.php index 0d663df..7afa95f 100644 --- a/src/Path/Root.php +++ b/src/Path/Root.php @@ -4,7 +4,7 @@ namespace Liip\Serializer\Path; -final class Root extends AbstractEntry +final class Root extends AbstractEntry implements \Stringable { public function __toString(): string { diff --git a/src/Recursion.php b/src/Recursion.php index ebaa4a8..69edc38 100644 --- a/src/Recursion.php +++ b/src/Recursion.php @@ -16,7 +16,7 @@ abstract class Recursion public static function check(string $className, array $stack, string $modelPath): bool { if (\array_key_exists($className, $stack) && $stack[$className] > 1) { - throw new \Exception(sprintf('recursion for %s at %s', key($stack), $modelPath)); + throw new \Exception(\sprintf('recursion for %s at %s', key($stack), $modelPath)); } return false; diff --git a/src/Serializer.php b/src/Serializer.php index 90babda..6e7406d 100644 --- a/src/Serializer.php +++ b/src/Serializer.php @@ -37,7 +37,7 @@ public function serialize(mixed $data, string $format, ?Context $context = null) try { return Json::encode($this->objectToArray($data, true, $context), \JSON_UNESCAPED_SLASHES); } catch (\JsonException $e) { - throw new Exception(sprintf('Failed to JSON encode data for %s. This is not supposed to happen.', get_debug_type($data)), 0, $e); + throw new Exception(\sprintf('Failed to JSON encode data for %s. This is not supposed to happen.', get_debug_type($data)), 0, $e); } } @@ -94,14 +94,14 @@ private function arrayToObject(array $data, string $type, ?Context $context): mi } $functionName = DeserializerGenerator::buildDeserializerFunctionName($type); - $filename = sprintf('%s/%s.php', $this->cacheDirectory, $functionName); + $filename = \sprintf('%s/%s.php', $this->cacheDirectory, $functionName); if (!file_exists($filename)) { throw UnsupportedTypeException::typeUnsupportedDeserialization($type); } require_once $filename; if (!\is_callable($functionName)) { - throw new Exception(sprintf('Internal Error: Deserializer for %s in file %s does not have expected function %s', $type, $filename, $functionName)); + throw new Exception(\sprintf('Internal Error: Deserializer for %s in file %s does not have expected function %s', $type, $filename, $functionName)); } try { @@ -129,7 +129,7 @@ private function objectToArray(mixed $data, bool $useStdClass, ?Context $context } } $functionName = SerializerGenerator::buildSerializerFunctionName($type, $version ?: null, $groups); - $filename = sprintf('%s/%s.php', $this->cacheDirectory, $functionName); + $filename = \sprintf('%s/%s.php', $this->cacheDirectory, $functionName); if (!file_exists($filename)) { throw UnsupportedTypeException::typeUnsupportedSerialization($type, $version, $groups); } @@ -137,7 +137,7 @@ private function objectToArray(mixed $data, bool $useStdClass, ?Context $context require_once $filename; if (!\is_callable($functionName)) { - throw new Exception(sprintf('Internal Error: Serializer for %s in file %s does not have expected function %s', $type, $filename, $functionName)); + throw new Exception(\sprintf('Internal Error: Serializer for %s in file %s does not have expected function %s', $type, $filename, $functionName)); } try { diff --git a/src/SerializerGenerator.php b/src/SerializerGenerator.php index 59be154..2915a70 100644 --- a/src/SerializerGenerator.php +++ b/src/SerializerGenerator.php @@ -30,7 +30,7 @@ final class SerializerGenerator public function __construct( private Serialization $templating, private GeneratorConfiguration $configuration, - private string $cacheDirectory + private string $cacheDirectory, ) { $this->filesystem = new Filesystem(); } @@ -95,7 +95,7 @@ private function writeFile( string $className, ?string $apiVersion, array $serializerGroups, - ClassMetadata $classMetadata + ClassMetadata $classMetadata, ): void { $functionName = self::buildSerializerFunctionName($className, $apiVersion, $serializerGroups); @@ -105,7 +105,7 @@ private function writeFile( $this->generateCodeForClass($classMetadata, $apiVersion, $serializerGroups, '', '$model') ); - $this->filesystem->dumpFile(sprintf('%s/%s.php', $this->cacheDirectory, $functionName), $code); + $this->filesystem->dumpFile(\sprintf('%s/%s.php', $this->cacheDirectory, $functionName), $code); } /** @@ -118,7 +118,7 @@ private function generateCodeForClass( array $serializerGroups, string $arrayPath, string $modelPath, - array $stack = [] + array $stack = [], ): string { $stack[$classMetadata->getClassName()] = ($stack[$classMetadata->getClassName()] ?? 0) + 1; @@ -140,7 +140,7 @@ private function generateCodeForField( array $serializerGroups, string $arrayPath, string $modelPath, - array $stack + array $stack, ): string { if (Recursion::hasMaxDepthReached($propertyMetadata, $stack)) { return ''; @@ -158,7 +158,7 @@ private function generateCodeForField( ); } if (!$propertyMetadata->isPublic()) { - throw new \Exception(sprintf('Property %s is not public and no getter has been defined. Stack %s', $modelPropertyPath, var_export($stack, true))); + throw new \Exception(\sprintf('Property %s is not public and no getter has been defined. Stack %s', $modelPropertyPath, var_export($stack, true))); } return $this->templating->renderConditional( @@ -177,7 +177,7 @@ private function generateCodeForFieldType( array $serializerGroups, string $fieldPath, string $modelPropertyPath, - array $stack + array $stack, ): string { switch ($type) { case $type instanceof PropertyTypeDateTime: @@ -214,7 +214,7 @@ private function generateCodeForArray( array $serializerGroups, string $arrayPath, string $modelPath, - array $stack + array $stack, ): string { $index = '$index'.mb_strlen($arrayPath); $subType = $type->getSubType(); diff --git a/tests/Fixtures/AccessorOrder.php b/tests/Fixtures/AccessorOrder.php index 29f29e6..e955006 100644 --- a/tests/Fixtures/AccessorOrder.php +++ b/tests/Fixtures/AccessorOrder.php @@ -35,7 +35,7 @@ public function __construct( * * @Serializer\Until("1") */ - public ?string $apiString2 + public ?string $apiString2, ) { $this->apiString1 = $apiString1; } diff --git a/tests/Fixtures/NonEmptyConstructor.php b/tests/Fixtures/NonEmptyConstructor.php index c759eac..1056b8e 100644 --- a/tests/Fixtures/NonEmptyConstructor.php +++ b/tests/Fixtures/NonEmptyConstructor.php @@ -22,7 +22,7 @@ public function __construct( /** * @Serializer\Type("string") */ - private string $optional = 'optional' + private string $optional = 'optional', ) { }