Completed
Push — master ( 920989...6e0273 )
by Dominik
02:11
created

Serializer::serialize()   B

Complexity

Conditions 5
Paths 9

Size

Total Lines 31
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0406

Importance

Changes 0
Metric Value
dl 0
loc 31
c 0
b 0
f 0
ccs 15
cts 17
cp 0.8824
rs 8.439
cc 5
eloc 17
nc 9
nop 3
crap 5.0406
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
        if ([] !== $embeddedFields) {
63 1
            $data['_embedded'] = $embeddedFields;
64
        }
65 1
        if ([] !== $links) {
66 1
            $data['_links'] = $links;
67
        }
68
69 1
        if ('' === $path) {
70 1
            return [$objectMapping->getName() => $data];
71
        }
72
73 1
        return $data;
74
    }
75
76
    /**
77
     * @param Request                $request
78
     * @param ObjectMappingInterface $objectMapping
79
     * @param $object
80
     * @param string $path
81
     *
82
     * @return array
83
     */
84 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...
85
        Request $request,
86
        ObjectMappingInterface $objectMapping,
87
        $object,
88
        string $path
89
    ): array {
90 1
        $data = [];
91 1
        foreach ($objectMapping->getFieldMappings() as $fieldMapping) {
92 1
            $name = $fieldMapping->getName();
93 1
            $subPath = '' !== $path ? $path.'.'.$name : $name;
94
95 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
96
97 1
            $data[$fieldMapping->getName()] = $fieldMapping
98 1
                ->getFieldSerializer()
99 1
                ->serializeField($subPath, $request, $object, $this);
100
        }
101
102 1
        return $data;
103
    }
104
105
    /**
106
     * @param Request                $request
107
     * @param ObjectMappingInterface $objectMapping
108
     * @param $object
109
     * @param string $path
110
     *
111
     * @return array
112
     */
113 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...
114
        Request $request,
115
        ObjectMappingInterface $objectMapping,
116
        $object,
117
        string $path
118
    ): array {
119 1
        $data = [];
120 1
        foreach ($objectMapping->getEmbeddedFieldMappings() as $fieldEmbeddedMapping) {
121 1
            $name = $fieldEmbeddedMapping->getName();
122 1
            $subPath = '' !== $path ? $path.'.'.$name : $name;
123
124 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
125
126 1
            $data[$fieldEmbeddedMapping->getName()] = $fieldEmbeddedMapping
127 1
                ->getFieldSerializer()
128 1
                ->serializeField($subPath, $request, $object, $this);
129
        }
130
131 1
        return $data;
132
    }
133
134
    /**
135
     * @param Request                $request
136
     * @param ObjectMappingInterface $objectMapping
137
     * @param $object
138
     * @param array  $fields
139
     * @param string $path
140
     *
141
     * @return array
142
     */
143 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...
144
        Request $request,
145
        ObjectMappingInterface $objectMapping,
146
        $object,
147
        array $fields,
148
        string $path
149
    ): array {
150 1
        $data = [];
151 1
        foreach ($objectMapping->getLinkMappings() as $linkMapping) {
152 1
            $name = $linkMapping->getName();
153 1
            $subPath = '' !== $path ? $path.'._links.'.$name : '_links.'.$name;
154
155 1
            $this->logger->info('deserialize: path {path}', ['path' => $subPath]);
156
157 1
            $data[$linkMapping->getName()] = $linkMapping
158 1
                ->getLinkSerializer()
159 1
                ->serializeLink($subPath, $request, $object, $fields)
160 1
                ->jsonSerialize();
161
        }
162
163 1
        return $data;
164
    }
165
}
166