Completed
Push — master ( cc21f4...3eeaf5 )
by Julien
06:41 queued 03:06
created

Mapping   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 289
Duplicated Lines 0 %

Test Coverage

Coverage 96.83%

Importance

Changes 0
Metric Value
eloc 65
dl 0
loc 289
ccs 61
cts 63
cp 0.9683
rs 9.68
c 0
b 0
f 0
wmc 34

16 Methods

Rating   Name   Duplication   Size   Complexity  
A getIdPrefix() 0 3 1
A getConfig() 0 3 1
A setMapping() 0 5 1
A setConfig() 0 5 1
A __construct() 0 5 1
A parseKeyFromId() 0 7 2
A getKeyFromModel() 0 10 3
A checkMappingExistence() 0 16 5
A getModelName() 0 8 1
A tryGetClassMetadataById() 0 7 3
A getMappingKeys() 0 5 1
A getKeyFromId() 0 10 2
A getClassMetadataByKey() 0 5 3
A hasClassMetadata() 0 9 3
A removePrefix() 0 10 3
A getClassMetadata() 0 9 3
1
<?php
2
3
namespace Mapado\RestClientSdk;
4
5
use Mapado\RestClientSdk\Exception\MappingException;
6
use Mapado\RestClientSdk\Mapping\ClassMetadata;
7
8
/**
9
 * Class Mapping
10
 *
11
 * @author Julien Deniau <[email protected]>
12
 */
