From cb3982e57c9ce615fc88fba2be59945de9a052bf Mon Sep 17 00:00:00 2001 From: Hide_D Date: Sat, 28 May 2022 15:53:06 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20DTO=EC=97=90=20DefaultValue,=20DefaultV?= =?UTF-8?q?alueGenerator=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/sammo/DTO/Attr/DefaultValue.php | 16 +++++ src/sammo/DTO/Attr/DefaultValueGenerator.php | 20 ++++++ src/sammo/DTO/DTO.php | 47 ++++++++++++-- src/sammo/DTO/Util/Util.php | 15 +++++ tests/DTOTest.php | 65 +++++++++++++++++--- 5 files changed, 150 insertions(+), 13 deletions(-) create mode 100644 src/sammo/DTO/Attr/DefaultValue.php create mode 100644 src/sammo/DTO/Attr/DefaultValueGenerator.php diff --git a/src/sammo/DTO/Attr/DefaultValue.php b/src/sammo/DTO/Attr/DefaultValue.php new file mode 100644 index 00000000..d83b3c28 --- /dev/null +++ b/src/sammo/DTO/Attr/DefaultValue.php @@ -0,0 +1,16 @@ +defaultValue; + } +} diff --git a/src/sammo/DTO/Attr/DefaultValueGenerator.php b/src/sammo/DTO/Attr/DefaultValueGenerator.php new file mode 100644 index 00000000..9ca7f76b --- /dev/null +++ b/src/sammo/DTO/Attr/DefaultValueGenerator.php @@ -0,0 +1,20 @@ +generator; + return $generator(); + } +} diff --git a/src/sammo/DTO/DTO.php b/src/sammo/DTO/DTO.php index c939fd41..76a31d3f 100644 --- a/src/sammo/DTO/DTO.php +++ b/src/sammo/DTO/DTO.php @@ -11,7 +11,6 @@ abstract class DTO public static function fromArray(\ArrayAccess|array $array): static { $reflection = new \ReflectionClass(static::class); - $args = []; if ($array instanceof \ArrayAccess) { $keyExists = fn (string|int $key) => $array->offsetExists($key); @@ -19,6 +18,11 @@ abstract class DTO $keyExists = fn (string|int $key) => array_key_exists($key, $array); } + $params = Util\Util::getConstructorParams($reflection); + + $args = []; + $lazyMap = []; + foreach ($reflection->getProperties( \ReflectionProperty::IS_PUBLIC ) as $property) { @@ -26,6 +30,19 @@ abstract class DTO $name = $property->getName(); $rawName = $name; + $param = $params[$name] ?? null; + + if (key_exists(Attr\DefaultValueGenerator::class, $attrs)){ + /** @var Attr\DefaultValueGenerator */ + $defaultValueSetter = $attrs[Attr\DefaultValueGenerator::class]->newInstance(); + } else if (key_exists(Attr\DefaultValue::class, $attrs)) { + /** @var Attr\DefaultValue */ + $defaultValueSetter = $attrs[Attr\DefaultValue::class]->newInstance(); + } + else{ + $defaultValueSetter = null; + } + if (key_exists(Attr\RawName::class, $attrs)) { $rawAttr = $attrs[Attr\RawName::class]; $attr = new Attr\RawName(...$rawAttr->getArguments()); @@ -33,13 +50,25 @@ abstract class DTO } if (!$keyExists($rawName)) { - if ($property->hasDefaultValue()) { - $args[$name] = $property->getDefaultValue(); + if ($param !== null && $param->isOptional()){ + $defaultValue = $param->getDefaultValue(); + } + else if ($property->hasDefaultValue()) { + $defaultValue = $property->getDefaultValue(); + } else if($defaultValueSetter !== null){ + $defaultValue = $defaultValueSetter->getDefaultValue(); } else if ($property->getType()->allowsNull()) { - $args[$name] = null; + $defaultValue = null; } else { throw new \Exception("Missing property: {$name}"); } + + if($param !== null){ + $args[$name] = $defaultValue; + } + else{ + $lazyMap[$name] = $defaultValue; + } continue; } @@ -60,10 +89,18 @@ abstract class DTO } $value = $converter->convertFrom($value); - $args[$name] = $value; + if($param !== null){ + $args[$name] = $value; + } + else{ + $lazyMap[$name] = $value; + } } $object = $reflection->newInstanceArgs($args); + foreach($lazyMap as $name => $value){ + $object->{$name} = $value; + } return $object; } diff --git a/src/sammo/DTO/Util/Util.php b/src/sammo/DTO/Util/Util.php index 5117e351..caa1c10b 100644 --- a/src/sammo/DTO/Util/Util.php +++ b/src/sammo/DTO/Util/Util.php @@ -20,6 +20,21 @@ class Util{ return $result; } + /** + * @return array + */ + public static function getConstructorParams(\ReflectionClass $class): array{ + $constructor = $class->getConstructor(); + if($constructor === null){ + return []; + } + $result = []; + foreach($constructor->getParameters() as $param){ + $result[$param->getName()] = $param; + } + return $result; + } + /** * @return array */ diff --git a/tests/DTOTest.php b/tests/DTOTest.php index f8e8f100..3574ff59 100644 --- a/tests/DTOTest.php +++ b/tests/DTOTest.php @@ -1,6 +1,8 @@ assertEquals($rawType, $testType); } - public function testMap(){ + public function testMap() + { $rawType = [ 'a' => 1, 'b' => [ @@ -336,7 +362,8 @@ class DTOTest extends PHPUnit\Framework\TestCase $this->assertEquals($rawType, $testType); } - public function testNestedMap(){ + public function testNestedMap() + { $rawType = [ 'a' => 1, 'b' => [ @@ -357,7 +384,8 @@ class DTOTest extends PHPUnit\Framework\TestCase $this->assertEquals($rawType, $testType); } - public function testRawName(){ + public function testRawName() + { $rawType = [ 'arg_name' => 1, 'vID' => 2, @@ -368,7 +396,8 @@ class DTOTest extends PHPUnit\Framework\TestCase $this->assertEquals($rawType, $testType); } - public function testDateTime(){ + public function testDateTime() + { $rawType = [ 'a' => '2022-01-01 10:11:22', 'b' => '2022-02-01T12:34:56.1234+09:00', @@ -387,4 +416,24 @@ class DTOTest extends PHPUnit\Framework\TestCase $this->assertEquals($testValue, $testType); } + + public function testDefaultValue() + { + $rawType = [ + 'c' => 3, + ]; + $testValue = [ + 'g' => true, + 'a' => null, + 'b' => false, + 'c' => 3, + 'e' => [1, 2, 3], + 'd' => '2022-04-01 00:00:00', + 'f' => 111, + ]; + $obj = TypeDefaultValue::fromArray($rawType); + $testType = $obj->toArray(); + + $this->assertEquals($testValue, $testType); + } }