Completed
Push — develop ( 0d96fa...aab434 )
by Neomerx
02:11
created

ModelSchemaInfo   A

Complexity

Total Complexity 32

Size/Duplication

Total Lines 400
Duplicated Lines 4.75 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
wmc 32
lcom 1
cbo 0
dl 19
loc 400
rs 9.6
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A getData() 0 17 1
A setData() 0 8 1
B registerClass() 0 27 4
A hasClass() 0 6 1
A getTable() 0 6 1
A getPrimaryKey() 0 6 1
A getAttributeTypes() 0 6 1
A getAttributeType() 0 6 1
A hasAttributeType() 0 6 1
A getAttributeLengths() 0 6 1
A hasAttributeLength() 0 6 1
A getAttributeLength() 0 6 1
A getAttributes() 0 6 1
A hasRelationship() 0 6 1
A getRelationshipType() 0 6 1
A getReverseRelationship() 0 6 1
A getReversePrimaryKey() 9 9 1
A getReverseForeignKey() 10 10 1
A getReverseModelClass() 0 6 1
A getForeignKey() 0 6 1
A getBelongsToManyRelationship() 0 6 1
A registerBelongsToOneRelationship() 0 17 1
A registerBelongsToManyRelationship() 0 23 1
A registerRelationshipType() 0 10 2
A registerReversedRelationship() 0 20 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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
    public function getData(): array
82
    {
83
        $result = [
84
            $this->foreignKeys,
85
            $this->belongsToMany,
86
            $this->relationshipTypes,
87
            $this->reversedRelationships,
88
            $this->tableNames,
89
            $this->primaryKeys,
90
            $this->attributeTypes,
91
            $this->attributeLengths,
92
            $this->attributes,
93
            $this->reversedClasses,
94
        ];
95
96
        return $result;
97
    }
98
99
    /**
100
     * @param array $data
101
     *
102
     * @return self
103
     */
104
    public function setData(array $data): self
105
    {
106
        list($this->foreignKeys, $this->belongsToMany, $this->relationshipTypes,
107
            $this->reversedRelationships,$this->tableNames, $this->primaryKeys,
108
            $this->attributeTypes, $this->attributeLengths, $this->attributes, $this->reversedClasses) = $data;
109
110
        return $this;
111
    }
112
113
    /**
114
     * @inheritdoc
115
     */
116
    public function registerClass(
117
        string $class,
118
        string $tableName,
119
        string $primaryKey,
120
        array $attributeTypes,
121
        array $attributeLengths
122
    ): ModelSchemaInfoInterface {
123
        if (empty($class) === true) {
124
            throw new InvalidArgumentException('class');
125
        }
126
127
        if (empty($tableName) === true) {
128
            throw new InvalidArgumentException('tableName');
129
        }
130
131
        if (empty($primaryKey) === true) {
132
            throw new InvalidArgumentException('primaryKey');
133
        }
134
135
        $this->tableNames[$class]       = $tableName;
136
        $this->primaryKeys[$class]      = $primaryKey;
137
        $this->attributeTypes[$class]   = $attributeTypes;
138
        $this->attributeLengths[$class] = $attributeLengths;
139
        $this->attributes[$class]       = array_keys($attributeTypes);
140
141
        return $this;
142
    }
143
144
    /**
145
     * @inheritdoc
146
     */
147
    public function hasClass(string $class): bool
148
    {
149
        $result = array_key_exists($class, $this->tableNames);
150
151
        return $result;
152
    }
153
154
    /**
155
     * @inheritdoc
156
     */
157
    public function getTable(string $class): string
158
    {
159
        $result = $this->tableNames[$class];
160
161
        return $result;
162
    }
163
164
    /**
165
     * @inheritdoc
166
     */
167
    public function getPrimaryKey(string $class): string
168
    {
169
        $result = $this->primaryKeys[$class];
170
171
        return $result;
172
    }
173
174
    /**
175
     * @inheritdoc
176
     */
177
    public function getAttributeTypes(string $class): array
178
    {
179
        $result = $this->attributeTypes[$class];
180
181
        return $result;
182
    }
183
184
    /**
185
     * @inheritdoc
186
     */
187
    public function getAttributeType(string $class, string $name): string
188
    {
189
        $result = $this->attributeTypes[$class][$name];
190
191
        return $result;
192
    }
193
194
    /**
195
     * @inheritdoc
196
     */
197
    public function hasAttributeType(string $class, string $name): bool
