Passed
Push — master ( 4e94c9...4bfcda )
by Michael
02:19
created

DataTypeManager::fromResource()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 9

Duplication

Lines 18
Ratio 100 %

Code Coverage

Tests 9
CRAP Score 4

Importance

Changes 0
Metric Value
dl 18
loc 18
ccs 9
cts 9
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 9
nc 4
nop 2
crap 4
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper\Handler;
5
6
use Mikemirten\Component\JsonApi\Mapper\Handler\DataTypeHandler\DataTypeHandlerInterface;
7
use Mikemirten\Component\JsonApi\Mapper\Handler\Exception\NotIterableAttribute;
8
use Mikemirten\Component\JsonApi\Mapper\Handler\Exception\UnknownDataTypeException;
9
use Mikemirten\Component\JsonApi\Mapper\Definition\Attribute;
10
11
/**
12
 * Data-type manager
13
 * Serves for data processing of types
14
 *
15
 * @package Mikemirten\Component\JsonApi\Mapper\Handler
16
 */
17
class DataTypeManager
18
{
19
    /**
20
     * List of generic types
21
     *
22
     * @var array
23
     */
24
    protected static $genericTypes = ['integer', 'float', 'string', 'boolean'];
25
26
    /**
27
     * Data-type handlers
28
     *
29
     * @var DataTypeHandlerInterface[]
30
     */
31
    protected $registeredTypes = [];
32
33
    /**
34
     * Register data-type handler
35
     *
36
     * @param DataTypeHandlerInterface $handler
37
     */
38 6
    public function registerDataTypeHandler(DataTypeHandlerInterface $handler)
39
    {
40 6
        foreach ($handler->supports() as $name) {
41 6
            $this->registeredTypes[$name] = $handler;
42
        }
43 6
    }
44
45
    /**
46
     * Process data-type
47
     *
48
     * @param  Attribute $definition
49
     * @param  mixed $value
50
     * @return mixed
51
     */
52 16 View Code Duplication
    public function toResource(Attribute $definition, $value)
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...
53
    {
54 16
        if (! $definition->hasType()) {
55 3
            return $this->processNotTypedToResource($definition, $value);
56
        }
57
58 13
        $type = $definition->getType();
59
60 13
        if (isset($this->registeredTypes[$type])) {
61 3
            return $this->processHandlerToResource($definition, $value);
62
        }
63
64 10
        if (in_array($type, self::$genericTypes)) {
65 9
            return $this->processGeneric($definition, $value);
66
        }
67
68 1
        throw new UnknownDataTypeException($definition);
69
    }
70
71
    /**
72
     * Process data-type
73
     *
74
     * @param  Attribute $definition
75
     * @param  mixed $value
76
     * @return mixed
77
     */
78 16 View Code Duplication
    public function fromResource(Attribute $definition, $value)
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...
79
    {
80 16
        if (! $definition->hasType()) {
81 3
            return $this->processNotTypedFromResource($definition, $value);
82
        }
83
84 13
        $type = $definition->getType();
85
86 13
        if (isset($this->registeredTypes[$type])) {
87 3
            return $this->processHandlerFromResource($definition, $value);
88
        }
89
90 10
        if (in_array($type, self::$genericTypes)) {
91 9
            return $this->processGeneric($definition, $value, false);
92
        }
93
94 1
        throw new UnknownDataTypeException($definition);
95
    }
96
97
    /**
98
     * Process not-typed value
99
     * Both directions: from object to resource and from resource to object
100
     *
101
     * @param  Attribute $definition
102
     * @param  mixed $value
103
     * @return mixed
104
     * @throws NotIterableAttribute
105
     */
106 3 View Code Duplication
    protected function processNotTypedToResource(Attribute $definition, $value)
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...
107
    {
108 3
        if (! $definition->isMany()) {
109 1
            return $value;
110
        }
111
112 2
        if ($value instanceof \Traversable) {
113
            return iterator_to_array($value, false);
114
        }
115
116 2
        if (is_array($value)) {
117 1
            return $value;
118
        }
119
120 1
        throw new NotIterableAttribute($definition, $value);
121
    }
122
123
    /**
124
     * Process not-typed value
125
     * Both directions: from object to resource and from resource to object
126
     *
127
     * @param  Attribute $definition
128
     * @param  mixed $value
129
     * @return mixed
130
     * @throws NotIterableAttribute
131
     */
132 3 View Code Duplication
    protected function processNotTypedFromResource(Attribute $definition, $value)
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...
133
    {
134 3
        if (! $definition->isMany()) {
135 1
            return $value;
136
        }
137
138 2
        if ($value instanceof \Traversable) {
139
            return $value;
140
        }
141
142 2
        if (is_array($value)) {
143 1
            return new \ArrayIterator($value);
144
        }
145
146 1
        throw new NotIterableAttribute($definition, $value);
147
    }
148
149
    /**
150
     * Process value by registered data-type handler.
151
     * From object to resource.
152
     *
153
     * @param  Attribute $definition
154
     * @param  mixed $value
155
     * @return mixed
156
     * @throws NotIterableAttribute
157
     */
158 3 View Code Duplication
    protected function processHandlerToResource(Attribute $definition, $value)
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...
159
    {
160 3
        $type = $definition->getType();
161 3
        $handler = $this->registeredTypes[$type];
162 3
        $parameters = $definition->getTypeParameters();
163
164 3
        if (! $definition->isMany()) {
165 1
            return $handler->toResource($value, $parameters);
166
        }
167
168 2
        if (! $value instanceof \Traversable && ! is_array($value)) {
169 1
            throw new NotIterableAttribute($definition, $value);
170
        }
171
172 1
        $collection = [];
173
174 1
        foreach ($value as $item) {
175 1
            $collection[] = $handler->toResource($item, $parameters);
176
        }
177
178 1
        return $collection;
179
    }
180
181
    /**
182
     * Process value by registered data-type handler.
183
     * From resource to object.
184
     *
185
     * @param  Attribute $definition
186
     * @param  mixed $value
187
     * @return mixed
188
     * @throws NotIterableAttribute
189
     */
190 3 View Code Duplication
    protected function processHandlerFromResource(Attribute $definition, $value)
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...
191
    {
192 3
        $type = $definition->getType();
193 3
        $handler = $this->registeredTypes[$type];
194 3
        $parameters = $definition->getTypeParameters();
195
196 3
        if (! $definition->isMany()) {
197 1
            return $handler->fromResource($value, $parameters);
198
        }
199
200 2
        if (! $value instanceof \Traversable && ! is_array($value)) {
201 1
            throw new NotIterableAttribute($definition, $value);
202
        }
203
204 1
        $collection = new \ArrayObject();
205
206 1
        foreach ($value as $item) {
207 1
            $collection[] = $handler->fromResource($item, $parameters);
208
        }
209
210 1
        return $collection;
211
    }
212
213
    /**
214
     * Process value by generic data-type
215
     * Both directions: from object to resource and from resource to object
216
     *
217
     * @param  Attribute $definition
218
     * @param  mixed     $value
219
     * @param  bool      $toResource
220
     * @return mixed
221
     */
222 18
    protected function processGeneric(Attribute $definition, $value, bool $toResource = true)
223
    {
224 18
        $type = $definition->getType();
225
226 18
        if (! $definition->isMany()) {
227 8
            return $this->processGenericType($type, $value);
228
        }
229
230 10
        if (! $value instanceof \Traversable && ! is_array($value)) {
231 2
            throw new NotIterableAttribute($definition, $value);
232
        }
233
234 8
        $collection = $toResource ? [] : new \ArrayObject();
235
236 8
        foreach ($value as $item) {
237 8
            $collection[] = $this->processGenericType($type, $item);
238
        }
239
240 8
        return $collection;
241
    }
242
243
    /**
244
     * Process generic data-types
245
     *
246
     * @param  string $type
247
     * @param  mixed  $value
248
     * @return bool|float|int|string
249
     */
250 16
    protected function processGenericType(string $type, $value)
251
    {
252 16
        if ($type === 'integer') {
253 4
            return (int) $value;
254
        }
255
256 12
        if ($type === 'float') {
257 4
            return (float) $value;
258
        }
259
260 8
        if ($type === 'boolean') {
261 4
            return (bool) $value;
262
        }
263
264 4
        return (string) $value;
265
    }
266
}