Skip to content

Commit

Permalink
Merge pull request #7282 from kenjis/refactor-URI-creation
Browse files Browse the repository at this point in the history
rework: URI creation and URL helper
  • Loading branch information
kenjis authored Aug 16, 2023
2 parents 3ad9d4a + c6f3d57 commit d73b455
Show file tree
Hide file tree
Showing 38 changed files with 706 additions and 461 deletions.
4 changes: 4 additions & 0 deletions system/Config/BaseService.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
use CodeIgniter\HTTP\Request;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\SiteURIFactory;
use CodeIgniter\HTTP\URI;
use CodeIgniter\Images\Handlers\BaseHandler;
use CodeIgniter\Language\Language;
Expand All @@ -47,6 +48,7 @@
use CodeIgniter\Router\Router;
use CodeIgniter\Security\Security;
use CodeIgniter\Session\Session;
use CodeIgniter\Superglobals;
use CodeIgniter\Throttle\Throttler;
use CodeIgniter\Typography\Typography;
use CodeIgniter\Validation\ValidationInterface;
Expand Down Expand Up @@ -123,6 +125,8 @@
* @method static RouteCollection routes($getShared = true)
* @method static Security security(App $config = null, $getShared = true)
* @method static Session session(App $config = null, $getShared = true)
* @method static SiteURIFactory siteurifactory(App $config = null, Superglobals $superglobals = null, $getShared = true)
* @method static Superglobals superglobals(array $server = null, array $get = null, bool $getShared = true)
* @method static Throttler throttler($getShared = true)
* @method static Timer timer($getShared = true)
* @method static Toolbar toolbar(ConfigToolbar $config = null, $getShared = true)
Expand Down
48 changes: 47 additions & 1 deletion system/Config/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\Response;
use CodeIgniter\HTTP\ResponseInterface;
use CodeIgniter\HTTP\SiteURIFactory;
use CodeIgniter\HTTP\URI;
use CodeIgniter\HTTP\UserAgent;
use CodeIgniter\Images\Handlers\BaseHandler;
Expand All @@ -52,6 +53,7 @@
use CodeIgniter\Session\Handlers\Database\PostgreHandler;
use CodeIgniter\Session\Handlers\DatabaseHandler;
use CodeIgniter\Session\Session;
use CodeIgniter\Superglobals;
use CodeIgniter\Throttle\Throttler;
use CodeIgniter\Typography\Typography;
use CodeIgniter\Validation\Validation;
Expand Down Expand Up @@ -693,6 +695,43 @@ public static function session(?SessionConfig $config = null, bool $getShared =
return $session;
}

/**
* The Factory for SiteURI.
*
* @return SiteURIFactory
*/
public static function siteurifactory(
?App $config = null,
?Superglobals $superglobals = null,
bool $getShared = true
) {
if ($getShared) {
return static::getSharedInstance('siteurifactory', $config, $superglobals);
}

$config ??= config('App');
$superglobals ??= AppServices::superglobals();

return new SiteURIFactory($config, $superglobals);
}

/**
* Superglobals.
*
* @return Superglobals
*/
public static function superglobals(
?array $server = null,
?array $get = null,
bool $getShared = true
) {
if ($getShared) {
return static::getSharedInstance('superglobals', $server, $get);
}

return new Superglobals($server, $get);
}

/**
* The Throttler class provides a simple method for implementing
* rate limiting in your applications.
Expand Down Expand Up @@ -744,14 +783,21 @@ public static function toolbar(?ToolbarConfig $config = null, bool $getShared =
*
* @param string $uri
*
* @return URI
* @return URI The current URI if $uri is null.
*/
public static function uri(?string $uri = null, bool $getShared = true)
{
if ($getShared) {
return static::getSharedInstance('uri', $uri);
}

if ($uri === null) {
$appConfig = config(App::class);
$factory = AppServices::siteurifactory($appConfig, AppServices::superglobals());

return $factory->createFromGlobals();
}

return new URI($uri);
}

