BuildBase   B
last analyzed

Complexity

Total Complexity 49

Size/Duplication

Total Lines 641
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 77.71%

Importance

Changes 2
Bugs 2 Features 0
Metric Value
wmc 49
c 2
b 2
f 0
lcom 1
cbo 3
dl 0
loc 641
ccs 122
cts 157
cp 0.7771
rs 8.3623

29 Methods

Rating   Name   Duplication   Size   Complexity  
A getId() 0 6 1
A getProjectId() 0 6 1
A getCommitId() 0 6 1
A getStatus() 0 6 1
A getLog() 0 6 1
A getBranch() 0 6 1
A getCreated() 0 10 2
A getStarted() 0 10 2
A getFinished() 0 10 2
A getCommitterEmail() 0 6 1
A getCommitMessage() 0 6 1
A getExtra() 0 6 1
A setId() 0 13 2
A setProjectId() 0 13 2
A setCommitId() 0 13 2
A setStatus() 0 13 2
A setLog() 0 12 2
A setBranch() 0 13 2
A setCreated() 0 12 2
A setStarted() 0 12 2
A setFinished() 0 12 2
A setCommitterEmail() 0 12 2
A setCommitMessage() 0 12 2
A setExtra() 0 12 2
A getProject() 0 18 3
A setProject() 0 15 4
A setProjectObject() 0 4 1
A getBuildBuildErrors() 0 4 1
A getBuildBuildMetas() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like BuildBase 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 BuildBase, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Build base model for table: build.
5
 */
6
7
namespace PHPCI\Model\Base;
8
9
use PHPCI\Model;
10
use b8\Store\Factory;
11
12
/**
13
 * Build Base Model.
14
 */
