Passed
Push — master ( da3841...78234a )
by Michael
03:01
created

AttributeHandler::processResourceToType()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 8

Duplication

Lines 16
Ratio 100 %

Code Coverage

Tests 7
CRAP Score 3.0175

Importance

Changes 0
Metric Value
dl 16
loc 16
c 0
b 0
f 0
ccs 7
cts 8
cp 0.875
rs 9.4285
cc 3
eloc 8
nc 3
nop 2
crap 3.0175
1
<?php
2
declare(strict_types = 1);
3
4
namespace Mikemirten\Component\JsonApi\Mapper\Handler;
5
6
use Mikemirten\Component\JsonApi\Document\ResourceObject;
7
use Mikemirten\Component\JsonApi\Mapper\Definition\Attribute;
8
use Mikemirten\Component\JsonApi\Mapper\Handler\DataTypeHandler\DataTypeHandlerInterface;
9
use Mikemirten\Component\JsonApi\Mapper\MappingContext;
10
11
/**
12
 * Attribute handler
13
 *
14
 * @package Mikemirten\Component\JsonApi\Mapper\Handler
15
 */
16
class AttributeHandler implements HandlerInterface
17
{
18
    /**
19
     * List of generic types
20
     *
21
     * @var array
22
     */
23
    protected $genericTypes = ['integer', 'float', 'string', 'boolean'];
24
25
    /**
26
     * Data-type handlers
27
     *
28
     * @var DataTypeHandlerInterface[]
29
     */
30
    protected $registeredTypes = [];
31
32
    /**
33
     * Register data-type handler
34
     *
35
     * @param DataTypeHandlerInterface $handler
36
     */
37 2
    public function registerDataTypeHandler(DataTypeHandlerInterface $handler)
38
    {
39 2
        foreach ($handler->supports() as $name)
40
        {
41 2
            $this->registeredTypes[$name] = $handler;
42
        }
43 2
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48 4
    public function toResource($object, ResourceObject $resource, MappingContext $context)
49
    {
50 4
        $definitions = $context->getDefinition()->getAttributes();
51
52 4
        foreach ($definitions as $definition)
53
        {
54 4
            $this->processAttributeToResource($object, $resource, $definition);
55
        }
56 3
    }
57
58
    /**
59
     * Process attribute to resource mapping
60
     *
61
     * @param mixed          $object
62
     * @param ResourceObject $resource
63
     * @param Attribute      $definition
64
     */
65 4 View Code Duplication
    protected function processAttributeToResource($object, ResourceObject $resource, Attribute $definition)
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...
66
    {
67 4
        $name   = $definition->getName();
68 4
        $getter = $definition->getGetter();
69
70 4
        $value = $object->$getter();
71
        
72 4
        if ($definition->hasType()) {
73 3
            $value = $this->processTypeToResource($definition, $value);
74
        }
75
76 3
        $resource->setAttribute($name, $value);
77 3
    }
78
79
    /**
80
     * Process data-type
81
     *
82
     * @param  Attribute $definition
83
     * @param  mixed     $value
84
     * @return mixed
85
     */
86 3 View Code Duplication
    protected function processTypeToResource(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...
87
    {
88 3
        $type = $definition->getType();
89
90 3
        if (isset($this->registeredTypes[$type])) {
91 1
            $parameters = $definition->getTypeParameters();
92
93 1
            return $this->registeredTypes[$type]->toResource($value, $parameters);
94
        }
95
96 2
        if (in_array($type, $this->genericTypes)) {
97 1
            return $this->processGenericType($type, $value);
98
        }
99
100 1
        throw new \LogicException(sprintf('Unable to handle unknown type "%s" of attribute "%s"', $type, $definition->getName()));
101
    }
102
103
    /**
104
     * Process data-type
105
     *
106
     * @param  Attribute $definition
107
     * @param  mixed     $value
108
     * @return mixed
109
     */
110 2 View Code Duplication
    protected function processResourceToType(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...
111
    {
112 2
        $type = $definition->getType();
113
114 2
        if (isset($this->registeredTypes[$type])) {
115 1
            $parameters = $definition->getTypeParameters();
116
117 1
            return $this->registeredTypes[$type]->fromResource($value, $parameters);
118
        }
119
120 1
        if (in_array($type, $this->genericTypes)) {
121 1
            return $this->processGenericType($type, $value);
122
        }
123
124
        throw new \LogicException(sprintf('Unable to handle unknown type "%s" of attribute "%s"', $type, $definition->getName()));
125
    }
126
127
    /**
128
     * Process generic data-types
129
     *
130
     * @param  string $type
131
     * @param  mixed  $value
132
     * @return bool|float|int|string
133
     */
134 2
    protected function processGenericType(string $type, $value)
135
    {
136 2
        if ($type === 'integer') {
137
            return (int) $value;
138
        }
139
140 2
        if ($type === 'float') {
141
            return (float) $value;
142
        }
143
144 2
        if ($type === 'bool') {
145
            return (bool) $value;
146
        }
147
148 2
        return (string) $value;
149
    }
150
151
    /**
152
     * {@inheritdoc}
153
     */
154 3
    public function fromResource($object, ResourceObject $resource, MappingContext $context)
155
    {
156 3
        $definitions = $context->getDefinition()->getAttributes();
157
158 3
        foreach ($definitions as $definition)
159
        {
160 3
            if (! $definition->hasSetter()) {
161
                continue;
162
            }
163
164 3
            $this->processResourceToAttribute($object, $resource, $definition);
165
        }
166 3
    }
167
168
    /**
169
     * Process resource to attribute mapping
170
     *
171
     * @param mixed          $object
172
     * @param ResourceObject $resource
173
     * @param Attribute      $definition
174
     */
175 3 View Code Duplication
    protected function processResourceToAttribute($object, ResourceObject $resource, Attribute $definition)
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...
176
    {
177 3
        $name = $definition->getName();
178
179 3
        if (! $resource->hasAttribute($name)) {
180
            return;
181
        }
182
183 3
        $value  = $resource->getAttribute($name);
184 3
        $setter = $definition->getSetter();
185
186 3
        if ($definition->hasType()) {
187 2
            $value = $this->processResourceToType($definition, $value);
188
        }
189
190 3
        $object->$setter($value);
191
    }
192
}