ProjectBase   B
last analyzed

Complexity

Total Complexity 49

Size/Duplication

Total Lines 676
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 55.9%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 49
c 2
b 1
f 0
lcom 1
cbo 3
dl 0
loc 676
ccs 90
cts 161
cp 0.559
rs 8.1651

31 Methods

Rating   Name   Duplication   Size   Complexity  
A getId() 0 6 1
A getTitle() 0 6 1
A getReference() 0 6 1
A getBranch() 0 6 1
A getSshPrivateKey() 0 6 1
A getType() 0 6 1
A getAccessInformation() 0 6 1
A getLastCommit() 0 6 1
A getBuildConfig() 0 6 1
A getSshPublicKey() 0 6 1
A getAllowPublicStatus() 0 6 1
A getArchived() 0 6 1
A getGroupId() 0 6 1
A setId() 0 13 2
A setTitle() 0 13 2
A setReference() 0 13 2
A setBranch() 0 13 2
A setSshPrivateKey() 0 12 2
A setType() 0 13 2
A setAccessInformation() 0 12 2
A setLastCommit() 0 12 2
A setBuildConfig() 0 12 2
A setSshPublicKey() 0 12 2
A setAllowPublicStatus() 0 13 2
A setArchived() 0 13 2
A setGroupId() 0 13 2
A getGroup() 0 18 3
A setGroup() 0 15 4
A setGroupObject() 0 4 1
A getProjectBuilds() 0 4 1
A getProjectBuildMetas() 0 4 1

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
/**
4
 * Project base model for table: project.
5
 */
6
7
namespace PHPCI\Model\Base;
8
9
use PHPCI\Model;
10
use b8\Store\Factory;
11
12
/**
13
 * Project Base Model.
14
 */
