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

Normalizer::supportsNormalization()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 1
nc 1
nop 2
crap 1
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