Passed
Pull Request — main (#1)
by Michael
03:43
created

AutoBindsToContainer::run()   A

Complexity

Conditions 3
Paths 1

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 16
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 15
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 24
ccs 16
cts 16
cp 1
crap 3
rs 9.7666
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MichaelRubel\AutoBinder\Traits;
6
7
use Illuminate\Support\Str;
8
use Symfony\Component\Finder\SplFileInfo;
9
10
trait AutoBindsToContainer
11
{
12
    /**
13
     * Run the folders scanning & bind the results.
14
     *
15
     * @return void
16
     */
17 9
    protected function run(): void
18
    {
19 9
        collect($this->getFolderFiles())
0 ignored issues
show
Bug introduced by
$this->getFolderFiles() of type Symfony\Component\Finder\SplFileInfo[]|array is incompatible with the type Illuminate\Contracts\Support\Arrayable expected by parameter $value of collect(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

19
        collect(/** @scrutinizer ignore-type */ $this->getFolderFiles())
Loading history...
20 9
            ->each(function (SplFileInfo $file) {
21 9
                $relativePath             = $file->getRelativePathname();
22 9
                $filenameWithoutExtension = $file->getFilenameWithoutExtension();
23 9
                $filenameWithRelativePath = $this->prepareFilename($relativePath);
24
25 9
                $interface = $this->interfaceFrom($filenameWithoutExtension);
26 9
                $concrete  = $this->concreteFrom($filenameWithRelativePath);
27
28 9
                if (! interface_exists($interface) || ! class_exists($concrete)) {
29 9
                    return;
30
                }
31
32 9
                $dependencies = collect($this->dependencies);
33
34 9
                $concrete = match (true) {
35 9
                    $dependencies->has($interface) => $dependencies->get($interface),
36 8
                    $dependencies->has($concrete)  => $dependencies->get($concrete),
37 7
                    default                        => $concrete,
38
                };
39
40 9
                app()->{$this->bindingType}($interface, $concrete);
41
            });
42
    }
43
44
    /**
45
     * Get the folder files.
46
     *
47
     * @return array
48
     */
49 9
    protected function getFolderFiles(): array
50
    {
51 9
        $filesystem = app('files');
52
53 9
        $folder = base_path($this->basePath . DIRECTORY_SEPARATOR . $this->classFolder);
54
55 9
        return $filesystem->isDirectory($folder)
56 9
            ? $filesystem->allFiles($folder)
57 9
            : [];
58
    }
59
60
    /**
61
     * Prepare the filename.
62
     *
63
     * @param string $filename
64
     *
65
     * @return string
66
     */
67 9
    protected function prepareFilename(string $filename): string
68
    {
69 9
        return (string) Str::of($filename)
70 9
            ->replace('/', '\\')
71 9
            ->substr(0, (int) strrpos($filename, '.'));
72
    }
73
74
    /**
75
     * Get the namespace from a given path.
76
     *
77
     * @param string $path
78
     *
79
     * @return string
80
     */
81 9
    protected function namespaceFrom(string $path): string
82
    {
83 9
        return (string) Str::of($path)
84 9
            ->replace('/', '\\')
85 9
            ->ucfirst();
86
    }
87
88
    /**
89
     * Get the interface from filename.
90
     *
91
     * @param string $filenameWithoutExtension
92
     *
93
     * @return string
94
     */
95 9
    protected function interfaceFrom(string $filenameWithoutExtension): string
96
    {
97 9
        $interface = $this->guessInterfaceWith($filenameWithoutExtension);
98
99 9
        if (is_null($interface)) {
100 4
            return $this->interfaceNamingspace
101
                . '\\'
102
                . $filenameWithoutExtension
103 4
                . ($this->interfaceNaming);
104
        }
105
106 5
        return $interface;
107
    }
108
109
    /**
110
     * Guess the interface with a given filename.
111
     *
112
     * @param string $filenameWithoutExtension
113
     *
114
     * @return string|null
115
     */
116 9
    protected function guessInterfaceWith(string $filenameWithoutExtension): ?string
117
    {
118 9
        if (! Str::contains($this->interfaceNamingspace, '\\')) {
119 5
            return $this->classNamespace
120
                . '\\'
121 5
                . $this->classFolder
122
                . '\\'
123 5
                . $this->interfaceNamingspace
124
                . '\\'
125
                . $filenameWithoutExtension
126 5
                . ($this->interfaceNaming);
127
        }
128
129 4
        return null;
130
    }
131
132
    /**
133
     * Get the concrete from filename.
134
     *
135
     * @param string $filenameWithRelativePath
136
     *
137
     * @return string
138
     */
139 9
    protected function concreteFrom(string $filenameWithRelativePath): string
140
    {
141 9
        return $this->classNamespace . '\\' . $this->classFolder . '\\' . $filenameWithRelativePath;
142
    }
143
}
144