CacheResolver::getEvents()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 1
nc 1
nop 0
crap 1
1
<?php
2
3
namespace MallardDuck\DynamicEcho\Composer;
4
5
use Illuminate\Contracts\Foundation\Application;
6
use Illuminate\Filesystem\Filesystem;
7
use Illuminate\Support\Collection;
8
use Illuminate\Support\Str;
9
10
class CacheResolver
11
{
12
    // TODO: consider Union Type once PHP8 support is a concern.
13
    private string $appNamespace;
14
15
    /**
16
     * The manifest path.
17
     *
18
     * @var string|null
19
     */
20
    public $manifestPath;
21
22
    /**
23
     * @var Filesystem
24
     */
25
    private Filesystem $filesystem;
26
27
    /**
28
     * @var array|null
29
     */
30
    private ?array $manifest = null;
31
32 28
    public function __construct(string $appNamespace, string $manifestPath)
33
    {
34 28
        $this->appNamespace = $appNamespace;
35 28
        $this->manifestPath = $manifestPath;
36 28
    }
37
38 28
    public function setFilesystem(Filesystem $filesystem): self
39
    {
40 28
        $this->filesystem = $filesystem;
41 28
        return $this;
42
    }
43
44 28
    public function build(): self
45
    {
46 28
        $packages = [];
47 28
        $events = [];
48
        // TODO: add a channels array to auto-discovery channels.
49 28
        if ($this->filesystem->exists($path = $this->getVendorPath() . '/composer/installed.json')) {
50
            $installed = json_decode($this->filesystem->get($path), true);
51
            $packages = $installed['packages'] ?? $installed;
52
        }
53
54 28
        $packages = collect($packages)->mapWithKeys(function ($package) {
55
            return [$this->format($package['name']) => $package['extra']['dynamic-echo'] ?? []];
56 28
        })->filter()->all();
57
58 28
        $namespaces = collect($packages)->mapWithKeys(static function ($val) {
59
            return [$val['namespace']];
60 28
        })->push($this->appNamespace)->all();
61
62 28
        if (null !== ($classMap = $this->getClassMap())) {
63
            $events = collect($classMap)->filter(static function ($val, $key) use ($namespaces) {
64
                return Str::startsWith($key, $namespaces);
65
            })->filter()->all();
66
        }
67
68 28
        $this->write($this->manifest = [
69 28
            'packages' => $packages,
70 28
            'events' => $events,
71
        ]);
72
73 28
        return $this;
74
    }
75
76 28
    public function getManifest(): array
77
    {
78 28
        if (! is_null($this->manifest)) {
79 28
            return $this->manifest;
80
        }
81
82
        if (! is_file($this->manifestPath)) {
83
            $this->build();
84
        }
85
86
        return $this->manifest = $this->filesystem->getRequire($this->manifestPath);
87
    }
88
89 28
    public function getEvents(): Collection
90
    {
91 28
        return collect($this->getManifest()['events']);
92
    }
93
94 28
    private function getVendorPath()
95
    {
96
        /** @var Application $app */
97 28
        $app = app();
98 28
        return $app->basePath('vendor');
99
    }
100
101 28
    private function getClassMap(): ?array
102
    {
103
        if (
104 28
            $this->filesystem->exists(
105 28
                $path = $this->getVendorPath() . '/composer/autoload_classmap.php'
106
            )
107
        ) {
108
            return require $path;
109
        }
110 28
        return null;
111
    }
112
113
    protected function format($package)
114
    {
115
        return str_replace($this->getVendorPath() . '/', '', $package);
116
    }
117
118 28
    protected function write(array $manifest): void
119
    {
120 28
        if (! is_writable($dirname = dirname($this->manifestPath))) {
121
            throw new \RuntimeException("The {$dirname} directory must be present and writable.");
122
        }
123
124 28
        $this->filesystem->replace(
125 28
            $this->manifestPath,
126 28
            '<?php return ' . var_export($manifest, true) . ';'
127
        );
128 28
    }
129
}
130