Passed
Push — master ( 13ff77...af00d8 )
by Caen
03:46 queued 15s
created

Hyde::getBladePagePath()   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
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Hyde\Framework;
4
5
use Composer\InstalledVersions;
6
use Hyde\Framework\Contracts\RouteContract;
7
use Hyde\Framework\Helpers\Features;
8
use Hyde\Framework\Models\Pages\BladePage;
9
use Hyde\Framework\Models\Pages\DocumentationPage;
10
use Hyde\Framework\Models\Pages\MarkdownPage;
11
use Hyde\Framework\Models\Pages\MarkdownPost;
12
use Hyde\Framework\Services\DiscoveryService;
13
use Illuminate\Support\Facades\View;
14
use Illuminate\Support\Str;
15
use Illuminate\Support\Traits\Macroable;
16
17
/**
18
 * General facade for Hyde services.
19
 *
20
 * @author  Caen De Silva <[email protected]>
21
 * @copyright 2022 Caen De Silva
22
 * @license MIT License
23
 *
24
 * @link https://hydephp.com/
25
 */
26
class Hyde
27
{
28
    use Macroable;
0 ignored issues
show
Bug introduced by
The trait Illuminate\Support\Traits\Macroable requires the property $name which is not provided by Hyde\Framework\Hyde.
Loading history...
29
30
    protected static string $basePath;
31
32
    public static function version(): string
33
    {
34
        return InstalledVersions::getPrettyVersion('hyde/framework') ?: 'unreleased';
35
    }
36
37
    public static function getBasePath(): string
38
    {
39
        /** @deprecated Set path in constructor when instantiating the Singleton. */
40
        if (! isset(static::$basePath)) {
41
            static::$basePath = getcwd();
42
        }
43
44
        return static::$basePath;
45
    }
46
47
    /**
48
     * @deprecated Set path in constructor when instantiating the Singleton.
49
     */
50
    public static function setBasePath(string $path): void
51
    {
52
        static::$basePath = $path;
53
    }
54
55
    // HydeHelperFacade
56
57
    public static function features(): Features
58
    {
59
        return new Features;
60
    }
61
62
    public static function hasFeature(string $feature): bool
63
    {
64
        return Features::enabled($feature);
65
    }
66
67
    public static function makeTitle(string $slug): string
68
    {
69
        $alwaysLowercase = ['a', 'an', 'the', 'in', 'on', 'by', 'with', 'of', 'and', 'or', 'but'];
70
71
        return ucfirst(str_ireplace(
0 ignored issues
show
Bug introduced by
It seems like str_ireplace($alwaysLowe...t\Str::headline($slug)) can also be of type array; however, parameter $string of ucfirst() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

71
        return ucfirst(/** @scrutinizer ignore-type */ str_ireplace(
Loading history...
72
            $alwaysLowercase,
73
            $alwaysLowercase,
74
            Str::headline($slug)
75
        ));
76
    }
77
78
    /**
79
     * File helper methods.
80
     *
81
     * If a method uses the name `path` it refers to an internal file path.
82
     * if a method uses the name `link` it refers to a web link used in Blade templates.
83
     */
84
85
    /**
86
     * Get an absolute file path from a supplied relative path.
87
     *
88
     * The function returns the fully qualified path to your site's root directory.
89
     *
90
     * You may also use the function to generate a fully qualified path to a given file
91
     * relative to the project root directory when supplying the path argument.
92
     *
93
     * @param  string  $path
94
     * @return string
95
     */
96
    public static function path(string $path = ''): string
97
    {
98
        if (empty($path)) {
99
            return static::getBasePath();
100
        }
101
102
        $path = unslash($path);
103
104
        return static::getBasePath().DIRECTORY_SEPARATOR.$path;
105
    }
106
107
    /**
108
     * Works similarly to the path() function, but returns a file in the Framework package.
109
     *
110
     * @param  string  $path
111
     * @return string
112
     */
113
    public static function vendorPath(string $path = ''): string
114
    {
115
        return static::path('vendor/hyde/framework/'.unslash($path));
116
    }
117
118
    /**
119
     * Format a link to an HTML file, allowing for pretty URLs, if enabled.
120
     *
121
     * @see \Hyde\Framework\Testing\Unit\FileHelperPageLinkPrettyUrlTest
122
     */
123
    public static function pageLink(string $destination): string
124
    {
125
        if (config('site.pretty_urls', false) === true) {
126
            if (str_ends_with($destination, '.html')) {
127
                if ($destination === 'index.html') {
128
                    return '/';
129
                }
130
                if ($destination === DocumentationPage::getOutputDirectory().'/index.html') {
131
                    return DocumentationPage::getOutputDirectory().'/';
132
                }
133
134
                return substr($destination, 0, -5);
135
            }
136
        }
137
138
        return $destination;
139
    }
140
141
    /**
142
     * Inject the proper number of `../` before the links in Blade templates.
143
     *
144
     * Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View.
145
     *
146
     * @param  string  $destination  relative to output directory on compiled site
147
     * @param  string|null  $current  the current URI path relative to the site root
148
     * @return string
149
     *
150
     * @see \Hyde\Framework\Testing\Unit\FileHelperRelativeLinkTest
151
     */
152
    public static function relativeLink(string $destination, ?string $current = null): string
153
    {
154
        if (str_starts_with($destination, '../')) {
155
            return $destination;
156
        }
157
158
        if ($current === null) {
159
            $current = static::currentPage();
160
        }
161
162
        $nestCount = substr_count($current, '/');
163
        $route = '';
164
        if ($nestCount > 0) {
165
            $route .= str_repeat('../', $nestCount);
166
        }
167
        $route .= static::pageLink($destination);
168
169
        return str_replace('//', '/', $route);
170
    }
171
172
    /**
173
     * Get the current page path, or fall back to the root path.
174
     */
175
    public static function currentPage(): string
176
    {
177
        return View::shared('currentPage', '');
178
    }
179
180
    /**
181
     * Get the current page route, or fall back to null.
182
     */
183
    public static function currentRoute(): ?RouteContract
184
    {
185
        return View::shared('currentRoute');
186
    }
187
188
    /**
189
     * Gets a relative web link to the given image stored in the _site/media folder.
190
     * Since v0.50.x you no longer have to supply a current page as it will be automatically retrieved from the View.
191
     */
192
    public static function image(string $name, string $current = null): string
193
    {
194
        if ($current === null) {
195
            $current = static::currentPage();
196
        }
197
198
        if (str_starts_with($name, 'http')) {
199
            return $name;
200
        }
201
202
        return static::relativeLink('media/'.basename($name), $current);
203
    }
204
205
    /**
206
     * Return a qualified URI path, if SITE_URL is set in .env, else return false.
207
     *
208
     * @param  string|null  $path  optional relative path suffix. Omit to return base url.
209
     * @return string|false
210
     */
211
    public static function uriPath(?string $path = ''): string|false
212
    {
213
        if (config('site.url', false)) {
214
            return rtrim(config('site.url'), '/').'/'.(trim($path, '/') ?? '');
0 ignored issues
show
Bug introduced by
It seems like $path can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

214
            return rtrim(config('site.url'), '/').'/'.(trim(/** @scrutinizer ignore-type */ $path, '/') ?? '');
Loading history...
215
        }
216
217
        return false;
218
    }
219
220
    /**
221
     * Wrapper for the copy function, but allows choosing if files may be overwritten.
222
     *
223
     * @param  string  $from  The source file path.
224
     * @param  string  $to  The destination file path.
225
     * @param  bool  $force  If true, existing files will be overwritten.
226
     * @return bool|int Returns true|false on copy() success|failure, or an error code on failure
227
     */
228
    public static function copy(string $from, string $to, bool $force = false): bool|int
229
    {
230
        if (! file_exists($from)) {
231
            return 404;
232
        }
233
234
        if (file_exists($to) && ! $force) {
235
            return 409;
236
        }
237
238
        return copy($from, $to);
239
    }
240
241
    /**
242
     * Fluent file helper methods.
243
     *
244
     * Provides a more fluent way of getting either the absolute path
245
     * to a model's source directory, or an absolute path to a file within it.
246
     *
247
     * These are intended to be used as a dynamic alternative to legacy code
248
     * Hyde::path('_pages/foo') becomes Hyde::getBladePagePath('foo')
249
     */
250
    public static function getModelSourcePath(string $model, string $path = ''): string
251
    {
252
        if (empty($path)) {
253
            return static::path(DiscoveryService::getFilePathForModelClassFiles($model));
254
        }
255
256
        $path = unslash($path);
257
258
        return static::path(DiscoveryService::getFilePathForModelClassFiles($model).DIRECTORY_SEPARATOR.$path);
259
    }
260
261
    public static function getBladePagePath(string $path = ''): string
262
    {
263
        return static::getModelSourcePath(BladePage::class, $path);
264
    }
265
266
    public static function getMarkdownPagePath(string $path = ''): string
267
    {
268
        return static::getModelSourcePath(MarkdownPage::class, $path);
269
    }
270
271
    public static function getMarkdownPostPath(string $path = ''): string
272
    {
273
        return static::getModelSourcePath(MarkdownPost::class, $path);
274
    }
275
276
    public static function getDocumentationPagePath(string $path = ''): string
277
    {
278
        return static::getModelSourcePath(DocumentationPage::class, $path);
279
    }
280
281
    /**
282
     * Get the absolute path to the compiled site directory, or a file within it.
283
     */
284
    public static function getSiteOutputPath(string $path = ''): string
285
    {
286
        if (empty($path)) {
287
            return StaticPageBuilder::$outputPath;
288
        }
289
290
        $path = unslash($path);
291
292
        return StaticPageBuilder::$outputPath.DIRECTORY_SEPARATOR.$path;
293
    }
294
295
    /**
296
     * Decode an absolute path created with a Hyde::path() helper into its relative counterpart.
297
     */
298
    public static function pathToRelative(string $path): string
299
    {
300
        return str_starts_with($path, static::path()) ? unslash(str_replace(
301
            static::path(),
302
            '',
303
            $path
304
        )) : $path;
305
    }
306
}
307