Completed
Pull Request — master (#37)
by
unknown
01:19
created

ComposerClassMap::searchPsrMaps()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 9.2248
c 0
b 0
f 0
cc 5
nc 5
nop 1
1
<?php
2
3
namespace Facade\Ignition\Support;
4
5
use Illuminate\Support\Str;
6
use Symfony\Component\Finder\Finder;
7
use Symfony\Component\Finder\SplFileInfo;
8
9
class ComposerClassMap
10
{
11
    /** @var \Composer\Autoload\ClassLoader */
12
    protected $composer;
13
14
    /** @var string */
15
    protected $basePath;
16
17
    public function __construct(?string $autoloaderPath = null)
18
    {
19
        $this->composer = require $autoloaderPath ?? base_path('/vendor/autoload.php');
20
        $this->basePath = app_path();
21
    }
22
23
    public function listClasses(): array
24
    {
25
        $classes = $this->composer->getClassMap();
26
27
        return array_merge($classes, $this->listClassesInPsrMaps());
28
    }
29
30
    public function searchClassMap(string $missingClass): ?string
31
    {
32
        foreach ($this->composer->getClassMap() as $fqcn => $file) {
33
            $basename = basename($file, '.php');
34
35
            if ($basename === $missingClass) {
36
                return $fqcn;
37
            }
38
        }
39
40
        return null;
41
    }
42
43
    public function listClassesInPsrMaps(): array
44
    {
45
        // TODO: This is incorrect. Doesnt list all fqcns. Need to parse namespace? e.g. App\LoginController is wrong
46
47
        $prefixes = array_merge(
48
            $this->composer->getPrefixes(),
49
            $this->composer->getPrefixesPsr4()
50
        );
51
52
        $classes = [];
53
54
        foreach ($prefixes as $namespace => $directories) {
55
            foreach ($directories as $directory) {
56
                $files = $this->getFiles($directory);
57
                foreach ($files as $file) {
58
                    /** @var SplFileInfo $file */
59
                    $fqcn = $this->getFullyQualifiedClassNameFromFile($namespace, $file);
60
                    $classes[$fqcn] = $file->getRelativePathname();
61
                }
62
            }
63
        }
64
65
        return $classes;
66
    }
67
68
    public function searchPsrMaps(string $missingClass): ?string
69
    {
70
        $prefixes = array_merge(
71
            $this->composer->getPrefixes(),
72
            $this->composer->getPrefixesPsr4()
73
        );
74
75
        foreach ($prefixes as $namespace => $directories) {
76
            foreach ($directories as $directory) {
77
                $files = $this->getFiles($directory);
78
79
                foreach ($files as $file) {
80
                    /** @var SplFileInfo $file */
81
                    $basename = basename($file->getRelativePathname(), '.php');
82
83
                    if ($basename === $missingClass) {
84
                        return $namespace.basename($file->getRelativePathname(), '.php');
85
                    }
86
                }
87
            }
88
        }
89
90
        return null;
91
    }
92
93
    protected function getFullyQualifiedClassNameFromFile(string $rootNamespace, SplFileInfo $file): string
94
    {
95
        $class = trim(str_replace($this->basePath, '', $file->getRealPath()), DIRECTORY_SEPARATOR);
96
97
        $class = str_replace(
98
            [DIRECTORY_SEPARATOR, 'App\\'],
99
            ['\\', app()->getNamespace()],
100
            ucfirst(Str::replaceLast('.php', '', $class))
101
        );
102
103
        return $rootNamespace.$class;
104
    }
105
106
    private function getFiles($directory, \Closure $closure = null)
107
    {
108
        return (new Finder)
109
            ->in($directory)
110
            ->files()
111
            ->filter(null !== $closure ? $closure : function ($file) {
112
                return ($file instanceof SplFileInfo);
113
            })
114
            ->name('*.php');
115
    }
116
}
117