Expand Down
85 changes: 12 additions & 73 deletions system/HTTP/IncomingRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,12 @@ public function __construct($config, ?URI $uri = null, $body = 'php://input', ?U

parent::__construct($config);

$this->detectURI($config->uriProtocol, $config->baseURL);
if ($uri instanceof SiteURI) {
$this->setPath($uri->getRoutePath());
} else {
$this->setPath($uri->getPath());
}

$this->detectLocale($config);
}

Expand Down Expand Up @@ -227,9 +232,9 @@ public function detectLocale($config)
* either provided by the user in the baseURL Config setting, or
* determined from the environment as needed.
*
* @deprecated $protocol and $baseURL are deprecated. No longer used.
*
* @return void
*
* @deprecated 4.4.0 No longer used.
*/
protected function detectURI(string $protocol, string $baseURL)
{
Expand Down Expand Up @@ -447,7 +452,7 @@ public function isSecure(): bool
}

/**
* Sets the relative path and updates the URI object.
* Sets the URI path relative to baseURL.
*
* Note: Since current_url() accesses the shared request
* instance, this can be used to change the "current URL"
Expand All @@ -457,88 +462,22 @@ public function isSecure(): bool
* @param App|null $config Optional alternate config to use
*
* @return $this
*
* @deprecated 4.4.0 This method will be private. The parameter $config is deprecated. No longer used.
*/
public function setPath(string $path, ?App $config = null)
{
$this->path = $path;

// @TODO remove this. The path of the URI object should be a full URI path,
// not a URI path relative to baseURL.
$this->uri->setPath($path);

$config ??= $this->config;

// It's possible the user forgot a trailing slash on their
// baseURL, so let's help them out.
$baseURL = ($config->baseURL === '') ? $config->baseURL : rtrim($config->baseURL, '/ ') . '/';

// Based on our baseURL and allowedHostnames provided by the developer
// and HTTP_HOST, set our current domain name, scheme.
if ($baseURL !== '') {
$host = $this->determineHost($config, $baseURL);

// Set URI::$baseURL
$uri = new URI($baseURL);
$currentBaseURL = (string) $uri->setHost($host);
$this->uri->setBaseURL($currentBaseURL);

$this->uri->setScheme(parse_url($baseURL, PHP_URL_SCHEME));
$this->uri->setHost($host);
$this->uri->setPort(parse_url($baseURL, PHP_URL_PORT));

// Ensure we have any query vars
$this->uri->setQuery($_SERVER['QUERY_STRING'] ?? '');

// Check if the scheme needs to be coerced into its secure version
if ($config->forceGlobalSecureRequests && $this->uri->getScheme() === 'http') {
$this->uri->setScheme('https');
}
} elseif (! is_cli()) {
// Do not change exit() to exception; Request is initialized before
// setting the exception handler, so if an exception is raised, an
// error will be displayed even if in the production environment.
// @codeCoverageIgnoreStart
exit('You have an empty or invalid baseURL. The baseURL value must be set in app/Config/App.php, or through the .env file.');
// @codeCoverageIgnoreEnd
}

return $this;
}

/**
* @deprecated 4.4.0 Moved to SiteURIFactory.
*/
private function determineHost(App $config, string $baseURL): string
{
$host = parse_url($baseURL, PHP_URL_HOST);

if (empty($config->allowedHostnames)) {
return $host;
}

// Update host if it is valid.
$httpHostPort = $this->getServer('HTTP_HOST');
if ($httpHostPort !== null) {
[$httpHost] = explode(':', $httpHostPort, 2);

if (in_array($httpHost, $config->allowedHostnames, true)) {
$host = $httpHost;
}
}

return $host;
}

/**
* Returns the URI path relative to baseURL,
* running detection as necessary.
*/
public function getPath(): string
{
if ($this->path === null) {
$this->detectPath($this->config->uriProtocol);
}

return $this->path;
}

