GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

BaseCoverFishValidator   B
last analyzed

Complexity

Total Complexity 54

Size/Duplication

Total Lines 509
Duplicated Lines 21.81 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 0
Metric Value
wmc 54
lcom 2
cbo 6
dl 111
loc 509
rs 7.0642
c 0
b 0
f 0

28 Methods

Rating   Name   Duplication   Size   Complexity  
A getResult() 0 8 2
A getValidationInfo() 0 4 1
A getValidationTag() 0 4 1
A getMapping() 0 4 1
A setMapping() 0 14 1
A validate() 0 4 1
A validateDefaultCoverClassMapping() 0 13 3
A validateClassFQNMapping() 12 12 2
A validateClassAccessorVisibility() 12 12 2
A validateClassMethod() 12 12 2
A validateEmptyDocBlock() 0 11 2
A validateMapping() 0 17 1
A prepareCoverFishResult() 0 7 1
A validateReflectionClass() 0 4 1
A validateReflectionMethod() 0 14 4
A validateReflectionClassForAccessorPublic() 10 10 2
A validateReflectionClassForAccessorNotPublic() 15 15 2
A validateReflectionClassForAccessorProtected() 10 10 2
A validateReflectionClassForAccessorNotProtected() 15 15 2
A validateReflectionClassForAccessorPrivate() 10 10 2
A validateReflectionClassForAccessorNotPrivate() 15 15 2
D validateReflectionClassForAccessorVisibility() 0 44 9
A clearValidationErrors() 0 7 1
A clearValidationWarnings() 0 7 1
A setValidationError() 0 12 2
A setValidationWarning() 0 6 1
A getReflectionClass() 0 10 2
A __construct() 0 6 1

How to fix   Duplicated Code    Complexity   

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:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

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

1
<?php
2
3
namespace DF\PHPCoverFish\Validator\Base;
4
5
use DF\PHPCoverFish\Common\ArrayCollection;
6
use DF\PHPCoverFish\Common\CoverFishMessageError;
7
use DF\PHPCoverFish\Common\CoverFishMessageWarning;
8
use DF\PHPCoverFish\Common\CoverFishResult;
9
use DF\PHPCoverFish\Common\CoverFishHelper;
10
use DF\PHPCoverFish\Common\CoverFishMapping;
11
use DF\PHPCoverFish\Common\CoverFishPHPUnitFile;
12
13
/**
14
 * Class BaseCoverFishValidator
15
 *
16
 * @package   DF\PHPCoverFish
17
 * @author    Patrick Paechnatz <[email protected]>
18
 * @copyright 2015 Patrick Paechnatz <[email protected]>
19
 * @license   http://www.opensource.org/licenses/MIT
20
 * @link      http://github.com/dunkelfrosch/phpcoverfish/tree
21
 * @since     class available since Release 0.9.0
22
 * @version   0.9.9
23
 */
