Decouple class Uri from App::instance()

This commit is contained in:
Giuseppe Criscione 2024-11-23 21:24:04 +01:00
parent a59ca34807
commit ee7825b076
11 changed files with 42 additions and 92 deletions

View File

@ -2,10 +2,8 @@
namespace Formwork;
use Formwork\Config\Config;
use Formwork\Exceptions\TranslatedException;
use Formwork\Utils\FileSystem;
use Formwork\Utils\Uri;
use Formwork\Utils\ZipErrors;
use ZipArchive;
@ -16,19 +14,14 @@ class Backupper
*/
protected const string DATE_FORMAT = 'YmdHis';
/**
* Backupper options
*
* @var array<string, mixed>
*/
protected array $options = [];
/**
* Return a new Backupper instance
*
* @param array<mixed> $options
*/
public function __construct(Config $config)
{
$this->options = $config->get('system.backup');
public function __construct(
protected array $options
) {
}
/**
@ -47,7 +40,7 @@ class Backupper
FileSystem::createDirectory($this->options['path'], recursive: true);
}
$name = sprintf('%s-%s-%s.zip', str_replace([' ', '.'], '-', Uri::host() ?? ''), $this->options['name'], date(self::DATE_FORMAT));
$name = sprintf('%s-%s-%s.zip', str_replace([' ', '.'], '-', $this->options['hostname'] ?? 'unknown-host'), $this->options['name'], date(self::DATE_FORMAT));
$destination = FileSystem::joinPaths($path, $name);

View File

@ -63,7 +63,7 @@ abstract class AbstractController
string $base = '/'
): RedirectResponse {
if (
!in_array($this->request->referer(), [null, Uri::current()], true)
!in_array($this->request->referer(), [null, $this->request->absoluteUri()], true)
&& $this->request->validateReferer(Path::join([$this->app->request()->root(), $base]))
) {
return new RedirectResponse($this->request->referer(), $responseStatus, $headers);

View File

@ -108,14 +108,9 @@ class Request
$defaultPort = self::DEFAULT_PORTS[$scheme];
return Path::join(
[
$port !== $defaultPort
? sprintf('%s://%s:%d/', $scheme, $host, $port)
: sprintf('%s://%s', $scheme, $host),
$this->root(),
]
);
return $port !== $defaultPort
? sprintf('%s://%s:%d/%s/', $scheme, $host, $port, trim($this->root(), '/'))
: sprintf('%s://%s/%s/', $scheme, $host, trim($this->root(), '/'));
}
public function uri(): string
@ -130,12 +125,7 @@ class Request
public function absoluteUri(): string
{
return Path::join(
[
$this->baseUri(),
$this->uri(),
]
);
return $this->baseUri() . ltrim($this->uri(), '/');
}
public function ip(): ?string
@ -185,7 +175,7 @@ class Request
public function validateReferer(?string $path = null): bool
{
$base = Uri::normalize(Uri::base() . '/' . $path);
$base = Uri::normalize(Uri::base($this->uri()) . '/' . $path);
return Str::startsWith((string) $this->referer(), $base);
}

View File

@ -2,6 +2,7 @@
namespace Formwork\Images;
use Formwork\App;
use Formwork\Files\File;
use Formwork\Images\ColorProfile\ColorProfile;
use Formwork\Images\Exif\ExifData;
@ -71,7 +72,8 @@ class Image extends File
public function absoluteUri(): string
{
return Uri::resolveRelative($this->uri());
$request = App::instance()->request();
return Uri::resolveRelative($this->uri(), $request->absoluteUri());
}
public function mimeType(): string

View File

@ -49,6 +49,6 @@ trait PageUri
*/
public function absoluteUri(string $path = '', bool|string $includeLanguage = true): string
{
return Uri::resolveRelative($this->uri($path, $includeLanguage));
return Uri::resolveRelative($this->uri($path, $includeLanguage), App::instance()->request()->absoluteUri());
}
}

View File