Expand Down Expand Up @@ -972,7 +911,7 @@ public function getFile(string $fileID)
*
* Do some final cleaning of the URI and return it, currently only used in static::_parse_request_uri()
*
* @deprecated Use URI::removeDotSegments() directly
* @deprecated 4.1.2 Use URI::removeDotSegments() directly
*/
protected function removeRelativeDirectory(string $uri): string
{
Expand Down
65 changes: 64 additions & 1 deletion system/HTTP/SiteURI.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ private function determineBaseURL(
$uri = new URI($baseURL);

// Update scheme
if ($scheme !== null) {
if ($scheme !== null && $scheme !== '') {
$uri->setScheme($scheme);
} elseif ($configApp->forceGlobalSecureRequests) {
$uri->setScheme('https');
Expand Down Expand Up @@ -363,4 +363,67 @@ protected function applyParts(array $parts): void
$this->password = $parts['pass'];
}
}

/**
* For base_url() helper.
*
* @param array|string $relativePath URI string or array of URI segments
* @param string|null $scheme URI scheme. E.g., http, ftp
*/
public function baseUrl($relativePath = '', ?string $scheme = null): string
{
$relativePath = $this->stringifyRelativePath($relativePath);

$config = clone config(App::class);
$config->indexPage = '';

$host = $this->getHost();

$uri = new self($config, $relativePath, $host, $scheme);

// Support protocol-relative links
if ($scheme === '') {
return substr((string) $uri, strlen($uri->getScheme()) + 1);
}

return (string) $uri;
}

/**
* @param array|string $relativePath URI string or array of URI segments
*/
private function stringifyRelativePath($relativePath): string
{
if (is_array($relativePath)) {
$relativePath = implode('/', $relativePath);
}

return $relativePath;
}

/**
* For site_url() helper.
*
* @param array|string $relativePath URI string or array of URI segments
* @param string|null $scheme URI scheme. E.g., http, ftp
* @param App|null $config Alternate configuration to use
*/
public function siteUrl($relativePath = '', ?string $scheme = null, ?App $config = null): string
{
$relativePath = $this->stringifyRelativePath($relativePath);

// Check current host.
$host = $config === null ? $this->getHost() : null;

$config ??= config(App::class);

$uri = new self($config, $relativePath, $host, $scheme);

// Support protocol-relative links
if ($scheme === '') {
return substr((string) $uri, strlen($uri->getScheme()) + 1);
}

return (string) $uri;
}
}
9 changes: 8 additions & 1 deletion system/HTTP/SiteURIFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,11 @@
use CodeIgniter\Superglobals;
use Config\App;

/**
* Creates SiteURI using superglobals.
*
* This class also updates superglobal $_SERVER and $_GET.
*/
final class SiteURIFactory
{
private App $appConfig;
Expand Down Expand Up @@ -42,6 +47,7 @@ public function createFromGlobals(): SiteURI
* Create the SiteURI object from URI string.
*
* @internal Used for testing purposes only.
* @testTag
*/
public function createFromString(string $uri): SiteURI
{
Expand All @@ -64,7 +70,7 @@ public function createFromString(string $uri): SiteURI
$fragment = '#' . $parts['fragment'];
}

$relativePath = $parts['path'] . $query . $fragment;
$relativePath = ($parts['path'] ?? '') . $query . $fragment;
$host = $this->getValidHost($parts['host']);

return new SiteURI($this->appConfig, $relativePath, $host, $parts['scheme']);
Expand All @@ -79,6 +85,7 @@ public function createFromString(string $uri): SiteURI
* @return string The route path
*
* @internal Used for testing purposes only.
* @testTag
*/
public function detectRoutePath(string $protocol = ''): string
{
Expand Down
Loading

0 comments on commit d73b455

Please sign in to comment.