Completed
Pull Request — master (#23)
by
unknown
06:16 queued 03:01
created

Hydrator   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 211
Duplicated Lines 0 %

Test Coverage

Coverage 74.07%

Importance

Changes 0
Metric Value
wmc 27
eloc 68
dl 0
loc 211
ccs 60
cts 81
cp 0.7407
rs 10
c 0
b 0
f 0

11 Methods

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