24
class BaseCoverFishValidator implements BaseCoverFishValidatorInterface
25
{
26
    /**
27
     * @var ArrayCollection
28
     */
29
    protected $validatorCollection;
30
31
    /**
32
     * @var string
33
     */
34
    protected $coversToken = null;
35
36
    /**
37
     * @var array
38
     */
39
    protected $result = array();
40
41
    /**
42
     * @var CoverFishHelper
43
     */
44
    protected $coverFishHelper;
45
46
    /**
47
     * @return array
48
     */
49
    public function getResult()
50
    {
51
        if (count($this->result) > 0) {
52
            return $this->result[0];
53
        }
54
55
        return null;
56
    }
57
58
    /**
59
     * @codeCoverageIgnore
60
     *
61
     * @return string
62
     */
63
    public function getValidationInfo()
64
    {
65
        return null;
66
    }
67
68
    /**
69
     * @codeCoverageIgnore
70
     *
71
     * @return string
72
     */
73
    public function getValidationTag()
74
    {
75
        return null;
76
    }
77
78
    /**
79
     * @codeCoverageIgnore
80
     *
81
     * @param CoverFishPHPUnitFile $phpUnitFile
82
     *
83
     * @return CoverFishMapping
84
     */
85
    public function getMapping(CoverFishPHPUnitFile $phpUnitFile)
86
    {
87
        return new CoverFishMapping();
88
    }
89
90
    /**
91
     * @param array $mappingOptions
92
     *
93
     * @return CoverFishMapping
94
     */
95
    public function setMapping(array $mappingOptions)
96
    {
97
        $coverMapping = new CoverFishMapping();
98
        $coverMapping->setAnnotation($mappingOptions['coverToken']);
99
        $coverMapping->setMethod($mappingOptions['coverMethod']);
100
        $coverMapping->setAccessor($mappingOptions['coverAccessor']);
101
        $coverMapping->setClass($mappingOptions['coverClass']);
102
        $coverMapping->setClassFQN($mappingOptions['coverClassFQN']);
103
        $coverMapping->setValidatorMatch($mappingOptions['validatorMatch']);
104
        $coverMapping->setValidatorClass($mappingOptions['validatorClass']);
105
        $coverMapping->setValidatorResult($this->validateMapping($coverMapping));
106
107
        return $coverMapping;
108
    }
109
110
    /**
111
     * @return bool
112
     */
113
    public function validate()
114
    {
115
        return false;
116
    }
117
118
    /**
119
     * @param CoverFishMapping $coverMapping
120
     * @param CoverFishResult  $coverFishResult
121
     *
122
     * @return CoverFishResult
123
     */
124
    public function validateDefaultCoverClassMapping(CoverFishMapping $coverMapping, CoverFishResult $coverFishResult)
125
    {
126
        if (empty($coverMapping->getClassFQN())) {
127
            $coverFishResult = $this->setValidationError(
128
                $coverFishResult,
129
                empty($coverMapping->getClass())
130
                    ? CoverFishMessageError::PHPUNIT_VALIDATOR_MISSING_DEFAULT_COVER_CLASS_PROBLEM
131
                    : CoverFishMessageError::PHPUNIT_REFLECTION_CLASS_NOT_DEFINED
132
            );
133
        }
134
135
        return $coverFishResult;
136
    }
137
138
    /**
139
     * @todo: mappingResult could be false, set a specific/real coverFishError here ...
140
     *
141
     * @param CoverFishMapping $coverMapping
142
     * @param CoverFishResult  $coverFishResult
143
     *
144
     * @return CoverFishResult
145
     */
146 View Code Duplication
    public function validateClassFQNMapping(CoverFishMapping $coverMapping, CoverFishResult $coverFishResult)
147
    {
148
        $classReflectionResult = $this->validateReflectionClass($coverMapping->getClassFQN());
149
        if ($classReflectionResult instanceof CoverFishMessageError) {
150
            $coverFishResult = $this->setValidationError(
151
                $coverFishResult,
152
                $classReflectionResult->getMessageCode()
153
            );
154
        }
155
156
        return $coverFishResult;
157
    }
158
159
    /**
160
     * @param CoverFishMapping $coverMapping
161
     * @param CoverFishResult  $coverFishResult
162
     *
163
     * @return CoverFishResult
164
     */
165 View Code Duplication
    public function validateClassAccessorVisibility(CoverFishMapping $coverMapping, CoverFishResult $coverFishResult)
166
    {
167
        $methodReflectionResult = $this->validateReflectionClassForAccessorVisibility($coverMapping->getClassFQN(), $coverMapping->getAccessor());
168
        if ($methodReflectionResult instanceof CoverFishMessageError) {
169
            $coverFishResult = $this->setValidationError(
170
                $coverFishResult,
171
                $methodReflectionResult->getMessageCode()
172
            );
173
        }
174
175
        return $coverFishResult;
176
    }
177
178
    /**
179
     * @param CoverFishMapping $coverMapping
180
     * @param CoverFishResult  $coverFishResult
181
     *
182
     * @return CoverFishResult
183
     */
184 View Code Duplication
    public function validateClassMethod(CoverFishMapping $coverMapping, CoverFishResult $coverFishResult)
185
    {
186
        $methodReflectionResult = $this->validateReflectionMethod($coverMapping->getClassFQN(), $coverMapping->getMethod());
187
        if ($methodReflectionResult instanceof CoverFishMessageError) {
188
            $coverFishResult = $this->setValidationError(
189
                $coverFishResult,
190
                $methodReflectionResult->getMessageCode()
191
            );
192
        }
193
194
        return $coverFishResult;
195
    }
196
197
    /**
198
     * @param CoverFishMapping $coverMapping
199
     * @param CoverFishResult  $coverFishResult
200
     *
201
     * @return CoverFishResult
202
     */
203
    public function validateEmptyDocBlock(CoverFishMapping $coverMapping, CoverFishResult $coverFishResult)
204
    {
205
        if (null === ($coverMapping->getAnnotation())) {
206
            $coverFishResult = $this->setValidationWarning(
207
                $coverFishResult,
208
                CoverFishMessageWarning::PHPUNIT_NO_DOCBLOCK_FOR_METHOD
209
            );
210
        }
211
212
        return $coverFishResult;
213
    }
214
215
    /**
216
     * main validator mapping "engine", if any of our cover validator checks will fail,
217
     * return corresponding result immediately ...
218
     *
219
     * @param CoverFishMapping $coverMapping
220
     *
221
     * @return CoverFishResult
222
     */
223
    public function validateMapping(CoverFishMapping $coverMapping)
224
    {
225
        /** @var CoverFishResult $coverFishResult */
226
        $coverFishResult = new CoverFishResult();
227
        // prepare base results, clear all validation errors and warnings
228
        $coverFishResult = $this->prepareCoverFishResult($coverFishResult);
229
        // E-01: check for classFQN/DefaultCoverClass existence/mapping validation-error
230
        $coverFishResult = $this->validateDefaultCoverClassMapping($coverMapping, $coverFishResult);
231
        // E-02: check for invalid classFQN validation-error
232
        $coverFishResult = $this->validateClassFQNMapping($coverMapping, $coverFishResult);
233
        // E-03: check for invalid accessor validation-error
234
        $coverFishResult = $this->validateClassAccessorVisibility($coverMapping, $coverFishResult);
235
        // E-04: check for invalid method validation-error
236
        $coverFishResult = $this->validateClassMethod($coverMapping, $coverFishResult);
237
238
        return $coverFishResult;
239
    }
240
241
    /**
242
     * @param CoverFishResult $coverFishResult
243
     *
244
     * @return CoverFishResult
245
     */
246
    public function prepareCoverFishResult(CoverFishResult $coverFishResult)
247
    {
248
        $this->clearValidationErrors($coverFishResult);
249
        $this->clearValidationWarnings($coverFishResult);
250
251
        return $coverFishResult;
252
    }
253
254
    /**
255
     * @param string $classFQN
256
     *
257
     * @return CoverFishMessageError|\ReflectionClass
258
     */
259
    public function validateReflectionClass($classFQN)
260
    {
261
        return $this->getReflectionClass($classFQN);
262
    }
263
264
    /**
265
     * @param string $classFQN
266
     * @param string $method
267
     *
268
     * @return CoverFishMessageError|\ReflectionMethod|false
269
     */
270
    public function validateReflectionMethod($classFQN, $method)
271
    {
272
        if (null === $classFQN || null === $method) {
273
            return false;
274
        }
275
276
        try {
277
            $reflectionMethod = new \ReflectionMethod($classFQN, $method);
278
        } catch (\ReflectionException $re) {
279
            return new CoverFishMessageError(CoverFishMessageError::PHPUNIT_REFLECTION_METHOD_NOT_FOUND, $method);
280
        }
281
282
        return $reflectionMethod;
283
    }
284
285
    /**
286
     * @param \ReflectionClass $reflectionClass
287
     *
288
     * @return bool|CoverFishMessageError
289
     */
290 View Code Duplication
    public function validateReflectionClassForAccessorPublic(\ReflectionClass $reflectionClass)
291
    {
292
        if (empty($methods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC))) {
293
            return new CoverFishMessageError(
294
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_PUBLIC_METHODS_FOUND, null
295
            );
296
        }
297
298
        return true;
299
    }