15
class ProjectBase extends Model
16
{
17
    /**
18
     * @var array
19
     */
20
    public static $sleepable = array();
21
22
    /**
23
     * @var string
24
     */
25
    protected $tableName = 'project';
26
27
    /**
28
     * @var string
29
     */
30
    protected $modelName = 'Project';
31
32
    /**
33
     * @var array
34
     */
35
    protected $data = array(
36
        'id' => null,
37
        'title' => null,
38
        'reference' => null,
39
        'branch' => null,
40
        'ssh_private_key' => null,
41
        'type' => null,
42
        'access_information' => null,
43
        'last_commit' => null,
44
        'build_config' => null,
45
        'ssh_public_key' => null,
46
        'allow_public_status' => null,
47
        'archived' => null,
48
        'group_id' => null,
49
    );
50
51
    /**
52
     * @var array
53
     */
54
    protected $getters = array(
55
        // Direct property getters:
56
        'id' => 'getId',
57
        'title' => 'getTitle',
58
        'reference' => 'getReference',
59
        'branch' => 'getBranch',
60
        'ssh_private_key' => 'getSshPrivateKey',
61
        'type' => 'getType',
62
        'access_information' => 'getAccessInformation',
63
        'last_commit' => 'getLastCommit',
64
        'build_config' => 'getBuildConfig',
65
        'ssh_public_key' => 'getSshPublicKey',
66
        'allow_public_status' => 'getAllowPublicStatus',
67
        'archived' => 'getArchived',
68
        'group_id' => 'getGroupId',
69
70
        // Foreign key getters:
71
        'Group' => 'getGroup',
72
    );
73
74
    /**
75
     * @var array
76
     */
77
    protected $setters = array(
78
        // Direct property setters:
79
        'id' => 'setId',
80
        'title' => 'setTitle',
81
        'reference' => 'setReference',
82
        'branch' => 'setBranch',
83
        'ssh_private_key' => 'setSshPrivateKey',
84
        'type' => 'setType',
85
        'access_information' => 'setAccessInformation',
86
        'last_commit' => 'setLastCommit',
87
        'build_config' => 'setBuildConfig',
88
        'ssh_public_key' => 'setSshPublicKey',
89
        'allow_public_status' => 'setAllowPublicStatus',
90
        'archived' => 'setArchived',
91
        'group_id' => 'setGroupId',
92
93
        // Foreign key setters:
94
        'Group' => 'setGroup',
95
    );
96
97
    /**
98
     * @var array
99
     */
100
    public $columns = array(
101
        'id' => array(
102
            'type' => 'int',
103
            'length' => 11,
104
            'primary_key' => true,
105
            'auto_increment' => true,
106
            'default' => null,
107
        ),
108
        'title' => array(
109
            'type' => 'varchar',
110
            'length' => 250,
111
            'default' => null,
112
        ),
113
        'reference' => array(
114
            'type' => 'varchar',
115
            'length' => 250,
116
            'default' => null,
117
        ),
118
        'branch' => array(
119
            'type' => 'varchar',
120
            'length' => 50,
121
            'default' => 'master',
122
        ),
123
        'ssh_private_key' => array(
124
            'type' => 'text',
125
            'nullable' => true,
126
            'default' => null,
127
        ),
128
        'type' => array(
129
            'type' => 'varchar',
130
            'length' => 50,
131
            'default' => null,
132
        ),
133
        'access_information' => array(
134
            'type' => 'varchar',
135
            'length' => 250,
136
            'nullable' => true,
137
            'default' => null,
138
        ),
139
        'last_commit' => array(
140
            'type' => 'varchar',
141
            'length' => 250,
142
            'nullable' => true,
143
            'default' => null,
144
        ),
145
        'build_config' => array(
146
            'type' => 'text',
147
            'nullable' => true,
148
            'default' => null,
149
        ),
150
        'ssh_public_key' => array(
151
            'type' => 'text',
152
            'nullable' => true,
153
            'default' => null,
154
        ),
155
        'allow_public_status' => array(
156
            'type' => 'int',
157
            'length' => 11,
158
        ),
159
        'archived' => array(
160
            'type' => 'tinyint',
161
            'length' => 1,
162
            'default' => null,
163
        ),
164
        'group_id' => array(
165
            'type' => 'int',
166
            'length' => 11,
167
            'default' => 1,
168
        ),
169
    );
170
171
    /**
172
     * @var array
173
     */
174
    public $indexes = array(
175
            'PRIMARY' => array('unique' => true, 'columns' => 'id'),
176
            'idx_project_title' => array('columns' => 'title'),
177
            'group_id' => array('columns' => 'group_id'),
178
    );
179
180
    /**
181
     * @var array
182
     */
183
    public $foreignKeys = array(
184
            'project_ibfk_1' => array(
185
                'local_col' => 'group_id',
186
                'update' => 'CASCADE',
187
                'delete' => '',
188
                'table' => 'project_group',
189
                'col' => 'id',
190
                ),
191
    );
192
193
    /**
194
     * Get the value of Id / id.
195
     *
196
     * @return int
197
     */
198 8
    public function getId()
199
    {
200 8
        $rtn = $this->data['id'];
201
202 8
        return $rtn;
203
    }
204
205
    /**
206
     * Get the value of Title / title.
207
     *
208
     * @return string
209
     */
210 7
    public function getTitle()
211
    {
212 7
        $rtn = $this->data['title'];
213
214 7
        return $rtn;
215
    }
216
217
    /**
218
     * Get the value of Reference / reference.
219
     *
220
     * @return string
221
     */
222 5
    public function getReference()
223
    {
224 5
        $rtn = $this->data['reference'];
225
226 5
        return $rtn;
227
    }
228
229
    /**
230
     * Get the value of Branch / branch.
231
     *
232
     * @return string
233
     */
234
    public function getBranch()
235
    {
236
        $rtn = $this->data['branch'];
237
238
        return $rtn;
239
    }
240
241
    /**
242
     * Get the value of SshPrivateKey / ssh_private_key.
243
     *
244
     * @return string
245
     */
246 1
    public function getSshPrivateKey()
247
    {
248 1
        $rtn = $this->data['ssh_private_key'];
249
250 1
        return $rtn;
251
    }
252
253
    /**
254
     * Get the value of Type / type.
255
     *
256
     * @return string
257
     */
258 12
    public function getType()
259
    {
260 12
        $rtn = $this->data['type'];
261
262 12
        return $rtn;
263
    }
264
265
    /**
266
     * Get the value of AccessInformation / access_information.
267
     *
268
     * @return string
269
     */
270
    public function getAccessInformation()
271
    {
272
        $rtn = $this->data['access_information'];
273
274
        return $rtn;
275
    }
276
277
    /**
278
     * Get the value of LastCommit / last_commit.
279
     *
280
     * @return string
281
     */
282
    public function getLastCommit()
283
    {
284
        $rtn = $this->data['last_commit'];
285
286
        return $rtn;
287
    }
288
289
    /**
290
     * Get the value of BuildConfig / build_config.
291
     *
292
     * @return string
293
     */
294 1
    public function getBuildConfig()
295
    {
296 1
        $rtn = $this->data['build_config'];
297
298 1
        return $rtn;
299
    }
300
301
    /**
302
     * Get the value of SshPublicKey / ssh_public_key.
303
     *
304
     * @return string
305
     */
306 1
    public function getSshPublicKey()
307
    {
308 1
        $rtn = $this->data['ssh_public_key'];
309
310 1
        return $rtn;
311
    }
312
313
    /**
314
     * Get the value of AllowPublicStatus / allow_public_status.
315
     *
316
     * @return int
317
     */
318 2
    public function getAllowPublicStatus()
319
    {
320 2
        $rtn = $this->data['allow_public_status'];
321
322 2
        return $rtn;
323
    }
324
325
    /**
326
     * Get the value of Archived / archived.
327
     *
328
     * @return int
329
     */
330
    public function getArchived()
331
    {
332
        $rtn = $this->data['archived'];
333
334
        return $rtn;
335
    }
336
337
    /**
338
     * Get the value of GroupId / group_id.
339
     *
340
     * @return int
341
     */
342
    public function getGroupId()
343
    {
344
        $rtn = $this->data['group_id'];
345
346
        return $rtn;
347
    }
348
349
    /**
350
     * Set the value of Id / id.
351
     *
352
     * Must not be null.
353
     *
354
     * @param $value int
355
     */
356 8
    public function setId($value)
357
    {
358 8
        $this->_validateNotNull('Id', $value);
359 8
        $this->_validateInt('Id', $value);
360
361 8
        if ($this->data['id'] === $value) {
362
            return;
363
        }
364
365 8
        $this->data['id'] = $value;
366
367 8
        $this->_setModified('id');
368 8
    }
369
370
    /**
371
     * Set the value of Title / title.
372
     *
373
     * Must not be null.
374
     *
375
     * @param $value string
376
     */
377 10
    public function setTitle($value)
378
    {
379 10
        $this->_validateNotNull('Title', $value);
380 10
        $this->_validateString('Title', $value);
381
382 10
        if ($this->data['title'] === $value) {
383
            return;
384
        }
385
386 10
        $this->data['title'] = $value;
387
388 10
        $this->_setModified('title');
389 10
    }
390
391
    /**
392
     * Set the value of Reference / reference.
393
     *
394
     * Must not be null.
395
     *
396
     * @param $value string
397
     */
398 5
    public function setReference($value)
399
    {
400 5
        $this->_validateNotNull('Reference', $value);
401 5
        $this->_validateString('Reference', $value);
402
403 5
        if ($this->data['reference'] === $value) {
404
            return;
405
        }
406
407 5
        $this->data['reference'] = $value;
408
409 5
        $this->_setModified('reference');
410 5
    }
411
412
    /**
413
     * Set the value of Branch / branch.
414
     *
415
     * Must not be null.
416
     *
417
     * @param $value string
418
     */
419 6
    public function setBranch($value)
420
    {
421 6
        $this->_validateNotNull('Branch', $value);
422 6
        $this->_validateString('Branch', $value);
423
424 6
        if ($this->data['branch'] === $value) {
425
            return;
426
        }
427
428 6
        $this->data['branch'] = $value;
429
430 6
        $this->_setModified('branch');
431 6
    }
432
433
    /**
434
     * Set the value of SshPrivateKey / ssh_private_key.
435
     *
436
     * @param $value string
437
     */
438 2
    public function setSshPrivateKey($value)
439
    {
440 2
        $this->_validateString('SshPrivateKey', $value);
441
442 2
        if ($this->data['ssh_private_key'] === $value) {
443
            return;
444
        }
445
446 2
        $this->data['ssh_private_key'] = $value;
447
448 2
        $this->_setModified('ssh_private_key');
449 2
    }
450
451
    /**
452
     * Set the value of Type / type.
453
     *
454
     * Must not be null.
455
     *
456
     * @param $value string
457
     */
458 13
    public function setType($value)
459
    {
460 13
        $this->_validateNotNull('Type', $value);
461 13
        $this->_validateString('Type', $value);
462
463 13
        if ($this->data['type'] === $value) {
464
            return;
465
        }
466
467 13
        $this->data['type'] = $value;
468
469 13
        $this->_setModified('type');
470 13
    }
471
472
    /**
473
     * Set the value of AccessInformation / access_information.
474
     *
475
     * @param $value string
476
     */
477 2
    public function setAccessInformation($value)
478
    {
479 2
        $this->_validateString('AccessInformation', $value);
480
481 2
        if ($this->data['access_information'] === $value) {
482
            return;
483
        }
484
485 2
        $this->data['access_information'] = $value;
486
487 2
        $this->_setModified('access_information');
488 2
    }
489
490
    /**
491
     * Set the value of LastCommit / last_commit.
492
     *
493
     * @param $value string
494
     */
495
    public function setLastCommit($value)
496
    {
497
        $this->_validateString('LastCommit', $value);
498
499
        if ($this->data['last_commit'] === $value) {
500
            return;
501
        }
502
503
        $this->data['last_commit'] = $value;
504
505
        $this->_setModified('last_commit');
506
    }
507
508
    /**
509
     * Set the value of BuildConfig / build_config.
510
     *
511
     * @param $value string
512
     */
513 2
    public function setBuildConfig($value)
514
    {
515 2
        $this->_validateString('BuildConfig', $value);
516
517 2
        if ($this->data['build_config'] === $value) {
518
            return;
519
        }
520
521 2
        $this->data['build_config'] = $value;
522
523 2
        $this->_setModified('build_config');
524 2
    }
525
526
    /**
527
     * Set the value of SshPublicKey / ssh_public_key.
528
     *
529
     * @param $value string
530
     */
531 2
    public function setSshPublicKey($value)
532
    {
533 2
        $this->_validateString('SshPublicKey', $value);
534
535 2
        if ($this->data['ssh_public_key'] === $value) {
536
            return;
537
        }
538
539 2
        $this->data['ssh_public_key'] = $value;
540
541 2
        $this->_setModified('ssh_public_key');
542 2
    }
543
544
    /**
545
     * Set the value of AllowPublicStatus / allow_public_status.
546
     *
547
     * Must not be null.
548
     *
549
     * @param $value int
550
     */
551 5
    public function setAllowPublicStatus($value)
552
    {
553 5
        $this->_validateNotNull('AllowPublicStatus', $value);
554 5
        $this->_validateInt('AllowPublicStatus', $value);
555
556 5
        if ($this->data['allow_public_status'] === $value) {
557
            return;
558
        }
559
560 5
        $this->data['allow_public_status'] = $value;
561
562 5
        $this->_setModified('allow_public_status');
563 5
    }
564
565
    /**
566
     * Set the value of Archived / archived.
567
     *
568
     * Must not be null.
569
     *
570
     * @param $value int
571
     */
572
    public function setArchived($value)
573
    {
574
        $this->_validateNotNull('Archived', $value);
575
        $this->_validateInt('Archived', $value);
576
577
        if ($this->data['archived'] === $value) {
578
            return;
579
        }
580
581
        $this->data['archived'] = $value;
582
583
        $this->_setModified('archived');
584
    }
585
586
    /**
587
     * Set the value of GroupId / group_id.
588
     *
589
     * Must not be null.
590
     *
591
     * @param $value int
592
     */
593
    public function setGroupId($value)
594
    {
595
        $this->_validateNotNull('GroupId', $value);
596
        $this->_validateInt('GroupId', $value);
597
598
        if ($this->data['group_id'] === $value) {
599
            return;
600
        }
601
602
        $this->data['group_id'] = $value;
603
604
        $this->_setModified('group_id');
605
    }
606
607
    /**
608
     * Get the ProjectGroup model for this Project by Id.
609
     *
610
     * @uses \PHPCI\Store\ProjectGroupStore::getById()
611
     * @uses \PHPCI\Model\ProjectGroup
612
     *
613
     * @return \PHPCI\Model\ProjectGroup
614
     */
615
    public function getGroup()
616
    {
617
        $key = $this->getGroupId();
618
619
        if (empty($key)) {
620
            return;
621
        }
622
623
        $cacheKey = 'Cache.ProjectGroup.'.$key;
624
        $rtn = $this->cache->get($cacheKey, null);
625
626
        if (empty($rtn)) {
627
            $rtn = Factory::getStore('ProjectGroup', '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...
628
            $this->cache->set($cacheKey, $rtn);
629
        }
630
631
        return $rtn;
632
    }
633
634
    /**
635
     * Set Group - Accepts an ID, an array representing a ProjectGroup or a ProjectGroup model.
636
     *
637
     * @param $value mixed
638
     */
639
    public function setGroup($value)
640
    {
641
        // Is this an instance of ProjectGroup?
642
        if ($value instanceof \PHPCI\Model\ProjectGroup) {
643
            return $this->setGroupObject($value);
644
        }
645
646
        // Is this an array representing a ProjectGroup item?
647
        if (is_array($value) && !empty($value['id'])) {
648
            return $this->setGroupId($value['id']);
649
        }
650
651
        // Is this a scalar value representing the ID of this foreign key?
652
        return $this->setGroupId($value);
653
    }
654
655
    /**
656
     * Set Group - Accepts a ProjectGroup model.
657
     * 
658
     * @param $value \PHPCI\Model\ProjectGroup
659
     */
660
    public function setGroupObject(\PHPCI\Model\ProjectGroup $value)
661
    {
662
        return $this->setGroupId($value->getId());
663
    }
664
665
    /**
666
     * Get Build models by ProjectId for this Project.
667
     *
668
     * @uses \PHPCI\Store\BuildStore::getByProjectId()
669
     * @uses \PHPCI\Model\Build
670
     *
671
     * @return \PHPCI\Model\Build[]
672
     */
673
    public function getProjectBuilds()
674
    {
675
        return Factory::getStore('Build', 'PHPCI')->getByProjectId($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 getByProjectId() does only exist in the following sub-classes of b8\Store: PHPCI\Store\Base\BuildMetaStoreBase, PHPCI\Store\Base\BuildStoreBase, PHPCI\Store\BuildMetaStore, PHPCI\Store\BuildStore. 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...
676
    }
677
678
    /**
679
     * Get BuildMeta models by ProjectId for this Project.
680
     *
681
     * @uses \PHPCI\Store\BuildMetaStore::getByProjectId()
682
     * @uses \PHPCI\Model\BuildMeta
683
     *
684
     * @return \PHPCI\Model\BuildMeta[]
685
     */
686
    public function getProjectBuildMetas()
687
    {
688
        return Factory::getStore('BuildMeta', 'PHPCI')->getByProjectId($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 getByProjectId() does only exist in the following sub-classes of b8\Store: PHPCI\Store\Base\BuildMetaStoreBase, PHPCI\Store\Base\BuildStoreBase, PHPCI\Store\BuildMetaStore, PHPCI\Store\BuildStore. 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...
689
    }
690
}
691