@ -24,7 +24,7 @@ class BackupController extends AbstractController
return $this->forward(ErrorsController::class, 'forbidden');
}
$backupper = new Backupper($this->config);
$backupper = $backupper = new Backupper([...$this->config->get('system.backup'), 'hostname' => $this->request->host()]);
try {
$file = $backupper->backup();
} catch (TranslatedException $e) {

View File

@ -337,7 +337,7 @@ class PagesController extends AbstractController
$this->panel->notify($this->translate('panel.pages.page.deleted'), 'success');
// Try to redirect to referer unless it's to Pages@edit
if ($this->request->referer() !== null && !Str::startsWith(Uri::normalize($this->request->referer()), Uri::make(['path' => $this->panel->uri('/pages/' . $routeParams->get('page') . '/edit/')]))) {
if ($this->request->referer() !== null && !Str::startsWith(Uri::normalize($this->request->referer()), Uri::make(['path' => $this->panel->uri('/pages/' . $routeParams->get('page') . '/edit/')], $this->request->baseUri()))) {
return $this->redirectToReferer(default: $this->generateRoute('panel.pages'), base: $this->panel->panelRoot());
}
return $this->redirect($this->generateRoute('panel.pages'));
@ -444,7 +444,7 @@ class PagesController extends AbstractController
$previousFileRoute = $this->generateRoute('panel.pages.file', ['page' => $routeParams->get('page'), 'filename' => $previousName]);
if (Str::removeEnd((string) Uri::path($this->request->referer()), '/') === $this->site->uri($previousFileRoute)) {
if (Str::removeEnd((string) Uri::path((string) $this->request->referer()), '/') === $this->site->uri($previousFileRoute)) {
return $this->redirect($this->generateRoute('panel.pages.file', ['page' => $routeParams->get('page'), 'filename' => $newName]));
}

View File

@ -40,7 +40,7 @@ class ToolsController extends AbstractController
return $this->forward(ErrorsController::class, 'forbidden');
}
$backupper = new Backupper($this->config);
$backupper = new Backupper([...$this->config->get('system.backup'), 'hostname' => $this->request->host()]);
$backups = Arr::map($backupper->getBackups(), fn (string $path, int $timestamp): array => [
'name' => basename($path),

View File

@ -50,7 +50,7 @@ class UpdatesController extends AbstractController
}
if ($this->config->get('system.updates.backupBefore')) {
$backupper = new Backupper($this->config);
$backupper = new Backupper([...$this->config->get('system.backup'), 'hostname' => $this->request->host()]);
try {
$backupper->backup();
} catch (TranslatedException) {

View File

@ -4,7 +4,6 @@ namespace Formwork\Panel\Security;
use Formwork\Http\Request;
use Formwork\Log\Registry;
use Formwork\Utils\Uri;
class AccessLimiter
{
@ -33,7 +32,7 @@ class AccessLimiter
protected Request $request
) {
// Hash visitor IP address followed by current host
$this->attemptHash = hash('sha256', $request->ip() . '@' . Uri::host());
$this->attemptHash = hash('sha256', $request->ip() . '@' . $request->host());
if ($registry->has($this->attemptHash)) {
[$this->attempts, $this->lastAttemptTime] = $registry->get($this->attemptHash);

View File

@ -2,7 +2,6 @@
namespace Formwork\Utils;
use Formwork\App;
use Formwork\Traits\StaticClass;
use InvalidArgumentException;
@ -22,25 +21,11 @@ class Uri
*/
protected static ?string $current = null;
/**
* Get current URI
*/
public static function current(): string
{
if (!isset(static::$current)) {
static::$current = static::base() . rtrim(App::instance()->request()->root(), '/') . App::instance()->request()->uri();
}
return static::$current;
}
/**
* Get the scheme of current or a given URI
*/
public static function scheme(?string $uri = null): ?string
public static function scheme(string $uri): ?string
{
if ($uri === null) {
return App::instance()->request()->isSecure() ? 'https' : 'http';
}
$scheme = static::parseComponent($uri, PHP_URL_SCHEME);
return $scheme !== null ? strtolower((string) $scheme) : null;
}
@ -48,11 +33,8 @@ class Uri
/**
* Get the host of current or a given URI
*/
public static function host(?string $uri = null): ?string
public static function host(string $uri): ?string
{
if ($uri === null) {
return strtolower((string) $_SERVER['SERVER_NAME']);
}
$host = static::parseComponent($uri, PHP_URL_HOST);
return $host !== null ? strtolower((string) $host) : null;
}
@ -60,76 +42,65 @@ class Uri
/**
* Get the port of current or a given URI
*/
public static function port(?string $uri = null): ?int
public static function port(string $uri): ?int
{
if ($uri === null) {
return (int) $_SERVER['SERVER_PORT'];
}
return static::parseComponent($uri, PHP_URL_PORT) ?? static::getDefaultPort(static::scheme($uri));
return static::parseComponent($uri, PHP_URL_PORT);
}
/**
* Return the default port of current URI or a given scheme
*/
public static function getDefaultPort(?string $scheme = null): ?int
public static function getDefaultPort(string $scheme): int
{
$scheme ??= static::scheme();
return self::DEFAULT_PORTS[$scheme] ?? null;
return self::DEFAULT_PORTS[$scheme] ?? throw new InvalidArgumentException(sprintf('Unknown scheme "%s"', $scheme));
}
/**
* Return whether current or a given port is default
*/
public static function isDefaultPort(?int $port = null, ?string $scheme = null): bool
public static function isDefaultPort(int $port, string $scheme): bool
{
$port ??= static::port();
$scheme ??= static::scheme();
return $port !== null && $scheme !== null && $port === static::getDefaultPort($scheme);
return $port === static::getDefaultPort($scheme);
}
/**
* Get the path of current or a given URI
*/
public static function path(?string $uri = null): ?string
public static function path(string $uri): ?string
{
$uri ??= static::current();
return static::parseComponent($uri, PHP_URL_PATH);
}
/**
* Get the absolute path of current or a given URI
*/
public static function absolutePath(?string $uri = null): string
public static function absolutePath(string $uri): string
{
$uri ??= static::current();
return static::base($uri) . static::path($uri);
}
/**
* Get the query of current or a given URI
*/
public static function query(?string $uri = null): ?string
public static function query(string $uri): ?string
{
$uri ??= static::current();
return static::parseComponent($uri, PHP_URL_QUERY);
}
/**
* Get the fragment of current or a given URI
*/
public static function fragment(?string $uri = null): ?string
public static function fragment(string $uri): ?string
{
$uri ??= static::current();
return static::parseComponent($uri, PHP_URL_FRAGMENT);
}
/**
* Get the base URI (scheme://host:port) of current or a given URI
*/
public static function base(?string $uri = null): string
public static function base(string $uri): string
{
$port = static::port($uri);
return static::scheme($uri) . '://' . static::host($uri) . (static::isDefaultPort($port, static::scheme($uri)) ? '' : ':' . $port);
return sprintf('%s://%s%s', static::scheme($uri), static::host($uri), static::port($uri) !== null ? ':' . static::port($uri) : '');
}
/**
@ -137,9 +108,8 @@ class Uri
*
* @return array<array<string>|string>
*/
public static function queryToArray(?string $uri = null): array
public static function queryToArray(string $uri): array
{
$uri ??= static::current();
parse_str(static::query($uri) ?? '', $array);
return $array;
}
@ -150,9 +120,8 @@ class Uri
*
* @return array{scheme: ?string, host: ?string, port: ?int, path: ?string, query: ?string, fragment: ?string}
*/
public static function parse(?string $uri = null): array
public static function parse(string $uri): array
{
$uri ??= static::current();
return [
'scheme' => static::scheme($uri),
'host' => static::host($uri),
@ -170,7 +139,7 @@ class Uri
*
* @see Uri::parse()
*/
public static function make(array $parts, ?string $uri = null, bool $forcePort = false): string
public static function make(array $parts, string $uri, bool $forcePort = false): string
{
$givenParts = array_keys($parts);
$parts = [...static::parse($uri), ...$parts];
@ -212,27 +181,24 @@ class Uri
/**
* Remove query from current or a given URI
*/
public static function removeQuery(?string $uri = null): string
public static function removeQuery(string $uri): string
{
$uri ??= static::current();
return static::make(['query' => ''], $uri);
}
/**
* Remove fragment from current or a given URI
*/
public static function removeFragment(?string $uri = null): string
public static function removeFragment(string $uri): string
{
$uri ??= static::current();
return static::make(['fragment' => ''], $uri);
}
/**
* Resolve a relative URI against current or a given base URI
*/
public static function resolveRelative(string $uri, ?string $base = null): string
public static function resolveRelative(string $uri, string $base): string
{
$base ??= static::current();
if (Str::startsWith($uri, '#')) {
return static::make(['fragment' => $uri], $base);
}