From 283fe21efe32f3474bc8124d6f495ee7d2836f7e Mon Sep 17 00:00:00 2001 From: Rinsvent Date: Sun, 8 Aug 2021 14:40:56 +0700 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BB=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=BA?= =?UTF-8?q?=D1=83=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81?= =?UTF-8?q?=D0=BE=D0=B2.=20=D0=9D=D1=83=D0=B6=D0=B5=D0=BD=20=D1=80=D0=B5?= =?UTF-8?q?=D1=84=D0=B0=D0=BA=D1=82=D0=BE=D1=80=D0=B8=D0=BD=D0=B3.=20?= =?UTF-8?q?=D0=9C=D0=B5=D1=82=D0=BE=D0=B4=20=D1=80=D0=B0=D0=B7=D1=80=D0=B0?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=B5=D1=82=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Data2DtoConverter.php | 41 +++++++++++++++---- tests/unit/Converter/FillTest.php | 8 ++++ .../unit/Converter/fixtures/FillTest/Bar.php | 8 ++++ .../fixtures/FillTest/BarInterface.php | 8 ++++ .../fixtures/FillTest/HelloRequest.php | 2 + 5 files changed, 58 insertions(+), 9 deletions(-) create mode 100644 tests/unit/Converter/fixtures/FillTest/Bar.php create mode 100644 tests/unit/Converter/fixtures/FillTest/BarInterface.php diff --git a/src/Data2DtoConverter.php b/src/Data2DtoConverter.php index 9eaacc6..bce5336 100644 --- a/src/Data2DtoConverter.php +++ b/src/Data2DtoConverter.php @@ -42,10 +42,27 @@ class Data2DtoConverter continue; } + $preparedPropertyType = $propertyType; + + if (interface_exists($preparedPropertyType)) { + $attributedPropertyClass = $this->grabPropertyDTOClass($property); + // Если не указали мета информацию для интерфейса - пропустим + if (!$attributedPropertyClass) { + continue; + } + // Если класс не реализует интерфейс свойства - пропустим + $interfaces = class_implements($attributedPropertyClass); + if (!isset($interfaces[$preparedPropertyType])) { + continue; + } + $preparedPropertyType = $attributedPropertyClass; + } + // Если это class, то рекурсивно заполняем дальше - if (class_exists($propertyType)) { - $value = $this->convert($value, $propertyType); + if (class_exists($preparedPropertyType)) { + $value = $this->convert($value, $preparedPropertyType); } + // присваиваем получившееся значение $property->setValue($object, $value); } @@ -109,13 +126,7 @@ class Data2DtoConverter private function transformArray(&$value, \ReflectionProperty $property): bool { - $attributedPropertyClass = null; - $propertyName = $property->getName(); - $propertyExtractor = new PropertyExtractor($property->class, $propertyName); - /** @var DTOMeta $dtoMeta */ - if ($dtoMeta = $propertyExtractor->fetch(DTOMeta::class)) { - $attributedPropertyClass = $dtoMeta->class; - } + $attributedPropertyClass = $this->grabPropertyDTOClass($property); /** @var \ReflectionNamedType $reflectionPropertyType */ $reflectionPropertyType = $property->getType(); @@ -135,4 +146,16 @@ class Data2DtoConverter } return true; } + + private function grabPropertyDTOClass(\ReflectionProperty $property): ?string + { + $attributedPropertyClass = null; + $propertyName = $property->getName(); + $propertyExtractor = new PropertyExtractor($property->class, $propertyName); + /** @var DTOMeta $dtoMeta */ + if ($dtoMeta = $propertyExtractor->fetch(DTOMeta::class)) { + $attributedPropertyClass = $dtoMeta->class; + } + return $attributedPropertyClass; + } } \ No newline at end of file diff --git a/tests/unit/Converter/FillTest.php b/tests/unit/Converter/FillTest.php index e950a09..cc939c1 100644 --- a/tests/unit/Converter/FillTest.php +++ b/tests/unit/Converter/FillTest.php @@ -3,6 +3,7 @@ namespace Rinsvent\Data2DTO\Tests\Converter; use Rinsvent\Data2DTO\Data2DtoConverter; +use Rinsvent\Data2DTO\Tests\unit\Converter\fixtures\FillTest\Bar; use Rinsvent\Data2DTO\Tests\unit\Converter\fixtures\FillTest\BuyRequest; use Rinsvent\Data2DTO\Tests\unit\Converter\fixtures\FillTest\HelloRequest; @@ -47,6 +48,9 @@ class FillTest extends \Codeception\Test\Unit 'isFirst' => true, 'extraData2' => '1234' ], + 'bar' => [ + 'barField' => 32 + ], 'extraData1' => 'qwer' ], HelloRequest::class); $this->assertInstanceOf(HelloRequest::class, $dto); @@ -65,5 +69,9 @@ class FillTest extends \Codeception\Test\Unit $this->assertCount(2, $dto->authors); $this->assertEquals('Tolkien', $dto->authors[0]->name); $this->assertEquals('Sapkovsky', $dto->authors[1]->name); + + $this->assertInstanceOf(Bar::class, $dto->bar); + $this->assertIsFloat($dto->bar->barField); + $this->assertEquals(32.0, $dto->bar->barField); } } diff --git a/tests/unit/Converter/fixtures/FillTest/Bar.php b/tests/unit/Converter/fixtures/FillTest/Bar.php new file mode 100644 index 0000000..1eb65d9 --- /dev/null +++ b/tests/unit/Converter/fixtures/FillTest/Bar.php @@ -0,0 +1,8 @@ +