Completed
Push — master ( f1462e...556a60 )
by Nikola
09:28 queued 07:57
created

TraitMetadata::hasPublicMethod()   C

Complexity

Conditions 7
Paths 7

Size

Total Lines 24
Code Lines 9

Duplication

Lines 12
Ratio 50 %

Code Coverage

Tests 0
CRAP Score 56

Importance

Changes 0
Metric Value
dl 12
loc 24
ccs 0
cts 16
cp 0
rs 6.7272
c 0
b 0
f 0
cc 7
eloc 9
nc 7
nop 2
crap 56
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\Trait_;
13
use RunOpenCode\AbstractBuilder\Exception\InvalidArgumentException;
14
use RunOpenCode\AbstractBuilder\Exception\RuntimeException;
15
use RunOpenCode\AbstractBuilder\Utils\ClassUtils;
16
17
/**
18
 * Class TraitMetadata
19
 *
20
 * @package RunOpenCode\AbstractBuilder\Ast\Metadata
21
 */
22
class TraitMetadata
23
{
24
    /**
25
     * @var string
26
     */
27
    private $namespace;
28
29
    /**
30
     * @var string
31
     */
32
    private $name;
33
34
    /**
35
     * @var string
36
     */
37
    private $fqcn;
38
39
    /**
40
     * @var TraitMetadata[]
41
     */
42
    private $traits;
43
44
    /**
45
     * @var MethodMetadata[]
46
     */
47
    private $methods;
48
49
    /**
50
     * @var string
51
     */
52
    private $filename;
53
54
    /**
55
     * @var Trait_
56
     */
57
    private $ast;
58
59
    public function __construct($namespace, $name, array $traits = [], array $methods = [], $filename = null, Trait_ $ast = null)
60
    {
61
        $this->namespace = $namespace;
62
        $this->name = $name;
63
64
        $this->fqcn = '\\'.$this->name;
65
66
        if ($this->namespace) {
67
            $this->fqcn = '\\'.$this->namespace.'\\'.$this->name;
68
        }
69
70
        if (ClassUtils::isClassNameValid($this->fqcn)) {
71
            throw new InvalidArgumentException(sprintf('Provided full qualified class name "%s" is not valid PHP trait name.', $this->fqcn));
72
        }
73
74
        $this->traits = $traits;
75
        $this->methods = $methods;
76
        $this->filename = $filename;
77
        $this->ast = $ast;
78
    }
79
80
    /**
81
     * @return string
82
     */
83
    public function getNamespace()
84
    {
85
        return $this->namespace;
86
    }
87
88
    /**
89
     * @return string
90
     */
91
    public function getName()
92
    {
93
        return $this->name;
94
    }
95
96
    /**
97
     * @return string
98
     */
99
    public function getFqcn()
100
    {
101
        return $this->fqcn;
102
    }
103
104
    /**
105
     * @return bool
106
     */
107
    public function hasTraits()
108
    {
109
        return count($this->traits) > 0;
110
    }
111
112
    /**
113
     * @return TraitMetadata[]
114
     */
115
    public function getTraits()
116
    {
117
        return $this->traits;
118
    }
119
120
    /**
121
     * @return MethodMetadata[]
122
     */
123
    public function getMethods()
124
    {
125
        return $this->methods;
126
    }
127
128
    /**
129
     * Check if trait has public method, with optional trait traverse.
130
     *
131
     * @param string $name
132
     * @param bool $traverse
133
     *
134
     * @return bool
135
     */
136
    public function hasPublicMethod($name, $traverse = true)
137
    {
138
        foreach ($this->methods as $method) {
139
140
            if ($name === $method->getName()) {
141
                return $method->isPublic();
142
            }
143
        }
144
145 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...
146
147
            /**
148
             * @var TraitMetadata $trait
149
             */
150
            foreach ($this->traits as $trait) {
151
152
                if ($trait->hasPublicMethod($name, $traverse)) {
153
                    return true;
154
                }
155
            }
156
        }
157
158
        return false;
159
    }
160
161
    /**
162
     * Get public method for trait, with optional trait traverse.
163
     *
164
     * @param string $name
165
     * @param bool $traverse
166
     *
167
     * @return MethodMetadata
168
     *
169
     * @throws \RunOpenCode\AbstractBuilder\Exception\RuntimeException
170
     */
171
    public function getPublicMethod($name, $traverse = true)
172
    {
173 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...
174
175
            if ($name === $method->getName()) {
176
177
                if ($method->isPublic()) {
178
                    return $method;
179
                }
180
181
                throw new RuntimeException(sprintf('Method "%s()" for trait "%s" exists, but it is not public.', $name, $this->fqcn));
182
            }
183
        }
184
185 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...
186
187
            /**
188
             * @var TraitMetadata $trait
189
             */
190
            foreach ($this->traits as $trait) {
191
192
                if ($trait->hasPublicMethod($name, $traverse)) {
193
                    return $trait->getPublicMethod($name, $traverse);
194
                }
195
            }
196
        }
197
198
        throw new RuntimeException(sprintf('Method "%s()" for trait "%s" does not exists.', $name, $this->fqcn));
199
    }
200
201
    /**
202
     * @return string
203
     */
204
    public function getFilename()
205
    {
206
        return $this->filename;
207
    }
208
209
    /**
210
     * @return Trait_
211
     */
212
    public function getAst()
213
    {
214
        return $this->ast;
215
    }
216
217
218
    /**
219
     * {@inheritdoc}
220
     */
221
    public function __toString()
222
    {
223
        return $this->getFqcn();
224
    }
225
}
226