PublicClass::leave()   A
last analyzed

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.2
c 0
b 0
f 0
cc 4
eloc 7
nc 4
nop 1
1
<?php
2
3
namespace Solidifier\Visitors\Encapsulation;
4
5
use Solidifier\Parser\Visitors\ContextualVisitor;
6
use PhpParser\Node;
7
use PhpParser\Node\Stmt\Property;
8
use PhpParser\Node\Stmt\ClassMethod;
9
use PhpParser\Node\Stmt\Class_;
10
11
class PublicClass extends ContextualVisitor
12
{
13
    private
14
        $threshold,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
Coding Style introduced by
The visibility should be declared for property $threshold.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
15
        $minMethodCount,
16
        $methods;
17
    
18
    public function __construct()
19
    {
20
        parent::__construct();
21
        
22
        $this->threshold = 0.50;
0 ignored issues
show
Coding Style introduced by
Equals sign not aligned with surrounding assignments; expected 6 spaces but found 1 space

This check looks for multiple assignments in successive lines of code. It will report an issue if the operators are not in a straight line.

To visualize

$a = "a";
$ab = "ab";
$abc = "abc";

will produce issues in the first and second line, while this second example

$a   = "a";
$ab  = "ab";
$abc = "abc";

will produce no issues.

Loading history...
23
        $this->minMethodCount = 4;
24
    }
25
    
26
    public function setThreshold($threshold)
27
    {
28
        $this->threshold = $threshold;
29
        
30
        return $this;
31
    }
32
    
33
    public function setMinMethodCount($minMethodCount)
34
    {
35
        $this->minMethodCount = $minMethodCount;
36
        
37
        return $this;
38
    }
39
    
40
    protected function enter(Node $node)
41
    {
42
        if($node instanceof Class_)
43
        {
44
            $this->methods = array();
45
        }
46
        elseif($node instanceof ClassMethod)
47
        {
48
            $this->enterClassMethod($node);
49
        }
50
    }
51
    
52
    private function enterClassMethod(ClassMethod $node)
53
    {
54
        $methodName = $node->name;
55
        
56
        if($this->isGetterOrSetter($methodName) !== true && $this->isNeitherConstructorNorDestructor($methodName))
57
        {
58
            $this->methods[$methodName] = $node->isPublic();
59
        }
60
    }
61
62
    private function isGetterOrSetter($methodName)
63
    {
64
        $prefix = strtolower(substr($methodName, 0, 3));
65
    
66
        return $prefix === 'get' || $prefix === 'set';
67
    }  
68
    
69
    private function isNeitherConstructorNorDestructor($methodName)
70
    {
71
        $name = strtolower($methodName);
72
        
73
        return $name !== '__construct' && $name !== '__destruct' && $name !== strtolower($this->currentObjectType->name);
74
    }
75
76
    protected function leave(Node $node)
77
    {
78
        if($node instanceof Class_)
79
        {
80
            $nbMethods = count($this->methods);
81
            
82
            if($nbMethods >= $this->minMethodCount)
83
            {
84
                $nbPublicMethods = count(array_filter($this->methods));
85
                
86
                if(((float)$nbPublicMethods / (float)$nbMethods) >= $this->threshold)
87
                {
88
                    $this->dispatch(new \Solidifier\Defects\PublicClass($node));
89
                }
90
            }
91
        }
92
    }
93
}