-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDefaultUrlGenerator.php
More file actions
111 lines (86 loc) · 3.25 KB
/
DefaultUrlGenerator.php
File metadata and controls
111 lines (86 loc) · 3.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<?php
declare(strict_types=1);
/**
* You may not change or alter any portion of this comment or credits
* of supporting developers from this source code or any supporting source code
* which is considered copyrighted (c) material of the original comment or credit authors.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* @copyright 2000-2026 XOOPS Project (https://xoops.org/)
* @license GNU GPL 2.0 or later (https://www.gnu.org/licenses/gpl-2.0.html)
* @author XOOPS Development Team
*/
namespace Xoops\Helpers\Provider;
use Xoops\Helpers\Contracts\UrlGeneratorInterface;
/**
* Default URL generator using XOOPS constants.
*
* Uses XOOPS_URL as the base URL. Falls back to server
* variables if XOOPS_URL is not defined.
*/
class DefaultUrlGenerator implements UrlGeneratorInterface
{
public function generate(string $path = '', array $query = [], bool $secure = false): string
{
$base = $this->getBaseUrl($secure);
$url = rtrim($base, '/');
if ($path !== '') {
$url .= '/' . ltrim($path, '/');
}
if ($query !== []) {
$url .= '?' . http_build_query($query, '', '&', PHP_QUERY_RFC3986);
}
return $url;
}
public function asset(string $path, bool $secure = false): string
{
return $this->generate($path, [], $secure);
}
public function module(string $dirname, string $path = '', array $query = []): string
{
$modulePath = 'modules/' . $dirname;
if ($path !== '') {
$modulePath .= '/' . ltrim($path, '/');
}
return $this->generate($modulePath, $query);
}
public function theme(string $name, string $path = ''): string
{
$themePath = 'themes/' . $name;
if ($path !== '') {
$themePath .= '/' . ltrim($path, '/');
}
return $this->generate($themePath);
}
private function getBaseUrl(bool $secure): string
{
if (defined('XOOPS_URL')) {
$url = (string) XOOPS_URL;
if ($secure) {
/** @var array<string, string|int>|false $parts */
$parts = parse_url($url);
if (is_array($parts) && isset($parts['host']) && is_string($parts['host'])) {
$port = isset($parts['port']) ? ':' . (int) $parts['port'] : '';
$path = isset($parts['path']) && is_string($parts['path']) ? $parts['path'] : '';
return 'https://' . $parts['host'] . $port . $path;
}
}
return $url;
}
$scheme = $secure
? 'https'
: ((($_SERVER['HTTPS'] ?? 'off') !== 'off') ? 'https' : 'http');
// Validate host to prevent host-header injection
$host = trim((string) ($_SERVER['HTTP_HOST'] ?? 'localhost'));
if (!preg_match('/^[A-Za-z0-9.\-]+(?::(\d{1,5}))?$/', $host, $matches)) {
$host = 'localhost';
} elseif (isset($matches[1]) && ((int) $matches[1] < 1 || (int) $matches[1] > 65535)) {
$host = 'localhost';
}
return $scheme . '://' . $host;
}
}