300
301
    /**
302
     * @param \ReflectionClass $reflectionClass
303
     *
304
     * @return bool|CoverFishMessageError
305
     */
306 View Code Duplication
    public function validateReflectionClassForAccessorNotPublic(\ReflectionClass $reflectionClass)
307
    {
308
        $methods = array_merge(
309
            $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE),
310
            $reflectionClass->getMethods(\ReflectionMethod::IS_PROTECTED)
311
        );
312
313
        if (empty($methods)) {
314
            return new CoverFishMessageError(
315
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_NOT_PUBLIC_METHODS_FOUND, null
316
            );
317
        }
318
319
        return true;
320
    }
321
322
    /**
323
     * @param \ReflectionClass $reflectionClass
324
     *
325
     * @return bool|CoverFishMessageError
326
     */
327 View Code Duplication
    public function validateReflectionClassForAccessorProtected(\ReflectionClass $reflectionClass)
328
    {
329
        if (empty($methods = $reflectionClass->getMethods(\ReflectionMethod::IS_PROTECTED))) {
330
            return new CoverFishMessageError(
331
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_PROTECTED_METHODS_FOUND, null
332
            );
333
        }
334
335
        return true;
336
    }
337
338
    /**
339
     * @param \ReflectionClass $reflectionClass
340
     *
341
     * @return bool|CoverFishMessageError
342
     */
