Test Failed
Push — master ( 1e706f...a3ebe4 )
by Dominik
01:49
created

Normalizer   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 160
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 10
dl 0
loc 160
ccs 49
cts 49
cp 1
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
B normalize() 0 25 3
A validateDataType() 0 10 2
A getObjectMapping() 0 10 2
B getDataByFieldNormalizationMappings() 0 25 3
A isWithinGroup() 0 16 4
A getSubPathByName() 0 4 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Serialization\Normalizer;
6
7
use Chubbyphp\Serialization\Mapping\NormalizationFieldMappingInterface;
8
use Chubbyphp\Serialization\Mapping\NormalizationObjectMappingInterface;
9
use Chubbyphp\Serialization\SerializerLogicException;
10
use Psr\Log\LoggerInterface;
11
use Psr\Log\NullLogger;
12
13
final class Normalizer implements NormalizerInterface
14
{
15
    /**
16
     * @var NormalizerObjectMappingRegistryInterface
17
     */
18
    private $normalizerObjectMappingRegistry;
19
20
    /**
21
     * @var LoggerInterface
22
     */
23
    private $logger;
24
25
    /**
26
     * @param NormalizerObjectMappingRegistryInterface $normalizerObjectMappingRegistry
27
     * @param LoggerInterface|null                     $logger
28
     */
29 4
    public function __construct(
30
        NormalizerObjectMappingRegistryInterface $normalizerObjectMappingRegistry,
31
        LoggerInterface $logger = null
32
    ) {
33 4
        $this->normalizerObjectMappingRegistry = $normalizerObjectMappingRegistry;
34 4
        $this->logger = $logger ?? new NullLogger();
35 4
    }
36
37
    /**
38
     * @param object                          $object
39
     * @param NormalizerContextInterface|null $context
40
     * @param string                          $path
41
     *
42
     * @return array
43
     */
44 4
    public function normalize($object, NormalizerContextInterface $context = null, string $path = ''): array
45
    {
46 4
        $this->validateDataType($object, $path);
47
48 3
        $context = $context ?? NormalizerContextBuilder::create()->getContext();
49
50 3
        $class = is_object($object) ? get_class($object) : $object;
51 3
        $objectMapping = $this->getObjectMapping($class);
52
53 2
        $fieldMappings = $objectMapping->getNormalizationFieldMappings($path);
54 2
        $fields = $this->getDataByFieldNormalizationMappings($context, $fieldMappings, $path, $object);
55
56 2
        $embeddedFieldMappings = $objectMapping->getNormalizationEmbeddedFieldMappings($path);
57 2
        $embeddedFields = $this->getDataByFieldNormalizationMappings($context, $embeddedFieldMappings, $path, $object);
58
59 2
        $data = $fields;
60
61 2
        if ([] !== $embeddedFields) {
62 1
            $data['_embedded'] = $embeddedFields;
63
        }
64
65 2
        $data['_type'] = $objectMapping->getNormalizationType();
66
67 2
        return $data;
68
    }
69
70
    /**
71
     * @param object $object
72
     * @param string $path
73
     *
74
     * @throws SerializerLogicException
75
     */
76 4
    private function validateDataType($object, string $path)
77
    {
78 4
        if (!is_object($object)) {
79 1
            $exception = SerializerLogicException::createWrongDataType(gettype($object), $path);
80
81 1
            $this->logger->error('serialize: {exception}', ['exception' => $exception->getMessage()]);
82
83 1
            throw $exception;
84
        }
85 3
    }
86
87
    /**
88
     * @param string $class
89
     *
90
     * @return NormalizationObjectMappingInterface
91
     *
92
     * @throws SerializerLogicException
93
     */
94 3
    private function getObjectMapping(string $class): NormalizationObjectMappingInterface
95
    {
96
        try {
97 3
            return $this->normalizerObjectMappingRegistry->getObjectMapping($class);
98 1
        } catch (SerializerLogicException $exception) {
99 1
            $this->logger->error('serialize: {exception}', ['exception' => $exception->getMessage()]);
100
101 1
            throw $exception;
102
        }
103
    }
104
105
    /**
106
     * @param NormalizerContextInterface           $context
107
     * @param NormalizationFieldMappingInterface[] $normalizationFieldMappings
108
     * @param string                               $path
109
     * @param $object
110
     *
111
     * @return array
112
     */
113 2
    private function getDataByFieldNormalizationMappings(
114
        NormalizerContextInterface $context,
115
        array $normalizationFieldMappings,
116
        string $path,
117
        $object
118
    ): array {
119 2
        $data = [];
120 2
        foreach ($normalizationFieldMappings as $normalizationFieldMapping) {
121 2
            $fieldNormalizer = $normalizationFieldMapping->getFieldNormalizer();
122
123 2
            if (!$this->isWithinGroup($context, $normalizationFieldMapping)) {
124 1
                continue;
125
            }
126
127 2
            $name = $normalizationFieldMapping->getName();
128
129 2
            $subPath = $this->getSubPathByName($path, $name);
130
131 2
            $this->logger->info('serialize: path {path}', ['path' => $subPath]);
132
133 2
            $data[$name] = $fieldNormalizer->normalizeField($subPath, $object, $context, $this);
134
        }
135
136 2
        return $data;
137
    }
138
139
    /**
140
     * @param NormalizerContextInterface         $context
141
     * @param NormalizationFieldMappingInterface $fieldMapping
142
     *
143
     * @return bool
144
     */
145 2
    private function isWithinGroup(
146
        NormalizerContextInterface $context,
147
        NormalizationFieldMappingInterface $fieldMapping
148
    ): bool {
149 2
        if ([] === $groups = $context->getGroups()) {
150 1
            return true;
151
        }
152
153 1
        foreach ($fieldMapping->getGroups() as $group) {
154 1
            if (in_array($group, $groups, true)) {
155 1
                return true;
156
            }
157
        }
158
159 1
        return false;
160
    }
161
162
    /**
163
     * @param string $path
164
     * @param string $name
165
     *
166
     * @return string
167
     */
168 2
    private function getSubPathByName(string $path, string $name): string
169
    {
170 2
        return '' === $path ? $name : $path.'.'.$name;
171
    }
172
}
173