Skip to content

Commit 408a7d1

Browse files
committed
refactor: URL helper site_url(), base_url(), current_url(), uri_string()
1 parent 17d82ad commit 408a7d1

File tree

5 files changed

+208
-201
lines changed

5 files changed

+208
-201
lines changed

system/HTTP/SiteURI.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,4 +363,87 @@ protected function applyParts(array $parts)
363363
$this->password = $parts['pass'];
364364
}
365365
}
366+
367+
/**
368+
* For baser_url() helper.
369+
*
370+
* @param array|string $relativePath URI string or array of URI segments
371+
* @param string|null $scheme URI scheme. E.g., http, ftp
372+
*/
373+
public function baseUrl($relativePath = '', ?string $scheme = null): string
374+
{
375+
$relativePath = $this->stringifyRelativePath($relativePath);
376+
377+
$config = clone config(App::class);
378+
$config->indexPage = '';
379+
380+
$host = $this->getHost();
381+
382+
$uri = new self($config, $relativePath, $host, $scheme);
383+
384+
return URI::createURIString(
385+
$uri->getScheme(),
386+
$uri->getAuthority(),
387+
$this->adjustPathTrailingSlash($uri, $relativePath),
388+
$uri->getQuery(),
389+
$uri->getFragment()
390+
);
391+
}
392+
393+
/**
394+
* @param array|string $relativePath URI string or array of URI segments
395+
*/
396+
private function stringifyRelativePath($relativePath): string
397+
{
398+
if (is_array($relativePath)) {
399+
$relativePath = implode('/', $relativePath);
400+
}
401+
402+
return $relativePath;
403+
}
404+
405+
/**
406+
* For site_url() helper.
407+
*
408+
* @param array|string $relativePath URI string or array of URI segments
409+
* @param string|null $scheme URI scheme. E.g., http, ftp
410+
* @param App|null $config Alternate configuration to use
411+
*/
412+
public function siteUrl($relativePath = '', ?string $scheme = null, ?App $config = null): string
413+
{
414+
$relativePath = $this->stringifyRelativePath($relativePath);
415+
416+
// Check current host.
417+
$host = $config === null ? $this->getHost() : null;
418+
419+
$config ??= config(App::class);
420+
421+
$uri = new self($config, $relativePath, $host, $scheme);
422+
423+
// Adjust path
424+
$path = $this->adjustPathTrailingSlash($uri, $relativePath);
425+
if ($config->indexPage !== '' && $relativePath === '') {
426+
$path = rtrim($path, '/');
427+
}
428+
429+
return URI::createURIString(
430+
$uri->getScheme(),
431+
$uri->getAuthority(),
432+
$path,
433+
$uri->getQuery(),
434+
$uri->getFragment()
435+
);
436+
}
437+
438+
private function adjustPathTrailingSlash(self $uri, string $relativePath): string
439+
{
440+
$parts = parse_url($this->getBaseURL() . $relativePath);
441+
$path = $parts['path'] ?? '';
442+
443+
if (substr($path, -1) === '/' && substr($uri->getPath(), -1) !== '/') {
444+
return $uri->getPath() . '/';
445+
}
446+
447+
return $uri->getPath();
448+
}
366449
}

system/Helpers/url_helper.php

Lines changed: 17 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -10,101 +10,15 @@
1010
*/
1111

1212
use CodeIgniter\HTTP\CLIRequest;
13-
use CodeIgniter\HTTP\Exceptions\HTTPException;
1413
use CodeIgniter\HTTP\IncomingRequest;
14+
use CodeIgniter\HTTP\SiteURI;
1515
use CodeIgniter\HTTP\URI;
1616
use CodeIgniter\Router\Exceptions\RouterException;
1717
use Config\App;
1818
use Config\Services;
1919

2020
// CodeIgniter URL Helpers
2121

