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