Skip to content

Commit

Permalink
TASK: Add support for single value valueobjects to normalizer
Browse files Browse the repository at this point in the history
  • Loading branch information
mficzel committed Mar 25, 2024
1 parent debbe6d commit 0bb2898
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 19 deletions.
1 change: 1 addition & 0 deletions Classes/Domain/Schema/OpenApiSchema.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ private static function fromObjectReflectionClass(\ReflectionClass $reflectionCl
'string', 'DateTimeImmutable', 'DateTime', 'DateInterval' => 'string',
'int' => 'integer',
'float' => 'number',
'bool' => 'boolean',
default => throw new \DomainException(
'Unsupported type ' . $singleConstructorParameter->getType()->getName()
. ' for single constructor parameter "' . $singleConstructorParameter->name . '"'
Expand Down
29 changes: 17 additions & 12 deletions Classes/Domain/Schema/SchemaDenormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ private static function convertValue(null|int|bool|string|float|array $value, st
};
} elseif (is_array($value) && class_exists($targetType) && self::isCollectionClassName($targetType)) {
return self::convertCollection($value, $targetType);
} elseif (is_array($value) && class_exists($targetType) && self::isValueObjectClassName($targetType)) {
} elseif (class_exists($targetType) && self::isValueObjectClassName($targetType)) {
return self::convertValueObject($value, $targetType);
}

Expand All @@ -92,22 +92,27 @@ private static function convertCollection(array $value, string $targetType): obj
}

/**
* @param array<string,mixed> $value
* @param array<string,mixed>|int|float|string|bool $value
*/
private static function convertValueObject(array $value, string $targetType): object
private static function convertValueObject(array|int|float|string|bool $value, string $targetType): object
{
$reflection = new ClassReflection($targetType);
$parameterReflections = $reflection->getConstructor()->getParameters();
$convertedArguments = [];
foreach ($parameterReflections as $name => $parameter) {
$type = $parameter->getType();
$convertedArguments[$name] = match (true) {
$type === null => throw new \DomainException('Cannot convert untyped property ' . $parameter->getName()),
$type instanceof \ReflectionNamedType => self::convertValue($value[$parameter->getName()], $type->getName()),
default => throw new \DomainException('Cannot convert ' . get_class($type) . ' yet'),
};
if (is_array($value)) {
foreach ($parameterReflections as $name => $parameter) {
$type = $parameter->getType();
$convertedArguments[$name] = match (true) {
$type === null => throw new \DomainException('Cannot convert untyped property ' . $parameter->getName()),
$type instanceof \ReflectionNamedType => self::convertValue($value[$parameter->getName()], $type->getName()),
default => throw new \DomainException('Cannot convert ' . get_class($type) . ' yet'),
};
}
return new $targetType(...$convertedArguments);
} elseif (count($parameterReflections) === 1 && $parameterReflections[0]->getName() === 'value' && $parameterReflections[0]->getType() instanceof \ReflectionNamedType) {
$convertedValue = self::convertValue($value, $parameterReflections[0]->getType()->getName());
return new $targetType(value: $convertedValue);
}

return new $targetType(...$convertedArguments);
throw new \DomainException('Only single value objects can be serialized as single value');
}
}
8 changes: 6 additions & 2 deletions Classes/Domain/Schema/SchemaNormalizer.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,14 @@ private static function convertCollection(object $value): array

/**
* @param object $value
* @return array<string,int|bool|float|string|array<mixed>|null>
* @return array<string,int|bool|float|string|array<mixed>|null>|int|float|string
*/
private static function convertValueObject(object $value): array
private static function convertValueObject(object $value): array|int|float|string
{
$properties = get_object_vars($value);
if (array_keys($properties) === ['value']) {
return $properties['value'];
}
return array_map(
fn($subvalue) => self::convertValue($subvalue),
get_object_vars($value)
Expand Down
9 changes: 4 additions & 5 deletions Tests/Unit/Domain/Schema/SchemaNormalizerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Sitegeist\SchemeOnYou\Tests\Unit\Domain\Schema;

use Neos\Http\Factories\UriFactory;
use PHPUnit\Framework\Assert;
use PHPUnit\Framework\TestCase;
use Sitegeist\SchemeOnYou\Domain\Schema\SchemaDenormalizer;
Expand Down Expand Up @@ -55,7 +54,7 @@ public static function valueNormalizationPairs(): iterable
yield 'NumberObject is converted' => [
Fixtures\Number::class,
new Fixtures\Number(value: 123.456),
["value" => 123.456]
123.456
];
yield 'DateTime' => [\DateTime::class, new \DateTime('2010-01-28T15:00:00+02:00'), '2010-01-28T15:00:00+02:00'];
yield 'DateTimeImmutable' => [\DateTimeImmutable::class, new \DateTimeImmutable('2010-01-28T15:00:00+02:00'), '2010-01-28T15:00:00+02:00'];
Expand Down Expand Up @@ -166,9 +165,9 @@ public static function valueNormalizationPairs(): iterable
),
[
'dayOfWeek' => 'https://schema.org/Monday',
'identifier' => ['value' => 'suppe'],
'identifier' => 'suppe',
'importantNumber' => 23,
'number' => ['value' => 23.42],
'number' => 23.42,
'postalAddress' => [
'streetAddress' => 'Sesame Street 123',
'addressRegion' => 'Manhatten',
Expand All @@ -189,7 +188,7 @@ public static function valueNormalizationPairs(): iterable
'postOfficeBoxNumber' => '67890',
]
],
'quantitativeValue' => ['value' => 666],
'quantitativeValue' => 666,
'weirdThing' => [
"if" => false,
"what" => "dis",
Expand Down

0 comments on commit 0bb2898

Please sign in to comment.