Completed
Push — master ( 31fba3...844081 )
by JHONATAN
02:27
created

Normalizer::normalize()   D

Complexity

Conditions 9
Paths 10

Size

Total Lines 40
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 21
CRAP Score 9.0076

Importance

Changes 0
Metric Value
dl 0
loc 40
ccs 21
cts 22
cp 0.9545
rs 4.909
c 0
b 0
f 0
cc 9
eloc 23
nc 10
nop 3
crap 9.0076
1
<?php
2
3
namespace Vox\Serializer;
4
5
use Metadata\MetadataFactoryInterface;
6
use RuntimeException;
7
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
8
use Vox\Data\Mapping\Bindings;
9
use Vox\Metadata\ClassMetadata;
10
use Vox\Metadata\PropertyMetadata;
11
12
class Normalizer implements NormalizerInterface
13
{
14
    /**
15
     * @var MetadataFactoryInterface
16
     */
17
    private $metadataFactory;
18
    
19 13
    public function __construct(MetadataFactoryInterface $metadataFactory)
20
    {
21 13
        $this->metadataFactory = $metadataFactory;
22 13
    }
23
    
24 3
    public function normalize($object, $format = null, array $context = array())
25
    {
26 3
        $objectMetadata = $this->metadataFactory->getMetadataForClass(get_class($object));
27
        
28 3
        if (!$objectMetadata instanceof ClassMetadata) {
29
            throw new RuntimeException('invalid metadata class');
30
        }
31
        
32 3
        $data = [];
33 3
        $data['type'] = get_class($object);
34
        
35
        /* @var $propertyMetadata PropertyMetadata */
36 3
        foreach ($objectMetadata->propertyMetadata as $propertyMetadata) {
37 3
            $binding = $propertyMetadata->getAnnotation(Bindings::class);
38 3
            $value   = $propertyMetadata->getValue($object);
39
            
40 3
            if (is_array($value) 
41 3
                && (preg_match('/\[\]$/', $propertyMetadata->type) || $propertyMetadata->type == 'array')) {
42 1
                $items = [];
43
                
44 1
                foreach ($value as $index => $item) {
45 1
                    $items[$index] = $this->normalizeIfSupported($item, $format, $context);
46
                }
47
                
48 1
                $value = $items;
49
            } else {
50 3
                $value = $this->normalizeIfSupported($value, $format, $context);
51
            }
52
            
53 3
            $target = $binding ? ($binding->target ?? $binding->source ?? null) : $propertyMetadata->name;
54
            
55 3
            if (preg_match('/\./', $target)) {
56 2
                $path = implode("']['", explode('.', sprintf("['%s']", $target)));
57 2
                eval("\$data$path = \$value;");
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
58
            } else {
59 3
                $data[$target] = $value;
60
            }
61
        }
62
        
63 3
        return $data;
64
    }
65
    
66 3
    private function normalizeIfSupported($value, $format, array $context)
67
    {
68 3
        if ($this->supportsNormalization($value) 
69 3
            && !in_array(spl_object_hash($value), $context['normalized'] ?? [])) {
70 2
            $context['normalized'][] = spl_object_hash($value);
71
            
72 2
            return $this->normalize($value, $format, $context);
73
        }
74
        
75 3
        return $value;
76
    }
77
78 3
    public function supportsNormalization($data, $format = null): bool
79
    {
80 3
        return is_object($data);
81
    }
82
}
83