Passed
Push — master ( 685595...680e76 )
by Julien
01:32
created

Mapping::getKeyFromModel()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 10
ccs 5
cts 5
cp 1
crap 3
rs 9.4285
c 0
b 0
f 0
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 1
        return $this->getClassMetadataByKey($key)->getModelName();
111
    }
112
113
    /**
114
     * return the list of mapping keys
115
     *
116
     * @return string[]
117
     */
118
    public function getMappingKeys()
119
    {
120 1
        return array_map(function (ClassMetadata $classMetadata) {
121 1
            return $classMetadata->getKey();
122 1
        }, $this->classMetadataList);
123
    }
124
125
    /**
126
     * get the key from an id (path)
127
     *
128
     * @param string $id
129
     *
130
     * @return string
131
     */
132
    public function getKeyFromId($id)
133
    {
134 1
        $key = $this->parseKeyFromId($id);
135 1
        $this->checkMappingExistence($key);
136
137 1
        return $key;
138
    }
139
140
    /**
141
     * getKeyFromModel
142
     *
143
     * @param string $modelName model name
144
     *
145
     * @return string
146
     *
147
     * @throws MappingException
148
     */
149
    public function getKeyFromModel($modelName)
150
    {
151 1
        foreach ($this->classMetadataList as $classMetadata) {
152 1
            if ($modelName === $classMetadata->getModelName()) {
153 1
                return $classMetadata->getKey();
154
            }
155
        }
156
157 1
        throw new MappingException(
158 1
            'Model name ' . $modelName . ' not found in mapping'
159
        );
160
    }
161
162
    /**
163
     * getClassMetadata for model name
164
     *
165
     * @param string $modelName
166
     *
167
     * @return ClassMetadata
168
     *
169
     * @throws MappingException
170
     */
171
    public function getClassMetadata($modelName)
172
    {
173 1
        foreach ($this->classMetadataList as $classMetadata) {
174 1
            if ($modelName === $classMetadata->getModelName()) {
175 1
                return $classMetadata;
176
            }
177
        }
178
179 1
        throw new MappingException($modelName . ' model is not mapped');
180
    }
181
182
    /**
183
     * getClassMetadata for id
184
     *
185
     * @param string $id
186
     *
187
     * @return ClassMetadata|null
188
     */
189
    public function tryGetClassMetadataById($id)
190
    {
191 1
        $key = $this->parseKeyFromId($id);
192
193 1
        foreach ($this->classMetadataList as $classMetadata) {
194 1
            if ($key === $classMetadata->getKey()) {
195 1
                return $classMetadata;
196
            }
197
        }
198 1
    }
199
200
    /**
201
     * hasClassMetadata
202
     *
203
     * @param string $modelName
204
     *
205
     * @return bool
206
     */
207
    public function hasClassMetadata($modelName)
208
    {
209 1
        foreach ($this->classMetadataList as $classMetadata) {
210 1
            if ($modelName === $classMetadata->getModelName()) {
211 1
                return true;
212
            }
213
        }
214
215 1
        return false;
216
    }
217
218
    /**
219
     * getMappingByKey
220
     *
221
     * @param string $key
222
     *
223
     * @return ClassMetadata|null
224
     */
225
    public function getClassMetadataByKey($key)
226
    {
227 1
        foreach ($this->classMetadataList as $classMetadata) {
228 1
            if ($key === $classMetadata->getKey()) {
229 1
                return $classMetadata;
230
            }
231
        }
232 1
    }
233
234
    /**
235
     * Parse the key from an id (path)
236
     *
237
     * @param string $id
238
     *
239
     * @return string|null
240
     */
241
    private function parseKeyFromId($id)
242
    {
243 1
        $id = $this->removePrefix($id);
244
245 1
        $matches = [];
246 1
        if (1 === preg_match('|/([^/]+)/[^/]+$|', $id, $matches)) {
247 1
            return $matches[1];
248
        }
249 1
    }
250
251
    /**
252
     * checkMappingExistence
253
     *
254
     * @param string $key
255
     * @param string|null $subKey
256
     */
257
    private function checkMappingExistence($key, $subKey = null)
258
    {
259 1
        if (empty($key)) {
260 1
            throw new MappingException('key is not set');
261
        }
262
263 1
        $metadata = $this->getClassMetadataByKey($key);
264 1
        if (!$metadata) {
265 1
            throw new MappingException($key . ' key is not mapped');
266
        }
267
268 1
        if (!empty($subKey)) {
269 1
            $methodName = 'get' . ucfirst($subKey);
270 1
            if (!$metadata->{$methodName}()) {
271 1
                throw new MappingException(
272 1
                    $key . ' key is mapped but no ' . $subKey . ' found'
273
                );
274
            }
275
        }
276 1
    }
277
278
    /**
279
     * removePrefix
280
     *
281
     * @param mixed $value
282
     *
283
     * @return string
284
     */
285
    private function removePrefix($value)
286
    {
287
        if (
288 1
            ($this->idPrefixLength > 0) &&
289 1
            (0 === strpos($value, $this->idPrefix))
290
        ) {
291 1
            return substr($value, $this->idPrefixLength);
292
        }
293
294 1
        return $value;
295
    }
296
}
297