Completed
Push — master ( eb9261...35316d )
by Nikola
03:46
created

ClassMetadata::getShortName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
/*
3
 * This file is part of the Abstract builder package, an RunOpenCode project.
4
 *
5
 * (c) 2017 RunOpenCode
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace RunOpenCode\AbstractBuilder\Ast\Metadata;
11
12
use PhpParser\Node\Stmt\Class_;
13
use RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException;
14
use RunOpenCode\AbstractBuilder\Exception\RuntimeException;
15
use RunOpenCode\AbstractBuilder\Utils\ClassUtils;
16
17
/**
18
 * Class ClassMetadata
19
 *
20
 * @package RunOpenCode\AbstractBuilder\Ast\Metadata
21
 */
22
class ClassMetadata
23
{
24
    /**
25
     * @var string
26
     */
27
    private $name;
28
29
    /**
30
     * @var ClassMetadata
31
     */
32
    private $parent;
33
34
    /**
35
     * @var TraitMetadata[]
36
     */
37
    private $traits;
38
39
    /**
40
     * @var bool
41
     */
42
    private $final;
43
44
    /**
45
     * @var bool
46
     */
47
    private $abstract;
48
49
    /**
50
     * @var MethodMetadata[]
51
     */
52
    private $methods;
53
54
    /**
55
     * @var Class_
56
     */
57
    private $ast;
58
59
    /**
60
     * ClassMetadata constructor.
61
     *
62
     * @param string $name
63
     * @param ClassMetadata|null $parent
64
     * @param bool $final
65
     * @param bool $abstract
66
     * @param MethodMetadata[] $methods
67
     * @param Class_ $ast
68
     */
69
    public function __construct($name, ClassMetadata $parent = null, array $traits = [], $final = false, $abstract = false, array $methods = [], Class_ $ast = null)
70
    {
71
        $this->name = $name;
72
73
        if (!ClassUtils::isClassNameValid($this->name)) {
74
            throw new InvalidArgumentException(sprintf('Provided class name "%s" is not valid PHP class name.', $this->name));
75
        }
76
77
        $this->parent = $parent;
78
        $this->traits = $traits;
79
        $this->final = $final;
80
        $this->abstract = $abstract;
81
        $this->methods = $methods;
82
        $this->ast = $ast;
83
    }
84
85
    /**
86
     * @return string
87
     */
88
    public function getName()
89
    {
90
        return $this->name;
91
    }
92
93
    /**
94
     * @return string
95
     */
96
    public function getFqcn()
97
    {
98
        return '\\'.$this->name;
99
    }
100
101
    /**
102
     * @return string
103
     */
104
    public function getShortName()
105
    {
106
        return end($parts = explode('\\', $this->name));
0 ignored issues
show
Bug introduced by
$parts = explode('\\', $this->name) cannot be passed to end() as the parameter $array expects a reference.
Loading history...
107
    }
108
109
    /**
110
     * @return bool
111
     */
112
    public function isAutoloadable()
113
    {
114
        return class_exists($this->getName(), true);
115
    }
116
117
    /**
118
     * Check if class inherits some other class.
119
     *
120
     * @return bool
121
     */
122
    public function hasParent()
123
    {
124
        return null !== $this->parent;
125
    }
126
127
    /**
128
     * @return ClassMetadata|null
129
     */
130
    public function getParent()
131
    {
132
        return $this->parent;
133
    }
134
135
    /**
136
     * @return bool
137
     */
138
    public function hasTraits()
139
    {
140
        return count($this->traits) > 0;
141
    }
142
143
    /**
144
     * @return TraitMetadata[]
145
     */
146
    public function getTraits()
147
    {
148
        return $this->traits;
149
    }
150
151
    /**
152
     * @return bool
153
     */
154
    public function isFinal()
155
    {
156
        return $this->final;
157
    }
158
159
    /**
160
     * @return bool
161
     */
162
    public function isAbstract()
163
    {
164
        return $this->abstract;
165
    }
166
167
    /**
168
     * @return MethodMetadata[]
169
     */
170
    public function getMethods()
171
    {
172
        return $this->methods;
173
    }
174
175
    /**
176
     * Check if class has method, with optional inheritance tree and trait traverse.
177
     *
178
     * @param string $name
179
     * @param bool $traverse
180
     *
181
     * @return bool
182
     */
183 View Code Duplication
    public function hasMethod($name, $traverse = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
184
    {
185
        foreach ($this->methods as $method) {
186
187
            if ($name === $method->getName()) {
188
                return true;
189
            }
190
        }
191
192
        if ($traverse && $this->hasTraits()) {
193
194
            /**
195
             * @var TraitMetadata $trait
196
             */
197
            foreach ($this->traits as $trait) {
198
199
                if ($trait->hasMethod($name, $traverse)) {
200
                    return true;
201
                }
202
            }
203
        }
204
205
206
        if ($traverse && $this->hasParent()) {
207
            return $this->getParent()->hasMethod($name, $traverse);
208
        }
209
210
        return false;
211
    }
212
213
    /**
214
     * Check if class has public method, with optional inheritance tree and trait traverse.
215
     *
216
     * @param string $name
217
     * @param bool $traverse
218
     *
219
     * @return bool
220
     */
221 View Code Duplication
    public function hasPublicMethod($name, $traverse = true)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
    {
223
        foreach ($this->methods as $method) {
224
225
            if ($name === $method->getName()) {
226
                return $method->isPublic();
227
            }
228
        }
229
230
        if ($traverse && $this->hasTraits()) {
231
232
            /**
233
             * @var TraitMetadata $trait
234
             */
235
            foreach ($this->traits as $trait) {
236
237
                if ($trait->hasPublicMethod($name, $traverse)) {
238
                    return true;
239
                }
240
            }
241
        }
242
243
        if ($traverse && $this->hasParent()) {
244
            return $this->getParent()->hasPublicMethod($name, $traverse);
245
        }
246
247
        return false;
248
    }
249
250
    /**
251
     * Get public method for class, with optional inheritance tree and trait traverse.
252
     *
253
     * @param string $name
254
     * @param bool $traverse
255
     *
256
     * @return MethodMetadata
257
     *
258
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
259
     */
260
    public function getPublicMethod($name, $traverse = true)
261
    {
262 View Code Duplication
        foreach ($this->methods as $method) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
263
264
            if ($name === $method->getName()) {
265
266
                if ($method->isPublic()) {
267
                    return $method;
268
                }
269
270
                throw new RuntimeException(sprintf('Method "%s()" for class "%s" exists, but it is not public.', $name, $this->name));
271
            }
272
        }
273
274 View Code Duplication
        if ($traverse && $this->hasTraits()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
275
276
            /**
277
             * @var TraitMetadata $trait
278
             */
279
            foreach ($this->traits as $trait) {
280
281
                if ($trait->hasPublicMethod($name, $traverse)) {
282
                    return $trait->getPublicMethod($name, $traverse);
283
                }
284
            }
285
        }
286
287
        if ($traverse && $this->hasParent() && $this->getParent()->hasPublicMethod($name, $traverse)) {
288
            return $this->getParent()->getPublicMethod($name, $traverse);
289
        }
290
291
        throw new RuntimeException(sprintf('Method "%s()" for class "%s" does not exists.', $name, $this->name));
292
    }
293
294
    /**
295
     * @return Class_
296
     */
297
    public function getAst()
298
    {
299
        return $this->ast;
300
    }
301
302
    /**
303
     * {@inheritdoc}
304
     */
305
    public function __toString()
306
    {
307
        return $this->getName();
308
    }
309
}
310