Passed
Push — master ( 1aec81...38365c )
by Marwan
06:35
created

Path::__call()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * @author Marwan Al-Soltany <[email protected]>
5
 * @copyright Marwan Al-Soltany 2021
6
 * For the full copyright and license information, please view
7
 * the LICENSE file that was distributed with this source code.
8
 */
9
10
declare(strict_types=1);
11
12
namespace MAKS\Velox\Frontend;
13
14
use MAKS\Velox\Backend\Config;
15
16
/**
17
 * A class that serves as a path resolver for different paths/URLs of the app.
18
 *
19
 * Example:
20
 * ```
21
 * // NOTE: all methods that have "resolve" as prefix
22
 * // can also be called without the resolve prefix
23
 * // Path::resolve*() -> Path:*() like Path::resolveUrl() -> Path::url()
24
 *
25
 * // get an absolute path from app root
26
 * $path = Path::resolve('some/path');
27
 *
28
 * // get a public URL from app root
29
 * $url = Path::resolveUrl('some/route');
30
 *
31
 *
32
 * // get a relative path from theme root
33
 * $path = Path::resolveFromTheme('some/file.ext');
34
 *
35
 * // get a public URL from theme root
36
 * $url = Path::resolveUrlFromTheme('some/file.ext');
37
 *
38
 *
39
 * // get a relative path from theme assets root
40
 * $path = Path::resolveFromAssets('some/file.ext');
41
 *
42
 * // get a public URL from theme assets root
43
 * $url = Path::resolveUrlFromAssets('some/file.ext');
44
 * ```
45
 *
46
 * @method static string url(string $path = '/')
47
 * @method static string fromTheme(string $path = '/', string $prefix = '')
48
 * @method static string urlFromTheme(string $path = '/')
49
 * @method static string fromAssets(string $path = '/', string $prefix = '')
50
 * @method static string urlFromAssets(string $path = '/')
51
 *
52
 * @since 1.0.0
53
 * @api
54
 */
