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

Hydrator   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Test Coverage

Coverage 98.57%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 60
c 2
b 0
f 0
dl 0
loc 190
ccs 69
cts 70
cp 0.9857
rs 10
wmc 25

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
B hydrateRelationships() 0 51 10
A hydrateItem() 0 19 4
A hydrateCollection() 0 8 2
A getCollection() 0 15 3
A getElementKey() 0 3 1
A getItemClass() 0 7 2
A getItemKey() 0 3 1
A getItem() 0 3 1
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