Completed
Pull Request — master (#53)
by Julien
02:22
created

ModelHydrator::guessCollectionClassname()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 3
nop 1
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
     * @access private
23
     */
24
    protected $sdk;
25
26
    /**
27
     * Constructor.
28
     *
29
     * @param SdkClient $sdk
30
     * @access public
31
     */
32
    public function __construct(SdkClient $sdk)
33
    {
34
        $this->sdk = $sdk;
35
    }
36
37
    /**
38
      * convertId
39
      *
40
      * @param string $id
41
      * @param string $modelName
42
      * @access public
43
      * @return string
44
      */
45
    public function convertId($id, $modelName)
46
    {
47
        $id = (string) $id;
48
49
        // add slash if needed to have a valid hydra id
50
        if (strpos($id, '/') === false) {
51
            $mapping = $this->sdk->getMapping();
52
            $key = $mapping->getKeyFromModel($modelName);
53
            $id = '/' . $key . '/' . $id;
54
55
            if ($prefix = $mapping->getIdPrefix()) {
56
                $id = $prefix . $id;
57
            }
58
        }
59
60
        return $id;
61
    }
62
63
    /**
64
     * convert data as array to entity
65
     *
66
     * @param array $data
67
     * @param string $modelName
68
     * @access public
69
     * @return object
70
     */
71
    public function hydrate($data, $modelName)
72
    {
73
        $mapping = $this->sdk->getMapping();
74
        $key = $mapping->getKeyFromModel($modelName);
75
        $modelName = $mapping->getModelName($key);
76
77
        return $this->deserialize($data, $modelName);
78
    }
79
80
    /**
81
     * convert API response to Collection containing entities
82
     *
83
     * @param array $data
84
     * @param string $modelName
85
     * @access public
86
     * @return array
87
     */
88
    public function hydrateList($data, $modelName)
89
    {
90
        $collectionKey = $this->sdk->getMapping()
91
            ->getConfig()['collectionKey'];
92
93
        if (is_array($data) && ArrayHelper::arrayHas($data, $collectionKey)) {
94
            return $this->deserializeAll($data, $modelName);
95
        }
96
97
        return new Collection();
98
    }
99
100
    /**
101
     * convert list of data as array to Collection containing entities
102
     *
103
     * @param array  $data
104
     * @param string $modelName
105
     *
106
     * @access private
107
     * @return Collection
108
     */
109
    private function deserializeAll($data, $modelName)
110
    {
111
        $collectionKey = $this->sdk->getMapping()
112
            ->getConfig()['collectionKey'];
113
114
        $itemList = array_map(
115
            function ($member) use ($modelName, $collectionKey) {
116
                return $this->deserialize($member, $modelName);
117
            },
118
            ArrayHelper::arrayGet($data, $collectionKey)
119
        );
120
121
122
        $extraProperties = array_filter(
123
            $data,
124
            function ($key) use ($collectionKey) {
125
                return $key !== $collectionKey;
126
            },
127
            ARRAY_FILTER_USE_KEY
128
        );
129
130
        $collectionClassName = $this->guessCollectionClassname($data);
131
132
        return new $collectionClassName($itemList, $extraProperties);
133
    }
134
135
    /**
136
     * convert array to entity
137
     *
138
     * @param array  $data
139
     * @param string $modelName
140
     * @access private
141
     * @return object|null
142
     */
143
    private function deserialize($data, $modelName)
144
    {
145
        if (empty($data)) {
146
            return null;
147
        }
148
149
        if (!is_array($data)) {
150
            return null;
151
        }
152
153
        return $this->sdk->getSerializer()->deserialize($data, $modelName);
154
    }
155
156
    /**
157
     * guess collection classname according to response data
158
     *
159
     * @param array $data
160
     * @access private
161
     * @return string
162
     */
163
    private function guessCollectionClassname($data)
164
    {
165
        switch (true) {
166
            case (!empty($data['@type']) && $data['@type'] === 'hydra:PagedCollection'):
167
                return HydraPaginatedCollection::class;
168
169
            case (array_key_exists('_embedded', $data)):
170
                return HalCollection::class;
171
172
            default:
173
                return Collection::class;
174
        }
175
    }
176
}
177