15
class BuildBase extends Model
16
{
17
    /**
18
     * @var array
19
     */
20
    public static $sleepable = array();
21
22
    /**
23
     * @var string
24
     */
25
    protected $tableName = 'build';
26
27
    /**
28
     * @var string
29
     */
30
    protected $modelName = 'Build';
31
32
    /**
33
     * @var array
34
     */
35
    protected $data = array(
36
        'id' => null,
37
        'project_id' => null,
38
        'commit_id' => null,
39
        'status' => null,
40
        'log' => null,
41
        'branch' => null,
42
        'created' => null,
43
        'started' => null,
44
        'finished' => null,
45
        'committer_email' => null,
46
        'commit_message' => null,
47
        'extra' => null,
48
    );
49
50
    /**
51
     * @var array
52
     */
53
    protected $getters = array(
54
        // Direct property getters:
55
        'id' => 'getId',
56
        'project_id' => 'getProjectId',
57
        'commit_id' => 'getCommitId',
58
        'status' => 'getStatus',
59
        'log' => 'getLog',
60
        'branch' => 'getBranch',
61
        'created' => 'getCreated',
62
        'started' => 'getStarted',
63
        'finished' => 'getFinished',
64
        'committer_email' => 'getCommitterEmail',
65
        'commit_message' => 'getCommitMessage',
66
        'extra' => 'getExtra',
67
68
        // Foreign key getters:
69
        'Project' => 'getProject',
70
    );
71
72
    /**
73
     * @var array
74
     */
75
    protected $setters = array(
76
        // Direct property setters:
77
        'id' => 'setId',
78
        'project_id' => 'setProjectId',
79
        'commit_id' => 'setCommitId',
80
        'status' => 'setStatus',
81
        'log' => 'setLog',
82
        'branch' => 'setBranch',
83
        'created' => 'setCreated',
84
        'started' => 'setStarted',
85
        'finished' => 'setFinished',
86
        'committer_email' => 'setCommitterEmail',
87
        'commit_message' => 'setCommitMessage',
88
        'extra' => 'setExtra',
89
90
        // Foreign key setters:
91
        'Project' => 'setProject',
92
    );
93
94
    /**
95
     * @var array
96
     */
97
    public $columns = array(
98
        'id' => array(
99
            'type' => 'int',
100
            'length' => 11,
101
            'primary_key' => true,
102
            'auto_increment' => true,
103
            'default' => null,
104
        ),
105
        'project_id' => array(
106
            'type' => 'int',
107
            'length' => 11,
108
            'default' => null,
109
        ),
110
        'commit_id' => array(
111
            'type' => 'varchar',
112
            'length' => 50,
113
            'default' => null,
114
        ),
115
        'status' => array(
116
            'type' => 'int',
117
            'length' => 11,
118
            'default' => null,
119
        ),
120
        'log' => array(
121
            'type' => 'mediumtext',
122
            'nullable' => true,
123
            'default' => null,
124
        ),
125
        'branch' => array(
126
            'type' => 'varchar',
127
            'length' => 50,
128
            'default' => 'master',
129
        ),
130
        'created' => array(
131
            'type' => 'datetime',
132
            'nullable' => true,
133
            'default' => null,
134
        ),
135
        'started' => array(
136
            'type' => 'datetime',
137
            'nullable' => true,
138
            'default' => null,
139
        ),
140
        'finished' => array(
141
            'type' => 'datetime',
142
            'nullable' => true,
143
            'default' => null,
144
        ),
145
        'committer_email' => array(
146
            'type' => 'varchar',
147
            'length' => 512,
148
            'nullable' => true,
149
            'default' => null,
150
        ),
151
        'commit_message' => array(
152
            'type' => 'text',
153
            'nullable' => true,
154
            'default' => null,
155
        ),
156
        'extra' => array(
157
            'type' => 'text',
158
            'nullable' => true,
159
            'default' => null,
160
        ),
161
    );
162
163
    /**
164
     * @var array
165
     */
166
    public $indexes = array(
167
            'PRIMARY' => array('unique' => true, 'columns' => 'id'),
168
            'project_id' => array('columns' => 'project_id'),
169
            'idx_status' => array('columns' => 'status'),
170
    );
171
172
    /**
173
     * @var array
174
     */
175
    public $foreignKeys = array(
176
            'build_ibfk_1' => array(
177
                'local_col' => 'project_id',
178
                'update' => 'CASCADE',
179
                'delete' => 'CASCADE',
180
                'table' => 'project',
181
                'col' => 'id',
182
                ),
183
    );
184
185
    /**
186
     * Get the value of Id / id.
187
     *
188
     * @return int
189
     */
190 23
    public function getId()
191
    {
192 23
        $rtn = $this->data['id'];
193
194 23
        return $rtn;
195
    }
196
197
    /**
198
     * Get the value of ProjectId / project_id.
199
     *
200
     * @return int
201
     */
202 3
    public function getProjectId()
203
    {
204 3
        $rtn = $this->data['project_id'];
205
206 3
        return $rtn;
207
    }
208
209
    /**
210
     * Get the value of CommitId / commit_id.
211
     *
212
     * @return string
213
     */
214 15
    public function getCommitId()
215
    {
216 15
        $rtn = $this->data['commit_id'];
217
218 15
        return $rtn;
219
    }
220
221
    /**
222
     * Get the value of Status / status.
223
     *
224
     * @return int
225
     */
226 8
    public function getStatus()
227
    {
228 8
        $rtn = $this->data['status'];
229
230 8
        return $rtn;
231
    }
232
233
    /**
234
     * Get the value of Log / log.
235
     *
236
     * @return string
237
     */
238 2
    public function getLog()
239
    {
240 2
        $rtn = $this->data['log'];
241
242 2
        return $rtn;
243
    }
244
245
    /**
246
     * Get the value of Branch / branch.
247
     *
248
     * @return string
249
     */
250 4
    public function getBranch()
251
    {
252 4
        $rtn = $this->data['branch'];
253
254 4
        return $rtn;
255
    }
256
257
    /**
258
     * Get the value of Created / created.
259
     *
260
     * @return \DateTime
261
     */
262 2
    public function getCreated()
263
    {
264 2
        $rtn = $this->data['created'];
265
266 2
        if (!empty($rtn)) {
267 2
            $rtn = new \DateTime($rtn);
268 2
        }
269
270 2
        return $rtn;
271
    }
272
273
    /**
274
     * Get the value of Started / started.
275
     *
276
     * @return \DateTime
277
     */
278 2
    public function getStarted()
279
    {
280 2
        $rtn = $this->data['started'];
281
282 2
        if (!empty($rtn)) {
283
            $rtn = new \DateTime($rtn);
284
        }
285
286 2
        return $rtn;
287
    }
288
289
    /**
290
     * Get the value of Finished / finished.
291
     *
292
     * @return \DateTime
293
     */
294 6
    public function getFinished()
295
    {
296 6
        $rtn = $this->data['finished'];
297
298 6
        if (!empty($rtn)) {
299 4
            $rtn = new \DateTime($rtn);
300 4
        }
301
302 6
        return $rtn;
303
    }
304
305
    /**
306
     * Get the value of CommitterEmail / committer_email.
307
     *
308
     * @return string
309
     */
310 3
    public function getCommitterEmail()
311
    {
312 3
        $rtn = $this->data['committer_email'];
313
314 3
        return $rtn;
315
    }
316
317
    /**
318
     * Get the value of CommitMessage / commit_message.
319
     *
320
     * @return string
321
     */
322
    public function getCommitMessage()
323
    {
324
        $rtn = $this->data['commit_message'];
325
326
        return $rtn;
327
    }
328
329
    /**
330
     * Get the value of Extra / extra.
331
     *
332
     * @return string
333
     */
334
    public function getExtra()
335
    {
336
        $rtn = $this->data['extra'];
337
338
        return $rtn;
339
    }
340
341
    /**
342
     * Set the value of Id / id.
343
     *
344
     * Must not be null.
345
     *
346
     * @param $value int
347
     */
348 6
    public function setId($value)
349
    {
350 6
        $this->_validateNotNull('Id', $value);
351 6
        $this->_validateInt('Id', $value);
352
353 6
        if ($this->data['id'] === $value) {
354
            return;
355
        }
356
357 6
        $this->data['id'] = $value;
358
359 6
        $this->_setModified('id');
360 6
    }
361
362
    /**
363
     * Set the value of ProjectId / project_id.
364
     *
365
     * Must not be null.
366
     *
367
     * @param $value int
368
     */
369 9
    public function setProjectId($value)
370
    {
371 9
        $this->_validateNotNull('ProjectId', $value);
372 9
        $this->_validateInt('ProjectId', $value);
373
374 9
        if ($this->data['project_id'] === $value) {
375
            return;
376
        }
377
378 9
        $this->data['project_id'] = $value;
379
380 9
        $this->_setModified('project_id');
381 9
    }
382
383
    /**
384
     * Set the value of CommitId / commit_id.
385
     *
386
     * Must not be null.
387
     *
388
     * @param $value string
389
     */
390 4
    public function setCommitId($value)
391
    {
392 4
        $this->_validateNotNull('CommitId', $value);
393 4
        $this->_validateString('CommitId', $value);
394
395 4
        if ($this->data['commit_id'] === $value) {
396
            return;
397
        }
398
399 4
        $this->data['commit_id'] = $value;
400
401 4
        $this->_setModified('commit_id');
402 4
    }
403
404
    /**
405
     * Set the value of Status / status.
406
     *
407
     * Must not be null.
408
     *
409
     * @param $value int
410
     */
411 10
    public function setStatus($value)
412
    {
413 10
        $this->_validateNotNull('Status', $value);
414 10
        $this->_validateInt('Status', $value);
415
416 10
        if ($this->data['status'] === $value) {
417
            return;
418
        }
419
420 10
        $this->data['status'] = $value;
421
422 10
        $this->_setModified('status');
423 10
    }
424
425
    /**
426
     * Set the value of Log / log.
427
     *
428
     * @param $value string
429
     */
430 1
    public function setLog($value)
431
    {
432 1
        $this->_validateString('Log', $value);
433
434 1
        if ($this->data['log'] === $value) {
435
            return;
436
        }
437
438 1
        $this->data['log'] = $value;
439
440 1
        $this->_setModified('log');
441 1
    }
442
443
    /**
444
     * Set the value of Branch / branch.
445
     *
446
     * Must not be null.
447
     *
448
     * @param $value string
449
     */
450 9
    public function setBranch($value)
451
    {
452 9
        $this->_validateNotNull('Branch', $value);
453 9
        $this->_validateString('Branch', $value);
454
455 9
        if ($this->data['branch'] === $value) {
456
            return;
457
        }
458
459 9
        $this->data['branch'] = $value;
460
461 9
        $this->_setModified('branch');
462 9
    }
463
464
    /**
465
     * Set the value of Created / created.
466
     *
467
     * @param $value \DateTime
468
     */
469 4
    public function setCreated($value)
470
    {
471 4
        $this->_validateDate('Created', $value);
472
473 4
        if ($this->data['created'] === $value) {
474 1
            return;
475
        }
476
477 4
        $this->data['created'] = $value;
478
479 4
        $this->_setModified('created');
480 4
    }
481
482
    /**
483
     * Set the value of Started / started.
484
     *
485
     * @param $value \DateTime
486
     */
487 5
    public function setStarted($value)
488
    {
489 5
        $this->_validateDate('Started', $value);
490
491 5
        if ($this->data['started'] === $value) {
492
            return;
493
        }
494
495 5
        $this->data['started'] = $value;
496
497 5
        $this->_setModified('started');
498 5
    }
499
500
    /**
501
     * Set the value of Finished / finished.
502
     *
503
     * @param $value \DateTime
504
     */
505 5
    public function setFinished($value)
506
    {
507 5
        $this->_validateDate('Finished', $value);
508
509 5
        if ($this->data['finished'] === $value) {
510
            return;
511
        }
512
513 5
        $this->data['finished'] = $value;
514
515 5
        $this->_setModified('finished');
516 5
    }
517
518
    /**
519
     * Set the value of CommitterEmail / committer_email.
520
     *
521
     * @param $value string
522
     */
523 2
    public function setCommitterEmail($value)
524
    {
525 2
        $this->_validateString('CommitterEmail', $value);
526
527 2
        if ($this->data['committer_email'] === $value) {
528
            return;
529
        }
530
531 2
        $this->data['committer_email'] = $value;
532
533 2
        $this->_setModified('committer_email');
534 2
    }
535
536
    /**
537
     * Set the value of CommitMessage / commit_message.
538
     *
539
     * @param $value string
540
     */
541 4
    public function setCommitMessage($value)
542
    {
543 4
        $this->_validateString('CommitMessage', $value);
544
545 4
        if ($this->data['commit_message'] === $value) {
546
            return;
547
        }
548
549 4
        $this->data['commit_message'] = $value;
550
551 4
        $this->_setModified('commit_message');
552 4
    }
553
554
    /**
555
     * Set the value of Extra / extra.
556
     *
557
     * @param $value string
558
     */
559 3
    public function setExtra($value)
560
    {
561 3
        $this->_validateString('Extra', $value);
562
563 3
        if ($this->data['extra'] === $value) {
564
            return;
565
        }
566
567 3
        $this->data['extra'] = $value;
568
569 3
        $this->_setModified('extra');
570 3
    }
571
572
    /**
573
     * Get the Project model for this Build by Id.
574
     *
575
     * @uses \PHPCI\Store\ProjectStore::getById()
576
     * @uses \PHPCI\Model\Project
577
     *
578
     * @return \PHPCI\Model\Project
579
     */
580
    public function getProject()
581
    {
582
        $key = $this->getProjectId();
583
584
        if (empty($key)) {
585
            return;
586
        }
587
588
        $cacheKey = 'Cache.Project.'.$key;
589
        $rtn = $this->cache->get($cacheKey, null);
590
591
        if (empty($rtn)) {
592
            $rtn = Factory::getStore('Project', 'PHPCI')->getById($key);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class b8\Store as the method getById() does only exist in the following sub-classes of b8\Store: PHPCI\Store\Base\BuildErrorStoreBase, PHPCI\Store\Base\BuildMetaStoreBase, PHPCI\Store\Base\BuildStoreBase, PHPCI\Store\Base\ProjectGroupStoreBase, PHPCI\Store\Base\ProjectStoreBase, PHPCI\Store\Base\UserStoreBase, PHPCI\Store\BuildErrorStore, PHPCI\Store\BuildMetaStore, PHPCI\Store\BuildStore, PHPCI\Store\ProjectGroupStore, PHPCI\Store\ProjectStore, PHPCI\Store\UserStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
593
            $this->cache->set($cacheKey, $rtn);
594
        }
595
596
        return $rtn;
597
    }
598
599
    /**
600
     * Set Project - Accepts an ID, an array representing a Project or a Project model.
601
     *
602
     * @param $value mixed
603
     */
604 4
    public function setProject($value)
605
    {
606
        // Is this an instance of Project?
607 4
        if ($value instanceof \PHPCI\Model\Project) {
608 3
            return $this->setProjectObject($value);
609
        }
610
611
        // Is this an array representing a Project item?
612 1
        if (is_array($value) && !empty($value['id'])) {
613
            return $this->setProjectId($value['id']);
614
        }
615
616
        // Is this a scalar value representing the ID of this foreign key?
617 1
        return $this->setProjectId($value);
618
    }
619
620
    /**
621
     * Set Project - Accepts a Project model.
622
     * 
623
     * @param $value \PHPCI\Model\Project
624
     */
625 8
    public function setProjectObject(\PHPCI\Model\Project $value)
626
    {
627 8
        return $this->setProjectId($value->getId());
628
    }
629
630
    /**
631
     * Get BuildError models by BuildId for this Build.
632
     *
633
     * @uses \PHPCI\Store\BuildErrorStore::getByBuildId()
634
     * @uses \PHPCI\Model\BuildError
635
     *
636
     * @return \PHPCI\Model\BuildError[]
637
     */
638
    public function getBuildBuildErrors()
639
    {
640
        return Factory::getStore('BuildError', 'PHPCI')->getByBuildId($this->getId());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class b8\Store as the method getByBuildId() does only exist in the following sub-classes of b8\Store: PHPCI\Store\Base\BuildErrorStoreBase, PHPCI\Store\Base\BuildMetaStoreBase, PHPCI\Store\BuildErrorStore, PHPCI\Store\BuildMetaStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
641
    }
642
643
    /**
644
     * Get BuildMeta models by BuildId for this Build.
645
     *
646
     * @uses \PHPCI\Store\BuildMetaStore::getByBuildId()
647
     * @uses \PHPCI\Model\BuildMeta
648
     *
649
     * @return \PHPCI\Model\BuildMeta[]
650
     */
651
    public function getBuildBuildMetas()
652
    {
653
        return Factory::getStore('BuildMeta', 'PHPCI')->getByBuildId($this->getId());
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class b8\Store as the method getByBuildId() does only exist in the following sub-classes of b8\Store: PHPCI\Store\Base\BuildErrorStoreBase, PHPCI\Store\Base\BuildMetaStoreBase, PHPCI\Store\BuildErrorStore, PHPCI\Store\BuildMetaStore. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
654
    }
655
}
656