Upgrade to 4.0.0
This commit is contained in:
@@ -39,8 +39,11 @@ class Cookie
|
||||
* @return bool true: cookie was created,
|
||||
* false: cookie creation failed
|
||||
*/
|
||||
public static function set(string $key, string $value, array $options = []): bool
|
||||
{
|
||||
public static function set(
|
||||
string $key,
|
||||
string $value,
|
||||
array $options = []
|
||||
): bool {
|
||||
// modify CMS caching behavior
|
||||
static::trackUsage($key);
|
||||
|
||||
@@ -59,8 +62,11 @@ class Cookie
|
||||
$_COOKIE[$key] = $value;
|
||||
|
||||
// store the cookie
|
||||
$options = compact('expires', 'path', 'domain', 'secure', 'httponly', 'samesite');
|
||||
return setcookie($key, $value, $options);
|
||||
return setcookie(
|
||||
$key,
|
||||
$value,
|
||||
compact('expires', 'path', 'domain', 'secure', 'httponly', 'samesite')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -70,13 +76,13 @@ class Cookie
|
||||
*/
|
||||
public static function lifetime(int $minutes): int
|
||||
{
|
||||
// absolute timestamp
|
||||
if ($minutes > 1000000000) {
|
||||
// absolute timestamp
|
||||
return $minutes;
|
||||
}
|
||||
|
||||
// minutes from now
|
||||
if ($minutes > 0) {
|
||||
// minutes from now
|
||||
return time() + ($minutes * 60);
|
||||
}
|
||||
|
||||
@@ -100,8 +106,11 @@ class Cookie
|
||||
* @return bool true: cookie was created,
|
||||
* false: cookie creation failed
|
||||
*/
|
||||
public static function forever(string $key, string $value, array $options = []): bool
|
||||
{
|
||||
public static function forever(
|
||||
string $key,
|
||||
string $value,
|
||||
array $options = []
|
||||
): bool {
|
||||
// 9999-12-31 if supported (lower on 32-bit servers)
|
||||
$options['lifetime'] = min(253402214400, PHP_INT_MAX);
|
||||
return static::set($key, $value, $options);
|
||||
@@ -111,10 +120,8 @@ class Cookie
|
||||
* Get a cookie value
|
||||
*
|
||||
* <code>
|
||||
*
|
||||
* cookie::get('mycookie', 'peter');
|
||||
* // sample output: 'hello' or if the cookie is not set 'peter'
|
||||
*
|
||||
* </code>
|
||||
*
|
||||
* @param string|null $key The name of the cookie
|
||||
@@ -122,8 +129,10 @@ class Cookie
|
||||
* if the cookie has not been found
|
||||
* @return string|array|null The found value
|
||||
*/
|
||||
public static function get(string|null $key = null, string|null $default = null): string|array|null
|
||||
{
|
||||
public static function get(
|
||||
string|null $key = null,
|
||||
string|null $default = null
|
||||
): string|array|null {
|
||||
if ($key === null) {
|
||||
return $_COOKIE;
|
||||
}
|
||||
@@ -131,8 +140,11 @@ class Cookie
|
||||
// modify CMS caching behavior
|
||||
static::trackUsage($key);
|
||||
|
||||
$value = $_COOKIE[$key] ?? null;
|
||||
return empty($value) ? $default : static::parse($value);
|
||||
if ($value = $_COOKIE[$key] ?? null) {
|
||||
return static::parse($value);
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,14 +103,16 @@ class Environment
|
||||
*
|
||||
* @param array|null $info Optional override for `$_SERVER`
|
||||
*/
|
||||
public function __construct(array|null $options = null, array|null $info = null)
|
||||
{
|
||||
public function __construct(
|
||||
array|null $options = null,
|
||||
array|null $info = null
|
||||
) {
|
||||
$this->detect($options, $info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the server's IP address
|
||||
* @see static::ip
|
||||
* @see ::ip
|
||||
*/
|
||||
public function address(): string|null
|
||||
{
|
||||
@@ -150,13 +152,17 @@ class Environment
|
||||
*
|
||||
* @param array|null $info Optional override for `$_SERVER`
|
||||
*/
|
||||
public function detect(array $options = null, array $info = null): array
|
||||
{
|
||||
$info ??= $_SERVER;
|
||||
$options = array_merge([
|
||||
public function detect(
|
||||
array $options = null,
|
||||
array $info = null
|
||||
): array {
|
||||
$defaults = [
|
||||
'cli' => null,
|
||||
'allowed' => null
|
||||
], $options ?? []);
|
||||
];
|
||||
|
||||
$info ??= $_SERVER;
|
||||
$options = array_merge($defaults, $options ?? []);
|
||||
|
||||
$this->info = static::sanitize($info);
|
||||
$this->cli = $this->detectCli($options['cli']);
|
||||
@@ -235,9 +241,9 @@ class Environment
|
||||
|
||||
$uri = new Uri($url, ['slash' => false]);
|
||||
|
||||
// the current environment is allowed,
|
||||
// stop before the exception below is thrown
|
||||
if ($uri->toString() === $this->baseUrl) {
|
||||
// the current environment is allowed,
|
||||
// stop before the exception below is thrown
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -318,7 +324,11 @@ class Environment
|
||||
// @codeCoverageIgnoreStart
|
||||
$term = getenv('TERM');
|
||||
|
||||
if (substr(PHP_SAPI, 0, 3) === 'cgi' && $term && $term !== 'unknown') {
|
||||
if (
|
||||
substr(PHP_SAPI, 0, 3) === 'cgi' &&
|
||||
$term &&
|
||||
$term !== 'unknown'
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -340,8 +350,7 @@ class Environment
|
||||
];
|
||||
|
||||
// prefer the standardized `Forwarded` header if defined
|
||||
$forwarded = $this->get('HTTP_FORWARDED');
|
||||
if ($forwarded) {
|
||||
if ($forwarded = $this->get('HTTP_FORWARDED')) {
|
||||
// only use the first (outermost) proxy by using the first set of values
|
||||
// before the first comma (but only a comma outside of quotes)
|
||||
if (Str::contains($forwarded, ',') === true) {
|
||||
@@ -513,7 +522,9 @@ class Environment
|
||||
return false;
|
||||
}
|
||||
|
||||
return in_array(strtolower($protocol), ['https', 'https, http']) === true;
|
||||
$protocols = ['https', 'https, http'];
|
||||
|
||||
return in_array(strtolower($protocol), $protocols) === true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -660,11 +671,12 @@ class Environment
|
||||
* @param mixed $default Optional default value, which should be
|
||||
* returned if no element has been found
|
||||
*/
|
||||
public static function getGlobally(string|false|null $key = null, $default = null)
|
||||
{
|
||||
public static function getGlobally(
|
||||
string|false|null $key = null,
|
||||
$default = null
|
||||
) {
|
||||
// first try the global `Environment` object if the CMS is running
|
||||
$app = App::instance(null, true);
|
||||
if ($app) {
|
||||
if ($app = App::instance(null, true)) {
|
||||
return $app->environment()->get($key, $default);
|
||||
}
|
||||
|
||||
@@ -851,8 +863,10 @@ class Environment
|
||||
/**
|
||||
* Sanitizes some `$_SERVER` keys
|
||||
*/
|
||||
public static function sanitize(string|array $key, $value = null)
|
||||
{
|
||||
public static function sanitize(
|
||||
string|array $key,
|
||||
$value = null
|
||||
) {
|
||||
if (is_array($key) === true) {
|
||||
foreach ($key as $k => $v) {
|
||||
$key[$k] = static::sanitize($k, $v);
|
||||
@@ -877,8 +891,9 @@ class Environment
|
||||
/**
|
||||
* Sanitizes the given host name
|
||||
*/
|
||||
protected static function sanitizeHost(string|null $host = null): string|null
|
||||
{
|
||||
protected static function sanitizeHost(
|
||||
string|null $host = null
|
||||
): string|null {
|
||||
if (empty($host) === true) {
|
||||
return null;
|
||||
}
|
||||
@@ -902,8 +917,9 @@ class Environment
|
||||
/**
|
||||
* Sanitizes the given port number
|
||||
*/
|
||||
protected static function sanitizePort(string|int|false|null $port = null): int|null
|
||||
{
|
||||
protected static function sanitizePort(
|
||||
string|int|false|null $port = null
|
||||
): int|null {
|
||||
// already fine
|
||||
if (is_int($port) === true) {
|
||||
return $port;
|
||||
|
||||
@@ -18,7 +18,6 @@ class Header
|
||||
{
|
||||
// configuration
|
||||
public static array $codes = [
|
||||
|
||||
// successful
|
||||
'_200' => 'OK',
|
||||
'_201' => 'Created',
|
||||
@@ -58,8 +57,11 @@ class Header
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function contentType(string $mime, string $charset = 'UTF-8', bool $send = true)
|
||||
{
|
||||
public static function contentType(
|
||||
string $mime,
|
||||
string $charset = 'UTF-8',
|
||||
bool $send = true
|
||||
) {
|
||||
if ($found = F::extensionToMime($mime)) {
|
||||
$mime = $found;
|
||||
}
|
||||
@@ -80,8 +82,10 @@ class Header
|
||||
/**
|
||||
* Creates headers by key and value
|
||||
*/
|
||||
public static function create(string|array $key, string|null $value = null): string
|
||||
{
|
||||
public static function create(
|
||||
string|array $key,
|
||||
string|null $value = null
|
||||
): string {
|
||||
if (is_array($key) === true) {
|
||||
$headers = [];
|
||||
|
||||
@@ -92,7 +96,8 @@ class Header
|
||||
return implode("\r\n", $headers);
|
||||
}
|
||||
|
||||
// prevent header injection by stripping any newline characters from single headers
|
||||
// prevent header injection by stripping
|
||||
// any newline characters from single headers
|
||||
return str_replace(["\r", "\n"], '', $key . ': ' . $value);
|
||||
}
|
||||
|
||||
@@ -258,8 +263,11 @@ class Header
|
||||
*
|
||||
* @return string|void
|
||||
*/
|
||||
public static function redirect(string $url, int $code = 302, bool $send = true)
|
||||
{
|
||||
public static function redirect(
|
||||
string $url,
|
||||
int $code = 302,
|
||||
bool $send = true
|
||||
) {
|
||||
$status = static::status($code, false);
|
||||
$location = 'Location:' . Url::unIdn($url);
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ class Params extends Obj
|
||||
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === false;
|
||||
return $this->isEmpty() === false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ class Query extends Obj
|
||||
|
||||
public function isNotEmpty(): bool
|
||||
{
|
||||
return empty((array)$this) === false;
|
||||
return $this->isEmpty() === false;
|
||||
}
|
||||
|
||||
public function toString(bool $questionMark = false): string
|
||||
|
||||
@@ -50,17 +50,6 @@ class Remote
|
||||
public array $options = [];
|
||||
|
||||
/**
|
||||
* Magic getter for request info data
|
||||
*/
|
||||
public function __call(string $method, array $arguments = [])
|
||||
{
|
||||
$method = str_replace('-', '_', Str::kebab($method));
|
||||
return $this->info[$method] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @throws \Exception when the curl request failed
|
||||
*/
|
||||
public function __construct(string $url, array $options = [])
|
||||
@@ -76,8 +65,7 @@ class Remote
|
||||
|
||||
// update the defaults with App config if set;
|
||||
// request the App instance lazily
|
||||
$app = App::instance(null, true);
|
||||
if ($app !== null) {
|
||||
if ($app = App::instance(null, true)) {
|
||||
$defaults = array_merge($defaults, $app->option('remote', []));
|
||||
}
|
||||
|
||||
@@ -91,8 +79,19 @@ class Remote
|
||||
$this->fetch();
|
||||
}
|
||||
|
||||
public static function __callStatic(string $method, array $arguments = []): static
|
||||
/**
|
||||
* Magic getter for request info data
|
||||
*/
|
||||
public function __call(string $method, array $arguments = [])
|
||||
{
|
||||
$method = str_replace('-', '_', Str::kebab($method));
|
||||
return $this->info[$method] ?? null;
|
||||
}
|
||||
|
||||
public static function __callStatic(
|
||||
string $method,
|
||||
array $arguments = []
|
||||
): static {
|
||||
return new static(
|
||||
url: $arguments[0],
|
||||
options: array_merge(
|
||||
|
||||
@@ -4,6 +4,9 @@ namespace Kirby\Http;
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Http\Request\Auth;
|
||||
use Kirby\Http\Request\Auth\BasicAuth;
|
||||
use Kirby\Http\Request\Auth\BearerAuth;
|
||||
use Kirby\Http\Request\Auth\SessionAuth;
|
||||
use Kirby\Http\Request\Body;
|
||||
use Kirby\Http\Request\Files;
|
||||
use Kirby\Http\Request\Query;
|
||||
@@ -24,9 +27,9 @@ use Kirby\Toolkit\Str;
|
||||
class Request
|
||||
{
|
||||
public static array $authTypes = [
|
||||
'basic' => 'Kirby\Http\Request\Auth\BasicAuth',
|
||||
'bearer' => 'Kirby\Http\Request\Auth\BearerAuth',
|
||||
'session' => 'Kirby\Http\Request\Auth\SessionAuth',
|
||||
'basic' => BasicAuth::class,
|
||||
'bearer' => BearerAuth::class,
|
||||
'session' => SessionAuth::class,
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -99,24 +102,37 @@ class Request
|
||||
$this->method = $this->detectRequestMethod($options['method'] ?? null);
|
||||
|
||||
if (isset($options['body']) === true) {
|
||||
$this->body = $options['body'] instanceof Body ? $options['body'] : new Body($options['body']);
|
||||
$this->body =
|
||||
$options['body'] instanceof Body
|
||||
? $options['body']
|
||||
: new Body($options['body']);
|
||||
}
|
||||
|
||||
if (isset($options['files']) === true) {
|
||||
$this->files = $options['files'] instanceof Files ? $options['files'] : new Files($options['files']);
|
||||
$this->files =
|
||||
$options['files'] instanceof Files
|
||||
? $options['files']
|
||||
: new Files($options['files']);
|
||||
}
|
||||
|
||||
if (isset($options['query']) === true) {
|
||||
$this->query = $options['query'] instanceof Query ? $options['query'] : new Query($options['query']);
|
||||
$this->query =
|
||||
$options['query'] instanceof Query
|
||||
? $options['query']
|
||||
: new Query($options['query']);
|
||||
}
|
||||
|
||||
if (isset($options['url']) === true) {
|
||||
$this->url = $options['url'] instanceof Uri ? $options['url'] : new Uri($options['url']);
|
||||
$this->url =
|
||||
$options['url'] instanceof Uri
|
||||
? $options['url']
|
||||
: new Uri($options['url']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
@@ -195,7 +211,10 @@ class Request
|
||||
*/
|
||||
public function data(): array
|
||||
{
|
||||
return array_replace($this->body()->toArray(), $this->query()->toArray());
|
||||
return array_replace(
|
||||
$this->body()->toArray(),
|
||||
$this->query()->toArray()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,7 +234,7 @@ class Request
|
||||
}
|
||||
|
||||
// final chain of options to detect the method
|
||||
$method = $method ?? Environment::getGlobally('REQUEST_METHOD', 'GET');
|
||||
$method ??= Environment::getGlobally('REQUEST_METHOD', 'GET');
|
||||
|
||||
// uppercase the shit out of it
|
||||
$method = strtoupper($method);
|
||||
|
||||
@@ -16,19 +16,12 @@ use SensitiveParameter;
|
||||
abstract class Auth
|
||||
{
|
||||
/**
|
||||
* Raw authentication data after the first space
|
||||
* in the `Authorization` header
|
||||
*/
|
||||
protected string $data;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $data Raw authentication data after the first space in the `Authorization` header
|
||||
*/
|
||||
public function __construct(
|
||||
#[SensitiveParameter]
|
||||
string $data
|
||||
protected string $data
|
||||
) {
|
||||
$this->data = $data;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -20,6 +20,7 @@ trait Data
|
||||
{
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
|
||||
@@ -6,7 +6,6 @@ use Closure;
|
||||
use Exception;
|
||||
use Kirby\Exception\LogicException;
|
||||
use Kirby\Filesystem\F;
|
||||
use Throwable;
|
||||
|
||||
/**
|
||||
* Representation of an Http response,
|
||||
@@ -82,6 +81,7 @@ class Response
|
||||
|
||||
/**
|
||||
* Improved `var_dump` output
|
||||
* @codeCoverageIgnore
|
||||
*/
|
||||
public function __debugInfo(): array
|
||||
{
|
||||
@@ -95,11 +95,7 @@ class Response
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
try {
|
||||
return $this->send();
|
||||
} catch (Throwable) {
|
||||
return '';
|
||||
}
|
||||
return $this->send();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -198,9 +194,8 @@ class Response
|
||||
* @since 3.7.0
|
||||
*
|
||||
* @codeCoverageIgnore
|
||||
* @todo Change return type to `never` once support for PHP 8.0 is dropped
|
||||
*/
|
||||
public static function go(string $url = '/', int $code = 302): void
|
||||
public static function go(string $url = '/', int $code = 302): never
|
||||
{
|
||||
die(static::redirect($url, $code));
|
||||
}
|
||||
@@ -251,7 +246,7 @@ class Response
|
||||
array $headers = []
|
||||
): static {
|
||||
if (is_array($body) === true) {
|
||||
$body = json_encode($body, $pretty === true ? JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES : 0);
|
||||
$body = json_encode($body, $pretty === true ? JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES : 0);
|
||||
}
|
||||
|
||||
return new static([
|
||||
|
||||
@@ -63,7 +63,7 @@ class Route
|
||||
/**
|
||||
* Magic getter for route attributes
|
||||
*/
|
||||
public function __call(string $key, array $arguments = null)
|
||||
public function __call(string $key, array $args = null): mixed
|
||||
{
|
||||
return $this->attributes[$key] ?? null;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ namespace Kirby\Http;
|
||||
|
||||
use Kirby\Cms\App;
|
||||
use Kirby\Exception\InvalidArgumentException;
|
||||
use Kirby\Toolkit\Properties;
|
||||
use SensitiveParameter;
|
||||
use Throwable;
|
||||
|
||||
@@ -19,8 +18,6 @@ use Throwable;
|
||||
*/
|
||||
class Uri
|
||||
{
|
||||
use Properties;
|
||||
|
||||
/**
|
||||
* Cache for the current Uri object
|
||||
*/
|
||||
@@ -29,32 +26,32 @@ class Uri
|
||||
/**
|
||||
* The fragment after the hash
|
||||
*/
|
||||
protected string|false|null $fragment = null;
|
||||
protected string|false|null $fragment;
|
||||
|
||||
/**
|
||||
* The host address
|
||||
*/
|
||||
protected string|null $host = null;
|
||||
protected string|null $host;
|
||||
|
||||
/**
|
||||
* The optional password for basic authentication
|
||||
*/
|
||||
protected string|false|null $password = null;
|
||||
protected string|false|null $password;
|
||||
|
||||
/**
|
||||
* The optional list of params
|
||||
*/
|
||||
protected Params|null $params = null;
|
||||
protected Params $params;
|
||||
|
||||
/**
|
||||
* The optional path
|
||||
*/
|
||||
protected Path|null $path = null;
|
||||
protected Path $path;
|
||||
|
||||
/**
|
||||
* The optional port number
|
||||
*/
|
||||
protected int|false|null $port = null;
|
||||
protected int|false|null $port;
|
||||
|
||||
/**
|
||||
* All original properties
|
||||
@@ -64,44 +61,25 @@ class Uri
|
||||
/**
|
||||
* The optional query string without leading ?
|
||||
*/
|
||||
protected Query|null $query = null;
|
||||
protected Query $query;
|
||||
|
||||
/**
|
||||
* https or http
|
||||
*/
|
||||
protected string|null $scheme = 'http';
|
||||
protected string|null $scheme;
|
||||
|
||||
/**
|
||||
* Supported schemes
|
||||
*/
|
||||
protected static array $schemes = ['http', 'https', 'ftp'];
|
||||
|
||||
protected bool $slash = false;
|
||||
protected bool $slash;
|
||||
|
||||
/**
|
||||
* The optional username for basic authentication
|
||||
*/
|
||||
protected string|false|null $username = null;
|
||||
|
||||
/**
|
||||
* Magic caller to access all properties
|
||||
*/
|
||||
public function __call(string $property, array $arguments = [])
|
||||
{
|
||||
return $this->$property ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that cloning also clones
|
||||
* the path and query objects
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->path = clone $this->path;
|
||||
$this->query = clone $this->query;
|
||||
$this->params = clone $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new URI object
|
||||
*
|
||||
@@ -122,7 +100,36 @@ class Uri
|
||||
$props = static::parsePath($props);
|
||||
}
|
||||
|
||||
$this->setProperties($this->props = $props);
|
||||
$this->props = $props;
|
||||
$this->setFragment($props['fragment'] ?? null);
|
||||
$this->setHost($props['host'] ?? null);
|
||||
$this->setParams($props['params'] ?? null);
|
||||
$this->setPassword($props['password'] ?? null);
|
||||
$this->setPath($props['path'] ?? null);
|
||||
$this->setPort($props['port'] ?? null);
|
||||
$this->setQuery($props['query'] ?? null);
|
||||
$this->setScheme($props['scheme'] ?? 'http');
|
||||
$this->setSlash($props['slash'] ?? false);
|
||||
$this->setUsername($props['username'] ?? null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic caller to access all properties
|
||||
*/
|
||||
public function __call(string $property, array $arguments = [])
|
||||
{
|
||||
return $this->$property ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that cloning also clones
|
||||
* the path and query objects
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
$this->path = clone $this->path;
|
||||
$this->query = clone $this->query;
|
||||
$this->params = clone $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -416,7 +423,7 @@ class Uri
|
||||
{
|
||||
$array = [];
|
||||
|
||||
foreach ($this->propertyData as $key => $value) {
|
||||
foreach ($this->props as $key => $value) {
|
||||
$value = $this->$key;
|
||||
|
||||
if (is_object($value) === true) {
|
||||
|
||||
@@ -38,9 +38,13 @@ class Url
|
||||
* Url Builder
|
||||
* Actually just a factory for `new Uri($parts)`
|
||||
*/
|
||||
public static function build(array $parts = [], string|null $url = null): string
|
||||
{
|
||||
return (string)(new Uri($url ?? static::current()))->clone($parts);
|
||||
public static function build(
|
||||
array $parts = [],
|
||||
string|null $url = null
|
||||
): string {
|
||||
$url ??= static::current();
|
||||
$uri = new Uri($url);
|
||||
return $uri->clone($parts)->toString();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +143,9 @@ class Url
|
||||
bool $leadingSlash = false,
|
||||
bool $trailingSlash = false
|
||||
): string {
|
||||
return Url::toObject($url)->path()->toString($leadingSlash, $trailingSlash);
|
||||
return Url::toObject($url)
|
||||
->path()
|
||||
->toString($leadingSlash, $trailingSlash);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -212,8 +218,10 @@ class Url
|
||||
/**
|
||||
* Smart resolver for internal and external urls
|
||||
*/
|
||||
public static function to(string|null $path = null, array $options = null): string
|
||||
{
|
||||
public static function to(
|
||||
string|null $path = null,
|
||||
array $options = null
|
||||
): string {
|
||||
// make sure $path is string
|
||||
$path ??= '';
|
||||
|
||||
|
||||
@@ -34,10 +34,19 @@ class Visitor
|
||||
*/
|
||||
public function __construct(array $arguments = [])
|
||||
{
|
||||
$this->ip($arguments['ip'] ?? Environment::getGlobally('REMOTE_ADDR', ''));
|
||||
$this->userAgent($arguments['userAgent'] ?? Environment::getGlobally('HTTP_USER_AGENT', ''));
|
||||
$this->acceptedLanguage($arguments['acceptedLanguage'] ?? Environment::getGlobally('HTTP_ACCEPT_LANGUAGE', ''));
|
||||
$this->acceptedMimeType($arguments['acceptedMimeType'] ?? Environment::getGlobally('HTTP_ACCEPT', ''));
|
||||
$ip = $arguments['ip'] ?? null;
|
||||
$ip ??= Environment::getGlobally('REMOTE_ADDR', '');
|
||||
$agent = $arguments['userAgent'] ?? null;
|
||||
$agent ??= Environment::getGlobally('HTTP_USER_AGENT', '');
|
||||
$language = $arguments['acceptedLanguage'] ?? null;
|
||||
$language ??= Environment::getGlobally('HTTP_ACCEPT_LANGUAGE', '');
|
||||
$mime = $arguments['acceptedMimeType'] ?? null;
|
||||
$mime ??= Environment::getGlobally('HTTP_ACCEPT', '');
|
||||
|
||||
$this->ip($ip);
|
||||
$this->userAgent($agent);
|
||||
$this->acceptedLanguage($language);
|
||||
$this->acceptedMimeType($mime);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,8 +56,9 @@ class Visitor
|
||||
*
|
||||
* @return $this|\Kirby\Toolkit\Obj|null
|
||||
*/
|
||||
public function acceptedLanguage(string|null $acceptedLanguage = null): static|Obj|null
|
||||
{
|
||||
public function acceptedLanguage(
|
||||
string|null $acceptedLanguage = null
|
||||
): static|Obj|null {
|
||||
if ($acceptedLanguage === null) {
|
||||
return $this->acceptedLanguages()->first();
|
||||
}
|
||||
@@ -108,8 +118,9 @@ class Visitor
|
||||
*
|
||||
* @return $this|\Kirby\Toolkit\Obj|null
|
||||
*/
|
||||
public function acceptedMimeType(string|null $acceptedMimeType = null): static|Obj|null
|
||||
{
|
||||
public function acceptedMimeType(
|
||||
string|null $acceptedMimeType = null
|
||||
): static|Obj|null {
|
||||
if ($acceptedMimeType === null) {
|
||||
return $this->acceptedMimeTypes()->first();
|
||||
}
|
||||
@@ -178,7 +189,8 @@ class Visitor
|
||||
*/
|
||||
public function prefersJson(): bool
|
||||
{
|
||||
return $this->preferredMimeType('application/json', 'text/html') === 'application/json';
|
||||
$preferred = $this->preferredMimeType('application/json', 'text/html');
|
||||
return $preferred === 'application/json';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,6 +205,7 @@ class Visitor
|
||||
if ($ip === null) {
|
||||
return $this->ip;
|
||||
}
|
||||
|
||||
$this->ip = $ip;
|
||||
return $this;
|
||||
}
|
||||
@@ -209,6 +222,7 @@ class Visitor
|
||||
if ($userAgent === null) {
|
||||
return $this->userAgent;
|
||||
}
|
||||
|
||||
$this->userAgent = $userAgent;
|
||||
return $this;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user