Passed
Push — testing ( 57c125...199f7f )
by Hennik
03:23
created

ClassFinder::tokenIsClassOrInterface()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Tools;
4
5
use Symfony\Component\Finder\Finder;
6
7
class ClassFinder
8
{
9
    /**
10
     * Find all the class and interface names in a given directory.
11
     *
12
     * @param string $directory
13
     *
14
     * @return array
15
     */
16
    public function findClasses($directory)
17
    {
18
        $classes = [];
19
20
        foreach (Finder::create()->in($directory)->name('*.php') as $file) {
21
            $classes[] = $this->findClass($file->getRealPath());
22
        }
23
24
        return array_filter($classes);
25
    }
26
27
    /**
28
     * Extract the class name from the file at the given path.
29
     *
30
     * @param string $path
31
     *
32
     * @return string|null
33
     */
34
    public function findClass($path)
35
    {
36
        $namespace = null;
37
38
        $tokens = token_get_all(file_get_contents($path));
39
40
        foreach ($tokens as $key => $token) {
41
            if ($this->tokenIsNamespace($token)) {
42
                $namespace = $this->getNamespace($key + 2, $tokens);
43
            } elseif ($this->tokenIsClassOrInterface($token)) {
44
                return ltrim($namespace . '\\' . $this->getClass($key + 2, $tokens), '\\');
45
            }
46
        }
47
    }
48
49
    /**
50
     * Find the namespace in the tokens starting at a given key.
51
     *
52
     * @param int   $key
53
     * @param array $tokens
54
     *
55
     * @return string
56
     */
57
    protected function getNamespace($key, array $tokens)
58
    {
59
        $namespace = null;
60
61
        $tokenCount = count($tokens);
62
63
        for ($i = $key; $i < $tokenCount; $i++) {
64
            if ($this->isPartOfNamespace($tokens[$i])) {
65
                $namespace .= $tokens[$i][1];
66
            } elseif ($tokens[$i] == ';') {
67
                return $namespace;
68
            }
69
        }
70
    }
71
72
    /**
73
     * Find the class in the tokens starting at a given key.
74
     *
75
     * @param int   $key
76
     * @param array $tokens
77
     *
78
     * @return string
79
     */
80
    protected function getClass($key, array $tokens)
81
    {
82
        $class = null;
83
84
        $tokenCount = count($tokens);
85
86
        for ($i = $key; $i < $tokenCount; $i++) {
87
            if ($this->isPartOfClass($tokens[$i])) {
88
                $class .= $tokens[$i][1];
89
            } elseif ($this->isWhitespace($tokens[$i])) {
90
                return $class;
91
            }
92
        }
93
    }
94
95
    /**
96
     * Determine if the given token is a namespace keyword.
97
     *
98
     * @param array|string $token
99
     *
100
     * @return bool
101
     */
102
    protected function tokenIsNamespace($token)
103
    {
104
        return is_array($token) && $token[0] == T_NAMESPACE;
105
    }
106
107
    /**
108
     * Determine if the given token is a class or interface keyword.
109
     *
110
     * @param array|string $token
111
     *
112
     * @return bool
113
     */
114
    protected function tokenIsClassOrInterface($token)
115
    {
116
        return is_array($token) && ($token[0] == T_CLASS || $token[0] == T_INTERFACE);
117
    }
118
119
    /**
120
     * Determine if the given token is part of the namespace.
121
     *
122
     * @param array|string $token
123
     *
124
     * @return bool
125
     */
126
    protected function isPartOfNamespace($token)
127
    {
128
        return is_array($token) && ($token[0] == T_STRING || $token[0] == T_NS_SEPARATOR);
129
    }
130
131
    /**
132
     * Determine if the given token is part of the class.
133
     *
134
     * @param array|string $token
135
     *
136
     * @return bool
137
     */
138
    protected function isPartOfClass($token)
139
    {
140
        return is_array($token) && $token[0] == T_STRING;
141
    }
142
143
    /**
144
     * Determine if the given token is whitespace.
145
     *
146
     * @param array|string $token
147
     *
148
     * @return bool
149
     */
150
    protected function isWhitespace($token)
151
    {
152
        return is_array($token) && $token[0] == T_WHITESPACE;
153
    }
154
}
155