FqcnFinder::hasClassName()   A
last analyzed

Complexity

Conditions 6
Paths 6

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 5
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 7
rs 9.2222
1
<?php
2
declare(strict_types=1);
3
4
namespace FlexFqcnFinder\Finder;
5
6
use FlexFqcnFinder\FqcnFinderInterface;
7
use FlexFqcnFinder\Repository\FileRepositoryInterface;
8
9
class FqcnFinder implements FqcnFinderInterface
10
{
11
    /**
12
     * @var FileRepositoryInterface
13
     */
14
    protected $phpFileRepository;
15
16
    public function __construct(FileRepositoryInterface $phpFileRepository)
17
    {
18
        $this->phpFileRepository = $phpFileRepository;
19
    }
20
21
    /**
22
     * @inheritDoc
23
     */
24
    public function find(): array
25
    {
26
        $fqcn = [];
27
        foreach ($this->phpFileRepository->getFiles() as $file) {
28
            $className = $this->getFqcnFromFile($file);
29
            if (!empty($className)) {
30
                $fqcn[] = $className;
31
            }
32
        }
33
34
        return $fqcn;
35
    }
36
37
    /**
38
     * @param string $phpFile
39
     * @return string|null
40
     */
41
    protected function getFqcnFromFile(string $phpFile)
42
    {
43
        $tokens = token_get_all((string) file_get_contents($phpFile));
44
        $count = count($tokens);
45
        $className = [];
46
        for ($i = 0; $i < $count; $i++) {
47
            if ($this->hasNamespace($tokens, $i) && empty($className)) {
48
                $className[] = $this->getNamespace($tokens, $i);
49
            }
50
51
            if ($this->hasClassName($tokens, $i)) {
52
                $className[] = $this->getClassName($tokens, $i);
53
                return implode('\\', $className);  // one class per file (psr-4 compliant)
54
            }
55
        }
56
57
        return null;
58
    }
59
60
    protected function hasNamespace(array $tokens, int $index): bool
61
    {
62
        return isset($tokens[$index][0]) && T_NAMESPACE === $tokens[$index][0];
63
    }
64
65
    protected function hasClassName(array $tokens, int $index): bool
66
    {
67
        return
68
            isset($tokens[$index][0]) &&
69
            (T_CLASS === $tokens[$index][0] || T_TRAIT === $tokens[$index][0] || T_INTERFACE === $tokens[$index][0]) &&
70
            T_WHITESPACE === $tokens[$index + 1][0] &&
71
            T_STRING === $tokens[$index + 2][0];
72
    }
73
74
    protected function getNamespace(array $tokens, $index): string
75
    {
76
        $namespace = '';
77
        $index += 2;
78
        while (isset($tokens[$index]) && is_array($tokens[$index])) {
79
            $namespace .= $tokens[$index++][1];
80
        }
81
82
        return $namespace;
83
    }
84
85
    protected function getClassName(array $tokens, $index): string
86
    {
87
        return $tokens[$index + 2][1];
88
    }
89
}
90