22-
if (! function_exists('_get_uri')) {
23-
/**
24-
* Used by the other URL functions to build a framework-specific URI
25-
* based on $request->getUri()->getBaseURL() and the App config.
26-
*
27-
* @internal Outside the framework this should not be used directly.
28-
*
29-
* @param array|string $relativePath URI string or array of URI segments.
30-
* May include queries or fragments.
31-
* @param App|null $config Alternative Config to use
32-
*
33-
* @throws HTTPException For invalid paths.
34-
* @throws InvalidArgumentException For invalid config.
35-
*/
36-
function _get_uri($relativePath = '', ?App $config = null): URI
37-
{
38-
$appConfig = null;
39-
if ($config === null) {
40-
/** @var App $appConfig */
41-
$appConfig = config('App');
42-
43-
if ($appConfig->baseURL === '') {
44-
throw new InvalidArgumentException(
45-
'_get_uri() requires a valid baseURL.'
46-
);
47-
}
48-
} elseif ($config->baseURL === '') {
49-
throw new InvalidArgumentException(
50-
'_get_uri() requires a valid baseURL.'
51-
);
52-
}
53-
54-
// Convert array of segments to a string
55-
if (is_array($relativePath)) {
56-
$relativePath = implode('/', $relativePath);
57-
}
58-
59-
// If a full URI was passed then convert it
60-
if (strpos($relativePath, '://') !== false) {
61-
$full = new URI($relativePath);
62-
$relativePath = URI::createURIString(
63-
null,
64-
null,
65-
$full->getPath(),
66-
$full->getQuery(),
67-
$full->getFragment()
68-
);
69-
}
70-
71-
$relativePath = URI::removeDotSegments($relativePath);
72-
73-
$request = Services::request();
74-
75-
if ($config === null) {
76-
$baseURL = $request instanceof CLIRequest
77-
? rtrim($appConfig->baseURL, '/ ') . '/'
78-
// Use the current baseURL for multiple domain support
79-
: $request->getUri()->getBaseURL();
80-
81-
$config = $appConfig;
82-
} else {
83-
$baseURL = rtrim($config->baseURL, '/ ') . '/';
84-
}
85-
86-
// Check for an index page
87-
$indexPage = '';
88-
if ($config->indexPage !== '') {
89-
$indexPage = $config->indexPage;
90-
91-
// Check if we need a separator
92-
if ($relativePath !== '' && $relativePath[0] !== '/' && $relativePath[0] !== '?') {
93-
$indexPage .= '/';
94-
}
95-
}
96-
97-
$uri = new URI($baseURL . $indexPage . $relativePath);
98-
99-
// Check if the baseURL scheme needs to be coerced into its secure version
100-
if ($config->forceGlobalSecureRequests && $uri->getScheme() === 'http') {
101-
$uri->setScheme('https');
102-
}
103-
104-
return $uri;
105-
}
106-
}
107-
10822
if (! function_exists('site_url')) {
10923
/**
11024
* Returns a site URL as defined by the App config.
@@ -115,15 +29,11 @@ function _get_uri($relativePath = '', ?App $config = null): URI
11529
*/
11630
function site_url($relativePath = '', ?string $scheme = null, ?App $config = null): string
11731
{
118-
$uri = _get_uri($relativePath, $config);
119-
120-
return URI::createURIString(
121-
$scheme ?? $uri->getScheme(),
122-
$uri->getAuthority(),
123-
$uri->getPath(),
124-
$uri->getQuery(),
125-
$uri->getFragment()
126-
);
32+
$currentURI = Services::request()->getUri();
33+
34+
assert($currentURI instanceof SiteURI);
35+
36+
return $currentURI->siteUrl($relativePath, $scheme, $config);
12737
}
12838
}
12939

@@ -137,18 +47,11 @@ function site_url($relativePath = '', ?string $scheme = null, ?App $config = nul
13747
*/
13848
function base_url($relativePath = '', ?string $scheme = null): string
13949
{
140-
/** @var App $config */
141-
$config = clone config('App');
142-
143-
// Use the current baseURL for multiple domain support
144-
$request = Services::request();
145-
$config->baseURL = $request instanceof CLIRequest
146-
? rtrim($config->baseURL, '/ ') . '/'
147-
: $request->getUri()->getBaseURL();
50+
$currentURI = Services::request()->getUri();
14851

149-
$config->indexPage = '';
52+
assert($currentURI instanceof SiteURI);
15053

151-
return site_url($relativePath, $scheme, $config);
54+
return $currentURI->baseUrl($relativePath, $scheme);
15255
}
15356
}
15457

@@ -166,18 +69,7 @@ function current_url(bool $returnObject = false, ?IncomingRequest $request = nul
16669
{
16770
$request ??= Services::request();
16871
/** @var CLIRequest|IncomingRequest $request */
169-
$routePath = $request->getPath();
170-
$currentURI = $request->getUri();
171-
172-
// Append queries and fragments
173-
if ($query = $currentURI->getQuery()) {
174-
$query = '?' . $query;
175-
}
176-
if ($fragment = $currentURI->getFragment()) {
177-
$fragment = '#' . $fragment;
178-
}
179-
180-
$uri = _get_uri($routePath . $query . $fragment);
72+
$uri = $request->getUri();
18173

18274
return $returnObject ? $uri : URI::createURIString($uri->getScheme(), $uri->getAuthority(), $uri->getPath());
18375
}
@@ -213,10 +105,13 @@ function previous_url(bool $returnObject = false)
213105
*/
214106
function uri_string(): string
215107
{
216-
// The value of Services::request()->getUri()->getPath() is overridden
217-
// by IncomingRequest constructor. If we use it here, the current tests
218-
// in CurrentUrlTest will fail.
219-
return ltrim(Services::request()->getPath(), '/');
108+
// The value of Services::request()->getUri()->getPath() returns
109+
// full URI path.
110+
$uri = Services::request()->getUri();
111+
112+
$path = $uri instanceof SiteURI ? $uri->getRoutePath() : $uri->getPath();
113+
114+
return ltrim($path, '/');
220115
}
221116
}
222117

0 commit comments

Comments
 (0)