Реализовал поддерку интерфейсов.

Нужен рефакторинг.
Метод разрастается
This commit is contained in:
Rinsvent 2021-08-08 14:40:56 +07:00
parent c2de3054b5
commit 283fe21efe
5 changed files with 59 additions and 10 deletions

View File

@ -42,10 +42,27 @@ class Data2DtoConverter
continue;
}
// Если это class, то рекурсивно заполняем дальше
if (class_exists($propertyType)) {
$value = $this->convert($value, $propertyType);
$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($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;
}
}

View File

@ -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);
}
}

View File

@ -0,0 +1,8 @@
<?php
namespace Rinsvent\Data2DTO\Tests\unit\Converter\fixtures\FillTest;
class Bar implements BarInterface
{
public float $barField;
}

View File

@ -0,0 +1,8 @@
<?php
namespace Rinsvent\Data2DTO\Tests\unit\Converter\fixtures\FillTest;
interface BarInterface
{
}

View File

@ -16,4 +16,6 @@ class HelloRequest
#[DTOMeta(class: Author::class)]
public array $authors;
public BuyRequest $buy;
#[DTOMeta(class: Bar::class)]
public BarInterface $bar;
}