Model   B
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 496
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 54
lcom 1
cbo 9
dl 0
loc 496
ccs 0
cts 212
cp 0
rs 7.0642
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
modelClass() 0 1 ?
A modelClassInstance() 0 4 1
A create() 0 22 3
A createFromRecord() 0 18 3
A findAll() 0 17 4
A getAll() 0 9 2
A find() 0 17 4
A get() 0 10 2
A findAllByQuery() 0 11 2
A findByQuery() 0 10 2
A findAllByCondition() 0 14 3
A getAllByCondition() 0 9 2
A findByCondition() 0 10 2
A getByCondition() 0 9 2
A findAllByCriteria() 0 15 3
A getAllByCriteria() 0 9 2
A findByCriteria() 0 10 2
A getByCriteria() 0 9 2
A findByRecord() 0 14 2
A getByRecord() 0 4 1
A findRecordByModel() 0 4 1
A getRecordByModel() 0 9 2
A findCache() 0 9 2
A findCacheByRecord() 0 4 1
A addToCache() 0 4 1
A notFoundException() 0 9 1
A notFoundByCriteriaException() 0 10 1
A notFoundByConditionException() 0 10 1

How to fix   Complexity   

Complex Class

Complex classes like Model often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Model, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * @copyright  Copyright (c) Flipbox Digital Limited
5
 * @license    https://github.com/flipbox/spark/blob/master/LICENSE
6
 * @link       https://github.com/flipbox/spark
7
 */
8
9
namespace flipbox\spark\services;
10
11
use craft\helpers\Json as JsonHelper;
12
use flipbox\spark\exceptions\ModelNotFoundException;
13
use flipbox\spark\exceptions\RecordNotFoundException;
14
use flipbox\spark\helpers\ArrayHelper;
15
use flipbox\spark\helpers\ModelHelper;
16
use flipbox\spark\models\Model as BaseModel;
17
use flipbox\spark\records\Record;
18
use yii\base\Component;
19
use yii\base\InvalidConfigException;
20
use yii\db\QueryInterface;
21
22
/**
23
 * @author Flipbox Factory <[email protected]>
24
 * @since 1.0.0
25
 */
