FileHelper_PHPClassInfo_Class::getNameNS()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
c 0
b 0
f 0
dl 0
loc 9
rs 10
cc 2
nc 2
nop 0
1
<?php
2
/**
3
 * File containing the {@link FileHelper_PHPClassInfo_Class} class.
4
 *
5
 * @package Application Utils
6
 * @subpackage FileHelper
7
 * @see FileHelper_PHPClassInfo_Class
8
 */
9
10
declare(strict_types=1);
11
12
namespace AppUtils;
13
14
/**
15
 * Container for the information on a single class found
16
 * in a PHP file. Used to easily access all available 
17
 * class details.
18
 *
19
 * @package Application Utils
20
 * @subpackage FileHelper
21
 * @author Sebastian Mordziol <[email protected]>
22
 */
23
class FileHelper_PHPClassInfo_Class 
24
{
25
   /**
26
    * @var FileHelper_PHPClassInfo
27
    */
28
    protected $info;
29
30
   /**
31
    * @var bool
32
    */
33
    protected $abstract = false;
34
    
35
   /**
36
    * @var bool
37
    */
38
    protected $final = false;
39
    
40
   /**
41
    * @var string
42
    */
43
    protected $extends = '';
44
    
45
   /**
46
    * @var string[]
47
    */
48
    protected $implements = array();
49
    
50
   /**
51
    * @var string
52
    */
53
    protected $name;
54
    
55
   /**
56
    * @var string
57
    */
58
    protected $declaration;
59
    
60
   /**
61
    * @var string
62
    */
63
    protected $keyword;
64
65
    /**
66
     * @var string
67
     */
68
    private $type;
69
70
    /**
71
    * @param FileHelper_PHPClassInfo $info The class info instance.
72
    * @param string $declaration The full class declaration, e.g. "class SomeName extends SomeOtherClass".
73
    * @param string $keyword The class keyword, if any, i.e. "abstract" or "final".
74
    */
75
    public function __construct(FileHelper_PHPClassInfo $info, string $declaration, string $keyword, string $type)
76
    {
77
        $this->info = $info;
78
        $this->declaration = $declaration;
79
        $this->keyword = $keyword;
80
        $this->type = $type;
81
        
82
        $this->analyzeCode();
83
    }
84
    
85
   /**
86
    * Check if this class is a subclass of the specified
87
    * class name.
88
    * 
89
    * @param string $className
90
    * @return bool
91
    */
92
    public function isSublassOf(string $className) : bool
93
    {
94
        return is_subclass_of($this->getNameNS(), $className);
95
    }
96
    
97
   /**
98
    * The class name without namespace.
99
    * @return string
100
    */
101
    public function getName() : string
102
    {
103
        return $this->name;
104
    }
105
    
106
   /**
107
    * The absolute class name with namespace (if any).
108
    * @return string
109
    */
110
    public function getNameNS() : string
111
    {
112
        $name = $this->getName();
113
        
114
        if($this->info->hasNamespace()) {
115
            $name = $this->info->getNamespace().'\\'.$this->name;
116
        }
117
        
118
        return $name;
119
    }
120
    
121
   /**
122
    * Whether it is an abstract class.
123
    * @return bool
124
    */
125
    public function isAbstract() : bool
126
    {
127
        return $this->abstract;
128
    }
129
    
130
   /**
131
    * Whether it is a final class.
132
    * @return bool
133
    */
134
    public function isFinal() : bool
135
    {
136
        return $this->final;
137
    }
138
139
   /**
140
    * The name of the class that this class extends (with namespace, if specified).
141
    * @return string
142
    */
143
    public function getExtends() : string
144
    {
145
        return $this->extends;
146
    }
147
    
148
   /**
149
    * A list of interfaces the class implements, if any.
150
    * @return string[]
151
    */
152
    public function getImplements() : array
153
    {
154
        return $this->implements;
155
    }
156
    
157
   /**
158
    * The class declaration string, with normalized spaces and sorted interface names.
159
    * NOTE: does not include the keyword "abstract" or "final".
160
    * 
161
    * @return string
162
    */
163
    public function getDeclaration() : string
164
    {
165
        $parts = array();
166
        $parts[] = $this->type;
167
        $parts[] = $this->getName();
168
        
169
        if(!empty($this->extends)) {
170
            $parts[] = 'extends';
171
            $parts[] = $this->extends;
172
        }
173
        
174
        if(!empty($this->implements)) {
175
            $parts[] = 'implements';
176
            $parts[] = implode(', ', $this->implements);
177
        }
178
        
179
        return implode(' ', $parts);
180
    }
181
    
182
   /**
183
    * The keyword before "class", e.g. "abstract".
184
    * @return string
185
    */
186
    public function getKeyword() : string
187
    {
188
        return $this->keyword;
189
    }
190
191
    public function isTrait() : bool
192
    {
193
        return $this->type === FileHelper_PHPClassInfo::TYPE_TRAIT;
194
    }
195
196
    public function isClass() : bool
197
    {
198
        return $this->type === FileHelper_PHPClassInfo::TYPE_CLASS;
199
    }
200
201
    public function isInterface() : bool
202
    {
203
        return $this->type === FileHelper_PHPClassInfo::TYPE_INTERFACE;
204
    }
205
206
    protected function analyzeCode() : void
207
    {
208
        if($this->keyword === 'abstract') {
209
            $this->abstract = true;
210
        } else if($this->keyword === 'final') {
211
            $this->final = true;
212
        }
213
        
214
        $declaration = $this->declaration;
215
        
216
        $parts = ConvertHelper::explodeTrim(' ', $declaration);
217
        
218
        $this->name = trim(array_shift($parts));
219
        
220
        $tokens = array(
221
            'implements' => array(),
222
            'extends' => array()
223
        );
224
        
225
        $tokenName = 'none';
226
        
227
        foreach($parts as $part)
228
        {
229
            $part = str_replace(',', '', $part);
230
            $part = trim($part);
231
            if(empty($part)) {
232
                continue;
233
            }
234
            
235
            $name = strtolower($part);
236
            if($name === 'extends' || $name === 'implements') {
237
                $tokenName = $name;
238
                continue;
239
            }
240
            
241
            $tokens[$tokenName][] = $part;
242
        }
243
        
244
        $this->implements = $tokens['implements'];
245
        
246
        if(!empty($this->implements)) {
247
            usort($this->implements, function(string $a, string $b) {
248
                return strnatcasecmp($a, $b);
249
            });
250
        }
251
        
252
        if(!empty($tokens['extends'])) {
253
            $this->extends = $tokens['extends'][0];
254
        }
255
    }
256
}
257