Completed
Push — master ( b27094...afbc6d )
by Julien
05:50 queued 01:38
created

ModelHydrator   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 154
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 0
Metric Value
dl 0
loc 154
ccs 40
cts 44
cp 0.9091
rs 10
c 0
b 0
f 0
wmc 16

7 Methods

Rating   Name   Duplication   Size   Complexity  
A hydrate() 0 7 1
A __construct() 0 3 1
A convertId() 0 16 3
A guessCollectionClassname() 0 11 4
A hydrateList() 0 10 3
A deserializeAll() 0 23 1
A deserialize() 0 11 3
1
<?php
2
3
namespace Mapado\RestClientSdk\Model;
4
5
use Mapado\RestClientSdk\Collection\Collection;
6
use Mapado\RestClientSdk\Collection\HalCollection;
7
use Mapado\RestClientSdk\Collection\HydraPaginatedCollection;
8
use Mapado\RestClientSdk\Helper\ArrayHelper;
9
use Mapado\RestClientSdk\SdkClient;
10
11
/**
12
 * Class ModelHydrator
13
 *
14
 * @author Julien Deniau <[email protected]>
15
 */
16
class ModelHydrator
17
{
18
    /**
19
     * sdk
20
     *
21
     * @var SdkClient
22
     */
23
    protected $sdk;
24
25
    /**
26
     * Constructor.
27
     *
28
     * @param SdkClient $sdk
29
     */
30
    public function __construct(SdkClient $sdk)
31
    {
32 1
        $this->sdk = $sdk;
33 1
    }
34
35
    /**
36
     * convertId
37
     *
38
     * @param mixed $id
39
     * @param string $modelName
40
     *
41
     * @return string
42
     */
43
    public function convertId($id, $modelName)
44
    {
45 1
        $id = (string) $id;
46
47
        // add slash if needed to have a valid hydra id
48 1
        if (false === strpos($id, '/')) {
49 1
            $mapping = $this->sdk->getMapping();
50 1
            $key = $mapping->getKeyFromModel($modelName);
51 1
            $id = '/' . $key . '/' . $id;
52
53 1
            if ($prefix = $mapping->getIdPrefix()) {
54 1
                $id = $prefix . $id;
55
            }
56
        }
57
58 1
        return $id;
59
    }
60
61
    /**
62
     * convert data as array to entity
63
     *
64
     * @param array $data
65
     * @param string $modelName
66
     *
67
     * @return object
68
     */
69
    public function hydrate($data, $modelName)
70
    {
71 1
        $mapping = $this->sdk->getMapping();
72 1
        $key = $mapping->getKeyFromModel($modelName);
73 1
        $modelName = $mapping->getModelName($key);
74
75 1
        return $this->deserialize($data, $modelName);
76
    }
77
78
    /**
79
     * convert API response to Collection containing entities
80
     *
81
     * @param array $data
82
     * @param string $modelName
83
     *
84
     * @return Collection
85
     */
86
    public function hydrateList($data, $modelName)
87
    {
88 1
        $collectionKey = $this->sdk->getMapping()
89 1
            ->getConfig()['collectionKey'];
90
91 1
        if (is_array($data) && ArrayHelper::arrayHas($data, $collectionKey)) {
92 1
            return $this->deserializeAll($data, $modelName);
93
        }
94
95
        return new Collection();
96
    }
97
98
    /**
99
     * convert list of data as array to Collection containing entities
100
     *
101
     * @param array  $data
102
     * @param string $modelName
103
     *
104
     * @return Collection
105
     */
106
    private function deserializeAll($data, $modelName)
107
    {
108 1
        $collectionKey = $this->sdk->getMapping()
109 1
            ->getConfig()['collectionKey'];
110
111 1
        $itemList = array_map(
112 1
            function ($member) use ($modelName) {
113 1
                return $this->deserialize($member, $modelName);
114 1
            },
115 1
            ArrayHelper::arrayGet($data, $collectionKey)
116
        );
117
118 1
        $extraProperties = array_filter(
119 1
            $data,
120 1
            function ($key) use ($collectionKey) {
121 1
                return $key !== $collectionKey;
122 1
            },
123 1
            ARRAY_FILTER_USE_KEY
124
        );
125
126 1
        $collectionClassName = $this->guessCollectionClassname($data);
127
128 1
        return new $collectionClassName($itemList, $extraProperties);
129
    }
130
131
    /**
132
     * convert array to entity
133
     *
134
     * @param array  $data
135
     * @param string $modelName
136
     *
137
     * @return object|null
138
     */
139
    private function deserialize($data, $modelName)
140
    {
141 1
        if (empty($data)) {
142
            return null;
143
        }
144
145 1
        if (!is_array($data)) {
0 ignored issues
show
introduced by
The condition is_array($data) is always true.
Loading history...
146
            return null;
147
        }
148
149 1
        return $this->sdk->getSerializer()->deserialize($data, $modelName);
150
    }
151
152
    /**
153
     * guess collection classname according to response data
154
     *
155
     * @param array $data
156
     *
157
     * @return string
158
     */
159
    private function guessCollectionClassname($data)
160
    {
161
        switch (true) {
162 1
            case !empty($data['@type']) && 'hydra:PagedCollection' === $data['@type']:
163 1
                return HydraPaginatedCollection::class;
164
165 1
            case array_key_exists('_embedded', $data):
166 1
                return HalCollection::class;
167
168
            default:
169
                return Collection::class;
170
        }
171
    }
172
}
173