343 View Code Duplication
    public function validateReflectionClassForAccessorNotProtected(\ReflectionClass $reflectionClass)
344
    {
345
        $methods = array_merge(
346
            $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE),
347
            $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC)
348
        );
349
350
        if (empty($methods)) {
351
            return new CoverFishMessageError(
352
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_NOT_PROTECTED_METHODS_FOUND, null
353
            );
354
        }
355
356
        return true;
357
    }
358
359
    /**
360
     * @param \ReflectionClass $reflectionClass
361
     *
362
     * @return bool|CoverFishMessageError
363
     */
364 View Code Duplication
    public function validateReflectionClassForAccessorPrivate(\ReflectionClass $reflectionClass)
365
    {
366
        if (empty($methods = $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE))) {
367
            return new CoverFishMessageError(
368
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_PRIVATE_METHODS_FOUND, null
369
            );
370
        }
371
372
        return true;
373
    }
374
375
    /**
376
     * @param \ReflectionClass $reflectionClass
377
     *
378
     * @return bool|CoverFishMessageError
379
     */
380 View Code Duplication
    public function validateReflectionClassForAccessorNotPrivate(\ReflectionClass $reflectionClass)
381
    {
382
        $methods = array_merge(
383
            $reflectionClass->getMethods(\ReflectionMethod::IS_PROTECTED),
384
            $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC)
385
        );
386
387
        if (empty($methods)) {
388
            return new CoverFishMessageError(
389
                CoverFishMessageError::PHPUNIT_REFLECTION_NO_NOT_PRIVATE_METHODS_FOUND, null
390
            );
391
        }
392
393
        return true;
394
    }
395
396
    /**
397
     * @param string $classFQN
398
     * @param string $accessor
399
     *
400
     * @return bool|CoverFishMessageError
401
     */
402
    public function validateReflectionClassForAccessorVisibility($classFQN, $accessor)
