Passed
Push — master ( 185723...2d6e9b )
by Caen
04:01 queued 13s
created

Filesystem::copy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Foundation\Kernel;
6
7
use Hyde\Facades\Site;
8
use Hyde\Foundation\HydeKernel;
9
use Hyde\Foundation\PharSupport;
10
use Hyde\Framework\Services\DiscoveryService;
11
use Hyde\Hyde;
12
use Hyde\Pages\BladePage;
13
use Hyde\Pages\DocumentationPage;
14
use Hyde\Pages\MarkdownPage;
15
use Hyde\Pages\MarkdownPost;
16
use Illuminate\Support\Collection;
17
use function array_map;
18
use function collect;
19
use function Hyde\normalize_slashes;
20
use function Hyde\path_join;
21
use function is_array;
22
use function is_string;
23
use function str_replace;
24
use function touch;
25
use function unlink;
26
use function unslash;
27
28
/**
29
 * File helper methods, bound to the HydeKernel instance, and is an integral part of the framework.
30
 *
31
 * All paths arguments are relative to the root of the application,
32
 * and will be automatically resolved to absolute paths.
33
 *
34
 * @see \Hyde\Framework\Testing\Feature\Foundation\FilesystemTest
35
 */
36
class Filesystem
37
{
38
    protected HydeKernel $kernel;
39
40
    public function __construct(HydeKernel $kernel)
41
    {
42
        $this->kernel = $kernel;
43
    }
44
45
    public function getBasePath(): string
46
    {
47
        return $this->kernel->getBasePath();
48
    }
49
50
    /**
51
     * Get an absolute file path from a supplied relative path.
52
     *
53
     * The function returns the fully qualified path to your site's root directory.
54
     *
55
     * You may also use the function to generate a fully qualified path to a given file
56
     * relative to the project root directory when supplying the path argument.
57
     */
58
    public function path(string $path = ''): string
59
    {
60
        if (empty($path)) {
61
            return $this->getBasePath();
62
        }
63
64
        $path = unslash($path);
65
66
        return path_join($this->getBasePath(), $path);
67
    }
68
69
    /**
70
     * Get an absolute file path from a supplied relative path.
71
     *
72
     * Input types are matched, meaning that if the input is a string so will the output be.
73
     */
74
    public function pathToAbsolute(string|array $path): string|array
75
    {
76
        if (is_array($path)) {
0 ignored issues
show
introduced by
The condition is_array($path) is always true.
Loading history...
77
            return array_map(fn (string $path): string => $this->pathToAbsolute($path), $path);
78
        }
79
80
        return $this->path($path);
81
    }
82
83
    /**
84
     * Decode an absolute path created with a Hyde::path() helper into its relative counterpart.
85
     */
86
    public function pathToRelative(string $path): string
87
    {
88
        return normalize_slashes(str_starts_with($path, $this->path())
89
            ? unslash(str_replace($this->path(), '', $path))
90
            : $path);
91
    }
92
93
    /**
94
     * Get the absolute path to the media source directory, or a file within it.
95
     */
96
    public function mediaPath(string $path = ''): string
97
    {
98
        if (empty($path)) {
99
            return $this->path(Hyde::getMediaDirectory());
100
        }
101
102
        $path = unslash($path);
103
104
        return $this->path(Hyde::getMediaDirectory()."/$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(Site::getOutputDirectory());
114
        }
115
116
        $path = unslash($path);
117
118
        return $this->path(Site::getOutputDirectory()."/$path");
119
    }
120
121
    /**
122
     * Get the absolute path to the compiled site's media directory, or a file within it.
123
     */
124
    public function siteMediaPath(string $path = ''): string
125
    {
126
        if (empty($path)) {
127
            return $this->sitePath(Hyde::getMediaOutputDirectory());
128
        }
129
130
        $path = unslash($path);
131
132
        return $this->sitePath(Hyde::getMediaOutputDirectory()."/$path");
133
    }
134
135
    /**
136
     * Works similarly to the path() function, but returns a file in the Framework package.
137
     *
138
     * @internal This is not intended to be used outside the HydePHP framework.
139
     */
140
    public function vendorPath(string $path = '', string $package = 'framework'): string
141
    {
142
        if (PharSupport::running() && ! PharSupport::hasVendorDirectory()) {
143
            return PharSupport::vendorPath($path, $package);
144
        }
145
146
        return $this->path("vendor/hyde/$package/".unslash($path));
147
    }
148
149
    /**
150
     * Touch one or more files in the project's directory.
151
     */
152
    public function touch(string|array $path): bool
153
    {
154
        if (is_string($path)) {
0 ignored issues
show
introduced by
The condition is_string($path) is always false.
Loading history...
155
            return touch($this->path($path));
156
        }
157
158
        foreach ($path as $p) {
159
            touch($this->path($p));
160
        }
161
162
        return true;
163
    }
164
165
    /**
166
     * Unlink one or more files in the project's directory.
167
     */
168
    public function unlink(string|array $path): bool
169
    {
170
        if (is_string($path)) {
0 ignored issues
show
introduced by
The condition is_string($path) is always false.
Loading history...
171
            return unlink($this->path($path));
172
        }
173
174
        foreach ($path as $p) {
175
            unlink($this->path($p));
176
        }
177
178
        return true;
179
    }
180
181
    /**
182
     * Unlink a file in the project's directory, but only if it exists.
183
     */
184
    public function unlinkIfExists(string $path): bool
185
    {
186
        if (file_exists($this->path($path))) {
187
            return unlink($this->path($path));
188
        }
189
190
        return false;
191
    }
192
193
    /**
194
     * Fluent file helper methods.
195
     *
196
     * Provides a more fluent way of getting either the absolute path
197
     * to a model's source directory, or an absolute path to a file within it.
198
     *
199
     * These are intended to be used as a dynamic alternative to legacy code
200
     * Hyde::path('_pages/foo') becomes Hyde::getBladePagePath('foo')
201
     */
202
    public function getModelSourcePath(string $model, string $path = ''): string
203
    {
204
        if (empty($path)) {
205
            return $this->path(DiscoveryService::getModelSourceDirectory($model));
206
        }
207
208
        return $this->path(path_join(DiscoveryService::getModelSourceDirectory($model), unslash($path)));
209
    }
210
211
    public function getBladePagePath(string $path = ''): string
212
    {
213
        return $this->getModelSourcePath(BladePage::class, $path);
214
    }
215
216
    public function getMarkdownPagePath(string $path = ''): string
217
    {
218
        return $this->getModelSourcePath(MarkdownPage::class, $path);
219
    }
220
221
    public function getMarkdownPostPath(string $path = ''): string
222
    {
223
        return $this->getModelSourcePath(MarkdownPost::class, $path);
224
    }
225
226
    public function getDocumentationPagePath(string $path = ''): string
227
    {
228
        return $this->getModelSourcePath(DocumentationPage::class, $path);
229
    }
230
231
    public function smartGlob(string $pattern, int $flags = 0): Collection
232
    {
233
        return collect(\Hyde\Facades\Filesystem::glob($pattern, $flags))
0 ignored issues
show
Bug introduced by
Hyde\Facades\Filesystem::glob($pattern, $flags) of type 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

233
        return collect(/** @scrutinizer ignore-type */ \Hyde\Facades\Filesystem::glob($pattern, $flags))
Loading history...
234
            ->map(fn (string $path): string => $this->pathToRelative($path));
235
    }
236
}
237