Completed
Push — master ( 43e796...2a9ed5 )
by Jasper
03:16
created

Hydrator::getItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 5
cts 5
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
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\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 \Swis\JsonApi\Client\Collection $jsonApiItems
66
     * @param \Swis\JsonApi\Client\Collection $items
67
     */
68 15
    public function hydrateRelationships(Collection $jsonApiItems, Collection $items)
69
    {
70 15
        $keyedItems = $items->keyBy(
71 15
            function (ItemInterface $item) {
72 15
                return $this->getItemKey($item);
73 15
            }
74
        );
75
76 15
        $jsonApiItems->each(
77 15
            function (ResourceItemInterface $jsonApiItem) use ($keyedItems) {
78 15
                if (!$jsonApiItem->has('relationships')) {
79 12
                    return;
80
                }
81
82 15
                $item = $this->getItem($keyedItems, $jsonApiItem);
83
84 15
                if ($item instanceof NullItem) {
85
                    return;
86
                }
87
88 15
                foreach ($jsonApiItem->get('relationships')->asArray() as $name => $relationship) {
89
                    /** @var \Art4\JsonApiClient\ElementInterface $data */
90 15
                    $data = $relationship->get('data');
91 15
                    $method = camel_case($name);
92
93 15
                    if ($data instanceof ResourceIdentifierInterface) {
94 15
                        $includedItem = $this->getItem($keyedItems, $data);
95
96 15
                        if ($includedItem instanceof NullItem) {
97 15
                            continue;
98
                        }
99
100 9
                        $item->setRelation($method, $includedItem);
101 15
                    } elseif ($data instanceof ResourceIdentifierCollectionInterface) {
102 15
                        $collection = $this->getCollection($keyedItems, $data);
103
104 15
                        $item->setRelation($method, $collection);
105
                    }
106
                }
107 15
            }
108
        );
109 15
    }
110
111
    /**
112
     * @param string $type
113
     *
114
     * @return \Swis\JsonApi\Client\Interfaces\ItemInterface
115
     */
116 24
    protected function getItemClass(string $type): ItemInterface
117
    {
118 24
        if ($this->typeMapper->hasMapping($type)) {
119 18
            return $this->typeMapper->getMapping($type);
120
        }
121
122 6
        return (new JenssegersItem())->setType($type);
123
    }
124
125
    /**
126
     * @param \Swis\JsonApi\Client\Collection                                                           $included
127
     * @param \Art4\JsonApiClient\ResourceIdentifierInterface|\Art4\JsonApiClient\ResourceItemInterface $identifier
128
     *
129
     * @return \Swis\JsonApi\Client\Interfaces\ItemInterface
130
     */
131 15
    protected function getItem(Collection $included, $identifier): ItemInterface
132
    {
133 15
        return $included->get(
134 15
            $this->getElementKey($identifier),
135 15
            function () {
136 15
                return new NullItem();
137 15
            }
138
        );
139
    }
140
141
    /**
142
     * @param \Swis\JsonApi\Client\Collection                                                                           $included
143
     * @param \Art4\JsonApiClient\ResourceIdentifierCollectionInterface|\Art4\JsonApiClient\ResourceCollectionInterface $identifierCollection
144
     *
145
     * @return \Swis\JsonApi\Client\Collection
146
     */
147 15
    protected function getCollection(Collection $included, $identifierCollection): Collection
148
    {
149 15
        $items = new Collection();
150
151 15
        foreach ($identifierCollection->asArray() as $identifier) {
152 15
            $item = $this->getItem($included, $identifier);
153
154 15
            if ($item instanceof NullItem) {
155 15
                continue;
156
            }
157
158 6
            $items->push($item);
159
        }
160
161 15
        return $items;
162
    }
163
164
    /**
165
     * @param \Swis\JsonApi\Client\Interfaces\ItemInterface $item
166
     *
167
     * @return string
168
     */
169 15
    protected function getItemKey(ItemInterface $item): string
170
    {
171 15
        return sprintf('%s:%s', $item->getType(), $item->getId());
172
    }
173
174
    /**
175
     * @param \Art4\JsonApiClient\ElementInterface $accessor
176
     *
177
     * @return string
178
     */
179 15
    protected function getElementKey(ElementInterface $accessor): string
180
    {
181 15
        return sprintf('%s:%s', $accessor->get('type'), $accessor->get('id'));
182
    }
183
}
184