Passed
Branch nested_save (73f795)
by JHONATAN
02:34
created

Normalizer   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 94.44%

Importance

Changes 0
Metric Value
wmc 16
dl 0
loc 74
ccs 34
cts 36
cp 0.9444
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A normalizeIfSupported() 0 10 3
A supportsNormalization() 0 3 1
C normalize() 0 45 11
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\Data\Mapping\Exclude;
10
use Vox\Metadata\ClassMetadata;
11
use Vox\Metadata\PropertyMetadata;
12
13
class Normalizer implements NormalizerInterface
14
{
15
    /**
16
     * @var MetadataFactoryInterface
17
     */
18
    private $metadataFactory;
19
    
20 17
    public function __construct(MetadataFactoryInterface $metadataFactory)
21
    {
22 17
        $this->metadataFactory = $metadataFactory;
23 17
    }
24
    
25 4
    public function normalize($object, $format = null, array $context = array())
26
    {
27 4
        $objectMetadata = $this->metadataFactory->getMetadataForClass(get_class($object));
28
        
29 4
        if (!$objectMetadata instanceof ClassMetadata) {
30
            throw new RuntimeException('invalid metadata class');
31
        }
32
        
33 4
        $data = [];
34 4
        $data['type'] = get_class($object);
35
        
36
        /* @var $propertyMetadata PropertyMetadata */
37 4
        foreach ($objectMetadata->propertyMetadata as $propertyMetadata) {
38 4
            $binding = $propertyMetadata->getAnnotation(Bindings::class);
39 4
            $value   = $propertyMetadata->getValue($object);
40
            
41 4
            if ($propertyMetadata->hasAnnotation(Exclude::class)
42 4
                && $propertyMetadata->getAnnotation(Exclude::class)->output) {
43
                continue;
44
            }
45
            
46 4
            if (is_array($value) 
47 4
                && (preg_match('/\[\]$/', $propertyMetadata->type) || $propertyMetadata->type == 'array')) {
48 1
                $items = [];
49
                
50 1
                foreach ($value as $index => $item) {
51 1
                    $items[$index] = $this->normalizeIfSupported($item, $format, $context);
52
                }
53
                
54 1
                $value = $items;
55
            } else {
56 4
                $value = $this->normalizeIfSupported($value, $format, $context);
57
            }
58
            
59 4
            $target = $binding ? ($binding->target ?? $binding->source ?? null) : $propertyMetadata->name;
60
            
61 4
            if (preg_match('/\./', $target)) {
62 2
                $path = implode("']['", explode('.', sprintf("['%s']", $target)));
63 2
                eval("\$data$path = \$value;");
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
64
            } else {
65 4
                $data[$target] = $value;
66
            }
67
        }
68
        
69 4
        return $data;
70
    }
71
    
72 4
    private function normalizeIfSupported($value, $format, array $context)
73
    {
74 4
        if ($this->supportsNormalization($value) 
75 4
            && !in_array(spl_object_hash($value), $context['normalized'] ?? [])) {
76 3
            $context['normalized'][] = spl_object_hash($value);
77
            
78 3
            return $this->normalize($value, $format, $context);
79
        }
80
        
81 4
        return $value;
82
    }
83
84 4
    public function supportsNormalization($data, $format = null): bool
85
    {
86 4
        return is_object($data);
87
    }
88
}
89