Completed
Push — master ( 7b9d9c...6bacbf )
by Neomerx
08:04
created

ModelSchemaInfo::getPrimaryKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php namespace Limoncello\Application\Data;
2
3
/**
4
 * Copyright 2015-2017 [email protected]
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 * http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 */
18
19
use InvalidArgumentException;
20
use Limoncello\Contracts\Data\ModelSchemaInfoInterface;
21
use Limoncello\Contracts\Data\RelationshipTypes;
22
23
/**
24
 * @package Limoncello\Application
25
 */
26
class ModelSchemaInfo implements ModelSchemaInfoInterface
27
{
28
    /**
29
     * @var array
30
     */
31
    private $relationshipTypes = [];
32
33
    /**
34
     * @var array
35
     */
36
    private $reversedRelationships = [];
37
38
    /**
39
     * @var array
40
     */
41
    private $reversedClasses = [];
42
43
    /**
44
     * @var array
45
     */
46
    private $foreignKeys = [];
47
48
    /**
49
     * @var array
50
     */
51
    private $belongsToMany = [];
52
53
    /**
54
     * @var array
55
     */
56
    private $tableNames = [];
57
58
    /**
59
     * @var array
60
     */
61
    private $primaryKeys = [];
62
63
    /**
64
     * @var array
65
     */
66
    private $attributeTypes = [];
67
68
    /**
69
     * @var array
70
     */
71
    private $attributeLengths = [];
72
73
    /**
74
     * @var array
75
     */
76
    private $attributes = [];
77
78
    /**
79
     * @return array
80
     */
81 8
    public function getData(): array
82
    {
83
        $result = [
84 8
            $this->foreignKeys,
85 8
            $this->belongsToMany,
86 8
            $this->relationshipTypes,
87 8
            $this->reversedRelationships,
88 8
            $this->tableNames,
89 8
            $this->primaryKeys,
90 8
            $this->attributeTypes,
91 8
            $this->attributeLengths,
92 8
            $this->attributes,
93 8
            $this->reversedClasses,
94
        ];
95
96 8
        return $result;
97
    }
98
99
    /**
100
     * @param array $data
101
     *
102
     * @return self
103
     */
104 7
    public function setData(array $data): self
105
    {
106 7
        list($this->foreignKeys, $this->belongsToMany, $this->relationshipTypes,
107 7
            $this->reversedRelationships,$this->tableNames, $this->primaryKeys,
108 7
            $this->attributeTypes, $this->attributeLengths, $this->attributes, $this->reversedClasses) = $data;
109
110 7
        return $this;
111
    }
112
113
    /**
114
     * @inheritdoc
115
     */
116 8
    public function registerClass(
117
        string $class,
118
        string $tableName,
119
        string $primaryKey,
120
        array $attributeTypes,
121
        array $attributeLengths
122
    ): ModelSchemaInfoInterface {
123 8
        if (empty($class) === true) {
124 1
            throw new InvalidArgumentException('class');
125
        }
126
127 8
        if (empty($tableName) === true) {
128 1
            throw new InvalidArgumentException('tableName');
129
        }
130
131 8
        if (empty($primaryKey) === true) {
132 1
            throw new InvalidArgumentException('primaryKey');
133
        }
134
135 8
        $this->tableNames[$class]       = $tableName;
136 8
        $this->primaryKeys[$class]      = $primaryKey;
137 8
        $this->attributeTypes[$class]   = $attributeTypes;
138 8
        $this->attributeLengths[$class] = $attributeLengths;
139 8
        $this->attributes[$class]       = array_keys($attributeTypes);
140
141 8
        return $this;
142
    }
143
144
    /**
145
     * @inheritdoc
146
     */
147 1
    public function hasClass(string $class): bool
148
    {
149 1
        $result = array_key_exists($class, $this->tableNames);
150
151 1
        return $result;
152
    }
153
154
    /**
155
     * @inheritdoc
156
     */
157 2
    public function getTable(string $class): string
158
    {
159 2
        $result = $this->tableNames[$class];
160
161 2
        return $result;
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167 2
    public function getPrimaryKey(string $class): string
168
    {
169 2
        $result = $this->primaryKeys[$class];
170
171 2
        return $result;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177 1
    public function getAttributeTypes(string $class): array
178
    {
179 1
        $result = $this->attributeTypes[$class];
180
181 1
        return $result;
182
    }
183
184
    /**
185
     * @inheritdoc
186
     */
187 1
    public function getAttributeType(string $class, string $name): string
188
    {
189 1
        $result = $this->attributeTypes[$class][$name];
190
191 1
        return $result;
192
    }
193
194
    /**
195
     * @inheritdoc
196
     */
197 1
    public function hasAttributeType(string $class, string $name): bool
198
    {
199 1
        $result = isset($this->attributeTypes[$class][$name]);
200
201 1
        return $result;
202
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207 1
    public function getAttributeLengths(string $class): array
208
    {
209 1
        $result = $this->attributeLengths[$class];
210
211 1
        return $result;
212
    }
213
214
    /**
215
     * @inheritdoc
216
     */
217 1
    public function hasAttributeLength(string $class, string $name): bool
218
    {
219 1
        $result = isset($this->attributeLengths[$class][$name]);
220
221 1
        return $result;
222
    }
223
224
    /**
225
     * @inheritdoc
226
     */
227 1
    public function getAttributeLength(string $class, string $name): int
228
    {
229 1
        $result = $this->attributeLengths[$class][$name];
230
231 1
        return $result;
232
    }
233
234
    /**
235
     * @inheritdoc
236
     */
237 1
    public function getAttributes(string $class): array
238
    {
239 1
        $result = $this->attributes[$class];
240
241 1
        return $result;
242
    }
243
244
    /**
245
     * @inheritdoc
246
     */
247 2
    public function hasRelationship(string $class, string $name): bool
248
    {
249 2
        $result = isset($this->relationshipTypes[$class][$name]);
250
251 2
        return $result;
252
    }
253
254
    /**
255
     * @inheritdoc
256
     */
257 2
    public function getRelationshipType(string $class, string $name): int
258
    {
259 2
        $result = $this->relationshipTypes[$class][$name];
260
261 2
        return $result;
262
    }
263
264
    /**
265
     * @inheritdoc
266
     */
267 2
    public function getReverseRelationship(string $class, string $name): array
268
    {
269 2
        $result = $this->reversedRelationships[$class][$name];
270
271 2
        return $result;
272
    }
273
274
    /**
275
     * @inheritdoc
276
     */
277 1 View Code Duplication
    public function getReversePrimaryKey(string $class, string $name): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
278
    {
279 1
        $reverseClass = $this->getReverseModelClass($class, $name);
280
281 1
        $table = $this->getTable($reverseClass);
282 1
        $key   = $this->getPrimaryKey($reverseClass);
283
284 1
        return [$key, $table];
285
    }
286
287
    /**
288
     * @inheritdoc
289
     */
290 1 View Code Duplication
    public function getReverseForeignKey(string $class, string $name): array
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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.

Loading history...
291
    {
292 1
        list ($reverseClass, $reverseName) = $this->getReverseRelationship($class, $name);
293
294 1
        $table = $this->getTable($reverseClass);
295
        // would work only if $name is hasMany relationship
296 1
        $key   = $this->getForeignKey($reverseClass, $reverseName);
297
298 1
        return [$key, $table];
299
    }
300
301
    /**
302
     * @inheritdoc
303
     */
304 1
    public function getReverseModelClass(string $class, string $name): string
305
    {
306 1
        $reverseClass = $this->reversedClasses[$class][$name];
307
308 1
        return $reverseClass;
309
    }
310
311
    /**
312
     * @inheritdoc
313
     */
314 1
    public function getForeignKey(string $class, string $name): string
315
    {
316 1
        $result = $this->foreignKeys[$class][$name];
317
318 1
        return $result;
319
    }
320
321
    /**
322
     * @inheritdoc
323
     */
324 1
    public function getBelongsToManyRelationship(string $class, string $name): array
325
    {
326 1
        $result = $this->belongsToMany[$class][$name];
327
328 1
        return $result;
329
    }
330
331
    /**
332
     * @inheritdoc
333
     */
334 8
    public function registerBelongsToOneRelationship(
335
        string $class,
336
        string $name,
337
        string $foreignKey,
338
        string $reverseClass,
339
        string $reverseName
340
    ): ModelSchemaInfoInterface {
341 8
        $this->registerRelationshipType(RelationshipTypes::BELONGS_TO, $class, $name);
342 8
        $this->registerRelationshipType(RelationshipTypes::HAS_MANY, $reverseClass, $reverseName);
343
344 8
        $this->registerReversedRelationship($class, $name, $reverseClass, $reverseName);
345 8
        $this->registerReversedRelationship($reverseClass, $reverseName, $class, $name);
346
347 8
        $this->foreignKeys[$class][$name] = $foreignKey;
348
349 8
        return $this;
350
    }
351
352
    /** @noinspection PhpTooManyParametersInspection
353
     * @inheritdoc
354
     */
355 8
    public function registerBelongsToManyRelationship(
356
        string $class,
357
        string $name,
358
        string $table,
359
        string $foreignKey,
360
        string $reverseForeignKey,
361
        string $reverseClass,
362
        string $reverseName
363
    ): ModelSchemaInfoInterface {
364 8
        $this->registerRelationshipType(RelationshipTypes::BELONGS_TO_MANY, $class, $name);
365 8
        $this->registerRelationshipType(RelationshipTypes::BELONGS_TO_MANY, $reverseClass, $reverseName);
366
367
        // NOTE:
368
        // `registerReversedRelationship` relies on duplicate registration check in `registerRelationshipType`
369
        // so it must be called afterwards
370 8
        $this->registerReversedRelationship($class, $name, $reverseClass, $reverseName);
371 8
        $this->registerReversedRelationship($reverseClass, $reverseName, $class, $name);
372
373 8
        $this->belongsToMany[$class][$name]               = [$table, $foreignKey, $reverseForeignKey];
374 8
        $this->belongsToMany[$reverseClass][$reverseName] = [$table, $reverseForeignKey, $foreignKey];
375
376 8
        return $this;
377
    }
378
379
    /**
380
     * @param int    $type
381
     * @param string $class
382
     * @param string $name
383
     *
384
     * @return void
385
     */
386 8
    private function registerRelationshipType(int $type, string $class, string $name): void
387
    {
388 8
        assert(empty($class) === false && empty($name) === false);
389 8
        assert(
390 8
            isset($this->relationshipTypes[$class][$name]) === false,
391 8
            "Relationship `$name` for class `$class` was already used."
392
        );
393
394 8
        $this->relationshipTypes[$class][$name] = $type;
395
    }
396
397
    /**
398
     * @param string $class
399
     * @param string $name
400
     * @param string $reverseClass
401
     * @param string $reverseName
402
     *
403
     * @return void
404
     */
405 8
    private function registerReversedRelationship(
406
        string $class,
407
        string $name,
408
        string $reverseClass,
409
        string $reverseName
410
    ): void {
411 8
        assert(
412 8
            empty($class) === false &&
413 8
            empty($name) === false &&
414 8
            empty($reverseClass) === false &&
415 8
            empty($reverseName) === false
416
        );
417
418
        // NOTE:
419
        // this function relies it would be called after
420
        // `registerRelationshipType` which prevents duplicate registrations
421
422 8
        $this->reversedRelationships[$class][$name] = [$reverseClass, $reverseName];
423 8
        $this->reversedClasses[$class][$name]       = $reverseClass;
424
    }
425
}
426