55
final class Path
56
{
57
    /**
58
     * Returns the current path, or compares it with the passed parameter.
59
     *
60
     * @param string|null $compareTo [optional] Some path on the server.
61
     *
62
     * @return string|bool If null is passed, the current path as string. Otherwise the result of comparing the current path with the passed parameter as boolean.
63
     */
64
    public static function current(?string $compareTo = null)
65
    {
66
        $path = $_SERVER['REQUEST_URI'];
67
68
        if ($compareTo) {
69
            return $path === $compareTo;
70
        }
71
72
        return $path;
73
    }
74
75
    /**
76
     * Returns the current URL, or compares it with the passed parameter.
77
     *
78
     * @param string|null $compareTo [optional] Some URL on the server.
79
     *
80
     * @return string|bool If null is passed, the current URL as string. Otherwise the result of comparing the current URL with the passed parameter as boolean.
81
     */
82
    public static function currentUrl(?string $compareTo = null)
83
    {
84
        $url = static::resolveUrl((string)static::current());
85
86
        if ($compareTo) {
87
            return $url === $compareTo;
88
        }
89
90
        return $url;
91
    }
92
93
    /**
94
     * Resolves the passed path to the app root path and returns it.
95
     *
96
     * @param string [optional] $path The path from app root.
97
     *
98
     * @return string An absolute path on the server starting from app root.
99
     */
100
    public static function resolve(string $path = '/'): string
101
    {
102
        static $root = null;
103
104
        if ($root === null) {
105
            $root = Config::get('global.paths.root');
106
        }
107
108
        $absolutePath = sprintf(
109
            '%s/%s',
110
            rtrim($root, '/'),
111
            ltrim($path, '/')
112
        );
113
114
        $canonicalPath = realpath($absolutePath);
115
116
        return $canonicalPath ? $canonicalPath : $absolutePath;
117
    }
118
119
    /**
120
     * Resolves the passed path to the base URL (starting from app root) and returns it.
121
     *
122
     * @param string [optional] $path The path from app root.
123
     *
124
     * @return string An absolute path on the server (public URL) starting from app root.
125
     */
126
    public static function resolveUrl(string $path = '/'): string
127
    {
128
        static $url = null;
129
130
        if ($url === null) {
131
            $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'];
132
        }
133
134
        return sprintf(
135
            '%s/%s',
136
            rtrim($url, '/'),
137
            ltrim($path, '/')
138
        );
139
    }
140
141
    /**
142
     * Resolves the passed path to the theme root path and returns it.
143
     *
144
     * @param string [optional] $path The path from theme root.
145
     * @param string [optional] $prefix The prefix to prefix the returned path with (base URL for example).
146
     *
147
     * @return string A relative path starting from app root to the root of the active theme directory.
148
     */
149
    public static function resolveFromTheme(string $path = '/', string $prefix = ''): string
150
    {
151
        static $theme = null;
152
153
        if ($theme === null) {
154
            $theme = str_replace(
155
                Config::get('global.paths.root'),
156
                '',
157
                Config::get('theme.paths.root')
158
            );
159
        }
160
161
        return sprintf(
162
            '%s/%s/%s',
163
            rtrim($prefix, '/'),
164
            trim($theme, '/'),
165
            ltrim($path, '/')
166
        );
167
    }
168
169
    /**
170
     * Resolves the passed path to the base URL (starting from active theme root) and returns it.
171
     *
172
     * @param string [optional] $path The path from theme root.
173
     *
174
     * @return string An absolute path on the server (public URL) starting from active theme root.
175
     */
176
    public static function resolveUrlFromTheme(string $path = '/'): string
177
    {
178
        return static::resolveFromTheme($path, static::resolveUrl());
179
    }
180
181
    /**
182
     * Resolves the passed path to the assets directory and returns it.
183
     *
184
     * @param string [optional] $path The path from theme root assets root.
185
     * @param string [optional] $prefix The prefix to prefix the returned path with (base URL for example).
186
     *
187
     * @return string A relative path starting from app root to the root of the assets directory of the active theme directory.
188
     */
189
    public static function resolveFromAssets(string $path = '/', string $prefix = ''): string
190
    {
191
        static $assets = null;
192
193
        if (!$assets) {
194
            $assets = str_replace(
195
                Config::get('theme.paths.root'),
196
                '',
197
                Config::get('theme.paths.assets')
198
            );
199
200
            $assets = static::resolveFromTheme($assets);
201
        }
202
203
        return sprintf(
204
            '%s/%s/%s',
205
            rtrim($prefix, '/'),
206
            trim($assets, '/'),
207
            ltrim($path, '/')
208
        );
209
    }
210
211
    /**
212
     * Resolves the passed path to the base URL (starting from active theme assets root) and returns it.
213
     *
214
     * @param string [optional] $path The path from theme root assets root.
215
     *
216
     * @return string An absolute path on the server (public URL) starting from active theme root.
217
     */
218
    public static function resolveUrlFromAssets(string $path = '/'): string
219
    {
220
        return static::resolveFromAssets($path, static::resolveUrl());
221
    }
222
223
224
    /**
225
     * Aliases `self::resolve*()` with a function of the same name without the "resolve" prefix.
226
     */
227
    public static function __callStatic(string $method, array $arguments)
228
    {
229
        $class  = static::class;
230
        $method = sprintf('resolve%s', ucfirst($method));
231
232
        if (!method_exists($class, $method)) {
233
            throw new \Exception("Call to undefined method {$class}::{$method}()");
234
        }
235
236
        return static::$method(...$arguments);
237
    }
238
239
    /**
240
     * Allows static methods handled by self::__callStatic() to be accessible via object operator `->`.
241
     */
242
    public function __call(string $method, array $arguments)
243
    {
244
        return static::__callStatic($method, $arguments);
245
    }
246
}
247