From 10f1937434ff8e38b21ad54963488e40a4ad2a7d Mon Sep 17 00:00:00 2001 From: Rinsvent Date: Sun, 15 Aug 2021 15:40:09 +0700 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20?= =?UTF-8?q?=D1=82=D0=B5=D0=B3=D0=B8=20=D0=B8=20=D0=BC=D0=B5=D1=82=D0=B0=20?= =?UTF-8?q?=D0=B8=D0=BD=D1=84=D0=BE=D1=80=D0=BC=D0=B0=D1=86=D0=B8=D0=B8=20?= =?UTF-8?q?=D0=BE=20=D0=B2=D0=BE=D0=B7=D0=B2=D1=80=D0=B0=D1=89=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D0=BE=D0=BC=20=D1=82=D0=B8=D0=BF=D0=B5=20=D0=94=D0=BE?= =?UTF-8?q?=D0=B1=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D1=83=20=D1=82=D1=80=D0=B0=D0=BD=D1=81=D1=84?= =?UTF-8?q?=D0=BE=D1=80=D0=BC=D0=B5=D1=80=D0=BE=D0=B2=20=D0=BA=D0=BB=D0=B0?= =?UTF-8?q?=D1=81=D1=81=D0=B0=20=D0=9F=D1=80=D0=BE=D0=B8=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D0=B3=D1=80=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=BE=D0=B1?= =?UTF-8?q?=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=BA=D1=83=20=D1=82=D0=B5=D0=B3?= =?UTF-8?q?=D0=BE=D0=B2=20=D0=9F=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F=D0=BB=20?= =?UTF-8?q?=D1=82=D0=B8=D0=BF=20=D0=BB=D0=B8=D1=86=D0=B5=D0=BD=D0=B7=D0=B8?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- composer.json | 2 +- src/Data2DtoConverter.php | 44 +++++++++++++++++++++++++++++++++------ src/Transformer/Meta.php | 4 ++++ 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/composer.json b/composer.json index cdbde74..7c56dca 100644 --- a/composer.json +++ b/composer.json @@ -1,7 +1,7 @@ { "name": "rinsvent/data2dto", "description": "Convert data to dto object", - "license": "proprietary", + "license": "MIT", "require": { "php": "^8.0", "ext-ctype": "*", diff --git a/src/Data2DtoConverter.php b/src/Data2DtoConverter.php index bce5336..a063a7c 100644 --- a/src/Data2DtoConverter.php +++ b/src/Data2DtoConverter.php @@ -2,6 +2,7 @@ namespace Rinsvent\Data2DTO; +use Rinsvent\AttributeExtractor\ClassExtractor; use Rinsvent\AttributeExtractor\PropertyExtractor; use Rinsvent\Data2DTO\Attribute\DTOMeta; use Rinsvent\Data2DTO\Attribute\PropertyPath; @@ -12,11 +13,16 @@ use function Symfony\Component\String\u; class Data2DtoConverter { - public function convert(array $data, string $class): object + public function convert(array $data, string $class, array $tags = [], ?object $instance = null): object { - $object = new $class; - + $tags = empty($tags) ? ['default'] : $tags; + $object = $instance ?? new $class; $reflectionObject = new \ReflectionObject($object); + $this->processClassTransformers($reflectionObject, $data, $tags); + if (is_object($data)) { + return $data; + } + $properties = $reflectionObject->getProperties(); /** @var \ReflectionProperty $property */ foreach ($properties as $property) { @@ -27,7 +33,7 @@ class Data2DtoConverter if ($dataPath = $this->grabDataPath($property, $data)) { $value = $data[$dataPath]; // Трансформируем данные - $this->processTransformers($property, $value); + $this->processTransformers($property, $value, $tags); if ($this->checkNullRule($value, $reflectionPropertyType)) { continue; @@ -98,12 +104,38 @@ class Data2DtoConverter return null; } - protected function processTransformers(\ReflectionProperty $property, &$data): void + protected function processClassTransformers(\ReflectionObject $object, &$data, array $tags): void + { + $className = $object->getName(); + $classExtractor = new ClassExtractor($className); + /** @var Meta $transformMeta */ + while ($transformMeta = $classExtractor->fetch(Meta::class)) { + $transformMeta->returnType = $className; + $filteredTags = array_diff($tags, $transformMeta->tags); + if (count($filteredTags) === count($tags)) { + continue; + } + + $transformer = $this->grabTransformer($transformMeta); + $transformer->transform($data, $transformMeta); + } + } + + protected function processTransformers(\ReflectionProperty $property, &$data, array $tags): void { $propertyName = $property->getName(); $propertyExtractor = new PropertyExtractor($property->class, $propertyName); /** @var Meta $transformMeta */ - if ($transformMeta = $propertyExtractor->fetch(Meta::class)) { + while ($transformMeta = $propertyExtractor->fetch(Meta::class)) { + $filteredTags = array_diff($tags, $transformMeta->tags); + if (count($filteredTags) === count($tags)) { + continue; + } + /** @var \ReflectionNamedType $reflectionPropertyType */ + $reflectionPropertyType = $property->getType(); + $propertyType = $reflectionPropertyType->getName(); + $transformMeta->returnType = $propertyType; + $transformMeta->allowsNull = $reflectionPropertyType->allowsNull(); $transformer = $this->grabTransformer($transformMeta); $transformer->transform($data, $transformMeta); } diff --git a/src/Transformer/Meta.php b/src/Transformer/Meta.php index 73e88dd..c0ac356 100644 --- a/src/Transformer/Meta.php +++ b/src/Transformer/Meta.php @@ -6,4 +6,8 @@ namespace Rinsvent\Data2DTO\Transformer; abstract class Meta { public const TYPE = 'simple'; + public ?string $returnType = null; + public ?bool $allowsNull = null; + /** @var string[] $tags */ + public array $tags = ['default']; } \ No newline at end of file