Изменил логику обхода

master
Rinsvent 3 years ago
parent befb6f3e1e
commit db0e7c0910
  1. 21
      src/DTO/Map.php
  2. 91
      src/Dto2DataConverter.php

@ -1,21 +0,0 @@
<?php
namespace Rinsvent\DTO2Data\DTO;
class Map
{
public array $properties = [];
public array $methods = [];
public function addProperty(string $propertyName, ?Map $map = null): static
{
$this->properties[$propertyName] = $map;
return $this;
}
public function addMethod(string $methodName, ?Map $map = null): static
{
$this->methods[$methodName] = $map;
return $this;
}
}

@ -2,6 +2,7 @@
namespace Rinsvent\DTO2Data; namespace Rinsvent\DTO2Data;
use ReflectionMethod;
use ReflectionProperty; use ReflectionProperty;
use Rinsvent\AttributeExtractor\ClassExtractor; use Rinsvent\AttributeExtractor\ClassExtractor;
use Rinsvent\AttributeExtractor\MethodExtractor; use Rinsvent\AttributeExtractor\MethodExtractor;
@ -9,7 +10,6 @@ use Rinsvent\AttributeExtractor\PropertyExtractor;
use Rinsvent\DTO2Data\Attribute\DataPath; use Rinsvent\DTO2Data\Attribute\DataPath;
use Rinsvent\DTO2Data\Attribute\HandleTags; use Rinsvent\DTO2Data\Attribute\HandleTags;
use Rinsvent\DTO2Data\Attribute\Schema; use Rinsvent\DTO2Data\Attribute\Schema;
use Rinsvent\DTO2Data\DTO\Map;
use Rinsvent\DTO2Data\Resolver\TransformerResolverStorage; use Rinsvent\DTO2Data\Resolver\TransformerResolverStorage;
use Rinsvent\DTO2Data\Transformer\Meta; use Rinsvent\DTO2Data\Transformer\Meta;
use Rinsvent\DTO2Data\Transformer\TransformerInterface; use Rinsvent\DTO2Data\Transformer\TransformerInterface;
@ -25,64 +25,69 @@ class Dto2DataConverter
{ {
$tags = empty($tags) ? ['default'] : $tags; $tags = empty($tags) ? ['default'] : $tags;
$schema = $this->grabSchema($object, $tags); $schema = $this->grabSchema($object, $tags);
return $this->convertByMap($object, $schema->map, $tags); return $this->convertObjectByMap($object, $schema->map, $tags);
} }
public function convertByMap(object $object, array $map, array $tags = []): array public function convertObjectByMap(object $object, array $map, array $tags = []): array
{ {
$data = []; $data = [];
$reflectionObject = new \ReflectionObject($object); $reflectionObject = new \ReflectionObject($object);
foreach ($map as $propertyKey => $property) { foreach ($map as $key => $propertyInfo) {
if (is_array($property)) { $sourceName = is_array($propertyInfo) ? $key : $propertyInfo;
$propertyName = $propertyKey;
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 { } else {
$propertyName = $property; continue;
} }
$property = new ReflectionProperty($object, $propertyName); if (is_object($value)) {
$value = $this->getValue($object, $property); // Если у объекта нет карты, то не сериализуем.
$childMap = $property; if (!is_array($propertyInfo)) {
if ($childMap && is_array($childMap) && !is_scalar($value)) { continue;
if (is_array($value)) {
$tmpValue = [];
foreach ($value as $objectDataItem) {
$tmpValue[] = $this->convertByMap($objectDataItem, $childMap, $tags);
} }
$value = $tmpValue; $value = $this->convertObjectByMap($value, $propertyInfo, $tags);
} else { } elseif (is_iterable($value)) {
$value = $this->convertByMap($value, $childMap, $tags); $tempValue = [];
foreach ($value as $item) {
if (is_scalar($item)) {
$tempValue[] = $item;
continue;
}
if (is_array($item)) {
continue;
} }
if (is_object($item)) {
$tempValue[] = $this->convertObjectByMap($item, $propertyInfo, $tags);
} }
$this->processTransformers($property, $value, $tags); }
$dataPath = $this->grabDataPath($property, $tags); $value = $tempValue;
$dataPath = $dataPath ?? $propertyName; } elseif (!is_scalar($value)) {
$data[$dataPath] = $value; continue;
} }
// foreach ($map->methods as $methodName => $childMap) { if (method_exists($object, $sourceName)) {
// $method = new \ReflectionMethod($object, $methodName); $this->processMethodTransformers($reflectionSource, $value, $tags);
// $value = $this->getMethodValue($object, $method); $dataPath = $this->grabMethodDataPath($reflectionSource, $tags);
// if ($childMap) { } else {
// $value = $this->convertByMap($value, $childMap, $tags); $this->processTransformers($reflectionSource, $value, $tags);
// } $dataPath = $this->grabDataPath($reflectionSource, $tags);
// $this->processMethodTransformers($method, $value, $tags); }
// $dataPath = $this->grabMethodDataPath($method, $tags);
// $dataPath = $dataPath ?? $propertyName;
// $data[$dataPath] = $value;
// }
$this->processClassTransformers($reflectionObject, $data, $tags);
return $data; $dataPath = $dataPath ?? $sourceName;
$data[$dataPath] = $value;
} }
public function convertArrayByMap(array $data, array $map, array $tags = []): array $this->processClassTransformers($reflectionObject, $data, $tags);
{
return $data;
} }
/** /**
* Получаем теги для обработки * Получаем теги для обработки
*/ */
@ -92,7 +97,7 @@ class Dto2DataConverter
/** @var HandleTags $tagsMeta */ /** @var HandleTags $tagsMeta */
if ($tagsMeta = $classExtractor->fetch(HandleTags::class)) { if ($tagsMeta = $classExtractor->fetch(HandleTags::class)) {
if (method_exists($object, $tagsMeta->method)) { if (method_exists($object, $tagsMeta->method)) {
$reflectionMethod = new \ReflectionMethod($object, $tagsMeta->method); $reflectionMethod = new ReflectionMethod($object, $tagsMeta->method);
if (!$reflectionMethod->isPublic()) { if (!$reflectionMethod->isPublic()) {
$reflectionMethod->setAccessible(true); $reflectionMethod->setAccessible(true);
} }
@ -150,7 +155,7 @@ class Dto2DataConverter
} }
} }
protected function processMethodTransformers(\ReflectionMethod $method, &$data, array $tags): void protected function processMethodTransformers(ReflectionMethod $method, &$data, array $tags): void
{ {
$methodName = $method->getName(); $methodName = $method->getName();
$methodExtractor = new MethodExtractor($method->class, $methodName); $methodExtractor = new MethodExtractor($method->class, $methodName);
@ -196,7 +201,7 @@ class Dto2DataConverter
return $value; return $value;
} }
private function getMethodValue(object $object, \ReflectionMethod $method) private function getMethodValue(object $object, ReflectionMethod $method)
{ {
if (!$method->isPublic()) { if (!$method->isPublic()) {
$method->setAccessible(true); $method->setAccessible(true);
@ -242,7 +247,7 @@ class Dto2DataConverter
return null; return null;
} }
private function grabMethodDataPath(\ReflectionMethod $method, array $tags): ?string private function grabMethodDataPath(ReflectionMethod $method, array $tags): ?string
{ {
$methodName = $method->getName(); $methodName = $method->getName();
$methodExtractor = new MethodExtractor($method->class, $methodName); $methodExtractor = new MethodExtractor($method->class, $methodName);

Loading…
Cancel
Save