FqcnFinder   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 31
c 1
b 0
f 0
dl 0
loc 79
rs 10
wmc 21

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getClassName() 0 3 1
A hasNamespace() 0 3 2
A getNamespace() 0 9 3
A __construct() 0 3 1
A getFqcnFromFile() 0 17 5
A find() 0 11 3
A hasClassName() 0 7 6
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