403
    {
404
        $reflectionClass = $this->getReflectionClass($classFQN);
405
        if ($reflectionClass instanceof CoverFishMessageError) {
406
            return $reflectionClass;
407
        }
408
409
        $accessorResult = null;
0 ignored issues
show
Unused Code introduced by
$accessorResult is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
410
411
        switch ($accessor) {
412
            case 'public':
413
                $accessorResult = $this->validateReflectionClassForAccessorPublic($reflectionClass);
414
                break;
415
416
            case 'protected':
417
                $accessorResult = $this->validateReflectionClassForAccessorProtected($reflectionClass);
418
                break;
419
420
            case 'private':
421
                $accessorResult = $this->validateReflectionClassForAccessorPrivate($reflectionClass);
422
                break;
423
424
            case '!public':
425
                $accessorResult = $this->validateReflectionClassForAccessorNotPublic($reflectionClass);
426
                break;
427
428
            case '!protected':
429
                $accessorResult = $this->validateReflectionClassForAccessorNotProtected($reflectionClass);
430
                break;
431
432
            case '!private':
433
                $accessorResult = $this->validateReflectionClassForAccessorNotPrivate($reflectionClass);
434
                break;
435
436
            default:
437
                return false;
438
        }
439
440
        if ($accessorResult instanceof CoverFishMessageError) {
441
            return $accessorResult;
442
        }
443
444
        return true;
445
    }
446
447
    /**
448
     * @param CoverFishResult $coverFishResult
449
     *
450
     * @return CoverFishResult
451
     */
452
    public function clearValidationErrors(CoverFishResult $coverFishResult)
453
    {
454
        $coverFishResult->setPass(true);
455
        $coverFishResult->clearErrors();
456
457
        return $coverFishResult;
458
    }
459
460
    /**
461
     * @param CoverFishResult $coverFishResult
462
     *
463
     * @return CoverFishResult
464
     */
465
    public function clearValidationWarnings(CoverFishResult $coverFishResult)
466
    {
467
        $coverFishResult->setPass(true);
468
        $coverFishResult->clearWarnings();
469
470
        return $coverFishResult;
471
    }
472
473
    /**
474
     * @param CoverFishResult $coverFishResult
475
     * @param int             $errorCode
476
     * @param string|null     $errorMessage
477
     *
478
     * @return CoverFishResult
479
     */
480
    public function setValidationError(CoverFishResult $coverFishResult, $errorCode, $errorMessage = null)
481
    {
482
        // skip validation if incoming mapping result is already invalid!
483
        if (false === $coverFishResult->isPass()) {
484
            return $coverFishResult;
485
        }
486
487
        $coverFishResult->setPass(false);
488
        $coverFishResult->addError(new CoverFishMessageError($errorCode, $errorMessage));
489
490
        return $coverFishResult;
491
    }
492
493
    /**
494
     * @param CoverFishResult $coverFishResult
495
     * @param int             $warningCode
496
     * @param string|null     $warningMessage
497
     *
498
     * @return CoverFishResult
499
     */
500
    public function setValidationWarning(CoverFishResult $coverFishResult, $warningCode, $warningMessage = null)
501
    {
502
        $coverFishResult->addWarning(new CoverFishMessageWarning($warningCode, $warningMessage));
503
504
        return $coverFishResult;
505
    }
506
507
    /**
508
     * @param string $classFQN
509
     *
510
     * @return CoverFishMessageError|\ReflectionClass
511
     */
512
    public function getReflectionClass($classFQN)
513
    {
514
        try {
515
            $reflectionClass = new \ReflectionClass($classFQN);
516
        } catch (\ReflectionException $re) {
517
            return new CoverFishMessageError(CoverFishMessageError::PHPUNIT_REFLECTION_CLASS_NOT_FOUND, $classFQN);
518
        }
519
520
        return $reflectionClass;
521
    }
522
523
    /**
524
     * @param string $coversToken
525
     */
526
    public function __construct($coversToken)
527
    {
528
        $this->coversToken = $coversToken;
529
        $this->validatorCollection = new ArrayCollection();
530
        $this->coverFishHelper = new CoverFishHelper();
531
    }
532
}