diff --git a/src/Attribute/Schema.php b/src/Attribute/Schema.php index ec26674..7966dba 100644 --- a/src/Attribute/Schema.php +++ b/src/Attribute/Schema.php @@ -2,16 +2,16 @@ namespace Rinsvent\DTO2Data\Attribute; -use Rinsvent\DTO2Data\DTO\Map; - #[\Attribute(\Attribute::TARGET_ALL|\Attribute::IS_REPEATABLE)] class Schema { + public ?array $baseMap = null; + public function __construct( public ?array $map = null, /** @var string[] $tags */ public array $tags = ['default'] ) { - $this->map = $map ?? $this->map; + $this->map = $map ?? $this->baseMap; } } diff --git a/src/Dto2DataConverter.php b/src/Dto2DataConverter.php index 9765fff..c3c3a9d 100644 --- a/src/Dto2DataConverter.php +++ b/src/Dto2DataConverter.php @@ -36,16 +36,12 @@ class Dto2DataConverter foreach ($map as $key => $propertyInfo) { $sourceName = is_array($propertyInfo) ? $key : $propertyInfo; - if (method_exists($object, $sourceName)) { - $reflectionSource = new ReflectionMethod($object, $sourceName); - $value = $this->getMethodValue($object, $reflectionSource); - } elseif (property_exists($object, $sourceName)) { - $reflectionSource = new ReflectionProperty($object, $sourceName); - $value = $this->getValue($object, $reflectionSource); - } else { + if (!method_exists($object, $sourceName) && !property_exists($object, $sourceName)) { continue; } + $value = $this->grabValue($object, $sourceName); + if (is_object($value)) { // Если у объекта нет карты, то не сериализуем. if (!is_array($propertyInfo)) { @@ -67,19 +63,12 @@ class Dto2DataConverter } } $value = $tempValue; - } elseif (!is_scalar($value)) { + } elseif (!is_scalar($value) && null !== $value) { continue; } - if (method_exists($object, $sourceName)) { - $this->processMethodTransformers($reflectionSource, $value, $tags); - $dataPath = $this->grabMethodDataPath($reflectionSource, $tags); - } else { - $this->processTransformers($reflectionSource, $value, $tags); - $dataPath = $this->grabDataPath($reflectionSource, $tags); - } - - $dataPath = $dataPath ?? $sourceName; + $this->processIterationTransformers($object, $sourceName, $value, $tags); + $dataPath = $this->grabIterationDataPath($object, $sourceName, $tags); $data[$dataPath] = $value; } @@ -88,6 +77,42 @@ class Dto2DataConverter return $data; } + protected function grabValue(object $object, $sourceName) + { + if (method_exists($object, $sourceName)) { + $reflectionSource = new ReflectionMethod($object, $sourceName); + return $this->getMethodValue($object, $reflectionSource); + } elseif (property_exists($object, $sourceName)) { + $reflectionSource = new ReflectionProperty($object, $sourceName); + return $this->getValue($object, $reflectionSource); + } + + return null; + } + + public function processIterationTransformers(object $object, string $sourceName, &$value, array $tags): void + { + if (method_exists($object, $sourceName)) { + $reflectionSource = new ReflectionMethod($object, $sourceName); + $this->processMethodTransformers($reflectionSource, $value, $tags); + } elseif (property_exists($object, $sourceName)) { + $reflectionSource = new ReflectionProperty($object, $sourceName); + $this->processTransformers($reflectionSource, $value, $tags); + } + } + + public function grabIterationDataPath(object $object, string $sourceName, array $tags): string + { + if (method_exists($object, $sourceName)) { + $reflectionSource = new ReflectionMethod($object, $sourceName); + $dataPath = $this->grabMethodDataPath($reflectionSource, $tags); + } elseif (property_exists($object, $sourceName)) { + $reflectionSource = new ReflectionProperty($object, $sourceName); + $dataPath = $this->grabDataPath($reflectionSource, $tags); + } + return $dataPath ?? $sourceName; + } + /** * Получаем теги для обработки */ diff --git a/tests/unit/Converter/fixtures/FillTest/HelloSchema.php b/tests/unit/Converter/fixtures/FillTest/HelloSchema.php index 787c2ef..5d26d30 100644 --- a/tests/unit/Converter/fixtures/FillTest/HelloSchema.php +++ b/tests/unit/Converter/fixtures/FillTest/HelloSchema.php @@ -3,12 +3,11 @@ namespace Rinsvent\DTO2Data\Tests\unit\Converter\fixtures\FillTest; use Rinsvent\DTO2Data\Attribute\Schema; -use Rinsvent\DTO2Data\DTO\Map; #[\Attribute(\Attribute::TARGET_ALL|\Attribute::IS_REPEATABLE)] class HelloSchema extends Schema { - public ?array $map = [ + public ?array $baseMap = [ 'surname', 'age', 'emails',