Passed
Push — master ( bc9d1b...b1e342 )
by Dominik
02:00
created

Serializer::serialize()   B

Complexity

Conditions 4
Paths 5

Size

Total Lines 30
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4.0312

Importance

Changes 0
Metric Value
dl 0
loc 30
ccs 14
cts 16
cp 0.875
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 16
nc 5
nop 3
crap 4.0312
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Serialization;
6
7
use Chubbyphp\Serialization\Mapping\ObjectMappingInterface;
8
use Chubbyphp\Serialization\Registry\ObjectMappingRegistryInterface;
9
use Psr\Http\Message\ServerRequestInterface as Request;
10
use Psr\Log\LoggerInterface;
11
use Psr\Log\NullLogger;
12
13
final class Serializer implements SerializerInterface
14
{
15
    /**
16
     * @var ObjectMappingRegistryInterface
17
     */
18
    private $objectMappingRegistry;
19
20
    /**
21
     * @var LoggerInterface
22
     */
23
    private $logger;
24
25
    /**
26
     * @param ObjectMappingRegistryInterface $objectMappingRegistry
27
     * @param LoggerInterface                $logger
28
     */
29 1
    public function __construct(ObjectMappingRegistryInterface $objectMappingRegistry, LoggerInterface $logger = null)
30
    {
31 1
        $this->objectMappingRegistry = $objectMappingRegistry;
32 1
        $this->logger = $logger ?? new NullLogger();
33 1
    }
34
35
    /**
36
     * @param Request $request
37
     * @param object  $object
38
     * @param string  $path
39
     *
40
     * @return array
41
     *
42
     * @throws NotObjectException
43
     */
44 1
    public function serialize(Request $request, $object, string $path = ''): array
45
    {
46 1
        if (!is_object($object)) {
47
            $this->logger->error('serialize: object without an object given {type}', ['type' => gettype($object)]);
48
49
            throw NotObjectException::createByType(gettype($object));
50
        }
51
52 1
        $objectClass = get_class($object);
53
54 1
        $objectMapping = $this->objectMappingRegistry->getObjectMappingForClass($objectClass);
55
56 1
        $fields = $this->serializeFields($request, $objectMapping, $object, $path);
57 1
        $embeddedFields = $this->serializeEmbeddedFields($request, $objectMapping, $object, $path);
58 1
        $links = $this->serializeLinks($request, $objectMapping, $object, $fields, $path);
59
60 1
        $data = $fields;
61
62 1
        $data['_type'] = $objectMapping->getType();
63
64 1
        if ([] !== $embeddedFields) {
65 1
            $data['_embedded'] = $embeddedFields;
66
        }
67
68 1
        if ([] !== $links) {
69 1
            $data['_links'] = $links;
70
        }
71
72 1
        return $data;
73
    }
74
75
    /**
76
     * @param Request                $request
77
     * @param ObjectMappingInterface $objectMapping
78
     * @param $object
79
     * @param string $path
80
     *
81
     * @return array
82
     */
83 1 View Code Duplication
    private function serializeFields(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84
        Request $request,
85
        ObjectMappingInterface $objectMapping,
86
        $object,
87
        string $path
88
    ): array {
89 1
        $data = [];
90 1
        foreach ($objectMapping->getFieldMappings() as $fieldMapping) {
91 1
            $name = $fieldMapping->getName();
92 1
            $subPath = '' !== $path ? $path.'.'.$name : $name;
93
94 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
95
96 1
            $data[$fieldMapping->getName()] = $fieldMapping
97 1
                ->getFieldSerializer()
98 1
                ->serializeField($subPath, $request, $object, $this);
99
        }
100
101 1
        return $data;
102
    }
103
104
    /**
105
     * @param Request                $request
106
     * @param ObjectMappingInterface $objectMapping
107
     * @param $object
108
     * @param string $path
109
     *
110
     * @return array
111
     */
112 1 View Code Duplication
    private function serializeEmbeddedFields(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
113
        Request $request,
114
        ObjectMappingInterface $objectMapping,
115
        $object,
116
        string $path
117
    ): array {
118 1
        $data = [];
119 1
        foreach ($objectMapping->getEmbeddedFieldMappings() as $fieldEmbeddedMapping) {
120 1
            $name = $fieldEmbeddedMapping->getName();
121 1
            $subPath = '' !== $path ? $path.'.'.$name : $name;
122
123 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
124
125 1
            $data[$fieldEmbeddedMapping->getName()] = $fieldEmbeddedMapping
126 1
                ->getFieldSerializer()
127 1
                ->serializeField($subPath, $request, $object, $this);
128
        }
129
130 1
        return $data;
131
    }
132
133
    /**
134
     * @param Request                $request
135
     * @param ObjectMappingInterface $objectMapping
136
     * @param $object
137
     * @param array  $fields
138
     * @param string $path
139
     *
140
     * @return array
141
     */
142 1 View Code Duplication
    private function serializeLinks(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
143
        Request $request,
144
        ObjectMappingInterface $objectMapping,
145
        $object,
146
        array $fields,
147
        string $path
148
    ): array {
149 1
        $data = [];
150 1
        foreach ($objectMapping->getLinkMappings() as $linkMapping) {
151 1
            $name = $linkMapping->getName();
152 1
            $subPath = '' !== $path ? $path.'._links.'.$name : '_links.'.$name;
153
154 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
155
156 1
            $data[$linkMapping->getName()] = $linkMapping
157 1
                ->getLinkSerializer()
158 1
                ->serializeLink($subPath, $request, $object, $fields)
159 1
                ->jsonSerialize();
160
        }
161
162 1
        return $data;
163
    }
164
}
165