198
    {
199
        $result = isset($this->attributeTypes[$class][$name]);
200
201
        return $result;
202
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207
    public function getAttributeLengths(string $class): array
208
    {
209
        $result = $this->attributeLengths[$class];
210
211
        return $result;
212
    }
213
214
    /**
215
     * @inheritdoc
216
     */
217
    public function hasAttributeLength(string $class, string $name): bool
218
    {
219
        $result = isset($this->attributeLengths[$class][$name]);
220
221
        return $result;
222
    }
223
224
    /**
225
     * @inheritdoc
226
     */
227
    public function getAttributeLength(string $class, string $name): int
228
    {
229
        $result = $this->attributeLengths[$class][$name];
230
231
        return $result;
232
    }
233
234
    /**
235
     * @inheritdoc
236
     */
237
    public function getAttributes(string $class): array
238
    {
239
        $result = $this->attributes[$class];
240
241
        return $result;
242
    }
243
244
    /**
245
     * @inheritdoc
246
     */
247
    public function hasRelationship(string $class, string $name): bool
248
    {
249
        $result = isset($this->relationshipTypes[$class][$name]);
250
251
        return $result;
252
    }
253
254
    /**
255
     * @inheritdoc
256
     */
257
    public function getRelationshipType(string $class, string $name): int
258
    {
259
        $result = $this->relationshipTypes[$class][$name];
260
261
        return $result;
262
    }
263
264
    /**
265
     * @inheritdoc
266
     */
267
    public function getReverseRelationship(string $class, string $name): array
268
    {
269
        $result = $this->reversedRelationships[$class][$name];
270
271
        return $result;
272
    }
273
274
    /**
275
     * @inheritdoc
276
     */
277 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
        $reverseClass = $this->getReverseModelClass($class, $name);
280
281
        $table = $this->getTable($reverseClass);
282
        $key   = $this->getPrimaryKey($reverseClass);
283
284
        return [$key, $table];
285
    }
286
287
    /**
288
     * @inheritdoc
289
     */
290 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
        list ($reverseClass, $reverseName) = $this->getReverseRelationship($class, $name);
293
294
        $table = $this->getTable($reverseClass);
295
        // would work only if $name is hasMany relationship
296
        $key   = $this->getForeignKey($reverseClass, $reverseName);
297
298
        return [$key, $table];
299
    }
300
301
    /**
302
     * @inheritdoc
303
     */
304
    public function getReverseModelClass(string $class, string $name): string
305
    {
306
        $reverseClass = $this->reversedClasses[$class][$name];
307
308
        return $reverseClass;
309
    }
310
311
    /**
312
     * @inheritdoc
313
     */
314
    public function getForeignKey(string $class, string $name): string
315
    {
316
        $result = $this->foreignKeys[$class][$name];
317
318
        return $result;
319
    }
320
321
    /**
322
     * @inheritdoc
323
     */
324
    public function getBelongsToManyRelationship(string $class, string $name): array
325
    {
326
        $result = $this->belongsToMany[$class][$name];
327
328
        return $result;
329
    }
330
331
    /**
332
     * @inheritdoc
333
     */
334
    public function registerBelongsToOneRelationship(
335
        string $class,
336
        string $name,
337
        string $foreignKey,
338
        string $reverseClass,
339
        string $reverseName
340
    ): ModelSchemaInfoInterface {
341
        $this->registerRelationshipType(RelationshipTypes::BELONGS_TO, $class, $name);
342
        $this->registerRelationshipType(RelationshipTypes::HAS_MANY, $reverseClass, $reverseName);
343
344
        $this->registerReversedRelationship($class, $name, $reverseClass, $reverseName);
345
        $this->registerReversedRelationship($reverseClass, $reverseName, $class, $name);
346
347
        $this->foreignKeys[$class][$name] = $foreignKey;
348
349
        return $this;
350
    }
351
352
    /** @noinspection PhpTooManyParametersInspection
353
     * @inheritdoc
354
     */
355
    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
        $this->registerRelationshipType(RelationshipTypes::BELONGS_TO_MANY, $class, $name);
365
        $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
        $this->registerReversedRelationship($class, $name, $reverseClass, $reverseName);
371
        $this->registerReversedRelationship($reverseClass, $reverseName, $class, $name);
372
373
        $this->belongsToMany[$class][$name]               = [$table, $foreignKey, $reverseForeignKey];
374
        $this->belongsToMany[$reverseClass][$reverseName] = [$table, $reverseForeignKey, $foreignKey];
375
376
        return $this;
377
    }
378
379
    /**
380
     * @param int    $type
381
     * @param string $class
382
     * @param string $name
383
     *
384
     * @return void
385
     */
386
    private function registerRelationshipType(int $type, string $class, string $name): void
387
    {
388
        assert(empty($class) === false && empty($name) === false);
389
        assert(
390
            isset($this->relationshipTypes[$class][$name]) === false,
391
            "Relationship `$name` for class `$class` was already used."
392
        );
393
394
        $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
    private function registerReversedRelationship(
406
        string $class,
407
        string $name,
408
        string $reverseClass,
409
        string $reverseName
410
    ): void {
411
        assert(
412
            empty($class) === false &&
413
            empty($name) === false &&
414
            empty($reverseClass) === false &&
415
            empty($reverseName) === false
416
        );
417
418
        // NOTE:
419
        // this function relies it would be called after
420
        // `registerRelationshipType` which prevents duplicate registrations
421
422
        $this->reversedRelationships[$class][$name] = [$reverseClass, $reverseName];
423
        $this->reversedClasses[$class][$name]       = $reverseClass;
424
    }
425
}
426