From 8fdd5c9ebb93b27619ceeb5a403f4a396382ba05 Mon Sep 17 00:00:00 2001 From: divyajose Date: Tue, 16 May 2023 16:50:31 +0530 Subject: [PATCH] Changes for symfony 6.2 upgrade --- .../Normalizer/ApiProductNormalizer.php | 6 +++- .../CompanyMembershipNormalizer.php | 6 +++- .../NameConverter/NameConverterBase.php | 4 +-- .../Normalizer/ApiPackageNormalizer.php | 8 +++-- .../Normalizer/EntityNormalizer.php | 6 +++- .../Normalizer/ReportCriteriaNormalizer.php | 9 ++++-- .../Serializer/ReportDefinitionSerializer.php | 3 +- src/Denormalizer/EdgeDateDenormalizer.php | 5 +-- src/Normalizer/ObjectNormalizer.php | 7 +++-- .../PropertiesPropertyNormalizer.php | 6 +++- .../PropertyAccessorDecorator.php | 31 +++++++------------ src/Serializer/EntitySerializer.php | 9 +++--- src/Serializer/JsonDecode.php | 2 +- ...rofileEntityReferencePropertyValidator.php | 2 +- tests/Serializer/EntitySerializerTest.php | 2 +- .../PropertiesPropertyTransformationTest.php | 2 +- .../HttpClient/FileSystemResponseFactory.php | 2 +- 17 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/Api/ApigeeX/Normalizer/ApiProductNormalizer.php b/src/Api/ApigeeX/Normalizer/ApiProductNormalizer.php index 8ebb08db..e29dbb08 100755 --- a/src/Api/ApigeeX/Normalizer/ApiProductNormalizer.php +++ b/src/Api/ApigeeX/Normalizer/ApiProductNormalizer.php @@ -52,7 +52,11 @@ public function normalize($object, $format = null, array $context = []) { $normalized = (array) parent::normalize($object, $format, $context); - return (object) $normalized; + //convert to ArrayObject as symfony normalizer throws error for std object. + //set ARRAY_AS_PROPS flag as we need entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $normalized = new \ArrayObject($normalized, $array_as_props); + return ($normalized); } /** diff --git a/src/Api/Management/Normalizer/CompanyMembershipNormalizer.php b/src/Api/Management/Normalizer/CompanyMembershipNormalizer.php index 227b9b34..40528439 100644 --- a/src/Api/Management/Normalizer/CompanyMembershipNormalizer.php +++ b/src/Api/Management/Normalizer/CompanyMembershipNormalizer.php @@ -39,7 +39,11 @@ public function normalize($object, $format = null, array $context = []) $normalized['developer'][] = (object) ['email' => $member, 'role' => $role]; } - return (object) $normalized; + //convert to ArrayObject as symfony normalizer throws error for std object. + //set ARRAY_AS_PROPS flag as we need entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $normalized = new \ArrayObject($normalized, $array_as_props); + return ($normalized); } /** diff --git a/src/Api/Monetization/NameConverter/NameConverterBase.php b/src/Api/Monetization/NameConverter/NameConverterBase.php index 5f684780..1b960005 100644 --- a/src/Api/Monetization/NameConverter/NameConverterBase.php +++ b/src/Api/Monetization/NameConverter/NameConverterBase.php @@ -25,7 +25,7 @@ abstract class NameConverterBase implements NameConverterInterface /** * {@inheritdoc} */ - public function normalize($propertyName) + public function normalize($propertyName): string { if ($externalPropertyName = array_search($propertyName, $this->getExternalToLocalMapping())) { return $externalPropertyName; @@ -37,7 +37,7 @@ public function normalize($propertyName) /** * {@inheritdoc} */ - public function denormalize($propertyName) + public function denormalize($propertyName): string { if (array_key_exists($propertyName, $this->getExternalToLocalMapping())) { return $this->getExternalToLocalMapping()[$propertyName]; diff --git a/src/Api/Monetization/Normalizer/ApiPackageNormalizer.php b/src/Api/Monetization/Normalizer/ApiPackageNormalizer.php index 6c086684..aaf39a32 100644 --- a/src/Api/Monetization/Normalizer/ApiPackageNormalizer.php +++ b/src/Api/Monetization/Normalizer/ApiPackageNormalizer.php @@ -54,10 +54,14 @@ public function normalize($object, $format = null, array $context = []) // Do not send redundant API product information to Apigee Edge, the // id of a referenced API product is enough. foreach ($normalized['product'] as $id => $data) { - $normalized['product'][$id] = (object) ['id' => $data->id]; + $normalized['product'][$id] = (object) ['id' => $data['id']]; } - return (object) $normalized; + //convert to ArrayObject as symfony normalizer throws error for std object. + //set ARRAY_AS_PROPS flag as we need entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $normalized = new \ArrayObject($normalized, $array_as_props); + return ($normalized); } /** diff --git a/src/Api/Monetization/Normalizer/EntityNormalizer.php b/src/Api/Monetization/Normalizer/EntityNormalizer.php index ade03680..e0e987ac 100644 --- a/src/Api/Monetization/Normalizer/EntityNormalizer.php +++ b/src/Api/Monetization/Normalizer/EntityNormalizer.php @@ -96,7 +96,11 @@ public function normalize($object, $format = null, array $context = []) } } - return (object) $normalized; + //convert to ArrayObject as symfony normalizer throws error for std object. + //set ARRAY_AS_PROPS flag as we need entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $normalized = new \ArrayObject($normalized, $array_as_props); + return ($normalized); } /** diff --git a/src/Api/Monetization/Normalizer/ReportCriteriaNormalizer.php b/src/Api/Monetization/Normalizer/ReportCriteriaNormalizer.php index 857a8e18..eb28d0b5 100644 --- a/src/Api/Monetization/Normalizer/ReportCriteriaNormalizer.php +++ b/src/Api/Monetization/Normalizer/ReportCriteriaNormalizer.php @@ -75,14 +75,19 @@ public function normalize($object, $format = null, array $context = []) // According to the API documentation it is always UTC. // https://docs.apigee.com/api-platform/monetization/create-reports#createreportdefapi $this->fixTimeZoneOnNormalization($object, $normalized, new \DateTimeZone('UTC')); - + $arr_empty = []; // Just in case, do not send empty array values either to this API. foreach ($normalized as $property => $value) { if (is_array($value) && empty($value)) { - unset($normalized->{$property}); + //Get all the array which is empty + $arr_empty[] = $property; } } + foreach ($arr_empty as $val) { + unset($normalized->{$val}); + } + return $normalized; } diff --git a/src/Api/Monetization/Serializer/ReportDefinitionSerializer.php b/src/Api/Monetization/Serializer/ReportDefinitionSerializer.php index d04d17e7..6826ade0 100644 --- a/src/Api/Monetization/Serializer/ReportDefinitionSerializer.php +++ b/src/Api/Monetization/Serializer/ReportDefinitionSerializer.php @@ -69,8 +69,9 @@ public static function getEntityTypeSpecificDefaultNormalizers(): array /** * {@inheritdoc} */ - public function deserialize($data, $type, $format, array $context = []) + public function deserialize($data, $type, $format, array $context = []): mixed { + $context['json_decode_associative'] = false; // Because of the decorator pattern in the EntitySerializer we have to // repeat this in here as well. if ($this->supportsDecoding($format)) { diff --git a/src/Denormalizer/EdgeDateDenormalizer.php b/src/Denormalizer/EdgeDateDenormalizer.php index 3a5ae6df..b09324e5 100644 --- a/src/Denormalizer/EdgeDateDenormalizer.php +++ b/src/Denormalizer/EdgeDateDenormalizer.php @@ -59,8 +59,9 @@ public function denormalize($data, $type, $format = null, array $context = []) } $context[$this->normalizer::FORMAT_KEY] = 'U'; $context[$this->normalizer::TIMEZONE_KEY] = new \DateTimeZone('UTC'); - - return $this->normalizer->denormalize(intval($data / 1000), $type, $format, $context); + //convert data in string format for denormaliser. + $data = (string) intval($data / 1000); + return $this->normalizer->denormalize($data, $type, $format, $context); } /** diff --git a/src/Normalizer/ObjectNormalizer.php b/src/Normalizer/ObjectNormalizer.php index eff2fab6..6157fa23 100644 --- a/src/Normalizer/ObjectNormalizer.php +++ b/src/Normalizer/ObjectNormalizer.php @@ -103,8 +103,11 @@ public function normalize($object, $format = null, array $context = []) return !is_null($value); }); ksort($asArray); - - return (object) $asArray; + //Need to convert to ArrayObject as symfony normalizer throws error for std object. + //Need to set ARRAY_AS_PROPS flag as we need Entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $asArray = new \ArrayObject($asArray, $array_as_props); + return ($asArray); } /** diff --git a/src/Normalizer/PropertiesPropertyNormalizer.php b/src/Normalizer/PropertiesPropertyNormalizer.php index 57661da8..68eab81c 100644 --- a/src/Normalizer/PropertiesPropertyNormalizer.php +++ b/src/Normalizer/PropertiesPropertyNormalizer.php @@ -39,7 +39,11 @@ public function normalize($object, $format = null, array $context = []) 'property' => parent::normalize($object, $format, $context), ]; - return (object) $return; + //convert to ArrayObject as symfony normalizer throws error for std object. + //set ARRAY_AS_PROPS flag as we need entries to be accessed as properties. + $array_as_props = \ArrayObject::ARRAY_AS_PROPS; + $return = new \ArrayObject($return, $array_as_props); + return ($return); } /** diff --git a/src/PropertyAccess/PropertyAccessorDecorator.php b/src/PropertyAccess/PropertyAccessorDecorator.php index e90cba7d..47429184 100644 --- a/src/PropertyAccess/PropertyAccessorDecorator.php +++ b/src/PropertyAccess/PropertyAccessorDecorator.php @@ -91,7 +91,7 @@ public function setValue(&$objectOrArray, $propertyPath, $value): void /** * {@inheritdoc} */ - public function getValue($objectOrArray, $propertyPath) + public function getValue($objectOrArray, $propertyPath): mixed { try { $value = $this->propertyAccessor->getValue($objectOrArray, $propertyPath); @@ -112,7 +112,7 @@ public function getValue($objectOrArray, $propertyPath) /** * {@inheritdoc} */ - public function isWritable($objectOrArray, $propertyPath) + public function isWritable($objectOrArray, $propertyPath): bool { return $this->propertyAccessor->isWritable($objectOrArray, $propertyPath); } @@ -120,7 +120,7 @@ public function isWritable($objectOrArray, $propertyPath) /** * {@inheritdoc} */ - public function isReadable($objectOrArray, $propertyPath) + public function isReadable($objectOrArray, $propertyPath): bool { return $this->propertyAccessor->isReadable($objectOrArray, $propertyPath); } @@ -174,6 +174,7 @@ private static function processTypeErrorOnGetValue($object, string $property, \T * @param $message * @param $trace * @param $i + * @param $propertyPath * @param $previous * * @see \Symfony\Component\PropertyAccess\PropertyAccessor::throwInvalidArgumentException() @@ -181,30 +182,20 @@ private static function processTypeErrorOnGetValue($object, string $property, \T * @psalm-suppress PossiblyFalseOperand * @psalm-suppress PossiblyFalseArgument */ - private static function processTypeErrorOnSetValue($message, $trace, $i, $previous = null): void + private static function processTypeErrorOnSetValue($message, $trace, $i, string $propertyPath, $previous = null): void { if (!isset($trace[$i]['file']) || __FILE__ !== $trace[$i]['file']) { return; } + if (preg_match('/^\S+::\S+\(\): Argument #\d+ \(\$\S+\) must be of type (\S+), (\S+) given/', $message, $matches)) { + [, $expectedType, $actualType] = $matches; - if (\PHP_VERSION_ID < 80000) { - if (0 !== strpos($message, 'Argument ')) { - return; - } - - $pos = strpos($message, $delim = 'must be of the type ') ?: (strpos($message, $delim = 'must be an instance of ') ?: strpos($message, $delim = 'must implement interface ')); - $pos += \strlen($delim); - $j = strpos($message, ',', $pos); - $type = substr($message, 2 + $j, strpos($message, ' given', $j) - $j - 2); - $message = substr($message, $pos, $j - $pos); - - throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given.', $message, 'NULL' === $type ? 'null' : $type), 0, $previous); + throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given at property path "%s".', $expectedType, 'NULL' === $actualType ? 'null' : $actualType, $propertyPath), 0, $previous); } + if (preg_match('/^Cannot assign (\S+) to property \S+::\$\S+ of type (\S+)$/', $message, $matches)) { + [, $actualType, $expectedType] = $matches; - if (preg_match('/^\S+::\S+\(\): Argument #\d+ \(\$\S+\) must be of type (\S+), (\S+) given/', $message, $matches)) { - list(, $expectedType, $actualType) = $matches; - - throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given.', $expectedType, 'NULL' === $actualType ? 'null' : $actualType), 0, $previous); + throw new InvalidArgumentException(sprintf('Expected argument of type "%s", "%s" given at property path "%s".', $expectedType, 'NULL' === $actualType ? 'null' : $actualType, $propertyPath), 0, $previous); } } } diff --git a/src/Serializer/EntitySerializer.php b/src/Serializer/EntitySerializer.php index b9643d64..0e0659eb 100755 --- a/src/Serializer/EntitySerializer.php +++ b/src/Serializer/EntitySerializer.php @@ -103,7 +103,7 @@ public function supportsNormalization($data, $format = null) /** * {@inheritdoc} */ - public function serialize($data, $format, array $context = []) + public function serialize($data, $format, array $context = []): string { if (!$this->supportsEncoding($format)) { throw new NotEncodableValueException(sprintf('Serialization for the format %s is not supported. Only %s supported.', $format, $this->format)); @@ -115,12 +115,13 @@ public function serialize($data, $format, array $context = []) /** * {@inheritdoc} */ - public function deserialize($data, $type, $format, array $context = []) + public function deserialize($data, $type, $format, array $context = []): mixed { if (!$this->supportsDecoding($format)) { throw new NotEncodableValueException(sprintf('Deserialization for the format %s is not supported. Only %s is supported.', $format, $this->format)); } + $context['json_decode_associative'] = false; return $this->serializer->deserialize($data, $type, $format, $context); } @@ -202,7 +203,7 @@ public function supportsDecoding($format) /** * {@inheritdoc} */ - public function encode($data, $format, array $context = []) + public function encode($data, $format, array $context = []): string { return $this->serializer->encode($data, $format, $context = []); } @@ -210,7 +211,7 @@ public function encode($data, $format, array $context = []) /** * {@inheritdoc} */ - public function supportsEncoding($format) + public function supportsEncoding($format): bool { return $this->format === $format && $this->serializer->supportsEncoding($format); } diff --git a/src/Serializer/JsonDecode.php b/src/Serializer/JsonDecode.php index 9b09a041..4270ce88 100644 --- a/src/Serializer/JsonDecode.php +++ b/src/Serializer/JsonDecode.php @@ -75,7 +75,7 @@ public function __construct($defaultContext = [], int $depth = 512) /** * {@inheritdoc} */ - public function decode($data, $format, array $context = []) + public function decode($data, $format, array $context = []): mixed { $context['json_decode_options'] = empty($context['json_decode_options']) ? $this->options : $context['json_decode_options']; diff --git a/tests/Api/Monetization/EntitySerializer/PropertyValidator/OrganizationProfileEntityReferencePropertyValidator.php b/tests/Api/Monetization/EntitySerializer/PropertyValidator/OrganizationProfileEntityReferencePropertyValidator.php index 3da842bb..8e42624e 100644 --- a/tests/Api/Monetization/EntitySerializer/PropertyValidator/OrganizationProfileEntityReferencePropertyValidator.php +++ b/tests/Api/Monetization/EntitySerializer/PropertyValidator/OrganizationProfileEntityReferencePropertyValidator.php @@ -41,7 +41,7 @@ public function validate(\stdClass $input, \stdClass $output, EntityInterface $e return; } - Assert::assertEquals($output->{static::validatedProperty()}, (object) ['id' => $entity->getOrganization()->id()]); + Assert::assertEquals((object) ['id' => $output->{static::validatedProperty()}->id], (object) ['id' => $entity->getOrganization()->id()]); $actual = json_decode($this->entitySerializer->serialize($entity->getOrganization(), 'json')); $expected = $input->{static::validatedProperty()}; diff --git a/tests/Serializer/EntitySerializerTest.php b/tests/Serializer/EntitySerializerTest.php index fc645a71..5e874533 100644 --- a/tests/Serializer/EntitySerializerTest.php +++ b/tests/Serializer/EntitySerializerTest.php @@ -106,7 +106,7 @@ public function testNormalize() * * @param \stdClass $normalized */ - public function testDenormalize(\stdClass $normalized): void + public function testDenormalize(mixed $normalized): void { // Set value of this nullable value to ensure that a special condition is triggered in the EntityDenormalizer. $normalized->nullable = null; diff --git a/tests/Structure/PropertiesPropertyTransformationTest.php b/tests/Structure/PropertiesPropertyTransformationTest.php index b4392960..8dff7849 100644 --- a/tests/Structure/PropertiesPropertyTransformationTest.php +++ b/tests/Structure/PropertiesPropertyTransformationTest.php @@ -71,7 +71,7 @@ public function testNormalize() * * @param \stdClass $normalized */ - public function testDenormalize(\stdClass $normalized): void + public function testDenormalize(mixed $normalized): void { /** @var \Apigee\Edge\Structure\PropertiesProperty $object */ $object = static::$denormalizer->denormalize($normalized, PropertiesProperty::class); diff --git a/tests/Test/HttpClient/FileSystemResponseFactory.php b/tests/Test/HttpClient/FileSystemResponseFactory.php index decc8b80..185eaa6c 100644 --- a/tests/Test/HttpClient/FileSystemResponseFactory.php +++ b/tests/Test/HttpClient/FileSystemResponseFactory.php @@ -62,7 +62,7 @@ public function __construct(AdapterInterface $adapter = null, DecoderInterface $ $adapter = new Local($folder); } $this->filesystem = new Filesystem($adapter); - $this->decoder = $decoder ?: new JsonDecode(true); + $this->decoder = $decoder ?: new JsonDecode([true]); } /**