mirror of
https://github.com/linuxserver/Heimdall.git
synced 2025-12-11 09:23:50 +09:00
Updates to vendors etc
This commit is contained in:
387
vendor/symfony/http-foundation/Request.php
vendored
387
vendor/symfony/http-foundation/Request.php
vendored
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\HttpFoundation;
|
||||
|
||||
use Symfony\Component\HttpFoundation\Exception\BadRequestException;
|
||||
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
|
||||
use Symfony\Component\HttpFoundation\Exception\JsonException;
|
||||
use Symfony\Component\HttpFoundation\Exception\SessionNotFoundException;
|
||||
@@ -65,70 +66,56 @@ class Request
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $trustedProxies = [];
|
||||
protected static array $trustedProxies = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $trustedHostPatterns = [];
|
||||
protected static array $trustedHostPatterns = [];
|
||||
|
||||
/**
|
||||
* @var string[]
|
||||
*/
|
||||
protected static $trustedHosts = [];
|
||||
protected static array $trustedHosts = [];
|
||||
|
||||
protected static $httpMethodParameterOverride = false;
|
||||
protected static bool $httpMethodParameterOverride = false;
|
||||
|
||||
/**
|
||||
* Custom parameters.
|
||||
*
|
||||
* @var ParameterBag
|
||||
*/
|
||||
public $attributes;
|
||||
public ParameterBag $attributes;
|
||||
|
||||
/**
|
||||
* Request body parameters ($_POST).
|
||||
*
|
||||
* @see getPayload() for portability between content types
|
||||
*
|
||||
* @var InputBag
|
||||
*/
|
||||
public $request;
|
||||
public InputBag $request;
|
||||
|
||||
/**
|
||||
* Query string parameters ($_GET).
|
||||
*
|
||||
* @var InputBag
|
||||
*/
|
||||
public $query;
|
||||
public InputBag $query;
|
||||
|
||||
/**
|
||||
* Server and execution environment parameters ($_SERVER).
|
||||
*
|
||||
* @var ServerBag
|
||||
*/
|
||||
public $server;
|
||||
public ServerBag $server;
|
||||
|
||||
/**
|
||||
* Uploaded files ($_FILES).
|
||||
*
|
||||
* @var FileBag
|
||||
*/
|
||||
public $files;
|
||||
public FileBag $files;
|
||||
|
||||
/**
|
||||
* Cookies ($_COOKIE).
|
||||
*
|
||||
* @var InputBag
|
||||
*/
|
||||
public $cookies;
|
||||
public InputBag $cookies;
|
||||
|
||||
/**
|
||||
* Headers (taken from the $_SERVER).
|
||||
*
|
||||
* @var HeaderBag
|
||||
*/
|
||||
public $headers;
|
||||
public HeaderBag $headers;
|
||||
|
||||
/**
|
||||
* @var string|resource|false|null
|
||||
@@ -138,76 +125,42 @@ class Request
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected $languages;
|
||||
protected ?array $languages = null;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected $charsets;
|
||||
protected ?array $charsets = null;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected $encodings;
|
||||
protected ?array $encodings = null;
|
||||
|
||||
/**
|
||||
* @var string[]|null
|
||||
*/
|
||||
protected $acceptableContentTypes;
|
||||
protected ?array $acceptableContentTypes = null;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $pathInfo;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $requestUri;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $baseUrl;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $basePath;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $method;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $format;
|
||||
|
||||
/**
|
||||
* @var SessionInterface|callable():SessionInterface|null
|
||||
*/
|
||||
protected $session;
|
||||
|
||||
/**
|
||||
* @var string|null
|
||||
*/
|
||||
protected $locale;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $defaultLocale = 'en';
|
||||
protected ?string $pathInfo = null;
|
||||
protected ?string $requestUri = null;
|
||||
protected ?string $baseUrl = null;
|
||||
protected ?string $basePath = null;
|
||||
protected ?string $method = null;
|
||||
protected ?string $format = null;
|
||||
protected SessionInterface|\Closure|null $session = null;
|
||||
protected ?string $locale = null;
|
||||
protected string $defaultLocale = 'en';
|
||||
|
||||
/**
|
||||
* @var array<string, string[]>|null
|
||||
*/
|
||||
protected static $formats;
|
||||
protected static ?array $formats = null;
|
||||
|
||||
protected static $requestFactory;
|
||||
protected static ?\Closure $requestFactory = null;
|
||||
|
||||
private ?string $preferredFormat = null;
|
||||
|
||||
private bool $isHostValid = true;
|
||||
private bool $isForwardedValid = true;
|
||||
private bool $isSafeContentPreferred;
|
||||
@@ -241,8 +194,7 @@ class Request
|
||||
self::HEADER_X_FORWARDED_PREFIX => 'X_FORWARDED_PREFIX',
|
||||
];
|
||||
|
||||
/** @var bool */
|
||||
private $isIisRewrite = false;
|
||||
private bool $isIisRewrite = false;
|
||||
|
||||
/**
|
||||
* @param array $query The GET parameters
|
||||
@@ -270,10 +222,8 @@ class Request
|
||||
* @param array $files The FILES parameters
|
||||
* @param array $server The SERVER parameters
|
||||
* @param string|resource|null $content The raw body data
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null)
|
||||
public function initialize(array $query = [], array $request = [], array $attributes = [], array $cookies = [], array $files = [], array $server = [], $content = null): void
|
||||
{
|
||||
$this->request = new InputBag($request);
|
||||
$this->query = new InputBag($query);
|
||||
@@ -304,7 +254,7 @@ class Request
|
||||
$request = self::createRequestFromFactory($_GET, $_POST, [], $_COOKIE, $_FILES, $_SERVER);
|
||||
|
||||
if (str_starts_with($request->headers->get('CONTENT_TYPE', ''), 'application/x-www-form-urlencoded')
|
||||
&& \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'])
|
||||
&& \in_array(strtoupper($request->server->get('REQUEST_METHOD', 'GET')), ['PUT', 'DELETE', 'PATCH'], true)
|
||||
) {
|
||||
parse_str($request->getContent(), $data);
|
||||
$request->request = new InputBag($data);
|
||||
@@ -326,6 +276,8 @@ class Request
|
||||
* @param array $files The request files ($_FILES)
|
||||
* @param array $server The server parameters ($_SERVER)
|
||||
* @param string|resource|null $content The raw body data
|
||||
*
|
||||
* @throws BadRequestException When the URI is invalid
|
||||
*/
|
||||
public static function create(string $uri, string $method = 'GET', array $parameters = [], array $cookies = [], array $files = [], array $server = [], $content = null): static
|
||||
{
|
||||
@@ -348,11 +300,20 @@ class Request
|
||||
$server['PATH_INFO'] = '';
|
||||
$server['REQUEST_METHOD'] = strtoupper($method);
|
||||
|
||||
$components = parse_url($uri);
|
||||
if (false === $components) {
|
||||
trigger_deprecation('symfony/http-foundation', '6.3', 'Calling "%s()" with an invalid URI is deprecated.', __METHOD__);
|
||||
$components = [];
|
||||
if (false === $components = parse_url(\strlen($uri) !== strcspn($uri, '?#') ? $uri : $uri.'#')) {
|
||||
throw new BadRequestException('Invalid URI.');
|
||||
}
|
||||
|
||||
if (false !== ($i = strpos($uri, '\\')) && $i < strcspn($uri, '?#')) {
|
||||
throw new BadRequestException('Invalid URI: A URI cannot contain a backslash.');
|
||||
}
|
||||
if (\strlen($uri) !== strcspn($uri, "\r\n\t")) {
|
||||
throw new BadRequestException('Invalid URI: A URI cannot contain CR/LF/TAB characters.');
|
||||
}
|
||||
if ('' !== $uri && (\ord($uri[0]) <= 32 || \ord($uri[-1]) <= 32)) {
|
||||
throw new BadRequestException('Invalid URI: A URI must not start nor end with ASCII control characters or spaces.');
|
||||
}
|
||||
|
||||
if (isset($components['host'])) {
|
||||
$server['SERVER_NAME'] = $components['host'];
|
||||
$server['HTTP_HOST'] = $components['host'];
|
||||
@@ -430,12 +391,10 @@ class Request
|
||||
* This is mainly useful when you need to override the Request class
|
||||
* to keep BC with an existing system. It should not be used for any
|
||||
* other purpose.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setFactory(?callable $callable)
|
||||
public static function setFactory(?callable $callable): void
|
||||
{
|
||||
self::$requestFactory = $callable;
|
||||
self::$requestFactory = null === $callable ? null : $callable(...);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -525,7 +484,7 @@ class Request
|
||||
}
|
||||
|
||||
return
|
||||
sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
|
||||
\sprintf('%s %s %s', $this->getMethod(), $this->getRequestUri(), $this->server->get('SERVER_PROTOCOL'))."\r\n".
|
||||
$this->headers.
|
||||
$cookieHeader."\r\n".
|
||||
$content;
|
||||
@@ -536,10 +495,8 @@ class Request
|
||||
*
|
||||
* It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
|
||||
* $_FILES is never overridden, see rfc1867
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function overrideGlobals()
|
||||
public function overrideGlobals(): void
|
||||
{
|
||||
$this->server->set('QUERY_STRING', static::normalizeQueryString(http_build_query($this->query->all(), '', '&')));
|
||||
|
||||
@@ -576,22 +533,26 @@ class Request
|
||||
*
|
||||
* You should only list the reverse proxies that you manage directly.
|
||||
*
|
||||
* @param array $proxies A list of trusted proxies, the string 'REMOTE_ADDR' will be replaced with $_SERVER['REMOTE_ADDR']
|
||||
* @param int $trustedHeaderSet A bit field of Request::HEADER_*, to set which headers to trust from your proxies
|
||||
*
|
||||
* @return void
|
||||
* @param array $proxies A list of trusted proxies, the string 'REMOTE_ADDR' will be replaced with $_SERVER['REMOTE_ADDR'] and 'PRIVATE_SUBNETS' by IpUtils::PRIVATE_SUBNETS
|
||||
* @param int-mask-of<Request::HEADER_*> $trustedHeaderSet A bit field to set which headers to trust from your proxies
|
||||
*/
|
||||
public static function setTrustedProxies(array $proxies, int $trustedHeaderSet)
|
||||
public static function setTrustedProxies(array $proxies, int $trustedHeaderSet): void
|
||||
{
|
||||
self::$trustedProxies = array_reduce($proxies, function ($proxies, $proxy) {
|
||||
if ('REMOTE_ADDR' !== $proxy) {
|
||||
$proxies[] = $proxy;
|
||||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
$proxies[] = $_SERVER['REMOTE_ADDR'];
|
||||
if (false !== $i = array_search('REMOTE_ADDR', $proxies, true)) {
|
||||
if (isset($_SERVER['REMOTE_ADDR'])) {
|
||||
$proxies[$i] = $_SERVER['REMOTE_ADDR'];
|
||||
} else {
|
||||
unset($proxies[$i]);
|
||||
$proxies = array_values($proxies);
|
||||
}
|
||||
}
|
||||
|
||||
return $proxies;
|
||||
}, []);
|
||||
if (false !== ($i = array_search('PRIVATE_SUBNETS', $proxies, true)) || false !== ($i = array_search('private_ranges', $proxies, true))) {
|
||||
unset($proxies[$i]);
|
||||
$proxies = array_merge($proxies, IpUtils::PRIVATE_SUBNETS);
|
||||
}
|
||||
|
||||
self::$trustedProxies = $proxies;
|
||||
self::$trustedHeaderSet = $trustedHeaderSet;
|
||||
}
|
||||
|
||||
@@ -621,12 +582,10 @@ class Request
|
||||
* You should only list the hosts you manage using regexs.
|
||||
*
|
||||
* @param array $hostPatterns A list of trusted host patterns
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function setTrustedHosts(array $hostPatterns)
|
||||
public static function setTrustedHosts(array $hostPatterns): void
|
||||
{
|
||||
self::$trustedHostPatterns = array_map(fn ($hostPattern) => sprintf('{%s}i', $hostPattern), $hostPatterns);
|
||||
self::$trustedHostPatterns = array_map(fn ($hostPattern) => \sprintf('{%s}i', $hostPattern), $hostPatterns);
|
||||
// we need to reset trusted hosts on trusted host patterns change
|
||||
self::$trustedHosts = [];
|
||||
}
|
||||
@@ -669,10 +628,8 @@ class Request
|
||||
* If these methods are not protected against CSRF, this presents a possible vulnerability.
|
||||
*
|
||||
* The HTTP method can only be overridden when the real HTTP method is POST.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function enableHttpMethodParameterOverride()
|
||||
public static function enableHttpMethodParameterOverride(): void
|
||||
{
|
||||
self::$httpMethodParameterOverride = true;
|
||||
}
|
||||
@@ -756,10 +713,7 @@ class Request
|
||||
return null !== $this->session && (!$skipIfUninitialized || $this->session instanceof SessionInterface);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function setSession(SessionInterface $session)
|
||||
public function setSession(SessionInterface $session): void
|
||||
{
|
||||
$this->session = $session;
|
||||
}
|
||||
@@ -814,9 +768,7 @@ class Request
|
||||
*/
|
||||
public function getClientIp(): ?string
|
||||
{
|
||||
$ipAddresses = $this->getClientIps();
|
||||
|
||||
return $ipAddresses[0];
|
||||
return $this->getClientIps()[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1112,7 +1064,7 @@ class Request
|
||||
|
||||
$https = $this->server->get('HTTPS');
|
||||
|
||||
return !empty($https) && 'off' !== strtolower($https);
|
||||
return $https && 'off' !== strtolower($https);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1148,13 +1100,13 @@ class Request
|
||||
}
|
||||
$this->isHostValid = false;
|
||||
|
||||
throw new SuspiciousOperationException(sprintf('Invalid Host "%s".', $host));
|
||||
throw new SuspiciousOperationException(\sprintf('Invalid Host "%s".', $host));
|
||||
}
|
||||
|
||||
if (\count(self::$trustedHostPatterns) > 0) {
|
||||
// to avoid host header injection attacks, you should provide a list of trusted host patterns
|
||||
|
||||
if (\in_array($host, self::$trustedHosts)) {
|
||||
if (\in_array($host, self::$trustedHosts, true)) {
|
||||
return $host;
|
||||
}
|
||||
|
||||
@@ -1171,7 +1123,7 @@ class Request
|
||||
}
|
||||
$this->isHostValid = false;
|
||||
|
||||
throw new SuspiciousOperationException(sprintf('Untrusted Host "%s".', $host));
|
||||
throw new SuspiciousOperationException(\sprintf('Untrusted Host "%s".', $host));
|
||||
}
|
||||
|
||||
return $host;
|
||||
@@ -1179,10 +1131,8 @@ class Request
|
||||
|
||||
/**
|
||||
* Sets the request method.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setMethod(string $method)
|
||||
public function setMethod(string $method): void
|
||||
{
|
||||
$this->method = null;
|
||||
$this->server->set('REQUEST_METHOD', $method);
|
||||
@@ -1230,7 +1180,7 @@ class Request
|
||||
}
|
||||
|
||||
if (!preg_match('/^[A-Z]++$/D', $method)) {
|
||||
throw new SuspiciousOperationException(sprintf('Invalid method override "%s".', $method));
|
||||
throw new SuspiciousOperationException('Invalid HTTP method override.');
|
||||
}
|
||||
|
||||
return $this->method = $method;
|
||||
@@ -1287,10 +1237,10 @@ class Request
|
||||
}
|
||||
|
||||
foreach (static::$formats as $format => $mimeTypes) {
|
||||
if (\in_array($mimeType, (array) $mimeTypes)) {
|
||||
if (\in_array($mimeType, (array) $mimeTypes, true)) {
|
||||
return $format;
|
||||
}
|
||||
if (null !== $canonicalMimeType && \in_array($canonicalMimeType, (array) $mimeTypes)) {
|
||||
if (null !== $canonicalMimeType && \in_array($canonicalMimeType, (array) $mimeTypes, true)) {
|
||||
return $format;
|
||||
}
|
||||
}
|
||||
@@ -1302,10 +1252,8 @@ class Request
|
||||
* Associates a format with mime types.
|
||||
*
|
||||
* @param string|string[] $mimeTypes The associated mime types (the preferred one must be the first as it will be used as the content type)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setFormat(?string $format, string|array $mimeTypes)
|
||||
public function setFormat(?string $format, string|array $mimeTypes): void
|
||||
{
|
||||
if (null === static::$formats) {
|
||||
static::initializeFormats();
|
||||
@@ -1334,26 +1282,12 @@ class Request
|
||||
|
||||
/**
|
||||
* Sets the request format.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setRequestFormat(?string $format)
|
||||
public function setRequestFormat(?string $format): void
|
||||
{
|
||||
$this->format = $format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the usual name of the format associated with the request's media type (provided in the Content-Type header).
|
||||
*
|
||||
* @deprecated since Symfony 6.2, use getContentTypeFormat() instead
|
||||
*/
|
||||
public function getContentType(): ?string
|
||||
{
|
||||
trigger_deprecation('symfony/http-foundation', '6.2', 'The "%s()" method is deprecated, use "getContentTypeFormat()" instead.', __METHOD__);
|
||||
|
||||
return $this->getContentTypeFormat();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the usual name of the format associated with the request's media type (provided in the Content-Type header).
|
||||
*
|
||||
@@ -1366,10 +1300,8 @@ class Request
|
||||
|
||||
/**
|
||||
* Sets the default locale.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setDefaultLocale(string $locale)
|
||||
public function setDefaultLocale(string $locale): void
|
||||
{
|
||||
$this->defaultLocale = $locale;
|
||||
|
||||
@@ -1388,10 +1320,8 @@ class Request
|
||||
|
||||
/**
|
||||
* Sets the locale.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setLocale(string $locale)
|
||||
public function setLocale(string $locale): void
|
||||
{
|
||||
$this->setPhpDefaultLocale($this->locale = $locale);
|
||||
}
|
||||
@@ -1454,7 +1384,7 @@ class Request
|
||||
public function getProtocolVersion(): ?string
|
||||
{
|
||||
if ($this->isFromTrustedProxy()) {
|
||||
preg_match('~^(HTTP/)?([1-9]\.[0-9]) ~', $this->headers->get('Via') ?? '', $matches);
|
||||
preg_match('~^(HTTP/)?([1-9]\.[0-9])\b~', $this->headers->get('Via') ?? '', $matches);
|
||||
|
||||
if ($matches) {
|
||||
return 'HTTP/'.$matches[2];
|
||||
@@ -1533,7 +1463,7 @@ class Request
|
||||
}
|
||||
|
||||
if (!\is_array($content)) {
|
||||
throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
|
||||
throw new JsonException(\sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
|
||||
}
|
||||
|
||||
return new InputBag($content);
|
||||
@@ -1559,7 +1489,7 @@ class Request
|
||||
}
|
||||
|
||||
if (!\is_array($content)) {
|
||||
throw new JsonException(sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
|
||||
throw new JsonException(\sprintf('JSON content was expected to decode to an array, "%s" returned.', get_debug_type($content)));
|
||||
}
|
||||
|
||||
return $content;
|
||||
@@ -1588,7 +1518,11 @@ class Request
|
||||
*/
|
||||
public function getPreferredFormat(?string $default = 'html'): ?string
|
||||
{
|
||||
if ($this->preferredFormat ??= $this->getRequestFormat(null)) {
|
||||
if (!isset($this->preferredFormat) && null !== $preferredFormat = $this->getRequestFormat(null)) {
|
||||
$this->preferredFormat = $preferredFormat;
|
||||
}
|
||||
|
||||
if ($this->preferredFormat ?? null) {
|
||||
return $this->preferredFormat;
|
||||
}
|
||||
|
||||
@@ -1610,28 +1544,25 @@ class Request
|
||||
{
|
||||
$preferredLanguages = $this->getLanguages();
|
||||
|
||||
if (empty($locales)) {
|
||||
if (!$locales) {
|
||||
return $preferredLanguages[0] ?? null;
|
||||
}
|
||||
|
||||
$locales = array_map($this->formatLocale(...), $locales);
|
||||
if (!$preferredLanguages) {
|
||||
return $locales[0];
|
||||
}
|
||||
|
||||
$extendedPreferredLanguages = [];
|
||||
foreach ($preferredLanguages as $language) {
|
||||
$extendedPreferredLanguages[] = $language;
|
||||
if (false !== $position = strpos($language, '_')) {
|
||||
$superLanguage = substr($language, 0, $position);
|
||||
if (!\in_array($superLanguage, $preferredLanguages)) {
|
||||
$extendedPreferredLanguages[] = $superLanguage;
|
||||
$combinations = array_merge(...array_map($this->getLanguageCombinations(...), $preferredLanguages));
|
||||
foreach ($combinations as $combination) {
|
||||
foreach ($locales as $locale) {
|
||||
if (str_starts_with($locale, $combination)) {
|
||||
return $locale;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$preferredLanguages = array_values(array_intersect($extendedPreferredLanguages, $locales));
|
||||
|
||||
return $preferredLanguages[0] ?? $locales[0];
|
||||
return $locales[0];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1649,32 +1580,91 @@ class Request
|
||||
$this->languages = [];
|
||||
foreach ($languages as $acceptHeaderItem) {
|
||||
$lang = $acceptHeaderItem->getValue();
|
||||
if (str_contains($lang, '-')) {
|
||||
$codes = explode('-', $lang);
|
||||
if ('i' === $codes[0]) {
|
||||
// Language not listed in ISO 639 that are not variants
|
||||
// of any listed language, which can be registered with the
|
||||
// i-prefix, such as i-cherokee
|
||||
if (\count($codes) > 1) {
|
||||
$lang = $codes[1];
|
||||
}
|
||||
} else {
|
||||
for ($i = 0, $max = \count($codes); $i < $max; ++$i) {
|
||||
if (0 === $i) {
|
||||
$lang = strtolower($codes[0]);
|
||||
} else {
|
||||
$lang .= '_'.strtoupper($codes[$i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->languages[] = $lang;
|
||||
$this->languages[] = self::formatLocale($lang);
|
||||
}
|
||||
$this->languages = array_unique($this->languages);
|
||||
|
||||
return $this->languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips the locale to only keep the canonicalized language value.
|
||||
*
|
||||
* Depending on the $locale value, this method can return values like :
|
||||
* - language_Script_REGION: "fr_Latn_FR", "zh_Hans_TW"
|
||||
* - language_Script: "fr_Latn", "zh_Hans"
|
||||
* - language_REGION: "fr_FR", "zh_TW"
|
||||
* - language: "fr", "zh"
|
||||
*
|
||||
* Invalid locale values are returned as is.
|
||||
*
|
||||
* @see https://wikipedia.org/wiki/IETF_language_tag
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc5646
|
||||
*/
|
||||
private static function formatLocale(string $locale): string
|
||||
{
|
||||
[$language, $script, $region] = self::getLanguageComponents($locale);
|
||||
|
||||
return implode('_', array_filter([$language, $script, $region]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of all possible combinations of the language components.
|
||||
*
|
||||
* For instance, if the locale is "fr_Latn_FR", this method will return:
|
||||
* - "fr_Latn_FR"
|
||||
* - "fr_Latn"
|
||||
* - "fr_FR"
|
||||
* - "fr"
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
private static function getLanguageCombinations(string $locale): array
|
||||
{
|
||||
[$language, $script, $region] = self::getLanguageComponents($locale);
|
||||
|
||||
return array_unique([
|
||||
implode('_', array_filter([$language, $script, $region])),
|
||||
implode('_', array_filter([$language, $script])),
|
||||
implode('_', array_filter([$language, $region])),
|
||||
$language,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array with the language components of the locale.
|
||||
*
|
||||
* For example:
|
||||
* - If the locale is "fr_Latn_FR", this method will return "fr", "Latn", "FR"
|
||||
* - If the locale is "fr_FR", this method will return "fr", null, "FR"
|
||||
* - If the locale is "zh_Hans", this method will return "zh", "Hans", null
|
||||
*
|
||||
* @see https://wikipedia.org/wiki/IETF_language_tag
|
||||
* @see https://datatracker.ietf.org/doc/html/rfc5646
|
||||
*
|
||||
* @return array{string, string|null, string|null}
|
||||
*/
|
||||
private static function getLanguageComponents(string $locale): array
|
||||
{
|
||||
$locale = str_replace('_', '-', strtolower($locale));
|
||||
$pattern = '/^([a-zA-Z]{2,3}|i-[a-zA-Z]{5,})(?:-([a-zA-Z]{4}))?(?:-([a-zA-Z]{2}))?(?:-(.+))?$/';
|
||||
if (!preg_match($pattern, $locale, $matches)) {
|
||||
return [$locale, null, null];
|
||||
}
|
||||
if (str_starts_with($matches[1], 'i-')) {
|
||||
// Language not listed in ISO 639 that are not variants
|
||||
// of any listed language, which can be registered with the
|
||||
// i-prefix, such as i-cherokee
|
||||
$matches[1] = substr($matches[1], 2);
|
||||
}
|
||||
|
||||
return [
|
||||
$matches[1],
|
||||
isset($matches[2]) ? ucfirst(strtolower($matches[2])) : null,
|
||||
isset($matches[3]) ? strtoupper($matches[3]) : null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a list of charsets acceptable by the client browser in preferable order.
|
||||
*
|
||||
@@ -1745,10 +1735,7 @@ class Request
|
||||
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (https://www.zend.com/)
|
||||
*/
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
protected function prepareRequestUri()
|
||||
protected function prepareRequestUri(): string
|
||||
{
|
||||
$requestUri = '';
|
||||
|
||||
@@ -1844,7 +1831,7 @@ class Request
|
||||
}
|
||||
|
||||
$basename = basename($baseUrl ?? '');
|
||||
if (empty($basename) || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
|
||||
if (!$basename || !strpos(rawurldecode($truncatedRequestUri), $basename)) {
|
||||
// no match whatsoever; set it blank
|
||||
return '';
|
||||
}
|
||||
@@ -1865,7 +1852,7 @@ class Request
|
||||
protected function prepareBasePath(): string
|
||||
{
|
||||
$baseUrl = $this->getBaseUrl();
|
||||
if (empty($baseUrl)) {
|
||||
if (!$baseUrl) {
|
||||
return '';
|
||||
}
|
||||
|
||||
@@ -1905,7 +1892,7 @@ class Request
|
||||
}
|
||||
|
||||
$pathInfo = substr($requestUri, \strlen($baseUrl));
|
||||
if (false === $pathInfo || '' === $pathInfo) {
|
||||
if ('' === $pathInfo) {
|
||||
// If substr() returns false then PATH_INFO is set to an empty string
|
||||
return '/';
|
||||
}
|
||||
@@ -1915,10 +1902,8 @@ class Request
|
||||
|
||||
/**
|
||||
* Initializes HTTP request formats.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected static function initializeFormats()
|
||||
protected static function initializeFormats(): void
|
||||
{
|
||||
static::$formats = [
|
||||
'html' => ['text/html', 'application/xhtml+xml'],
|
||||
@@ -1966,7 +1951,7 @@ class Request
|
||||
|
||||
$len = \strlen($prefix);
|
||||
|
||||
if (preg_match(sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
|
||||
if (preg_match(\sprintf('#^(%%[[:xdigit:]]{2}|.){%d}#', $len), $string, $match)) {
|
||||
return $match[0];
|
||||
}
|
||||
|
||||
@@ -2058,7 +2043,7 @@ class Request
|
||||
}
|
||||
$this->isForwardedValid = false;
|
||||
|
||||
throw new ConflictingHeadersException(sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::TRUSTED_HEADERS[self::HEADER_FORWARDED], self::TRUSTED_HEADERS[$type]));
|
||||
throw new ConflictingHeadersException(\sprintf('The request has both a trusted "%s" header and a trusted "%s" header, conflicting with each other. You should either configure your proxy to remove one of them, or configure your project to distrust the offending one.', self::TRUSTED_HEADERS[self::HEADER_FORWARDED], self::TRUSTED_HEADERS[$type]));
|
||||
}
|
||||
|
||||
private function normalizeAndFilterClientIps(array $clientIps, string $ip): array
|
||||
|
||||
Reference in New Issue
Block a user