Passed
Push — master ( ab30be...0d1280 )
by Caen
03:32 queued 14s
created

Filesystem::touch()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 5
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Foundation\Kernel;
6
7
use Hyde\Hyde;
8
use Hyde\Foundation\HydeKernel;
9
use Hyde\Foundation\PharSupport;
10
use Illuminate\Support\Collection;
11
use Hyde\Framework\Actions\Internal\FileFinder;
12
13
use function collect;
14
use function Hyde\normalize_slashes;
15
use function Hyde\path_join;
16
use function file_exists;
17
use function str_replace;
18
use function array_map;
19
use function is_array;
20
use function str_starts_with;
21
use function Hyde\unslash;
22
use function unlink;
23
use function touch;
24
25
/**
26
 * File helper methods, bound to the HydeKernel instance, and is an integral part of the framework.
27
 *
28
 * All paths arguments are relative to the root of the application,
29
 * and will be automatically resolved to absolute paths.
30
 */
31
class Filesystem
32
{
33
    protected HydeKernel $kernel;
34
35
    public function __construct(HydeKernel $kernel)
36
    {
37
        $this->kernel = $kernel;
38
    }
39
40
    public function getBasePath(): string
41
    {
42
        return $this->kernel->getBasePath();
43
    }
44
45
    /**
46
     * Get an absolute file path from a supplied relative path.
47
     *
48
     * The function returns the fully qualified path to your site's root directory.
49
     *
50
     * You may also use the function to generate a fully qualified path to a given file
51
     * relative to the project root directory when supplying the path argument.
52
     */
53
    public function path(string $path = ''): string
54
    {
55
        if (empty($path)) {
56
            return $this->getBasePath();
57
        }
58
59
        if (str_starts_with($path, 'phar://')) {
60
            return $path;
61
        }
62
63
        $path = unslash($this->pathToRelative($path));
64
65
        return path_join($this->getBasePath(), $path);
66
    }
67
68
    /**
69
     * Get an absolute file path from a supplied relative path.
70
     *
71
     * Input types are matched, meaning that if the input is a string so will the output be.
72
     *
73
     * @param  string|array<string>  $path
74
     * @return ($path is string ? string : array<string>)
0 ignored issues
show
Documentation Bug introduced by
The doc comment ($path at position 1 could not be parsed: Unknown type name '$path' at position 1 in ($path.
Loading history...
75
     */
76
    public function pathToAbsolute(string|array $path): string|array
77
    {
78
        if (is_array($path)) {
0 ignored issues
show
introduced by
The condition is_array($path) is always true.
Loading history...
79
            return array_map(fn (string $path): string => $this->pathToAbsolute($path), $path);
80
        }
81
82
        return $this->path($path);
83
    }
84
85
    /**
86
     * Decode an absolute path created with a Hyde::path() helper into its relative counterpart.
87
     */
88
    public function pathToRelative(string $path): string
89
    {
90
        return normalize_slashes(str_starts_with($path, $this->path())
91
            ? unslash(str_replace($this->path(), '', $path))
92
            : $path);
93
    }
94
95
    /**
96
     * Get the absolute path to the media source directory, or a file within it.
97
     */
98
    public function mediaPath(string $path = ''): string
99
    {
100
        if (empty($path)) {
101
            return $this->path(Hyde::getMediaDirectory());
0 ignored issues
show
Bug introduced by
The method getMediaDirectory() does not exist on Hyde\Hyde. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

101
            return $this->path(Hyde::/** @scrutinizer ignore-call */ getMediaDirectory());
Loading history...
102
        }
103
104
        return $this->path(path_join(Hyde::getMediaDirectory(), unslash($path)));
105
    }
106
107
    /**
108
     * Get the absolute path to the compiled site directory, or a file within it.
109
     */
110
    public function sitePath(string $path = ''): string
111
    {
112
        if (empty($path)) {
113
            return $this->path(Hyde::getOutputDirectory());
0 ignored issues
show
Bug introduced by
The method getOutputDirectory() does not exist on Hyde\Hyde. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

113
            return $this->path(Hyde::/** @scrutinizer ignore-call */ getOutputDirectory());
Loading history...
114
        }
115
116
        return $this->path(path_join(Hyde::getOutputDirectory(), unslash($path)));
117
    }
118
119
    /**
120
     * Get the absolute path to the compiled site's media directory, or a file within it.
121
     */
122
    public function siteMediaPath(string $path = ''): string
123
    {
124
        if (empty($path)) {
125
            return $this->sitePath(Hyde::getMediaOutputDirectory());
0 ignored issues
show
Bug introduced by
The method getMediaOutputDirectory() does not exist on Hyde\Hyde. Since you implemented __callStatic, consider adding a @method annotation. ( Ignorable by Annotation )

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

125
            return $this->sitePath(Hyde::/** @scrutinizer ignore-call */ getMediaOutputDirectory());
Loading history...
126
        }
127
128
        $path = unslash($path);
129
130
        return $this->sitePath(Hyde::getMediaOutputDirectory()."/$path");
131
    }
132
133
    /**
134
     * Works similarly to the path() function, but returns a file in the Framework package.
135
     *
136
     * @internal This is not intended to be used outside the HydePHP framework.
137
     */
138
    public function vendorPath(string $path = '', string $package = 'framework'): string
139
    {
140
        if (PharSupport::running() && ! PharSupport::hasVendorDirectory()) {
141
            return PharSupport::vendorPath($path, $package);
142
        }
143
144
        return $this->path("vendor/hyde/$package/".unslash($path));
145
    }
146
147
    /**
148
     * Touch one or more files in the project's directory.
149
     *
150
     * @param  string|array<string>  $path
151
     */
152
    public function touch(string|array $path): bool
153
    {
154
        return collect($path)->map(function (string $path): bool {
0 ignored issues
show
Bug introduced by
$path of type string[] 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

154
        return collect(/** @scrutinizer ignore-type */ $path)->map(function (string $path): bool {
Loading history...
155
            return touch($this->path($path));
156
        })->contains(false) === false;
157
    }
158
159
    /**
160
     * Unlink one or more files in the project's directory.
161
     *
162
     * @param  string|array<string>  $path
163
     */
164
    public function unlink(string|array $path): bool
165
    {
166
        return collect($path)->map(function (string $path): bool {
0 ignored issues
show
Bug introduced by
$path of type string[] 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

166
        return collect(/** @scrutinizer ignore-type */ $path)->map(function (string $path): bool {
Loading history...
167
            return unlink($this->path($path));
168
        })->contains(false) === false;
169
    }
170
171
    /**
172
     * Unlink a file in the project's directory, but only if it exists.
173
     */
174
    public function unlinkIfExists(string $path): bool
175
    {
176
        return file_exists($this->path($path)) && unlink($this->path($path));
177
    }
178
179
    /** @return \Illuminate\Support\Collection<int, string> */
180
    public function smartGlob(string $pattern, int $flags = 0): Collection
181
    {
182
        /** @var \Illuminate\Support\Collection<int, string> $files */
183
        $files = collect(\Hyde\Facades\Filesystem::glob($pattern, $flags));
0 ignored issues
show
Bug introduced by
Hyde\Facades\Filesystem::glob($pattern, $flags) of type string[] 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

183
        $files = collect(/** @scrutinizer ignore-type */ \Hyde\Facades\Filesystem::glob($pattern, $flags));
Loading history...
184
185
        return $files->map(fn (string $path): string => $this->pathToRelative($path));
186
    }
187
188
    /**
189
     * @param  string|array<string>|false  $matchExtensions
190
     * @return \Illuminate\Support\Collection<int, string>
191
     */
192
    public function findFiles(string $directory, string|array|false $matchExtensions = false, bool $recursive = false): Collection
193
    {
194
        /** @var \Hyde\Framework\Actions\Internal\FileFinder $finder */
195
        $finder = app(FileFinder::class);
196
197
        return $finder->handle($directory, $matchExtensions, $recursive);
198
    }
199
}
200