Skip to content

Commit

Permalink
Fix: cast nullable property
Browse files Browse the repository at this point in the history
  • Loading branch information
yzen-dev committed Jul 11, 2023
1 parent b12ba5c commit 5f78b33
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 25 deletions.
2 changes: 1 addition & 1 deletion composer.json
@@ -1,6 +1,6 @@
{
"name": "yzen.dev/plain-to-class",
"version": "3.0.1",
"version": "3.0.2",
"description": "Class-transformer to transform your dataset into a structured object",
"minimum-stability": "dev",
"prefer-stable": true,
Expand Down
38 changes: 19 additions & 19 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion src/Reflection/Types/PropertyType.php
Expand Up @@ -14,10 +14,12 @@ class PropertyType
/**
* @param string $name Name of type
* @param bool $isScalar
* @param bool $isNullable
*/
public function __construct(
public string $name,
public bool $isScalar
public bool $isScalar,
public bool $isNullable
) {
}
}
15 changes: 11 additions & 4 deletions src/Reflection/Types/PropertyTypeFactory.php
Expand Up @@ -29,13 +29,16 @@ public static function create(RuntimeReflectionProperty $property)

$type = TypeEnums::TYPE_MIXED;
$isScalar = true;
$isNullable = true;

if ($reflectionType instanceof ReflectionType) {
$type = $reflectionType;
$isNullable = $reflectionType->allowsNull();
}
if ($reflectionType instanceof ReflectionNamedType) {
$type = $reflectionType->getName();
$isScalar = $reflectionType->isBuiltin();
$isNullable = $reflectionType->allowsNull();
}

if ($type === TypeEnums::TYPE_ARRAY) {
Expand All @@ -49,7 +52,8 @@ public static function create(RuntimeReflectionProperty $property)
$arrayType ??= TypeEnums::TYPE_MIXED;
$type = new ArrayType(
$type,
$isScalar
$isScalar,
$isNullable
);
$type->itemsType = $arrayType ?? TypeEnums::TYPE_MIXED;
$type->isScalarItems = in_array($arrayType, [TypeEnums::TYPE_INTEGER, TypeEnums::TYPE_FLOAT, TypeEnums::TYPE_STRING, TypeEnums::TYPE_BOOLEAN, TypeEnums::TYPE_MIXED]);
Expand All @@ -60,20 +64,23 @@ public static function create(RuntimeReflectionProperty $property)
if ($isScalar || $property->notTransform()) {
return new ScalarType(
$type,
$isScalar
$isScalar,
$isNullable
);
}

if (function_exists('enum_exists') && enum_exists($type)) {
return new EnumType(
$type,
$isScalar
$isScalar,
$isNullable
);
}

return new TransformableType(
$type,
$isScalar
$isScalar,
$isNullable
);
}
}
4 changes: 4 additions & 0 deletions src/ValueCasting.php
Expand Up @@ -47,6 +47,10 @@ public function __construct(ReflectionProperty $property, HydratorConfig $config
*/
public function castAttribute(mixed $value): mixed
{
if ($this->property->type->isNullable && empty($value)) {
return null;
}

if (($this->property->type->isScalar && !$this->property->type instanceof ArrayType) || $this->property->notTransform()) {
return $this->castScalar($this->property->type->name, $value);
}
Expand Down
17 changes: 17 additions & 0 deletions tests/Units/DTO/TypesDto.php
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Tests\Units\DTO;

use ClassTransformer\Attributes\WritingStyle;

class TypesDto
{
public ?int $nullableInt;

public ?string $nullableString;
public ?float $nullableFloat;
public ?bool $nullableBool;

}
18 changes: 18 additions & 0 deletions tests/Units/ValueCastingTest.php
Expand Up @@ -6,6 +6,7 @@
use PHPUnit\Framework\TestCase;
use Tests\Units\DTO\ExtendedDto;
use ClassTransformer\Reflection\RuntimeReflectionProperty;
use Tests\Units\DTO\TypesDto;

class ValueCastingTest extends TestCase
{
Expand Down Expand Up @@ -46,6 +47,23 @@ public function testCreateProperty(): void
$value = $caster->castAttribute('1');
$this->assertIsInt($value);
$this->assertEquals(1, $value);


$caster = new ValueCasting(new RuntimeReflectionProperty(new \ReflectionProperty(TypesDto::class, 'nullableInt')));
$value = $caster->castAttribute('');
$this->assertNull($value);

$caster = new ValueCasting(new RuntimeReflectionProperty(new \ReflectionProperty(TypesDto::class, 'nullableString')));
$value = $caster->castAttribute('');
$this->assertNull($value);

$caster = new ValueCasting(new RuntimeReflectionProperty(new \ReflectionProperty(TypesDto::class, 'nullableFloat')));
$value = $caster->castAttribute('');
$this->assertNull($value);

$caster = new ValueCasting(new RuntimeReflectionProperty(new \ReflectionProperty(TypesDto::class, 'nullableBool')));
$value = $caster->castAttribute('');
$this->assertNull($value);
}

public function testCreateArrayProperty(): void
Expand Down

0 comments on commit 5f78b33

Please sign in to comment.