Passed
Push — master ( 5574d5...24b486 )
by Jasper
04:36
created

Hydrator::hydrateRelationships()   B

Complexity

Conditions 10
Paths 1

Size

Total Lines 51
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 10.0033

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 29
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 51
ccs 30
cts 31
cp 0.9677
crap 10.0033
rs 7.6666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Swis\JsonApi\Client\JsonApi;
4
5
use Art4\JsonApiClient\ElementInterface;
6
use Art4\JsonApiClient\ResourceCollectionInterface;
7
use Art4\JsonApiClient\ResourceIdentifierCollectionInterface;
8
use Art4\JsonApiClient\ResourceIdentifierInterface;
9
use Art4\JsonApiClient\ResourceItemInterface;
10
use Illuminate\Support\Str;
11
use Swis\JsonApi\Client\Collection;
12
use Swis\JsonApi\Client\Interfaces\ItemInterface;
13
use Swis\JsonApi\Client\Interfaces\TypeMapperInterface;
14
use Swis\JsonApi\Client\Item;
15
use Swis\JsonApi\Client\Meta;
16
17
class Hydrator
18
{
19
    /**
20
     * @var \Swis\JsonApi\Client\Interfaces\TypeMapperInterface
21
     */
22
    protected $typeMapper;
23
24
    /**
25
     * @var \Swis\JsonApi\Client\JsonApi\LinksParser
26
     */
27
    protected $linksParser;
28
29
    /**
30
     * @param \Swis\JsonApi\Client\Interfaces\TypeMapperInterface $typeMapper
31
     * @param \Swis\JsonApi\Client\JsonApi\LinksParser            $linksParser
32
     */
33 55
    public function __construct(TypeMapperInterface $typeMapper, LinksParser $linksParser)
34
    {
35 55
        $this->typeMapper = $typeMapper;
36 55
        $this->linksParser = $linksParser;
37 55
    }
38
39
    /**
40
     * @param \Art4\JsonApiClient\ResourceItemInterface $jsonApiItem
41
     *
42
     * @return \Swis\JsonApi\Client\Interfaces\ItemInterface
43
     */
44 55
    public function hydrateItem(ResourceItemInterface $jsonApiItem): ItemInterface
45
    {
46 55
        $item = $this->getItemClass($jsonApiItem->get('type'));
47
48 55
        $item->setId($jsonApiItem->get('id'));
49
50 55
        if ($jsonApiItem->has('attributes')) {
51 55
            $item->fill($jsonApiItem->get('attributes')->asArray(true));
52
        }
53
54 55
        if ($jsonApiItem->has('links')) {
55 50
            $item->setLinks($this->linksParser->parse($jsonApiItem->get('links')->asArray(false)));
56
        }
57
58 55
        if ($jsonApiItem->has('meta')) {
59 50
            $item->setMeta(new Meta($jsonApiItem->get('meta')->asArray(true)));
60
        }
61
62 55
        return $item;
63
    }
64
65
    /**
66
     * @param \Art4\JsonApiClient\ResourceCollectionInterface $jsonApiCollection
67
     *
68
     * @return \Swis\JsonApi\Client\Collection
69
     */
70 5
    public function hydrateCollection(ResourceCollectionInterface $jsonApiCollection): Collection
71
    {
72 5
        $collection = new Collection();
73 5
        foreach ($jsonApiCollection->asArray() as $item) {
74 5
            $collection->push($this->hydrateItem($item));
75
        }
76
77 5
        return $collection;
78
    }
79
80
    /**
81
     * @param \Swis\JsonApi\Client\Collection $jsonApiItems
82
     * @param \Swis\JsonApi\Client\Collection $items
83
     */
84 30
    public function hydrateRelationships(Collection $jsonApiItems, Collection $items)
85
    {
86 30
        $keyedItems = $items->reverse()->keyBy(
87 12
            function (ItemInterface $item) {
88 30
                return $this->getItemKey($item);
89 30
            }
90
        );
91
92 30
        $jsonApiItems->each(
93 12
            function (ResourceItemInterface $jsonApiItem) use ($keyedItems) {
94 30
                if (!$jsonApiItem->has('relationships')) {
95 20
                    return;
96
                }
97
98 30
                $item = $this->getItem($keyedItems, $jsonApiItem);
99
100 30
                if ($item === null) {
101
                    return;
102
                }
103
104 30
                foreach ($jsonApiItem->get('relationships')->asArray() as $name => $relationship) {
105 30
                    if (!$relationship->has('data')) {
106 5
                        continue;
107
                    }
108
109
                    /** @var \Art4\JsonApiClient\ElementInterface $data */
110 25
                    $data = $relationship->get('data');
111 25
                    $method = Str::camel($name);
112
113 25
                    $links = null;
114 25
                    if ($relationship->has('links')) {
115 25
                        $links = $this->linksParser->parse($relationship->get('links')->asArray(false));
116
                    }
117
118 25
                    $meta = null;
119 25
                    if ($relationship->has('meta')) {
120 25
                        $meta = new Meta($relationship->get('meta')->asArray(true));
121
                    }
122
123 25
                    if ($data instanceof ResourceIdentifierInterface) {
124 25
                        $includedItem = $this->getItem($keyedItems, $data);
125
126 25
                        if ($includedItem === null) {
127 25
                            continue;
128
                        }
129
130 15
                        $item->setRelation($method, $includedItem, $links, $meta);
131 25
                    } elseif ($data instanceof ResourceIdentifierCollectionInterface) {
132 25
                        $collection = $this->getCollection($keyedItems, $data);
133
134 25
                        $item->setRelation($method, $collection, $links, $meta);
135
                    }
136
                }
137 30
            }
138
        );
139 30
    }
140
141
    /**
142
     * @param string $type
143
     *
144
     * @return \Swis\JsonApi\Client\Interfaces\ItemInterface
145
     */
146 55
    protected function getItemClass(string $type): ItemInterface
147
    {
148 55
        if ($this->typeMapper->hasMapping($type)) {
149 45
            return $this->typeMapper->getMapping($type);
150
        }
151
152 10
        return (new Item())->setType($type);
153
    }
154
155
    /**
156
     * @param \Swis\JsonApi\Client\Collection                                                           $included
157
     * @param \Art4\JsonApiClient\ResourceIdentifierInterface|\Art4\JsonApiClient\ResourceItemInterface $identifier
158
     *
159
     * @return \Swis\JsonApi\Client\Interfaces\ItemInterface|null
160
     */
161 30
    protected function getItem(Collection $included, $identifier)
162
    {
163 30
        return $included->get($this->getElementKey($identifier));
164
    }
165
166
    /**
167
     * @param \Swis\JsonApi\Client\Collection                                                                           $included
168
     * @param \Art4\JsonApiClient\ResourceIdentifierCollectionInterface|\Art4\JsonApiClient\ResourceCollectionInterface $identifierCollection
169
     *
170
     * @return \Swis\JsonApi\Client\Collection
171
     */
172 25
    protected function getCollection(Collection $included, $identifierCollection): Collection
173
    {
174 25
        $items = new Collection();
175
176 25
        foreach ($identifierCollection->asArray() as $identifier) {
177 25
            $item = $this->getItem($included, $identifier);
178
179 25
            if ($item === null) {
180 25
                continue;
181
            }
182
183 10
            $items->push($item);
184
        }
185
186 25
        return $items;
187
    }
188
189
    /**
190
     * @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
191
     *
192
     * @return string
193
     */
194 30
    protected function getItemKey(ItemInterface $item): string
195
    {
196 30
        return sprintf('%s:%s', $item->getType(), $item->getId());
197
    }
198
199
    /**
200
     * @param \Art4\JsonApiClient\ElementInterface $accessor
201
     *
202
     * @return string
203
     */
204 30
    protected function getElementKey(ElementInterface $accessor): string
205
    {
206 30
        return sprintf('%s:%s', $accessor->get('type'), $accessor->get('id'));
207
    }
208
}
209