Passed
Push — master ( 7acf4e...727c5c )
by Stéphane
02:27
created

DauxHelper::isValidUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 1
nc 2
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php namespace Todaymade\Daux;
2
3
use Todaymade\Daux\Exception\LinkNotFoundException;
4
use Todaymade\Daux\Tree\Builder;
5
use Todaymade\Daux\Tree\Directory;
6
7
class DauxHelper
8
{
9
    /**
10
     * Set a new base_url for the configuration
11
     *
12
     * @param Config $config
13
     * @param string $base_url
14
     */
15
    public static function rebaseConfiguration(Config $config, $base_url)
16
    {
17
        // Avoid changing the url if it is already correct
18
        if ($config['base_url'] == $base_url && !empty($config['theme'])) {
19
            return;
20
        }
21
22
        // Change base url for all links on the pages
23
        $config['base_url'] = $config['base_page'] = $base_url;
24
        $config['theme'] = static::getTheme($config, $base_url);
25
        $config['image'] = str_replace('<base_url>', $base_url, $config['image']);
26
    }
27
28
    protected static function resolveVariant(Config $params)
29
    {
30
        if (array_key_exists('theme-variant', $params['html'])) {
31
            return;
32
        }
33
34
        if (is_dir(realpath(($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme'])))) {
35
            return;
36
        }
37
38
        $theme = explode('-', $params['html']['theme']);
39
40
        // do we have a variant or only a theme ?
41
        if (isset($theme[1])) {
42
            $params['html']['theme-variant'] = array_pop($theme);
43
            $params['html']['theme'] = implode('-', $theme);
44
        } else {
45
            $params['html']['theme'] = array_pop($theme);
46
        }
47
48
        if (!is_dir(realpath($params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme']))) {
49
            throw new \RuntimeException("Theme '{$params['html']['theme']}' not found");
50
        }
51
    }
52
53
    /**
54
     * @param Config $params
55
     * @param string $current_url
56
     * @return array
57
     */
58
    protected static function getTheme(Config $params, $current_url)
59
    {
60
        self::resolveVariant($params);
61
62
        $theme_folder = $params->getThemesPath() . DIRECTORY_SEPARATOR . $params['html']['theme'];
63
        $theme_url = $params['base_url'] . 'themes/' . $params['html']['theme'] . '/';
64
65
        $theme = [];
66
        if (is_file($theme_folder . DIRECTORY_SEPARATOR . 'config.json')) {
67
            $theme = json_decode(file_get_contents($theme_folder . DIRECTORY_SEPARATOR . 'config.json'), true);
68
            if (!$theme) {
69
                $theme = [];
70
            }
71
        }
72
73
        //Default parameters for theme
74
        $theme += [
75
            'name' => $params['html']['theme'],
76
            'css' => [],
77
            'js' => [],
78
            'fonts' => [],
79
            'favicon' => '<base_url>themes/daux/img/favicon.png',
80
            'templates' => $theme_folder . DIRECTORY_SEPARATOR . 'templates',
81
            'variants' => [],
82
        ];
83
84
        if (array_key_exists('theme-variant', $params['html'])) {
85
            $variant = $params['html']['theme-variant'];
86
            if (!array_key_exists($variant, $theme['variants'])) {
87
                throw new Exception("Variant '$variant' not found for theme '$theme[name]'");
88
            }
89
90
            // These will be replaced
91
            foreach (['templates', 'favicon'] as $element) {
92
                if (array_key_exists($element, $theme['variants'][$variant])) {
93
                    $theme[$element] = $theme['variants'][$variant][$element];
94
                }
95
            }
96
97
            // These will be merged
98
            foreach (['css', 'js', 'fonts'] as $element) {
99
                if (array_key_exists($element, $theme['variants'][$variant])) {
100
                    $theme[$element] = array_merge($theme[$element], $theme['variants'][$variant][$element]);
101
                }
102
            }
103
        }
104
105
        $substitutions = [
106
            '<local_base>' => $params['local_base'],
107
            '<base_url>' => $current_url,
108
            '<theme_url>' => $theme_url,
109
        ];
110
111
        // Substitute some placeholders
112
        $theme['templates'] = strtr($theme['templates'], $substitutions);
113
        $theme['favicon'] = utf8_encode(strtr($theme['favicon'], $substitutions));
114
115
        foreach (['css', 'js', 'fonts'] as $element) {
116
            foreach ($theme[$element] as $key => $value) {
117
                $theme[$element][$key] = utf8_encode(strtr($value, $substitutions));
118
            }
119
        }
120
121
        return $theme;
122
    }
123
124
    /**
125
     * Remove all '/./' and '/../' in a path, without actually checking the path
126
     *
127
     * @param string $path
128
     * @return string
129
     */
130
    public static function getCleanPath($path)
131
    {
132
        $path = str_replace(['/', '\\'], DIRECTORY_SEPARATOR, $path);
133
        $parts = array_filter(explode(DIRECTORY_SEPARATOR, $path), 'strlen');
134
        $absolutes = [];
135
        foreach ($parts as $part) {
136
            if ('.' == $part) {
137
                continue;
138
            }
139
            if ('..' == $part) {
140
                array_pop($absolutes);
141
            } else {
142
                $absolutes[] = $part;
143
            }
144
        }
145
146
        return implode(DIRECTORY_SEPARATOR, $absolutes);
147
    }
148
149
    /**
150
     * Get the possible output file names for a source file.
151
     *
152
     * @param Config $config
153
     * @param string $part
154
     * @return string[]
155
     */
156 16
    public static function getFilenames(Config $config, $part)
157
    {
158 16
        $extensions = implode('|', array_map('preg_quote', $config['valid_content_extensions'])) . '|html';
159
160 16
        $raw = preg_replace('/(.*)?\\.(' . $extensions . ')$/', '$1', $part);
161 16
        $raw = Builder::removeSortingInformations($raw);
162
163 16
        return ["$raw.html", $raw];
164
    }
165
166
    /**
167
     * Locate a file in the tree. Returns the file if found or false
168
     *
169
     * @param Directory $tree
170
     * @param string $request
171
     * @return Tree\Content|Tree\Raw|false
172
     */
173 17
    public static function getFile($tree, $request)
174
    {
175 17
        $request = explode('/', $request);
176 17
        foreach ($request as $node) {
177
            // If the element we're in currently is not a
178
            // directory, we failed to find the requested file
179 17
            if (!$tree instanceof Directory) {
180 1
                return false;
181
            }
182
183
            // Some relative paths may start with ./
184 17
            if ($node == '.') {
185 3
                continue;
186
            }
187
188 17
            if ($node == '..') {
189 2
                $tree = $tree->getParent();
190 2
                continue;
191
            }
192
193
            // if the node exists in the current request tree,
194
            // change the $tree variable to reference the new
195
            // node and proceed to the next url part
196 17
            if (isset($tree->getEntries()[$node])) {
197 17
                $tree = $tree->getEntries()[$node];
198 17
                continue;
199
            }
200
201
            // We try a second time by decoding the url
202 12
            $node = DauxHelper::slug(urldecode($node));
203 12
            if (isset($tree->getEntries()[$node])) {
204
                $tree = $tree->getEntries()[$node];
205
                continue;
206
            }
207
208
            // if the node doesn't exist, we can try
209
            // two variants of the requested file:
210
            // with and w/o the .html extension
211 12
            foreach (static::getFilenames($tree->getConfig(), $node) as $filename) {
212 12
                if (isset($tree->getEntries()[$filename])) {
213 12
                    $tree = $tree->getEntries()[$filename];
214 12
                    continue 2;
215
                }
216
            }
217
218
            // At this stage, we're in a directory, but no
219
            // sub-item matches, so the current node must
220
            // be an index page or we failed
221 3
            if ($node !== 'index' && $node !== 'index.html') {
222 3
                return false;
223
            }
224
225
            return $tree->getIndexPage();
226
        }
227
228
        // If the entry we found is not a directory, we're done
229 17
        if (!$tree instanceof Directory) {
230 17
            return $tree;
231
        }
232
233
        if ($index = $tree->getIndexPage()) {
234
            return $index;
235
        }
236
237
        return false;
238
    }
239
240
    /**
241
     * Generate a URL friendly "slug" from a given string.
242
     *
243
     * Taken from Stringy
244
     *
245
     * @param  string $title
246
     * @return string
247
     */
248 28
    public static function slug($title)
249
    {
250
        // Convert to ASCII
251 28
        foreach (static::charsArray() as $key => $value) {
252 28
            $title = str_replace($value, $key, $title);
253
        }
254
255
        // Remove unsupported characters
256 28
        $title = preg_replace('/[^\x20-\x7E]/u', '', $title);
257
258 28
        $separator = '_';
259
        // Convert all dashes into underscores
260 28
        $title = preg_replace('![' . preg_quote('-') . ']+!u', $separator, $title);
261
262
        // Remove all characters that are not valid in a URL: 
263
        // $-_.+!*'(), separator, letters, numbers, or whitespace.
264 28
        $title = preg_replace('![^-' . preg_quote($separator) . '\!\'\(\),\.\+\*\$\pL\pN\s]+!u', '', $title);
265
266
        // Replace all separator characters and whitespace by a single separator
267 28
        $title = preg_replace('![' . preg_quote($separator) . '\s]+!u', $separator, $title);
268
269 28
        return trim($title, $separator);
270
    }
271
272
    /**
273
     * Returns the replacements for the slug() method.
274
     *
275
     * Taken from Stringy
276
     *
277
     * @return array An array of replacements.
278
     */
279 28
    public static function charsArray()
280
    {
281 28
        static $charsArray;
282
283 28
        if (isset($charsArray)) {
284 28
            return $charsArray;
285
        }
286
287
        return $charsArray = [
288
            'a'    => [
289 1
                'à', 'á', 'ả', 'ã', 'ạ', 'ă', 'ắ', 'ằ', 'ẳ', 'ẵ',
290
                'ặ', 'â', 'ấ', 'ầ', 'ẩ', 'ẫ', 'ậ', 'ä', 'ā', 'ą',
291
                'å', 'α', 'ά', 'ἀ', 'ἁ', 'ἂ', 'ἃ', 'ἄ', 'ἅ', 'ἆ',
292
                'ἇ', 'ᾀ', 'ᾁ', 'ᾂ', 'ᾃ', 'ᾄ', 'ᾅ', 'ᾆ', 'ᾇ', 'ὰ',
293
                'ά', 'ᾰ', 'ᾱ', 'ᾲ', 'ᾳ', 'ᾴ', 'ᾶ', 'ᾷ', 'а', 'أ', ],
294
            'b'    => ['б', 'β', 'Ъ', 'Ь', 'ب'],
295
            'c'    => ['ç', 'ć', 'č', 'ĉ', 'ċ'],
296
            'd'    => ['ď', 'ð', 'đ', 'ƌ', 'ȡ', 'ɖ', 'ɗ', 'ᵭ', 'ᶁ', 'ᶑ',
297
                'д', 'δ', 'د', 'ض', ],
298
            'e'    => ['é', 'è', 'ẻ', 'ẽ', 'ẹ', 'ê', 'ế', 'ề', 'ể', 'ễ',
299
                'ệ', 'ë', 'ē', 'ę', 'ě', 'ĕ', 'ė', 'ε', 'έ', 'ἐ',
300
                'ἑ', 'ἒ', 'ἓ', 'ἔ', 'ἕ', 'ὲ', 'έ', 'е', 'ё', 'э',
301
                'є', 'ə', ],
302
            'f'    => ['ф', 'φ', 'ف'],
303
            'g'    => ['ĝ', 'ğ', 'ġ', 'ģ', 'г', 'ґ', 'γ', 'ج'],
304
            'h'    => ['ĥ', 'ħ', 'η', 'ή', 'ح', 'ه'],
305
            'i'    => ['í', 'ì', 'ỉ', 'ĩ', 'ị', 'î', 'ï', 'ī', 'ĭ', 'į',
306
                'ı', 'ι', 'ί', 'ϊ', 'ΐ', 'ἰ', 'ἱ', 'ἲ', 'ἳ', 'ἴ',
307
                'ἵ', 'ἶ', 'ἷ', 'ὶ', 'ί', 'ῐ', 'ῑ', 'ῒ', 'ΐ', 'ῖ',
308
                'ῗ', 'і', 'ї', 'и', ],
309
            'j'    => ['ĵ', 'ј', 'Ј'],
310
            'k'    => ['ķ', 'ĸ', 'к', 'κ', 'Ķ', 'ق', 'ك'],
311
            'l'    => ['ł', 'ľ', 'ĺ', 'ļ', 'ŀ', 'л', 'λ', 'ل'],
312
            'm'    => ['м', 'μ', 'م'],
313
            'n'    => ['ñ', 'ń', 'ň', 'ņ', 'ʼn', 'ŋ', 'ν', 'н', 'ن'],
314
            'o'    => ['ó', 'ò', 'ỏ', 'õ', 'ọ', 'ô', 'ố', 'ồ', 'ổ', 'ỗ',
315
                'ộ', 'ơ', 'ớ', 'ờ', 'ở', 'ỡ', 'ợ', 'ø', 'ō', 'ő',
316
                'ŏ', 'ο', 'ὀ', 'ὁ', 'ὂ', 'ὃ', 'ὄ', 'ὅ', 'ὸ', 'ό',
317
                'ö', 'о', 'و', 'θ', ],
318
            'p'    => ['п', 'π'],
319
            'r'    => ['ŕ', 'ř', 'ŗ', 'р', 'ρ', 'ر'],
320
            's'    => ['ś', 'š', 'ş', 'с', 'σ', 'ș', 'ς', 'س', 'ص'],
321
            't'    => ['ť', 'ţ', 'т', 'τ', 'ț', 'ت', 'ط'],
322
            'u'    => ['ú', 'ù', 'ủ', 'ũ', 'ụ', 'ư', 'ứ', 'ừ', 'ử', 'ữ',
323
                'ự', 'ü', 'û', 'ū', 'ů', 'ű', 'ŭ', 'ų', 'µ', 'у', ],
324
            'v'    => ['в'],
325
            'w'    => ['ŵ', 'ω', 'ώ'],
326
            'x'    => ['χ'],
327
            'y'    => ['ý', 'ỳ', 'ỷ', 'ỹ', 'ỵ', 'ÿ', 'ŷ', 'й', 'ы', 'υ',
328
                'ϋ', 'ύ', 'ΰ', 'ي', ],
329
            'z'    => ['ź', 'ž', 'ż', 'з', 'ζ', 'ز'],
330
            'aa'   => ['ع'],
331
            'ae'   => ['æ'],
332
            'ch'   => ['ч'],
333
            'dj'   => ['ђ', 'đ'],
334
            'dz'   => ['џ'],
335
            'gh'   => ['غ'],
336
            'kh'   => ['х', 'خ'],
337
            'lj'   => ['љ'],
338
            'nj'   => ['њ'],
339
            'oe'   => ['œ'],
340
            'ps'   => ['ψ'],
341
            'sh'   => ['ш'],
342
            'shch' => ['щ'],
343
            'ss'   => ['ß'],
344
            'th'   => ['þ', 'ث', 'ذ', 'ظ'],
345
            'ts'   => ['ц'],
346
            'ya'   => ['я'],
347
            'yu'   => ['ю'],
348
            'zh'   => ['ж'],
349
            '(c)'  => ['©'],
350
            'A'    => ['Á', 'À', 'Ả', 'Ã', 'Ạ', 'Ă', 'Ắ', 'Ằ', 'Ẳ', 'Ẵ',
351
                'Ặ', 'Â', 'Ấ', 'Ầ', 'Ẩ', 'Ẫ', 'Ậ', 'Ä', 'Å', 'Ā',
352
                'Ą', 'Α', 'Ά', 'Ἀ', 'Ἁ', 'Ἂ', 'Ἃ', 'Ἄ', 'Ἅ', 'Ἆ',
353
                'Ἇ', 'ᾈ', 'ᾉ', 'ᾊ', 'ᾋ', 'ᾌ', 'ᾍ', 'ᾎ', 'ᾏ', 'Ᾰ',
354
                'Ᾱ', 'Ὰ', 'Ά', 'ᾼ', 'А', ],
355
            'B'    => ['Б', 'Β'],
356
            'C'    => ['Ç', 'Ć', 'Č', 'Ĉ', 'Ċ'],
357
            'D'    => ['Ď', 'Ð', 'Đ', 'Ɖ', 'Ɗ', 'Ƌ', 'ᴅ', 'ᴆ', 'Д', 'Δ'],
358
            'E'    => ['É', 'È', 'Ẻ', 'Ẽ', 'Ẹ', 'Ê', 'Ế', 'Ề', 'Ể', 'Ễ',
359
                'Ệ', 'Ë', 'Ē', 'Ę', 'Ě', 'Ĕ', 'Ė', 'Ε', 'Έ', 'Ἐ',
360
                'Ἑ', 'Ἒ', 'Ἓ', 'Ἔ', 'Ἕ', 'Έ', 'Ὲ', 'Е', 'Ё', 'Э',
361
                'Є', 'Ə', ],
362
            'F'    => ['Ф', 'Φ'],
363
            'G'    => ['Ğ', 'Ġ', 'Ģ', 'Г', 'Ґ', 'Γ'],
364
            'H'    => ['Η', 'Ή'],
365
            'I'    => ['Í', 'Ì', 'Ỉ', 'Ĩ', 'Ị', 'Î', 'Ï', 'Ī', 'Ĭ', 'Į',
366
                'İ', 'Ι', 'Ί', 'Ϊ', 'Ἰ', 'Ἱ', 'Ἳ', 'Ἴ', 'Ἵ', 'Ἶ',
367
                'Ἷ', 'Ῐ', 'Ῑ', 'Ὶ', 'Ί', 'И', 'І', 'Ї', ],
368
            'K'    => ['К', 'Κ'],
369
            'L'    => ['Ĺ', 'Ł', 'Л', 'Λ', 'Ļ'],
370
            'M'    => ['М', 'Μ'],
371
            'N'    => ['Ń', 'Ñ', 'Ň', 'Ņ', 'Ŋ', 'Н', 'Ν'],
372
            'O'    => ['Ó', 'Ò', 'Ỏ', 'Õ', 'Ọ', 'Ô', 'Ố', 'Ồ', 'Ổ', 'Ỗ',
373
                'Ộ', 'Ơ', 'Ớ', 'Ờ', 'Ở', 'Ỡ', 'Ợ', 'Ö', 'Ø', 'Ō',
374
                'Ő', 'Ŏ', 'Ο', 'Ό', 'Ὀ', 'Ὁ', 'Ὂ', 'Ὃ', 'Ὄ', 'Ὅ',
375
                'Ὸ', 'Ό', 'О', 'Θ', 'Ө', ],
376
            'P'    => ['П', 'Π'],
377
            'R'    => ['Ř', 'Ŕ', 'Р', 'Ρ'],
378
            'S'    => ['Ş', 'Ŝ', 'Ș', 'Š', 'Ś', 'С', 'Σ'],
379
            'T'    => ['Ť', 'Ţ', 'Ŧ', 'Ț', 'Т', 'Τ'],
380
            'U'    => ['Ú', 'Ù', 'Ủ', 'Ũ', 'Ụ', 'Ư', 'Ứ', 'Ừ', 'Ử', 'Ữ',
381
                'Ự', 'Û', 'Ü', 'Ū', 'Ů', 'Ű', 'Ŭ', 'Ų', 'У', ],
382
            'V'    => ['В'],
383
            'W'    => ['Ω', 'Ώ'],
384
            'X'    => ['Χ'],
385
            'Y'    => ['Ý', 'Ỳ', 'Ỷ', 'Ỹ', 'Ỵ', 'Ÿ', 'Ῠ', 'Ῡ', 'Ὺ', 'Ύ',
386
                'Ы', 'Й', 'Υ', 'Ϋ', ],
387
            'Z'    => ['Ź', 'Ž', 'Ż', 'З', 'Ζ'],
388
            'AE'   => ['Æ'],
389
            'CH'   => ['Ч'],
390
            'DJ'   => ['Ђ'],
391
            'DZ'   => ['Џ'],
392
            'KH'   => ['Х'],
393
            'LJ'   => ['Љ'],
394
            'NJ'   => ['Њ'],
395
            'PS'   => ['Ψ'],
396
            'SH'   => ['Ш'],
397
            'SHCH' => ['Щ'],
398
            'SS'   => ['ẞ'],
399
            'TH'   => ['Þ'],
400
            'TS'   => ['Ц'],
401
            'YA'   => ['Я'],
402
            'YU'   => ['Ю'],
403
            'ZH'   => ['Ж'],
404
            ' '    => ["\xC2\xA0", "\xE2\x80\x80", "\xE2\x80\x81",
405
                "\xE2\x80\x82", "\xE2\x80\x83", "\xE2\x80\x84",
406
                "\xE2\x80\x85", "\xE2\x80\x86", "\xE2\x80\x87",
407
                "\xE2\x80\x88", "\xE2\x80\x89", "\xE2\x80\x8A",
408
                "\xE2\x80\xAF", "\xE2\x81\x9F", "\xE3\x80\x80", ],
409
        ];
410
    }
411
412
    /**
413
     * @param string $from
414
     * @param string $to
415
     * @return string
416
     */
417 12
    public static function getRelativePath($from, $to)
418
    {
419
        // some compatibility fixes for Windows paths
420 12
        $from = is_dir($from) ? rtrim($from, '\/') . '/' : $from;
421 12
        $to = is_dir($to) ? rtrim($to, '\/') . '/' : $to;
422 12
        $from = str_replace('\\', '/', $from);
423 12
        $to = str_replace('\\', '/', $to);
424
425 12
        $from = explode('/', $from);
426 12
        $to = explode('/', $to);
427 12
        $relPath = $to;
428
429 12
        foreach ($from as $depth => $dir) {
430
            // find first non-matching dir
431 12
            if ($dir === $to[$depth]) {
432
                // ignore this directory
433 8
                array_shift($relPath);
434
            } else {
435
                // get number of remaining dirs to $from
436 12
                $remaining = count($from) - $depth;
437 12
                if ($remaining > 1) {
438
                    // add traversals up to first matching dir
439 4
                    $padLength = (count($relPath) + $remaining - 1) * -1;
440 4
                    $relPath = array_pad($relPath, $padLength, '..');
441 4
                    break;
442
                } else {
443
                    //$relPath[0] = './' . $relPath[0];
444
                }
445
            }
446
        }
447
448 12
        return implode('/', $relPath);
449
    }
450
451 1
    public static function isAbsolutePath($path)
452
    {
453 1
        if (!is_string($path)) {
454
            $mess = sprintf('String expected but was given %s', gettype($path));
455
            throw new \InvalidArgumentException($mess);
456
        }
457
458 1
        if (!ctype_print($path)) {
459
            $mess = 'Path can NOT have non-printable characters or be empty';
460
            throw new \DomainException($mess);
461
        }
462
463
        // Optional wrapper(s).
464 1
        $regExp = '%^(?<wrappers>(?:[[:print:]]{2,}://)*)';
465
466
        // Optional root prefix.
467 1
        $regExp .= '(?<root>(?:[[:alpha:]]:/|/)?)';
468
469
        // Actual path.
470 1
        $regExp .= '(?<path>(?:[[:print:]]*))$%';
471
472 1
        $parts = [];
473 1
        if (!preg_match($regExp, $path, $parts)) {
474
            $mess = sprintf('Path is NOT valid, was given %s', $path);
475
            throw new \DomainException($mess);
476
        }
477
478 1
        return '' !== $parts['root'];
479
    }
480
481 1
    public static function getAbsolutePath($path) {
482 1
        if (DauxHelper::isAbsolutePath($path)) {
483
            return $path;
484
        }
485
486 1
        return getcwd() . '/' . $path;
487
    }
488
489
    /**
490
     * @param string|null $path
491
     * @param string $basedir
492
     * @param string $var The constant name to check
493
     * @param "dir"|"file" $type
0 ignored issues
show
Documentation Bug introduced by Stéphane Goetz
The doc comment "dir"|"file" at position 0 could not be parsed: Unknown type name '"dir"' at position 0 in "dir"|"file".
Loading history...
494
     * @return false|null|string
495
     */
496 1
    public static function findLocation($path, $basedir, $var, $type) {
497
        // VFS, used only in tests
498 1
        if (substr($path, 0, 6) == "vfs://") {
499 1
            return $path;
500
        }
501
502
        // When running through `daux --serve` we set an environment variable to know where we started from
503 1
        $env = getenv($var);
504 1
        if ($env && DauxHelper::is($env, $type)) {
505
            return $env;
506
        }
507
508
        // If Path is explicitly null, it's useless to go further
509 1
        if ($path == null) {
510 1
            return null;
511
        }
512
513
        // Check if it's relative to the current directory or an absolute path
514 1
        if (DauxHelper::is($path, $type)) {
515 1
            return DauxHelper::getAbsolutePath($path);
516
        }
517
518
        // Check if it exists relative to Daux's root
519
        $newPath = $basedir . DIRECTORY_SEPARATOR . $path;
520
        if (DauxHelper::is($newPath, $type)) {
521
            return $newPath;
522
        }
523
524
        return false;
525
    }
526
527 1
    public static function is($path, $type) {
528 1
        return ($type == 'dir') ? is_dir($path) : file_exists($path);
529
    }
530
531
    /**
532
     * @param Config $config
533
     * @param string $url
534
     * @return Entry
0 ignored issues
show
Bug introduced by Stéphane Goetz
The type Todaymade\Daux\Entry was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
535
     * @throws LinkNotFoundException
536
     */
537 12
    public static function resolveInternalFile($config, $url)
538
    {
539 12
        $triedAbsolute = false;
540
541
        // Legacy absolute paths could start with
542
        // "!" In this case we will try to find
543
        // the file starting at the root
544 12
        if ($url[0] == '!' || $url[0] == '/') {
545 4
            $url = ltrim($url, '!/');
546
547 4
            if ($file = DauxHelper::getFile($config['tree'], $url)) {
548 4
                return $file;
0 ignored issues
show
Bug Best Practice introduced by Stéphane Goetz
The expression return $file returns the type Todaymade\Daux\Tree\Cont...Todaymade\Daux\Tree\Raw which is incompatible with the documented return type Todaymade\Daux\Entry.
Loading history...
549
            }
550
551 1
            $triedAbsolute = true;
552
        }
553
554
        // Seems it's not an absolute path or not found,
555
        // so we'll continue with the current folder
556 9
        if ($file = DauxHelper::getFile($config->getCurrentPage()->getParent(), $url)) {
557 8
            return $file;
0 ignored issues
show
Bug Best Practice introduced by Stéphane Goetz
The expression return $file returns the type Todaymade\Daux\Tree\Cont...Todaymade\Daux\Tree\Raw which is incompatible with the documented return type Todaymade\Daux\Entry.
Loading history...
558
        }
559
560
        // If we didn't already try it, we'll
561
        // do a pass starting at the root
562 3
        if (!$triedAbsolute && $file = DauxHelper::getFile($config['tree'], $url)) {
563
            return $file;
0 ignored issues
show
Bug Best Practice introduced by Stéphane Goetz
The expression return $file returns the type Todaymade\Daux\Tree\Cont...Todaymade\Daux\Tree\Raw which is incompatible with the documented return type Todaymade\Daux\Entry.
Loading history...
564
        }
565
566 3
        throw new LinkNotFoundException("Could not locate file '$url'");
567
    }
568
569 19
    public static function isValidUrl($url)
570
    {
571 19
        return !empty($url) && $url[0] != '#';
572
    }
573
574 14
    public static function isExternalUrl($url)
575
    {
576 14
        return preg_match('#^(?:[a-z]+:)?//|^mailto:#', $url);
577
    }
578
}
579