Passed
Push — master ( fd4a88...7449e0 )
by Caen
04:01 queued 12s
created

Hyperlinks::image()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 6
c 0
b 0
f 0
nc 3
nop 2
dl 0
loc 13
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Hyde\Foundation\Kernel;
6
7
use Hyde\Facades\Config;
8
use Hyde\Foundation\HydeKernel;
9
use Hyde\Framework\Exceptions\BaseUrlNotSetException;
10
use Hyde\Framework\Exceptions\FileNotFoundException;
11
use Illuminate\Support\Str;
12
use function substr_count;
13
use function file_exists;
14
use function str_replace;
15
use function str_repeat;
16
use function substr;
17
use function blank;
18
use function rtrim;
19
use function trim;
20
21
/**
22
 * Contains helpers and logic for resolving web paths for compiled files.
23
 *
24
 * It's bound to the HydeKernel instance, and is an integral part of the framework.
25
 *
26
 * @see \Hyde\Framework\Testing\Feature\Foundation\HyperlinksTest
27
 */
28
class Hyperlinks
29
{
30
    protected HydeKernel $kernel;
31
32
    public function __construct(HydeKernel $kernel)
33
    {
34
        $this->kernel = $kernel;
35
    }
36
37
    /**
38
     * Format a web link to an HTML file, allowing for pretty URLs, if enabled.
39
     *
40
     * @see \Hyde\Framework\Testing\Unit\Foundation\HyperlinkFormatHtmlPathTest
41
     */
42
    public function formatLink(string $destination): string
43
    {
44
        if (Config::getBool('hyde.pretty_urls', false) === true) {
45
            if (str_ends_with($destination, '.html')) {
46
                if ($destination === 'index.html') {
47
                    return '/';
48
                }
49
50
                if (str_ends_with($destination, 'index.html')) {
51
                    return substr($destination, 0, -10);
52
                }
53
54
                return substr($destination, 0, -5);
55
            }
56
        }
57
58
        return $destination;
59
    }
60
61
    /**
62
     * Inject the proper number of `../` before the links in Blade templates.
63
     *
64
     * @param  string  $destination  relative to output directory on compiled site
65
     *
66
     * @see \Hyde\Framework\Testing\Unit\Foundation\HyperlinkFileHelperRelativeLinkTest
67
     */
68
    public function relativeLink(string $destination): string
69
    {
70
        if (str_starts_with($destination, '../')) {
71
            return $destination;
72
        }
73
74
        $nestCount = substr_count($this->kernel->currentPage() ?? '', '/');
75
        $route = '';
76
        if ($nestCount > 0) {
77
            $route .= str_repeat('../', $nestCount);
78
        }
79
        $route .= $this->formatLink($destination);
80
81
        return str_replace('//', '/', $route);
82
    }
83
84
    /**
85
     * Gets a relative web link to the given file stored in the _site/media folder.
86
     *
87
     * An exception will be thrown if the file does not exist in the _media directory,
88
     * and the second argument is set to true.
89
     */
90
    public function mediaLink(string $destination, bool $validate = false): string
91
    {
92
        if ($validate && ! file_exists($sourcePath = "{$this->kernel->getMediaDirectory()}/$destination")) {
93
            throw new FileNotFoundException($sourcePath);
94
        }
95
96
        return $this->relativeLink("{$this->kernel->getMediaOutputDirectory()}/$destination");
97
    }
98
99
    /**
100
     * Gets a relative web link to the given image stored in the _site/media folder.
101
     * If the image is remote (starts with http) it will be returned as is.
102
     *
103
     * If true is passed as the second argument, and a base URL is set,
104
     * the image will be returned with a qualified absolute URL.
105
     */
106
    public function asset(string $name, bool $preferQualifiedUrl = false): string
107
    {
108
        if (str_starts_with($name, 'http')) {
109
            return $name;
110
        }
111
112
        $name = Str::start($name, "{$this->kernel->getMediaOutputDirectory()}/");
113
114
        if ($preferQualifiedUrl && $this->hasSiteUrl()) {
115
            return $this->url($name);
116
        }
117
118
        return $this->relativeLink($name);
119
    }
120
121
    /**
122
     * Check if a site base URL has been set in config (or .env).
123
     */
124
    public function hasSiteUrl(): bool
125
    {
126
        return ! blank(Config::getNullableString('hyde.url'));
127
    }
128
129
    /**
130
     * Return a qualified URL to the supplied path if a base URL is set.
131
     *
132
     * @param  string  $path  optional relative path suffix. Omit to return base url.
133
     *
134
     * @throws BaseUrlNotSetException If no site URL is set and no default is provided
135
     */
136
    public function url(string $path = ''): string
137
    {
138
        $path = $this->formatLink(trim($path, '/'));
139
140
        if ($this->hasSiteUrl()) {
141
            return rtrim(rtrim((string) Config::getNullableString('hyde.url'), '/')."/$path", '/');
142
        }
143
144
        throw new BaseUrlNotSetException();
145
    }
146
}
147