Passed
Push — master ( e2caf5...ecb50c )
by Caen
03:51 queued 12s
created

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

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