13
class Mapping
14
{
15
    public const DEFAULT_CONFIG = ['collectionKey' => 'hydra:member'];
16
17
    /**
18
     * @var string
19
     */
20
    private $idPrefix;
21
22
    /**
23
     * @var int
24
     */
25
    private $idPrefixLength;
26
27
    /**
28
     * @var ClassMetadata[]
29
     */
30
    private $classMetadataList = [];
31
32
    /**
33
     * config
34
     *
35
     * @var array
36
     */
37
    private $config;
38
39
    /**
40
     * Constructor.
41
     *
42
     * @param string $idPrefix
43
     */
44
    public function __construct($idPrefix = '', $config = [])
45
    {
46 1
        $this->idPrefix = $idPrefix;
47 1
        $this->idPrefixLength = strlen($idPrefix);
48 1
        $this->setConfig($config);
49 1
    }
50
51
    /**
52
     * getIdPrefix
53
     *
54
     * @return string
55
     */
56
    public function getIdPrefix()
57
    {
58
        return $this->idPrefix;
59
    }
60
61
    /**
62
     * Getter for config
63
     *
64
     * @return array
65
     */
66
    public function getConfig()
67
    {
68 1
        return $this->config;
69
    }
70
71
    /**
72
     * Setter for config
73
     *
74
     * @param array $config
75
     *
76
     * @return Mapping
77
     */
78
    public function setConfig(array $config)
79
    {
80 1
        $this->config = array_merge(self::DEFAULT_CONFIG, $config);
81
82 1
        return $this;
83
    }
84
85
    /**
86
     * setMapping
87
     *
88
     * @param ClassMetadata[] $classMetadataList
89
     *
90
     * @return Mapping
91
     */
92
    public function setMapping(array $classMetadataList)
93
    {
94 1
        $this->classMetadataList = $classMetadataList;
95
96 1
        return $this;
97
    }
98
99
    /**
100
     * return a model class name for a given key
101
     *
102
     * @param string $key
103
     *
104
     * @return string
105
     */
106
    public function getModelName($key)
107
    {
108 1
        $this->checkMappingExistence($key, 'modelName');
109
110
        /** @var ClassMetadata */
111 1
        $classMetadata = $this->getClassMetadataByKey($key);
112
113 1
        return $classMetadata->getModelName();
114
    }
115
116
    /**
117
     * return the list of mapping keys
118
     *
119
     * @return string[]
120
     */
121
    public function getMappingKeys()
122
    {
123 1
        return array_map(function (ClassMetadata $classMetadata) {
124 1
            return $classMetadata->getKey();
125 1
        }, $this->classMetadataList);
126
    }
127
128
    /**
129
     * get the key from an id (path)
130
     *
131
     * @param string $id
132
     *
133
     * @return string
134
     */
135
    public function getKeyFromId($id)
136
    {
137 1
        $key = $this->parseKeyFromId($id);
138 1
        if (null === $key) {
139
            throw new MappingException("Unable to parse key from id {$id}.");
140
        }
141
142 1
        $this->checkMappingExistence($key);
143
144 1
        return $key;
145
    }
146
147
    /**
148
     * getKeyFromModel
149
     *
150
     * @param string $modelName model name
151
     *
152
     * @return string
153
     *
154
     * @throws MappingException
155
     */
156
    public function getKeyFromModel($modelName)
157
    {
158 1
        foreach ($this->classMetadataList as $classMetadata) {
159 1
            if ($modelName === $classMetadata->getModelName()) {
160 1
                return $classMetadata->getKey();
161
            }
162
        }
163
164 1
        throw new MappingException(
165 1
            'Model name ' . $modelName . ' not found in mapping'
166
        );
167
    }
168
169
    /**
170
     * getClassMetadata for model name
171
     *
172
     * @param string $modelName
173
     *
174
     * @return ClassMetadata
175
     *
176
     * @throws MappingException
177
     */
178
    public function getClassMetadata($modelName)
179
    {
180 1
        foreach ($this->classMetadataList as $classMetadata) {
181 1
            if ($modelName === $classMetadata->getModelName()) {
182 1
                return $classMetadata;
183
            }
184
        }
185
186 1
        throw new MappingException($modelName . ' model is not mapped');
187
    }
188
189
    /**
190
     * getClassMetadata for id
191
     *
192
     * @param string $id
193
     *
194
     * @return ClassMetadata|null
195
     */
196
    public function tryGetClassMetadataById($id)
197
    {
198 1
        $key = $this->parseKeyFromId($id);
199
200 1
        foreach ($this->classMetadataList as $classMetadata) {
201 1
            if ($key === $classMetadata->getKey()) {
202 1
                return $classMetadata;
203
            }
204
        }
205 1
    }
206
207
    /**
208
     * hasClassMetadata
209
     *
210
     * @param string $modelName
211
     *
212
     * @return bool
213
     */
214
    public function hasClassMetadata($modelName)
215
    {
216 1
        foreach ($this->classMetadataList as $classMetadata) {
217 1
            if ($modelName === $classMetadata->getModelName()) {
218 1
                return true;
219
            }
220
        }
221
222 1
        return false;
223
    }
224
225
    /**
226
     * getMappingByKey
227
     *
228
     * @param string $key
229
     *
230
     * @return ClassMetadata|null
231
     */
232
    public function getClassMetadataByKey($key)
233
    {
234 1
        foreach ($this->classMetadataList as $classMetadata) {
235 1
            if ($key === $classMetadata->getKey()) {
236 1
                return $classMetadata;
237
            }
238
        }
239 1
    }
240
241
    /**
242
     * Parse the key from an id (path)
243
     *
244
     * @param string $id
245
     *
246
     * @return string|null
247
     */
248
    private function parseKeyFromId($id)
249
    {
250 1
        $id = $this->removePrefix($id);
251
252 1
        $matches = [];
253 1
        if (1 === preg_match('|/([^/]+)/[^/]+$|', $id, $matches)) {
254 1
            return $matches[1];
255
        }
256 1
    }
257
258
    /**
259
     * checkMappingExistence
260
     *
261
     * @param string $key
262
     * @param string|null $subKey
263
     */
264
    private function checkMappingExistence($key, $subKey = null)
265
    {
266 1
        if (empty($key)) {
267 1
            throw new MappingException('key is not set');
268
        }
269
270 1
        $metadata = $this->getClassMetadataByKey($key);
271 1
        if (!$metadata) {
272 1
            throw new MappingException($key . ' key is not mapped');
273
        }
274
275 1
        if (!empty($subKey)) {
276 1
            $methodName = 'get' . ucfirst($subKey);
277 1
            if (!$metadata->{$methodName}()) {
278 1
                throw new MappingException(
279 1
                    $key . ' key is mapped but no ' . $subKey . ' found'
280
                );
281
            }
282
        }
283 1
    }
284
285
    /**
286
     * removePrefix
287
     *
288
     * @param mixed $value
289
     *
290
     * @return string
291
     */
292
    private function removePrefix($value)
293
    {
294
        if (
295 1
            ($this->idPrefixLength > 0) &&
296 1
            (0 === strpos($value, $this->idPrefix))
297
        ) {
298 1
            return substr($value, $this->idPrefixLength);
299
        }
300
301 1
        return $value;
302
    }
303
}
304