Completed
Push — master ( 6f0513...c4b248 )
by Jasper
08:29 queued 06:06
created

Hydrator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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