Completed
Push — master ( 535b5e...300324 )
by Jasper
13s queued 13s
created

Hydrator::hydrateRelationships()   B

Complexity

Conditions 10
Paths 1

Size

Total Lines 50
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 29
CRAP Score 10.0036

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 10
eloc 28
nc 1
nop 2
dl 0
loc 50
ccs 29
cts 30
cp 0.9667
crap 10.0036
rs 7.6666
c 1
b 0
f 0

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