26
abstract class Model extends Component
27
{
28
29
    use traits\Model;
30
31
    /**
32
     * @var BaseModel[]
33
     */
34
    protected $cacheAll;
35
36
37
    /*******************************************
38
     * MODEL CLASSES
39
     *******************************************/
40
41
    /**
42
     * @return string
43
     */
44
    abstract public static function modelClass(): string;
45
46
    /**
47
     * @return string
48
     */
49
    public static function modelClassInstance(): string
50
    {
51
        return BaseModel::class;
52
    }
53
54
    /*******************************************
55
     * CREATE
56
     *******************************************/
57
58
    /**
59
     * @param array|Record $config
60
     * @param string|null $toScenario
61
     * @throws InvalidConfigException
62
     * @return BaseModel
63
     */
64
    public function create($config = [], string $toScenario = null): BaseModel
65
    {
66
67
        // Treat records as known data and set via config
68
        if ($config instanceof Record) {
69
            return $this->createFromRecord($config, $toScenario);
70
        }
71
72
        // Force Array
73
        if (!is_array($config)) {
74
            $config = ArrayHelper::toArray($config, [], false);
75
        }
76
77
        // Set the model class
78
        $config['class'] = static::modelClass();
79
80
        return ModelHelper::create(
81
            $config,
82
            static::modelClassInstance(),
83
            $toScenario
84
        );
85
    }
86
87
    /**
88
     * @param Record $record
89
     * @param string|null $toScenario
90
     * @throws InvalidConfigException
91
     * @return BaseModel
92
     */
93
    protected function createFromRecord(Record $record, string $toScenario = null): BaseModel
94
    {
95
96
        if (null !== $toScenario) {
97
            $record->setScenario($toScenario);
98
        }
99
100
        $modelClass = static::modelClass();
101
102
        /** @var BaseModel $model */
103
        $model = new $modelClass($record);
104
105
        if (null !== $toScenario) {
106
            $model->setScenario($toScenario);
107
        }
108
109
        return $model;
110
    }
111
112
    /*******************************************
113
     * FIND/GET ALL
114
     *******************************************/
115
116
    /**
117
     * @param string $toScenario
118
     * @return BaseModel[]
119
     */
120
    public function findAll(string $toScenario = null)
121
    {
122
123
        // Check addToCache
124
        if (is_null($this->cacheAll)) {
125
            $this->cacheAll = [];
126
127
            // Find record in db
128
            if ($records = $this->findAllRecords()) {
129
                foreach ($records as $record) {
130
                    $this->cacheAll[] = $this->findByRecord($record, $toScenario);
131
                }
132
            }
133
        }
134
135
        return $this->cacheAll;
136
    }
137
138
    /**
139
     * @param string $toScenario
140
     * @return BaseModel[]
141
     * @throws ModelNotFoundException
142
     */
143
    public function getAll(string $toScenario = null): array
144
    {
145
146
        if (!$models = $this->findAll($toScenario)) {
147
            $this->notFoundException();
148
        }
149
150
        return $models;
151
    }
152
153
    /*******************************************
154
     * FIND/GET
155
     *******************************************/
156
157
    /**
158
     * @param $identifier
159
     * @param string $toScenario
160
     * @return BaseModel|null
161
     */
162
    public function find($identifier, string $toScenario = null)
163
    {
164
165
        if ($identifier instanceof BaseModel) {
166
            $this->addToCache($identifier);
167
168
            if (null !== $toScenario) {
169
                $identifier->setScenario($toScenario);
170
            }
171
172
            return $identifier;
173
        } elseif ($identifier instanceof Record) {
174
            return $this->findByRecord($identifier, $toScenario);
175
        }
176
177
        return null;
178
    }
179
180
    /**
181
     * @param $identifier
182
     * @param string $toScenario
183
     * @return BaseModel
184
     * @throws ModelNotFoundException
185
     */
186
    public function get($identifier, string $toScenario = null): BaseModel
187
    {
188
189
        // Find model by ID
190
        if (!$model = $this->find($identifier, $toScenario)) {
191
            $this->notFoundException();
192
        }
193
194
        return $model;
195
    }
196
197
    /*******************************************
198
     * FIND/GET BY QUERY
199
     *******************************************/
200
201
    /**
202
     * @param QueryInterface $query
203
     * @param string $toScenario
204
     * @return BaseModel[]
205
     */
206
    public function findAllByQuery(QueryInterface $query, string $toScenario = null): array
207
    {
208
209
        $models = array();
210
211
        foreach ($query->all() as $record) {
212
            $models[] = $this->findByRecord($record, $toScenario);
213
        }
214
215
        return $models;
216
    }
217
218
    /**
219
     * @param QueryInterface $query
220
     * @param string $toScenario
221
     * @return BaseModel|null
222
     */
223
    public function findByQuery(QueryInterface $query, string $toScenario = null)
224
    {
225
226
        /** @var Record $record */
227
        if (!$record = $query->one()) {
228
            return null;
229
        }
230
231
        return $this->findByRecord($record, $toScenario);
0 ignored issues
show
Documentation introduced by
$record is of type array|boolean, but the function expects a object<flipbox\spark\records\Record>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
232
    }
233
234
    /*******************************************
235
     * FIND/GET BY CONDITION
236
     *******************************************/
237
238
    /**
239
     * @param $condition
240
     * @param string $toScenario
241
     * @return BaseModel[]
242
     */
243
    public function findAllByCondition($condition, string $toScenario = null): array
244
    {
245
246
        $models = [];
247
248
        // Find record in db
249
        if ($records = $this->findAllRecordsByCondition($condition)) {
250
            foreach ($records as $record) {
251
                $models[] = $this->findByRecord($record, $toScenario);
252
            }
253
        }
254
255
        return $models;
256
    }
257
258
    /**
259
     * @param $condition
260
     * @param string $toScenario
261
     * @return BaseModel[]
262
     * @throws ModelNotFoundException
263
     */
264
    public function getAllByCondition($condition, string $toScenario = null): array
265
    {
266
267
        if (!$models = $this->findAllByCondition($condition, $toScenario)) {
268
            $this->notFoundByConditionException($condition);
269
        }
270
271
        return $models;
272
    }
273
274
    /**
275
     * @param $condition
276
     * @param string $toScenario
277
     * @return BaseModel|null
278
     */
279
    public function findByCondition($condition, string $toScenario = null)
280
    {
281
282
        // Find record in db
283
        if ($record = $this->findRecordByCondition($condition)) {
284
            return $this->findByRecord($record, $toScenario);
285
        }
286
287
        return null;
288
    }
289
290
    /**
291
     * @param $condition
292
     * @param string $toScenario
293
     * @return BaseModel
294
     * @throws ModelNotFoundException
295
     */
296
    public function getByCondition($condition, string $toScenario = null): BaseModel
297
    {
298
299
        if (!$model = $this->findByCondition($condition, $toScenario)) {
300
            $this->notFoundByConditionException($condition);
301
        }
302
303
        return $model;
304
    }
305
306
    /*******************************************
307
     * FIND/GET BY CRITERIA
308
     *******************************************/
309
310
    /**
311
     * @param $criteria
312
     * @param string $toScenario
313
     * @return BaseModel[]
314
     */
315
    public function findAllByCriteria($criteria, string $toScenario = null): array
316
    {
317
318
        $models = [];
319
320
        // Find record in db
321
        if ($records = $this->findAllRecordsByCriteria($criteria)
322
        ) {
323
            foreach ($records as $record) {
324
                $models[] = $this->findByRecord($record, $toScenario);
325
            }
326
        }
327
328
        return $models;
329
    }
330
331
    /**
332
     * @param $criteria
333
     * @param string $toScenario
334
     * @return BaseModel[]
335
     * @throws ModelNotFoundException
336
     */
337
    public function getAllByCriteria($criteria, string $toScenario = null): array
338
    {
339
340
        if (!$models = $this->findAllByCriteria($criteria, $toScenario)) {
341
            $this->notFoundByCriteriaException($criteria);
342
        }
343
344
        return $models;
345
    }
346
347
    /**
348
     * @param $criteria
349
     * @param string $toScenario
350
     * @return BaseModel|null
351
     */
352
    public function findByCriteria($criteria, string $toScenario = null)
353
    {
354
355
        // Find record in db
356
        if ($record = $this->findRecordByCriteria($criteria)) {
357
            return $this->findByRecord($record, $toScenario);
358
        }
359
360
        return null;
361
    }
362
363
    /**
364
     * @param $criteria
365
     * @param string $toScenario
366
     * @return BaseModel
367
     * @throws ModelNotFoundException
368
     */
369
    public function getByCriteria($criteria, string $toScenario = null): BaseModel
370
    {
371
372
        if (!$model = $this->findByCriteria($criteria, $toScenario)) {
373
            $this->notFoundByCriteriaException($criteria);
374
        }
375
376
        return $model;
377
    }
378
379
380
    /*******************************************
381
     * FIND/GET BY RECORD
382
     *******************************************/
383
384
    /**
385
     * @param Record $record
386
     * @param string $toScenario
387
     * @return BaseModel
388
     */
389
    public function findByRecord(Record $record, string $toScenario = null): BaseModel
390
    {
391
392
        // Check addToCache
393
        if (!$model = $this->findCacheByRecord($record)) {
394
            // New model
395
            $model = $this->createFromRecord($record, $toScenario);
396
397
            // Cache it
398
            $this->addToCache($model);
399
        }
400
401
        return $model;
402
    }
403
404
    /**
405
     * @param Record $record
406
     * @param string $toScenario
407
     * @return BaseModel
408
     */
409
    public function getByRecord(Record $record, string $toScenario = null): BaseModel
410
    {
411
        return $this->findByRecord($record, $toScenario);
412
    }
413
414
    /**
415
     * @param BaseModel $model
416
     * @return Record|null
417
     */
418
    public function findRecordByModel(BaseModel $model)
419
    {
420
        return null;
421
    }
422
423
    /**
424
     * @param BaseModel $model
425
     * @return Record
426
     * @throws RecordNotFoundException
427
     */
428
    public function getRecordByModel(BaseModel $model): Record
429
    {
430
431
        if (!$record = $this->findRecordByModel($model)) {
432
            throw new RecordNotFoundException("Record does not exist found.");
433
        }
434
435
        return $record;
436
    }
437
438
    /*******************************************
439
     * CACHE
440
     *******************************************/
441
442
    /**
443
     * @param $identifier
444
     * @return BaseModel|null
445
     */
446
    public function findCache($identifier)
447
    {
448
449
        if ($identifier instanceof Record) {
450
            return $this->findCacheByRecord($identifier);
451
        }
452
453
        return null;
454
    }
455
456
    /**
457
     * @param Record $record
458
     * @return BaseModel|null
459
     */
460
    public function findCacheByRecord(Record $record)
461
    {
462
        return null;
463
    }
464
465
    /**
466
     * @param BaseModel $model
467
     * @return static
468
     */
469
    public function addToCache(BaseModel $model)
470
    {
471
        return $this;
472
    }
473
474
475
    /*******************************************
476
     * EXCEPTIONS
477
     *******************************************/
478
479
    /**
480
     * @throws ModelNotFoundException
481
     */
482
    protected function notFoundException()
483
    {
484
485
        throw new ModelNotFoundException(
486
            sprintf(
487
                "Model does not exist."
488
            )
489
        );
490
    }
491
492
    /**
493
     * @param null $criteria
494
     * @throws ModelNotFoundException
495
     */
496
    protected function notFoundByCriteriaException($criteria = null)
497
    {
498
499
        throw new ModelNotFoundException(
500
            sprintf(
501
                'Model does not exist with the criteria "%s".',
502
                (string)JsonHelper::encode($criteria)
503
            )
504
        );
505
    }
506
507
    /**
508
     * @param null $condition
509
     * @throws ModelNotFoundException
510
     */
511
    protected function notFoundByConditionException($condition = null)
512
    {
513
514
        throw new ModelNotFoundException(
515
            sprintf(
516
                'Model does not exist with the condition "%s".',
517
                (string)JsonHelper::encode($condition)
518
            )
519
        );
520
    }
521
}
522