*/
- #[\ReturnTypeWillChange]
- public function getIterator()
+ public function getIterator(): \ArrayIterator
{
return new \ArrayIterator($this->arguments);
}
diff --git a/core/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php b/core/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
index 182ba080d5..d385d3f833 100644
--- a/core/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
+++ b/core/vendor/symfony/event-dispatcher/ImmutableEventDispatcher.php
@@ -30,21 +30,33 @@ public function dispatch(object $event, string $eventName = null): object
return $this->dispatcher->dispatch($event, $eventName);
}
+ /**
+ * @return never
+ */
public function addListener(string $eventName, callable|array $listener, int $priority = 0)
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
+ /**
+ * @return never
+ */
public function addSubscriber(EventSubscriberInterface $subscriber)
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
+ /**
+ * @return never
+ */
public function removeListener(string $eventName, callable|array $listener)
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
}
+ /**
+ * @return never
+ */
public function removeSubscriber(EventSubscriberInterface $subscriber)
{
throw new \BadMethodCallException('Unmodifiable event dispatchers must not be modified.');
diff --git a/core/vendor/symfony/event-dispatcher/LegacyEventDispatcherProxy.php b/core/vendor/symfony/event-dispatcher/LegacyEventDispatcherProxy.php
deleted file mode 100644
index 6e17c8fcc9..0000000000
--- a/core/vendor/symfony/event-dispatcher/LegacyEventDispatcherProxy.php
+++ /dev/null
@@ -1,31 +0,0 @@
-
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
-
-namespace Symfony\Component\EventDispatcher;
-
-use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
-
-trigger_deprecation('symfony/event-dispatcher', '5.1', '%s is deprecated, use the event dispatcher without the proxy.', LegacyEventDispatcherProxy::class);
-
-/**
- * A helper class to provide BC/FC with the legacy signature of EventDispatcherInterface::dispatch().
- *
- * @author Nicolas Grekas
- *
- * @deprecated since Symfony 5.1
- */
-final class LegacyEventDispatcherProxy
-{
- public static function decorate(?EventDispatcherInterface $dispatcher): ?EventDispatcherInterface
- {
- return $dispatcher;
- }
-}
diff --git a/core/vendor/symfony/event-dispatcher/composer.json b/core/vendor/symfony/event-dispatcher/composer.json
index c05373f331..287037822d 100644
--- a/core/vendor/symfony/event-dispatcher/composer.json
+++ b/core/vendor/symfony/event-dispatcher/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": ">=8.1",
- "symfony/event-dispatcher-contracts": "^2|^3"
+ "symfony/event-dispatcher-contracts": "^2.5|^3"
},
"require-dev": {
"symfony/dependency-injection": "^5.4|^6.0",
@@ -25,21 +25,18 @@
"symfony/config": "^5.4|^6.0",
"symfony/error-handler": "^5.4|^6.0",
"symfony/http-foundation": "^5.4|^6.0",
- "symfony/service-contracts": "^1.1|^2|^3",
+ "symfony/service-contracts": "^2.5|^3",
"symfony/stopwatch": "^5.4|^6.0",
"psr/log": "^1|^2|^3"
},
"conflict": {
- "symfony/dependency-injection": "<5.4"
+ "symfony/dependency-injection": "<5.4",
+ "symfony/service-contracts": "<2.5"
},
"provide": {
"psr/event-dispatcher-implementation": "1.0",
"symfony/event-dispatcher-implementation": "2.0|3.0"
},
- "suggest": {
- "symfony/dependency-injection": "",
- "symfony/http-kernel": ""
- },
"autoload": {
"psr-4": { "Symfony\\Component\\EventDispatcher\\": "" },
"exclude-from-classmap": [
diff --git a/core/vendor/symfony/filesystem/Filesystem.php b/core/vendor/symfony/filesystem/Filesystem.php
index 3b3cf7a1c5..a379ce1863 100644
--- a/core/vendor/symfony/filesystem/Filesystem.php
+++ b/core/vendor/symfony/filesystem/Filesystem.php
@@ -31,6 +31,8 @@ class Filesystem
* If the target file is newer, it is overwritten only when the
* $overwriteNewerFiles option is set to true.
*
+ * @return void
+ *
* @throws FileNotFoundException When originFile doesn't exist
* @throws IOException When copy fails
*/
@@ -82,6 +84,8 @@ public function copy(string $originFile, string $targetFile, bool $overwriteNewe
/**
* Creates a directory recursively.
*
+ * @return void
+ *
* @throws IOException On any directory creation failure
*/
public function mkdir(string|iterable $dirs, int $mode = 0777)
@@ -123,6 +127,8 @@ public function exists(string|iterable $files): bool
* @param int|null $time The touch time as a Unix timestamp, if not supplied the current system time is used
* @param int|null $atime The access time as a Unix timestamp, if not supplied the current system time is used
*
+ * @return void
+ *
* @throws IOException When touch fails
*/
public function touch(string|iterable $files, int $time = null, int $atime = null)
@@ -137,6 +143,8 @@ public function touch(string|iterable $files, int $time = null, int $atime = nul
/**
* Removes files or directories.
*
+ * @return void
+ *
* @throws IOException When removal fails
*/
public function remove(string|iterable $files)
@@ -203,12 +211,14 @@ private static function doRemove(array $files, bool $isRecursive): void
* @param int $umask The mode mask (octal)
* @param bool $recursive Whether change the mod recursively or not
*
+ * @return void
+ *
* @throws IOException When the change fails
*/
public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool $recursive = false)
{
foreach ($this->toIterable($files) as $file) {
- if (\is_int($mode) && !self::box('chmod', $file, $mode & ~$umask)) {
+ if (!self::box('chmod', $file, $mode & ~$umask)) {
throw new IOException(sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file);
}
if ($recursive && is_dir($file) && !is_link($file)) {
@@ -223,6 +233,8 @@ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool
* @param string|int $user A user name or number
* @param bool $recursive Whether change the owner recursively or not
*
+ * @return void
+ *
* @throws IOException When the change fails
*/
public function chown(string|iterable $files, string|int $user, bool $recursive = false)
@@ -249,6 +261,8 @@ public function chown(string|iterable $files, string|int $user, bool $recursive
* @param string|int $group A group name or number
* @param bool $recursive Whether change the group recursively or not
*
+ * @return void
+ *
* @throws IOException When the change fails
*/
public function chgrp(string|iterable $files, string|int $group, bool $recursive = false)
@@ -272,6 +286,8 @@ public function chgrp(string|iterable $files, string|int $group, bool $recursive
/**
* Renames a file or a directory.
*
+ * @return void
+ *
* @throws IOException When target file or directory already exists
* @throws IOException When origin cannot be renamed
*/
@@ -313,6 +329,8 @@ private function isReadable(string $filename): bool
/**
* Creates a symbolic link or copy a directory.
*
+ * @return void
+ *
* @throws IOException When symlink fails
*/
public function symlink(string $originDir, string $targetDir, bool $copyOnWindows = false)
@@ -349,6 +367,8 @@ public function symlink(string $originDir, string $targetDir, bool $copyOnWindow
*
* @param string|string[] $targetFiles The target file(s)
*
+ * @return void
+ *
* @throws FileNotFoundException When original file is missing or not a file
* @throws IOException When link fails, including if link already exists
*/
@@ -381,7 +401,7 @@ public function hardlink(string $originFile, string|iterable $targetFiles)
/**
* @param string $linkType Name of the link type, typically 'symbolic' or 'hard'
*/
- private function linkException(string $origin, string $target, string $linkType)
+ private function linkException(string $origin, string $target, string $linkType): never
{
if (self::$lastError) {
if ('\\' === \DIRECTORY_SEPARATOR && str_contains(self::$lastError, 'error code(1314)')) {
@@ -438,11 +458,9 @@ public function makePathRelative(string $endPath, string $startPath): string
$startPath = str_replace('\\', '/', $startPath);
}
- $splitDriveLetter = function ($path) {
- return (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
- ? [substr($path, 2), strtoupper($path[0])]
- : [$path, null];
- };
+ $splitDriveLetter = fn ($path) => (\strlen($path) > 2 && ':' === $path[1] && '/' === $path[2] && ctype_alpha($path[0]))
+ ? [substr($path, 2), strtoupper($path[0])]
+ : [$path, null];
$splitPath = function ($path) {
$result = [];
@@ -508,6 +526,8 @@ public function makePathRelative(string $endPath, string $startPath): string
* - $options['copy_on_windows'] Whether to copy files instead of links on Windows (see symlink(), defaults to false)
* - $options['delete'] Whether to delete files that are not in the source directory (defaults to false)
*
+ * @return void
+ *
* @throws IOException When file type is unknown
*/
public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = [])
@@ -632,6 +652,8 @@ public function tempnam(string $dir, string $prefix, string $suffix = ''): strin
*
* @param string|resource $content The data to write into the file
*
+ * @return void
+ *
* @throws IOException if the file cannot be written to
*/
public function dumpFile(string $filename, $content)
@@ -642,6 +664,12 @@ public function dumpFile(string $filename, $content)
$dir = \dirname($filename);
+ if (is_link($filename) && $linkTarget = $this->readlink($filename)) {
+ $this->dumpFile(Path::makeAbsolute($linkTarget, $dir), $content);
+
+ return;
+ }
+
if (!is_dir($dir)) {
$this->mkdir($dir);
}
@@ -671,6 +699,8 @@ public function dumpFile(string $filename, $content)
* @param string|resource $content The content to append
* @param bool $lock Whether the file should be locked when writing to it
*
+ * @return void
+ *
* @throws IOException If the file is not writable
*/
public function appendToFile(string $filename, $content/* , bool $lock = false */)
@@ -730,7 +760,7 @@ private static function box(string $func, mixed ...$args): mixed
/**
* @internal
*/
- public static function handleError(int $type, string $msg)
+ public static function handleError(int $type, string $msg): void
{
self::$lastError = $msg;
}
diff --git a/core/vendor/symfony/finder/Finder.php b/core/vendor/symfony/finder/Finder.php
index f70caa0827..62c3f9e24f 100644
--- a/core/vendor/symfony/finder/Finder.php
+++ b/core/vendor/symfony/finder/Finder.php
@@ -45,27 +45,27 @@ class Finder implements \IteratorAggregate, \Countable
public const IGNORE_DOT_FILES = 2;
public const IGNORE_VCS_IGNORED_FILES = 4;
- private $mode = 0;
- private $names = [];
- private $notNames = [];
- private $exclude = [];
- private $filters = [];
- private $depths = [];
- private $sizes = [];
- private $followLinks = false;
- private $reverseSorting = false;
- private $sort = false;
- private $ignore = 0;
- private $dirs = [];
- private $dates = [];
- private $iterators = [];
- private $contains = [];
- private $notContains = [];
- private $paths = [];
- private $notPaths = [];
- private $ignoreUnreadableDirs = false;
-
- private static $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];
+ private int $mode = 0;
+ private array $names = [];
+ private array $notNames = [];
+ private array $exclude = [];
+ private array $filters = [];
+ private array $depths = [];
+ private array $sizes = [];
+ private bool $followLinks = false;
+ private bool $reverseSorting = false;
+ private \Closure|int|false $sort = false;
+ private int $ignore = 0;
+ private array $dirs = [];
+ private array $dates = [];
+ private array $iterators = [];
+ private array $contains = [];
+ private array $notContains = [];
+ private array $paths = [];
+ private array $notPaths = [];
+ private bool $ignoreUnreadableDirs = false;
+
+ private static array $vcsPatterns = ['.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg'];
public function __construct()
{
@@ -74,10 +74,8 @@ public function __construct()
/**
* Creates a new Finder.
- *
- * @return static
*/
- public static function create()
+ public static function create(): static
{
return new static();
}
@@ -87,7 +85,7 @@ public static function create()
*
* @return $this
*/
- public function directories()
+ public function directories(): static
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
@@ -99,7 +97,7 @@ public function directories()
*
* @return $this
*/
- public function files()
+ public function files(): static
{
$this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
@@ -122,7 +120,7 @@ public function files()
* @see DepthRangeFilterIterator
* @see NumberComparator
*/
- public function depth($levels)
+ public function depth(string|int|array $levels): static
{
foreach ((array) $levels as $level) {
$this->depths[] = new Comparator\NumberComparator($level);
@@ -150,7 +148,7 @@ public function depth($levels)
* @see DateRangeFilterIterator
* @see DateComparator
*/
- public function date($dates)
+ public function date(string|array $dates): static
{
foreach ((array) $dates as $date) {
$this->dates[] = new Comparator\DateComparator($date);
@@ -175,7 +173,7 @@ public function date($dates)
*
* @see FilenameFilterIterator
*/
- public function name($patterns)
+ public function name(string|array $patterns): static
{
$this->names = array_merge($this->names, (array) $patterns);
@@ -191,7 +189,7 @@ public function name($patterns)
*
* @see FilenameFilterIterator
*/
- public function notName($patterns)
+ public function notName(string|array $patterns): static
{
$this->notNames = array_merge($this->notNames, (array) $patterns);
@@ -213,7 +211,7 @@ public function notName($patterns)
*
* @see FilecontentFilterIterator
*/
- public function contains($patterns)
+ public function contains(string|array $patterns): static
{
$this->contains = array_merge($this->contains, (array) $patterns);
@@ -235,7 +233,7 @@ public function contains($patterns)
*
* @see FilecontentFilterIterator
*/
- public function notContains($patterns)
+ public function notContains(string|array $patterns): static
{
$this->notContains = array_merge($this->notContains, (array) $patterns);
@@ -259,7 +257,7 @@ public function notContains($patterns)
*
* @see FilenameFilterIterator
*/
- public function path($patterns)
+ public function path(string|array $patterns): static
{
$this->paths = array_merge($this->paths, (array) $patterns);
@@ -283,7 +281,7 @@ public function path($patterns)
*
* @see FilenameFilterIterator
*/
- public function notPath($patterns)
+ public function notPath(string|array $patterns): static
{
$this->notPaths = array_merge($this->notPaths, (array) $patterns);
@@ -305,7 +303,7 @@ public function notPath($patterns)
* @see SizeRangeFilterIterator
* @see NumberComparator
*/
- public function size($sizes)
+ public function size(string|int|array $sizes): static
{
foreach ((array) $sizes as $size) {
$this->sizes[] = new Comparator\NumberComparator($size);
@@ -327,7 +325,7 @@ public function size($sizes)
*
* @see ExcludeDirectoryFilterIterator
*/
- public function exclude($dirs)
+ public function exclude(string|array $dirs): static
{
$this->exclude = array_merge($this->exclude, (array) $dirs);
@@ -343,7 +341,7 @@ public function exclude($dirs)
*
* @see ExcludeDirectoryFilterIterator
*/
- public function ignoreDotFiles(bool $ignoreDotFiles)
+ public function ignoreDotFiles(bool $ignoreDotFiles): static
{
if ($ignoreDotFiles) {
$this->ignore |= static::IGNORE_DOT_FILES;
@@ -363,7 +361,7 @@ public function ignoreDotFiles(bool $ignoreDotFiles)
*
* @see ExcludeDirectoryFilterIterator
*/
- public function ignoreVCS(bool $ignoreVCS)
+ public function ignoreVCS(bool $ignoreVCS): static
{
if ($ignoreVCS) {
$this->ignore |= static::IGNORE_VCS_FILES;
@@ -381,7 +379,7 @@ public function ignoreVCS(bool $ignoreVCS)
*
* @return $this
*/
- public function ignoreVCSIgnored(bool $ignoreVCSIgnored)
+ public function ignoreVCSIgnored(bool $ignoreVCSIgnored): static
{
if ($ignoreVCSIgnored) {
$this->ignore |= static::IGNORE_VCS_IGNORED_FILES;
@@ -398,8 +396,10 @@ public function ignoreVCSIgnored(bool $ignoreVCSIgnored)
* @see ignoreVCS()
*
* @param string|string[] $pattern VCS patterns to ignore
+ *
+ * @return void
*/
- public static function addVCSPattern($pattern)
+ public static function addVCSPattern(string|array $pattern)
{
foreach ((array) $pattern as $p) {
self::$vcsPatterns[] = $p;
@@ -419,7 +419,7 @@ public static function addVCSPattern($pattern)
*
* @see SortableIterator
*/
- public function sort(\Closure $closure)
+ public function sort(\Closure $closure): static
{
$this->sort = $closure;
@@ -451,7 +451,7 @@ public function sortByExtension(): static
*
* @see SortableIterator
*/
- public function sortByName(bool $useNaturalSort = false)
+ public function sortByName(bool $useNaturalSort = false): static
{
$this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME;
@@ -499,7 +499,7 @@ public function sortBySize(): static
*
* @see SortableIterator
*/
- public function sortByType()
+ public function sortByType(): static
{
$this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
@@ -517,7 +517,7 @@ public function sortByType()
*
* @see SortableIterator
*/
- public function sortByAccessedTime()
+ public function sortByAccessedTime(): static
{
$this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
@@ -529,7 +529,7 @@ public function sortByAccessedTime()
*
* @return $this
*/
- public function reverseSorting()
+ public function reverseSorting(): static
{
$this->reverseSorting = true;
@@ -549,7 +549,7 @@ public function reverseSorting()
*
* @see SortableIterator
*/
- public function sortByChangedTime()
+ public function sortByChangedTime(): static
{
$this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
@@ -567,7 +567,7 @@ public function sortByChangedTime()
*
* @see SortableIterator
*/
- public function sortByModifiedTime()
+ public function sortByModifiedTime(): static
{
$this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
@@ -584,7 +584,7 @@ public function sortByModifiedTime()
*
* @see CustomFilterIterator
*/
- public function filter(\Closure $closure)
+ public function filter(\Closure $closure): static
{
$this->filters[] = $closure;
@@ -596,7 +596,7 @@ public function filter(\Closure $closure)
*
* @return $this
*/
- public function followLinks()
+ public function followLinks(): static
{
$this->followLinks = true;
@@ -610,7 +610,7 @@ public function followLinks()
*
* @return $this
*/
- public function ignoreUnreadableDirs(bool $ignore = true)
+ public function ignoreUnreadableDirs(bool $ignore = true): static
{
$this->ignoreUnreadableDirs = $ignore;
@@ -626,7 +626,7 @@ public function ignoreUnreadableDirs(bool $ignore = true)
*
* @throws DirectoryNotFoundException if one of the directories does not exist
*/
- public function in($dirs)
+ public function in(string|array $dirs): static
{
$resolvedDirs = [];
@@ -655,8 +655,7 @@ public function in($dirs)
*
* @throws \LogicException if the in() method has not been called
*/
- #[\ReturnTypeWillChange]
- public function getIterator()
+ public function getIterator(): \Iterator
{
if (0 === \count($this->dirs) && 0 === \count($this->iterators)) {
throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
@@ -674,9 +673,7 @@ public function getIterator()
$iterator = new \AppendIterator();
foreach ($this->dirs as $dir) {
- $iterator->append(new \IteratorIterator(new LazyIterator(function () use ($dir) {
- return $this->searchInDirectory($dir);
- })));
+ $iterator->append(new \IteratorIterator(new LazyIterator(fn () => $this->searchInDirectory($dir))));
}
foreach ($this->iterators as $it) {
@@ -699,7 +696,7 @@ public function getIterator()
*
* @throws \InvalidArgumentException when the given argument is not iterable
*/
- public function append(iterable $iterator)
+ public function append(iterable $iterator): static
{
if ($iterator instanceof \IteratorAggregate) {
$this->iterators[] = $iterator->getIterator();
@@ -721,10 +718,8 @@ public function append(iterable $iterator)
/**
* Check if any results were found.
- *
- * @return bool
*/
- public function hasResults()
+ public function hasResults(): bool
{
foreach ($this->getIterator() as $_) {
return true;
@@ -735,11 +730,8 @@ public function hasResults()
/**
* Counts all the results collected by the iterators.
- *
- * @return int
*/
- #[\ReturnTypeWillChange]
- public function count()
+ public function count(): int
{
return iterator_count($this->getIterator());
}
diff --git a/core/vendor/symfony/finder/Gitignore.php b/core/vendor/symfony/finder/Gitignore.php
index 070074b3ba..bf05c5b379 100644
--- a/core/vendor/symfony/finder/Gitignore.php
+++ b/core/vendor/symfony/finder/Gitignore.php
@@ -79,9 +79,7 @@ private static function lineToRegex(string $gitignoreLine): string
}
$regex = preg_quote(str_replace('\\', '', $gitignoreLine), '~');
- $regex = preg_replace_callback('~\\\\\[((?:\\\\!)?)([^\[\]]*)\\\\\]~', function (array $matches): string {
- return '['.('' !== $matches[1] ? '^' : '').str_replace('\\-', '-', $matches[2]).']';
- }, $regex);
+ $regex = preg_replace_callback('~\\\\\[((?:\\\\!)?)([^\[\]]*)\\\\\]~', fn (array $matches): string => '['.('' !== $matches[1] ? '^' : '').str_replace('\\-', '-', $matches[2]).']', $regex);
$regex = preg_replace('~(?:(?:\\\\\*){2,}(/?))+~', '(?:(?:(?!//).(? $iterator The Iterator to filter
@@ -45,11 +45,8 @@ public function __construct(\Iterator $iterator, array $filters)
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
$fileinfo = $this->current();
diff --git a/core/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php b/core/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
index f592e1913b..718d42b162 100644
--- a/core/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/DateRangeFilterIterator.php
@@ -22,7 +22,7 @@
*/
class DateRangeFilterIterator extends \FilterIterator
{
- private $comparators = [];
+ private array $comparators = [];
/**
* @param \Iterator $iterator
@@ -37,11 +37,8 @@ public function __construct(\Iterator $iterator, array $comparators)
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
$fileinfo = $this->current();
diff --git a/core/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php b/core/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
index f593a3f082..1cddb5fa8c 100644
--- a/core/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/DepthRangeFilterIterator.php
@@ -23,7 +23,7 @@
*/
class DepthRangeFilterIterator extends \FilterIterator
{
- private $minDepth = 0;
+ private int $minDepth = 0;
/**
* @param \RecursiveIteratorIterator<\RecursiveIterator> $iterator The Iterator to filter
@@ -40,11 +40,8 @@ public function __construct(\RecursiveIteratorIterator $iterator, int $minDepth
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
return $this->getInnerIterator()->getDepth() >= $this->minDepth;
}
diff --git a/core/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php b/core/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
index 0a931c9925..21303781eb 100644
--- a/core/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/FileTypeFilterIterator.php
@@ -23,7 +23,7 @@ class FileTypeFilterIterator extends \FilterIterator
public const ONLY_FILES = 1;
public const ONLY_DIRECTORIES = 2;
- private $mode;
+ private int $mode;
/**
* @param \Iterator $iterator The Iterator to filter
@@ -38,11 +38,8 @@ public function __construct(\Iterator $iterator, int $mode)
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
$fileinfo = $this->current();
if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
diff --git a/core/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php b/core/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
index 59358ba3c6..bdc71ffdd9 100644
--- a/core/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/FilecontentFilterIterator.php
@@ -25,11 +25,8 @@ class FilecontentFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
if (!$this->matchRegexps && !$this->noMatchRegexps) {
return true;
@@ -53,10 +50,8 @@ public function accept()
* Converts string to regexp if necessary.
*
* @param string $str Pattern: string or regexp
- *
- * @return string
*/
- protected function toRegex(string $str)
+ protected function toRegex(string $str): string
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
diff --git a/core/vendor/symfony/finder/Iterator/FilenameFilterIterator.php b/core/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
index 77b3b24193..05d9535811 100644
--- a/core/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/FilenameFilterIterator.php
@@ -24,11 +24,8 @@ class FilenameFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
return $this->isAccepted($this->current()->getFilename());
}
@@ -40,10 +37,8 @@ public function accept()
* Glob strings are transformed with Glob::toRegex().
*
* @param string $str Pattern: glob or regexp
- *
- * @return string
*/
- protected function toRegex(string $str)
+ protected function toRegex(string $str): string
{
return $this->isRegex($str) ? $str : Glob::toRegex($str);
}
diff --git a/core/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php b/core/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
index a2ec902b47..82a9df301c 100644
--- a/core/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/MultiplePcreFilterIterator.php
@@ -50,10 +50,8 @@ public function __construct(\Iterator $iterator, array $matchPatterns, array $no
* If there is no regexps defined in the class, this method will accept the string.
* Such case can be handled by child classes before calling the method if they want to
* apply a different behavior.
- *
- * @return bool
*/
- protected function isAccepted(string $string)
+ protected function isAccepted(string $string): bool
{
// should at least not match one rule to exclude
foreach ($this->noMatchRegexps as $regex) {
@@ -79,10 +77,8 @@ protected function isAccepted(string $string)
/**
* Checks whether the string is a regex.
- *
- * @return bool
*/
- protected function isRegex(string $str)
+ protected function isRegex(string $str): bool
{
$availableModifiers = 'imsxuADU';
@@ -110,8 +106,6 @@ protected function isRegex(string $str)
/**
* Converts string into regexp.
- *
- * @return string
*/
- abstract protected function toRegex(string $str);
+ abstract protected function toRegex(string $str): string;
}
diff --git a/core/vendor/symfony/finder/Iterator/PathFilterIterator.php b/core/vendor/symfony/finder/Iterator/PathFilterIterator.php
index 85f2be7e25..c6d58139f5 100644
--- a/core/vendor/symfony/finder/Iterator/PathFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/PathFilterIterator.php
@@ -25,11 +25,8 @@ class PathFilterIterator extends MultiplePcreFilterIterator
{
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
$filename = $this->current()->getRelativePathname();
@@ -51,10 +48,8 @@ public function accept()
* Use only / as directory separator (on Windows also).
*
* @param string $str Pattern: regexp or dirname
- *
- * @return string
*/
- protected function toRegex(string $str)
+ protected function toRegex(string $str): string
{
return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
}
diff --git a/core/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/core/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
index 68c0908b1b..3582e6c168 100644
--- a/core/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
+++ b/core/vendor/symfony/finder/Iterator/RecursiveDirectoryIterator.php
@@ -23,20 +23,13 @@
*/
class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
{
- /**
- * @var bool
- */
- private $ignoreUnreadableDirs;
-
- /**
- * @var bool
- */
- private $rewindable;
+ private bool $ignoreUnreadableDirs;
+ private ?bool $rewindable = null;
// these 3 properties take part of the performance optimization to avoid redoing the same work in all iterations
- private $rootPath;
- private $subPath;
- private $directorySeparator = '/';
+ private string $rootPath;
+ private string $subPath;
+ private string $directorySeparator = '/';
/**
* @throws \RuntimeException
@@ -57,17 +50,15 @@ public function __construct(string $path, int $flags, bool $ignoreUnreadableDirs
/**
* Return an instance of SplFileInfo with support for relative paths.
- *
- * @return SplFileInfo
*/
- #[\ReturnTypeWillChange]
- public function current()
+ public function current(): SplFileInfo
{
// the logic here avoids redoing the same work in all iterations
- if (null === $subPathname = $this->subPath) {
- $subPathname = $this->subPath = $this->getSubPath();
+ if (!isset($this->subPath)) {
+ $this->subPath = $this->getSubPath();
}
+ $subPathname = $this->subPath;
if ('' !== $subPathname) {
$subPathname .= $this->directorySeparator;
}
@@ -80,13 +71,7 @@ public function current()
return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname);
}
- /**
- * @param bool $allowLinks
- *
- * @return bool
- */
- #[\ReturnTypeWillChange]
- public function hasChildren($allowLinks = false)
+ public function hasChildren(bool $allowLinks = false): bool
{
$hasChildren = parent::hasChildren($allowLinks);
@@ -105,12 +90,9 @@ public function hasChildren($allowLinks = false)
}
/**
- * @return \RecursiveDirectoryIterator
- *
* @throws AccessDeniedException
*/
- #[\ReturnTypeWillChange]
- public function getChildren()
+ public function getChildren(): \RecursiveDirectoryIterator
{
try {
$children = parent::getChildren();
@@ -132,11 +114,8 @@ public function getChildren()
/**
* Do nothing for non rewindable stream.
- *
- * @return void
*/
- #[\ReturnTypeWillChange]
- public function rewind()
+ public function rewind(): void
{
if (false === $this->isRewindable()) {
return;
@@ -147,10 +126,8 @@ public function rewind()
/**
* Checks if the stream is rewindable.
- *
- * @return bool
*/
- public function isRewindable()
+ public function isRewindable(): bool
{
if (null !== $this->rewindable) {
return $this->rewindable;
diff --git a/core/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php b/core/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
index 575bf29b7e..925830a2e9 100644
--- a/core/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/SizeRangeFilterIterator.php
@@ -22,7 +22,7 @@
*/
class SizeRangeFilterIterator extends \FilterIterator
{
- private $comparators = [];
+ private array $comparators = [];
/**
* @param \Iterator $iterator
@@ -37,11 +37,8 @@ public function __construct(\Iterator $iterator, array $comparators)
/**
* Filters the iterator values.
- *
- * @return bool
*/
- #[\ReturnTypeWillChange]
- public function accept()
+ public function accept(): bool
{
$fileinfo = $this->current();
if (!$fileinfo->isFile()) {
diff --git a/core/vendor/symfony/finder/Iterator/SortableIterator.php b/core/vendor/symfony/finder/Iterator/SortableIterator.php
index e8b556502e..177cd0b602 100644
--- a/core/vendor/symfony/finder/Iterator/SortableIterator.php
+++ b/core/vendor/symfony/finder/Iterator/SortableIterator.php
@@ -48,21 +48,13 @@ public function __construct(\Traversable $iterator, int|callable $sort, bool $re
$order = $reverseOrder ? -1 : 1;
if (self::SORT_BY_NAME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_NAME_NATURAL === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_NAME_CASE_INSENSITIVE === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcasecmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
} elseif (self::SORT_BY_TYPE === $sort) {
$this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
if ($a->isDir() && $b->isFile()) {
@@ -74,29 +66,19 @@ public function __construct(\Traversable $iterator, int|callable $sort, bool $re
return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
};
} elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getATime() - $b->getATime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getATime() - $b->getATime());
} elseif (self::SORT_BY_CHANGED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getCTime() - $b->getCTime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getCTime() - $b->getCTime());
} elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getMTime() - $b->getMTime());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getMTime() - $b->getMTime());
} elseif (self::SORT_BY_EXTENSION === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * strnatcmp($a->getExtension(), $b->getExtension());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * strnatcmp($a->getExtension(), $b->getExtension());
} elseif (self::SORT_BY_SIZE === $sort) {
- $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
- return $order * ($a->getSize() - $b->getSize());
- };
+ $this->sort = static fn (\SplFileInfo $a, \SplFileInfo $b) => $order * ($a->getSize() - $b->getSize());
} elseif (self::SORT_BY_NONE === $sort) {
$this->sort = $order;
} elseif (\is_callable($sort)) {
- $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : $sort(...);
+ $this->sort = $reverseOrder ? static fn (\SplFileInfo $a, \SplFileInfo $b) => -$sort($a, $b) : $sort(...);
} else {
throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
}
diff --git a/core/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/core/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
index 29fc2d99b1..7e6051d389 100644
--- a/core/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
+++ b/core/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php
@@ -126,9 +126,7 @@ private function parentDirectoriesUpTo(string $from, string $upTo): array
{
return array_filter(
$this->parentDirectoriesUpwards($from),
- static function (string $directory) use ($upTo): bool {
- return str_starts_with($directory, $upTo);
- }
+ static fn (string $directory): bool => str_starts_with($directory, $upTo)
);
}
diff --git a/core/vendor/symfony/finder/SplFileInfo.php b/core/vendor/symfony/finder/SplFileInfo.php
index 11604a2efa..867e8e81a2 100644
--- a/core/vendor/symfony/finder/SplFileInfo.php
+++ b/core/vendor/symfony/finder/SplFileInfo.php
@@ -18,8 +18,8 @@
*/
class SplFileInfo extends \SplFileInfo
{
- private $relativePath;
- private $relativePathname;
+ private string $relativePath;
+ private string $relativePathname;
/**
* @param string $file The file name
@@ -37,10 +37,8 @@ public function __construct(string $file, string $relativePath, string $relative
* Returns the relative path.
*
* This path does not contain the file name.
- *
- * @return string
*/
- public function getRelativePath()
+ public function getRelativePath(): string
{
return $this->relativePath;
}
@@ -49,10 +47,8 @@ public function getRelativePath()
* Returns the relative path name.
*
* This path contains the file name.
- *
- * @return string
*/
- public function getRelativePathname()
+ public function getRelativePathname(): string
{
return $this->relativePathname;
}
@@ -67,11 +63,9 @@ public function getFilenameWithoutExtension(): string
/**
* Returns the contents of the file.
*
- * @return string
- *
* @throws \RuntimeException
*/
- public function getContents()
+ public function getContents(): string
{
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
try {
diff --git a/core/vendor/symfony/http-foundation/AcceptHeader.php b/core/vendor/symfony/http-foundation/AcceptHeader.php
index 180e9604c7..853c000e00 100644
--- a/core/vendor/symfony/http-foundation/AcceptHeader.php
+++ b/core/vendor/symfony/http-foundation/AcceptHeader.php
@@ -46,11 +46,10 @@ public function __construct(array $items)
*/
public static function fromString(?string $headerValue): self
{
- $index = 0;
-
$parts = HeaderUtils::split($headerValue ?? '', ',;=');
- return new self(array_map(function ($subParts) use (&$index) {
+ return new self(array_map(function ($subParts) {
+ static $index = 0;
$part = array_shift($subParts);
$attributes = HeaderUtils::combine($subParts);
@@ -115,9 +114,7 @@ public function all(): array
*/
public function filter(string $pattern): self
{
- return new self(array_filter($this->items, function (AcceptHeaderItem $item) use ($pattern) {
- return preg_match($pattern, $item->getValue());
- }));
+ return new self(array_filter($this->items, fn (AcceptHeaderItem $item) => preg_match($pattern, $item->getValue())));
}
/**
diff --git a/core/vendor/symfony/http-foundation/BinaryFileResponse.php b/core/vendor/symfony/http-foundation/BinaryFileResponse.php
index 72cef7c0ea..cd716e590e 100644
--- a/core/vendor/symfony/http-foundation/BinaryFileResponse.php
+++ b/core/vendor/symfony/http-foundation/BinaryFileResponse.php
@@ -319,7 +319,7 @@ public function sendContent(): static
while ('' !== $data) {
$read = fwrite($out, $data);
if (false === $read || connection_aborted()) {
- break;
+ break 2;
}
if (0 < $length) {
$length -= $read;
@@ -358,6 +358,8 @@ public function getContent(): string|false
/**
* Trust X-Sendfile-Type header.
+ *
+ * @return void
*/
public static function trustXSendfileTypeHeader()
{
diff --git a/core/vendor/symfony/http-foundation/CHANGELOG.md b/core/vendor/symfony/http-foundation/CHANGELOG.md
index fdea3d67e1..a98d23d9d1 100644
--- a/core/vendor/symfony/http-foundation/CHANGELOG.md
+++ b/core/vendor/symfony/http-foundation/CHANGELOG.md
@@ -1,9 +1,24 @@
CHANGELOG
=========
+6.3
+---
+
+ * Calling `ParameterBag::getDigit()`, `getAlnum()`, `getAlpha()` on an `array` throws a `UnexpectedValueException` instead of a `TypeError`
+ * Add `ParameterBag::getString()` to convert a parameter into string and throw an exception if the value is invalid
+ * Add `ParameterBag::getEnum()`
+ * Create migration for session table when pdo handler is used
+ * Add support for Relay PHP extension for Redis
+ * The `Response::sendHeaders()` method now takes an optional HTTP status code as parameter, allowing to send informational responses such as Early Hints responses (103 status code)
+ * Add `IpUtils::isPrivateIp()`
+ * Add `Request::getPayload(): InputBag`
+ * Deprecate conversion of invalid values in `ParameterBag::getInt()` and `ParameterBag::getBoolean()`,
+ * Deprecate ignoring invalid values when using `ParameterBag::filter()`, unless flag `FILTER_NULL_ON_FAILURE` is set
+
6.2
---
+ * Add `StreamedJsonResponse` class for efficient JSON streaming
* The HTTP cache store uses the `xxh128` algorithm
* Deprecate calling `JsonResponse::setCallback()`, `Response::setExpires/setLastModified/setEtag()`, `MockArraySessionStorage/NativeSessionStorage::setMetadataBag()`, `NativeSessionStorage::setSaveHandler()` without arguments
* Add request matchers under the `Symfony\Component\HttpFoundation\RequestMatcher` namespace
diff --git a/core/vendor/symfony/http-foundation/ExpressionRequestMatcher.php b/core/vendor/symfony/http-foundation/ExpressionRequestMatcher.php
index 5628ea8bc1..fe65e920d9 100644
--- a/core/vendor/symfony/http-foundation/ExpressionRequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/ExpressionRequestMatcher.php
@@ -29,6 +29,9 @@ class ExpressionRequestMatcher extends RequestMatcher
private ExpressionLanguage $language;
private Expression|string $expression;
+ /**
+ * @return void
+ */
public function setExpression(ExpressionLanguage $language, Expression|string $expression)
{
$this->language = $language;
@@ -38,7 +41,7 @@ public function setExpression(ExpressionLanguage $language, Expression|string $e
public function matches(Request $request): bool
{
if (!isset($this->language)) {
- throw new \LogicException('Unable to match the request as the expression language is not available.');
+ throw new \LogicException('Unable to match the request as the expression language is not available. Try running "composer require symfony/expression-language".');
}
return $this->language->evaluate($this->expression, [
diff --git a/core/vendor/symfony/http-foundation/FileBag.php b/core/vendor/symfony/http-foundation/FileBag.php
index 7ed39408fd..b74a02e2e1 100644
--- a/core/vendor/symfony/http-foundation/FileBag.php
+++ b/core/vendor/symfony/http-foundation/FileBag.php
@@ -31,12 +31,18 @@ public function __construct(array $parameters = [])
$this->replace($parameters);
}
+ /**
+ * @return void
+ */
public function replace(array $files = [])
{
$this->parameters = [];
$this->add($files);
}
+ /**
+ * @return void
+ */
public function set(string $key, mixed $value)
{
if (!\is_array($value) && !$value instanceof UploadedFile) {
@@ -46,6 +52,9 @@ public function set(string $key, mixed $value)
parent::set($key, $this->convertFileInformation($value));
}
+ /**
+ * @return void
+ */
public function add(array $files = [])
{
foreach ($files as $key => $file) {
@@ -75,7 +84,7 @@ protected function convertFileInformation(array|UploadedFile $file): array|Uploa
$file = new UploadedFile($file['tmp_name'], $file['name'], $file['type'], $file['error'], false);
}
} else {
- $file = array_map(function ($v) { return $v instanceof UploadedFile || \is_array($v) ? $this->convertFileInformation($v) : $v; }, $file);
+ $file = array_map(fn ($v) => $v instanceof UploadedFile || \is_array($v) ? $this->convertFileInformation($v) : $v, $file);
if (array_keys($keys) === $keys) {
$file = array_filter($file);
}
diff --git a/core/vendor/symfony/http-foundation/HeaderBag.php b/core/vendor/symfony/http-foundation/HeaderBag.php
index 0883024b3b..c49a239726 100644
--- a/core/vendor/symfony/http-foundation/HeaderBag.php
+++ b/core/vendor/symfony/http-foundation/HeaderBag.php
@@ -63,7 +63,7 @@ public function __toString(): string
*
* @param string|null $key The name of the headers to return or null to get them all
*
- * @return array>|array
+ * @return ($key is null ? array> : list)
*/
public function all(string $key = null): array
{
@@ -86,6 +86,8 @@ public function keys(): array
/**
* Replaces the current HTTP headers by a new set.
+ *
+ * @return void
*/
public function replace(array $headers = [])
{
@@ -95,6 +97,8 @@ public function replace(array $headers = [])
/**
* Adds new headers the current HTTP headers set.
+ *
+ * @return void
*/
public function add(array $headers)
{
@@ -126,6 +130,8 @@ public function get(string $key, string $default = null): ?string
*
* @param string|string[]|null $values The value or an array of values
* @param bool $replace Whether to replace the actual value or not (true by default)
+ *
+ * @return void
*/
public function set(string $key, string|array|null $values, bool $replace = true)
{
@@ -170,6 +176,8 @@ public function contains(string $key, string $value): bool
/**
* Removes a header.
+ *
+ * @return void
*/
public function remove(string $key)
{
@@ -202,6 +210,8 @@ public function getDate(string $key, \DateTime $default = null): ?\DateTimeInter
/**
* Adds a custom Cache-Control directive.
+ *
+ * @return void
*/
public function addCacheControlDirective(string $key, bool|string $value = true)
{
@@ -228,6 +238,8 @@ public function getCacheControlDirective(string $key): bool|string|null
/**
* Removes a Cache-Control directive.
+ *
+ * @return void
*/
public function removeCacheControlDirective(string $key)
{
@@ -254,6 +266,9 @@ public function count(): int
return \count($this->headers);
}
+ /**
+ * @return string
+ */
protected function getCacheControlHeader()
{
ksort($this->cacheControl);
diff --git a/core/vendor/symfony/http-foundation/InputBag.php b/core/vendor/symfony/http-foundation/InputBag.php
index 877ac60f3a..77990f5711 100644
--- a/core/vendor/symfony/http-foundation/InputBag.php
+++ b/core/vendor/symfony/http-foundation/InputBag.php
@@ -43,7 +43,7 @@ public function get(string $key, mixed $default = null): string|int|float|bool|n
/**
* Replaces the current input values by a new set.
*/
- public function replace(array $inputs = [])
+ public function replace(array $inputs = []): void
{
$this->parameters = [];
$this->add($inputs);
@@ -52,7 +52,7 @@ public function replace(array $inputs = [])
/**
* Adds input values.
*/
- public function add(array $inputs = [])
+ public function add(array $inputs = []): void
{
foreach ($inputs as $input => $value) {
$this->set($input, $value);
@@ -64,7 +64,7 @@ public function add(array $inputs = [])
*
* @param string|int|float|bool|array|null $value
*/
- public function set(string $key, mixed $value)
+ public function set(string $key, mixed $value): void
{
if (null !== $value && !\is_scalar($value) && !\is_array($value) && !$value instanceof \Stringable) {
throw new \InvalidArgumentException(sprintf('Expected a scalar, or an array as a 2nd argument to "%s()", "%s" given.', __METHOD__, get_debug_type($value)));
@@ -73,6 +73,34 @@ public function set(string $key, mixed $value)
$this->parameters[$key] = $value;
}
+ /**
+ * Returns the parameter value converted to an enum.
+ *
+ * @template T of \BackedEnum
+ *
+ * @param class-string $class
+ * @param ?T $default
+ *
+ * @return ?T
+ */
+ public function getEnum(string $key, string $class, \BackedEnum $default = null): ?\BackedEnum
+ {
+ try {
+ return parent::getEnum($key, $class, $default);
+ } catch (\UnexpectedValueException $e) {
+ throw new BadRequestException($e->getMessage(), $e->getCode(), $e);
+ }
+ }
+
+ /**
+ * Returns the parameter value converted to string.
+ */
+ public function getString(string $key, string $default = ''): string
+ {
+ // Shortcuts the parent method because the validation on scalar is already done in get().
+ return (string) $this->get($key, $default);
+ }
+
public function filter(string $key, mixed $default = null, int $filter = \FILTER_DEFAULT, mixed $options = []): mixed
{
$value = $this->has($key) ? $this->all()[$key] : $default;
@@ -90,6 +118,22 @@ public function filter(string $key, mixed $default = null, int $filter = \FILTER
throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null)));
}
- return filter_var($value, $filter, $options);
+ $options['flags'] ??= 0;
+ $nullOnFailure = $options['flags'] & \FILTER_NULL_ON_FAILURE;
+ $options['flags'] |= \FILTER_NULL_ON_FAILURE;
+
+ $value = filter_var($value, $filter, $options);
+
+ if (null !== $value || $nullOnFailure) {
+ return $value;
+ }
+
+ $method = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1];
+ $method = ($method['object'] ?? null) === $this ? $method['function'] : 'filter';
+ $hint = 'filter' === $method ? 'pass' : 'use method "filter()" with';
+
+ trigger_deprecation('symfony/http-foundation', '6.3', 'Ignoring invalid values when using "%s::%s(\'%s\')" is deprecated and will throw a "%s" in 7.0; '.$hint.' flag "FILTER_NULL_ON_FAILURE" to keep ignoring them.', $this::class, $method, $key, BadRequestException::class);
+
+ return false;
}
}
diff --git a/core/vendor/symfony/http-foundation/IpUtils.php b/core/vendor/symfony/http-foundation/IpUtils.php
index 917eb6e1a4..ceab620c2f 100644
--- a/core/vendor/symfony/http-foundation/IpUtils.php
+++ b/core/vendor/symfony/http-foundation/IpUtils.php
@@ -18,6 +18,21 @@
*/
class IpUtils
{
+ public const PRIVATE_SUBNETS = [
+ '127.0.0.0/8', // RFC1700 (Loopback)
+ '10.0.0.0/8', // RFC1918
+ '192.168.0.0/16', // RFC1918
+ '172.16.0.0/12', // RFC1918
+ '169.254.0.0/16', // RFC3927
+ '0.0.0.0/8', // RFC5735
+ '240.0.0.0/4', // RFC1112
+ '::1/128', // Loopback
+ 'fc00::/7', // Unique Local Address
+ 'fe80::/10', // Link Local Address
+ '::ffff:0:0/96', // IPv4 translations
+ '::/128', // Unspecified address
+ ];
+
private static array $checkedIps = [];
/**
@@ -60,23 +75,23 @@ public static function checkIp(string $requestIp, string|array $ips): bool
public static function checkIp4(string $requestIp, string $ip): bool
{
$cacheKey = $requestIp.'-'.$ip.'-v4';
- if (isset(self::$checkedIps[$cacheKey])) {
- return self::$checkedIps[$cacheKey];
+ if (null !== $cacheValue = self::getCacheResult($cacheKey)) {
+ return $cacheValue;
}
if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
if (str_contains($ip, '/')) {
[$address, $netmask] = explode('/', $ip, 2);
if ('0' === $netmask) {
- return self::$checkedIps[$cacheKey] = false !== filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4);
+ return self::setCacheResult($cacheKey, false !== filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4));
}
if ($netmask < 0 || $netmask > 32) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
} else {
$address = $ip;
@@ -84,10 +99,10 @@ public static function checkIp4(string $requestIp, string $ip): bool
}
if (false === ip2long($address)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
- return self::$checkedIps[$cacheKey] = 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask);
+ return self::setCacheResult($cacheKey, 0 === substr_compare(sprintf('%032b', ip2long($requestIp)), sprintf('%032b', ip2long($address)), 0, $netmask));
}
/**
@@ -105,8 +120,8 @@ public static function checkIp4(string $requestIp, string $ip): bool
public static function checkIp6(string $requestIp, string $ip): bool
{
$cacheKey = $requestIp.'-'.$ip.'-v6';
- if (isset(self::$checkedIps[$cacheKey])) {
- return self::$checkedIps[$cacheKey];
+ if (null !== $cacheValue = self::getCacheResult($cacheKey)) {
+ return $cacheValue;
}
if (!((\extension_loaded('sockets') && \defined('AF_INET6')) || @inet_pton('::1'))) {
@@ -115,14 +130,14 @@ public static function checkIp6(string $requestIp, string $ip): bool
// Check to see if we were given a IP4 $requestIp or $ip by mistake
if (!filter_var($requestIp, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
if (str_contains($ip, '/')) {
[$address, $netmask] = explode('/', $ip, 2);
if (!filter_var($address, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
if ('0' === $netmask) {
@@ -130,11 +145,11 @@ public static function checkIp6(string $requestIp, string $ip): bool
}
if ($netmask < 1 || $netmask > 128) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
} else {
if (!filter_var($ip, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
$address = $ip;
@@ -145,7 +160,7 @@ public static function checkIp6(string $requestIp, string $ip): bool
$bytesTest = unpack('n*', @inet_pton($requestIp));
if (!$bytesAddr || !$bytesTest) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
for ($i = 1, $ceil = ceil($netmask / 16); $i <= $ceil; ++$i) {
@@ -153,11 +168,11 @@ public static function checkIp6(string $requestIp, string $ip): bool
$left = ($left <= 16) ? $left : 16;
$mask = ~(0xFFFF >> $left) & 0xFFFF;
if (($bytesAddr[$i] & $mask) != ($bytesTest[$i] & $mask)) {
- return self::$checkedIps[$cacheKey] = false;
+ return self::setCacheResult($cacheKey, false);
}
}
- return self::$checkedIps[$cacheKey] = true;
+ return self::setCacheResult($cacheKey, true);
}
/**
@@ -191,4 +206,36 @@ public static function anonymize(string $ip): string
return $ip;
}
+
+ /**
+ * Checks if an IPv4 or IPv6 address is contained in the list of private IP subnets.
+ */
+ public static function isPrivateIp(string $requestIp): bool
+ {
+ return self::checkIp($requestIp, self::PRIVATE_SUBNETS);
+ }
+
+ private static function getCacheResult(string $cacheKey): ?bool
+ {
+ if (isset(self::$checkedIps[$cacheKey])) {
+ // Move the item last in cache (LRU)
+ $value = self::$checkedIps[$cacheKey];
+ unset(self::$checkedIps[$cacheKey]);
+ self::$checkedIps[$cacheKey] = $value;
+
+ return self::$checkedIps[$cacheKey];
+ }
+
+ return null;
+ }
+
+ private static function setCacheResult(string $cacheKey, bool $result): bool
+ {
+ if (1000 < \count(self::$checkedIps)) {
+ // stop memory leak if there are many keys
+ self::$checkedIps = \array_slice(self::$checkedIps, 500, null, true);
+ }
+
+ return self::$checkedIps[$cacheKey] = $result;
+ }
}
diff --git a/core/vendor/symfony/http-foundation/ParameterBag.php b/core/vendor/symfony/http-foundation/ParameterBag.php
index 72c8f0949c..9d7012de35 100644
--- a/core/vendor/symfony/http-foundation/ParameterBag.php
+++ b/core/vendor/symfony/http-foundation/ParameterBag.php
@@ -60,6 +60,8 @@ public function keys(): array
/**
* Replaces the current parameters by a new set.
+ *
+ * @return void
*/
public function replace(array $parameters = [])
{
@@ -68,6 +70,8 @@ public function replace(array $parameters = [])
/**
* Adds parameters.
+ *
+ * @return void
*/
public function add(array $parameters = [])
{
@@ -79,6 +83,9 @@ public function get(string $key, mixed $default = null): mixed
return \array_key_exists($key, $this->parameters) ? $this->parameters[$key] : $default;
}
+ /**
+ * @return void
+ */
public function set(string $key, mixed $value)
{
$this->parameters[$key] = $value;
@@ -94,6 +101,8 @@ public function has(string $key): bool
/**
* Removes a parameter.
+ *
+ * @return void
*/
public function remove(string $key)
{
@@ -105,7 +114,7 @@ public function remove(string $key)
*/
public function getAlpha(string $key, string $default = ''): string
{
- return preg_replace('/[^[:alpha:]]/', '', $this->get($key, $default));
+ return preg_replace('/[^[:alpha:]]/', '', $this->getString($key, $default));
}
/**
@@ -113,7 +122,7 @@ public function getAlpha(string $key, string $default = ''): string
*/
public function getAlnum(string $key, string $default = ''): string
{
- return preg_replace('/[^[:alnum:]]/', '', $this->get($key, $default));
+ return preg_replace('/[^[:alnum:]]/', '', $this->getString($key, $default));
}
/**
@@ -121,8 +130,20 @@ public function getAlnum(string $key, string $default = ''): string
*/
public function getDigits(string $key, string $default = ''): string
{
- // we need to remove - and + because they're allowed in the filter
- return str_replace(['-', '+'], '', $this->filter($key, $default, \FILTER_SANITIZE_NUMBER_INT));
+ return preg_replace('/[^[:digit:]]/', '', $this->getString($key, $default));
+ }
+
+ /**
+ * Returns the parameter as string.
+ */
+ public function getString(string $key, string $default = ''): string
+ {
+ $value = $this->get($key, $default);
+ if (!\is_scalar($value) && !$value instanceof \Stringable) {
+ throw new \UnexpectedValueException(sprintf('Parameter value "%s" cannot be converted to "string".', $key));
+ }
+
+ return (string) $value;
}
/**
@@ -130,7 +151,8 @@ public function getDigits(string $key, string $default = ''): string
*/
public function getInt(string $key, int $default = 0): int
{
- return (int) $this->get($key, $default);
+ // In 7.0 remove the fallback to 0, in case of failure an exception will be thrown
+ return $this->filter($key, $default, \FILTER_VALIDATE_INT, ['flags' => \FILTER_REQUIRE_SCALAR]) ?: 0;
}
/**
@@ -138,13 +160,39 @@ public function getInt(string $key, int $default = 0): int
*/
public function getBoolean(string $key, bool $default = false): bool
{
- return $this->filter($key, $default, \FILTER_VALIDATE_BOOL);
+ return $this->filter($key, $default, \FILTER_VALIDATE_BOOL, ['flags' => \FILTER_REQUIRE_SCALAR]);
+ }
+
+ /**
+ * Returns the parameter value converted to an enum.
+ *
+ * @template T of \BackedEnum
+ *
+ * @param class-string $class
+ * @param ?T $default
+ *
+ * @return ?T
+ */
+ public function getEnum(string $key, string $class, \BackedEnum $default = null): ?\BackedEnum
+ {
+ $value = $this->get($key);
+
+ if (null === $value) {
+ return $default;
+ }
+
+ try {
+ return $class::from($value);
+ } catch (\ValueError|\TypeError $e) {
+ throw new \UnexpectedValueException(sprintf('Parameter "%s" cannot be converted to enum: %s.', $key, $e->getMessage()), $e->getCode(), $e);
+ }
}
/**
* Filter key.
*
- * @param int $filter FILTER_* constant
+ * @param int $filter FILTER_* constant
+ * @param int|array{flags?: int, options?: array} $options Flags from FILTER_* constants
*
* @see https://php.net/filter-var
*/
@@ -162,11 +210,31 @@ public function filter(string $key, mixed $default = null, int $filter = \FILTER
$options['flags'] = \FILTER_REQUIRE_ARRAY;
}
+ if (\is_object($value) && !$value instanceof \Stringable) {
+ throw new \UnexpectedValueException(sprintf('Parameter value "%s" cannot be filtered.', $key));
+ }
+
if ((\FILTER_CALLBACK & $filter) && !(($options['options'] ?? null) instanceof \Closure)) {
throw new \InvalidArgumentException(sprintf('A Closure must be passed to "%s()" when FILTER_CALLBACK is used, "%s" given.', __METHOD__, get_debug_type($options['options'] ?? null)));
}
- return filter_var($value, $filter, $options);
+ $options['flags'] ??= 0;
+ $nullOnFailure = $options['flags'] & \FILTER_NULL_ON_FAILURE;
+ $options['flags'] |= \FILTER_NULL_ON_FAILURE;
+
+ $value = filter_var($value, $filter, $options);
+
+ if (null !== $value || $nullOnFailure) {
+ return $value;
+ }
+
+ $method = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS | \DEBUG_BACKTRACE_PROVIDE_OBJECT, 2)[1];
+ $method = ($method['object'] ?? null) === $this ? $method['function'] : 'filter';
+ $hint = 'filter' === $method ? 'pass' : 'use method "filter()" with';
+
+ trigger_deprecation('symfony/http-foundation', '6.3', 'Ignoring invalid values when using "%s::%s(\'%s\')" is deprecated and will throw an "%s" in 7.0; '.$hint.' flag "FILTER_NULL_ON_FAILURE" to keep ignoring them.', $this::class, $method, $key, \UnexpectedValueException::class);
+
+ return false;
}
/**
diff --git a/core/vendor/symfony/http-foundation/Request.php b/core/vendor/symfony/http-foundation/Request.php
index 80866bb3ba..633b4a63e2 100644
--- a/core/vendor/symfony/http-foundation/Request.php
+++ b/core/vendor/symfony/http-foundation/Request.php
@@ -89,6 +89,8 @@ class Request
/**
* Request body parameters ($_POST).
*
+ * @see getPayload() for portability between content types
+ *
* @var InputBag
*/
public $request;
@@ -263,6 +265,8 @@ public function __construct(array $query = [], array $request = [], array $attri
* @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)
{
@@ -340,6 +344,10 @@ public static function create(string $uri, string $method = 'GET', array $parame
$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 (isset($components['host'])) {
$server['SERVER_NAME'] = $components['host'];
$server['HTTP_HOST'] = $components['host'];
@@ -417,6 +425,8 @@ public static function create(string $uri, string $method = 'GET', array $parame
* 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)
{
@@ -521,6 +531,8 @@ public function __toString(): string
*
* It overrides $_GET, $_POST, $_REQUEST, $_SERVER, $_COOKIE.
* $_FILES is never overridden, see rfc1867
+ *
+ * @return void
*/
public function overrideGlobals()
{
@@ -561,6 +573,8 @@ public function overrideGlobals()
*
* @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
*/
public static function setTrustedProxies(array $proxies, int $trustedHeaderSet)
{
@@ -602,12 +616,12 @@ public static function getTrustedHeaderSet(): int
* 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)
{
- self::$trustedHostPatterns = array_map(function ($hostPattern) {
- return 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 = [];
}
@@ -650,6 +664,8 @@ public static function normalizeQueryString(?string $qs): string
* 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()
{
@@ -735,6 +751,9 @@ public function hasSession(bool $skipIfUninitialized = false): bool
return null !== $this->session && (!$skipIfUninitialized || $this->session instanceof SessionInterface);
}
+ /**
+ * @return void
+ */
public function setSession(SessionInterface $session)
{
$this->session = $session;
@@ -745,7 +764,7 @@ public function setSession(SessionInterface $session)
*
* @param callable(): SessionInterface $factory
*/
- public function setSessionFactory(callable $factory)
+ public function setSessionFactory(callable $factory): void
{
$this->session = $factory;
}
@@ -1155,6 +1174,8 @@ public function getHost(): string
/**
* Sets the request method.
+ *
+ * @return void
*/
public function setMethod(string $method)
{
@@ -1276,6 +1297,8 @@ public function getFormat(?string $mimeType): ?string
* 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)
{
@@ -1306,6 +1329,8 @@ public function getRequestFormat(?string $default = 'html'): ?string
/**
* Sets the request format.
+ *
+ * @return void
*/
public function setRequestFormat(?string $format)
{
@@ -1336,6 +1361,8 @@ public function getContentTypeFormat(): ?string
/**
* Sets the default locale.
+ *
+ * @return void
*/
public function setDefaultLocale(string $locale)
{
@@ -1356,6 +1383,8 @@ public function getDefaultLocale(): string
/**
* Sets the locale.
+ *
+ * @return void
*/
public function setLocale(string $locale)
{
@@ -1477,9 +1506,19 @@ public function getContent(bool $asResource = false)
return $this->content;
}
+ /**
+ * Gets the decoded form or json request body.
+ */
+ public function getPayload(): InputBag
+ {
+ return $this->request->count() ? clone $this->request : new InputBag($this->toArray());
+ }
+
/**
* Gets the request body decoded as array, typically from a JSON payload.
*
+ * @see getPayload() for portability between content types
+ *
* @throws JsonException When the body cannot be decoded to an array
*/
public function toArray(): array
@@ -1693,6 +1732,9 @@ public function preferSafeContent(): bool
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (https://www.zend.com/)
*/
+ /**
+ * @return string
+ */
protected function prepareRequestUri()
{
$requestUri = '';
@@ -1861,6 +1903,8 @@ protected function preparePathInfo(): string
/**
* Initializes HTTP request formats.
+ *
+ * @return void
*/
protected static function initializeFormats()
{
diff --git a/core/vendor/symfony/http-foundation/RequestMatcher.php b/core/vendor/symfony/http-foundation/RequestMatcher.php
index c2addd36e8..8c5f1d8134 100644
--- a/core/vendor/symfony/http-foundation/RequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/RequestMatcher.php
@@ -69,6 +69,8 @@ public function __construct(string $path = null, string $host = null, string|arr
* Adds a check for the HTTP scheme.
*
* @param string|string[]|null $scheme An HTTP scheme or an array of HTTP schemes
+ *
+ * @return void
*/
public function matchScheme(string|array|null $scheme)
{
@@ -77,6 +79,8 @@ public function matchScheme(string|array|null $scheme)
/**
* Adds a check for the URL host name.
+ *
+ * @return void
*/
public function matchHost(?string $regexp)
{
@@ -87,6 +91,8 @@ public function matchHost(?string $regexp)
* Adds a check for the the URL port.
*
* @param int|null $port The port number to connect to
+ *
+ * @return void
*/
public function matchPort(?int $port)
{
@@ -95,6 +101,8 @@ public function matchPort(?int $port)
/**
* Adds a check for the URL path info.
+ *
+ * @return void
*/
public function matchPath(?string $regexp)
{
@@ -105,6 +113,8 @@ public function matchPath(?string $regexp)
* Adds a check for the client IP.
*
* @param string $ip A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
+ *
+ * @return void
*/
public function matchIp(string $ip)
{
@@ -115,20 +125,22 @@ public function matchIp(string $ip)
* Adds a check for the client IP.
*
* @param string|string[]|null $ips A specific IP address or a range specified using IP/netmask like 192.168.1.0/24
+ *
+ * @return void
*/
public function matchIps(string|array|null $ips)
{
$ips = null !== $ips ? (array) $ips : [];
- $this->ips = array_reduce($ips, static function (array $ips, string $ip) {
- return array_merge($ips, preg_split('/\s*,\s*/', $ip));
- }, []);
+ $this->ips = array_reduce($ips, static fn (array $ips, string $ip) => array_merge($ips, preg_split('/\s*,\s*/', $ip)), []);
}
/**
* Adds a check for the HTTP method.
*
* @param string|string[]|null $method An HTTP method or an array of HTTP methods
+ *
+ * @return void
*/
public function matchMethod(string|array|null $method)
{
@@ -137,6 +149,8 @@ public function matchMethod(string|array|null $method)
/**
* Adds a check for request attribute.
+ *
+ * @return void
*/
public function matchAttribute(string $key, string $regexp)
{
diff --git a/core/vendor/symfony/http-foundation/RequestMatcher/IpsRequestMatcher.php b/core/vendor/symfony/http-foundation/RequestMatcher/IpsRequestMatcher.php
index 2ddff038df..333612e2f2 100644
--- a/core/vendor/symfony/http-foundation/RequestMatcher/IpsRequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/RequestMatcher/IpsRequestMatcher.php
@@ -30,9 +30,7 @@ class IpsRequestMatcher implements RequestMatcherInterface
*/
public function __construct(array|string $ips)
{
- $this->ips = array_reduce((array) $ips, static function (array $ips, string $ip) {
- return array_merge($ips, preg_split('/\s*,\s*/', $ip));
- }, []);
+ $this->ips = array_reduce((array) $ips, static fn (array $ips, string $ip) => array_merge($ips, preg_split('/\s*,\s*/', $ip)), []);
}
public function matches(Request $request): bool
diff --git a/core/vendor/symfony/http-foundation/RequestMatcher/IsJsonRequestMatcher.php b/core/vendor/symfony/http-foundation/RequestMatcher/IsJsonRequestMatcher.php
index 5da46840f4..875f992be1 100644
--- a/core/vendor/symfony/http-foundation/RequestMatcher/IsJsonRequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/RequestMatcher/IsJsonRequestMatcher.php
@@ -23,12 +23,6 @@ class IsJsonRequestMatcher implements RequestMatcherInterface
{
public function matches(Request $request): bool
{
- try {
- json_decode($request->getContent(), true, 512, \JSON_BIGINT_AS_STRING | \JSON_THROW_ON_ERROR);
- } catch (\JsonException) {
- return false;
- }
-
- return true;
+ return json_validate($request->getContent());
}
}
diff --git a/core/vendor/symfony/http-foundation/RequestMatcher/MethodRequestMatcher.php b/core/vendor/symfony/http-foundation/RequestMatcher/MethodRequestMatcher.php
index c7a915980c..b37f6e3c87 100644
--- a/core/vendor/symfony/http-foundation/RequestMatcher/MethodRequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/RequestMatcher/MethodRequestMatcher.php
@@ -32,9 +32,7 @@ class MethodRequestMatcher implements RequestMatcherInterface
*/
public function __construct(array|string $methods)
{
- $this->methods = array_reduce(array_map('strtoupper', (array) $methods), static function (array $methods, string $method) {
- return array_merge($methods, preg_split('/\s*,\s*/', $method));
- }, []);
+ $this->methods = array_reduce(array_map('strtoupper', (array) $methods), static fn (array $methods, string $method) => array_merge($methods, preg_split('/\s*,\s*/', $method)), []);
}
public function matches(Request $request): bool
diff --git a/core/vendor/symfony/http-foundation/RequestMatcher/SchemeRequestMatcher.php b/core/vendor/symfony/http-foundation/RequestMatcher/SchemeRequestMatcher.php
index 4f5eabc2c5..9c9cd58b98 100644
--- a/core/vendor/symfony/http-foundation/RequestMatcher/SchemeRequestMatcher.php
+++ b/core/vendor/symfony/http-foundation/RequestMatcher/SchemeRequestMatcher.php
@@ -32,9 +32,7 @@ class SchemeRequestMatcher implements RequestMatcherInterface
*/
public function __construct(array|string $schemes)
{
- $this->schemes = array_reduce(array_map('strtolower', (array) $schemes), static function (array $schemes, string $scheme) {
- return array_merge($schemes, preg_split('/\s*,\s*/', $scheme));
- }, []);
+ $this->schemes = array_reduce(array_map('strtolower', (array) $schemes), static fn (array $schemes, string $scheme) => array_merge($schemes, preg_split('/\s*,\s*/', $scheme)), []);
}
public function matches(Request $request): bool
diff --git a/core/vendor/symfony/http-foundation/RequestStack.php b/core/vendor/symfony/http-foundation/RequestStack.php
index 6b13fa1e6e..5aa8ba7934 100644
--- a/core/vendor/symfony/http-foundation/RequestStack.php
+++ b/core/vendor/symfony/http-foundation/RequestStack.php
@@ -31,6 +31,8 @@ class RequestStack
*
* This method should generally not be called directly as the stack
* management should be taken care of by the application itself.
+ *
+ * @return void
*/
public function push(Request $request)
{
diff --git a/core/vendor/symfony/http-foundation/Response.php b/core/vendor/symfony/http-foundation/Response.php
index c141cbc0bb..888c6ad858 100644
--- a/core/vendor/symfony/http-foundation/Response.php
+++ b/core/vendor/symfony/http-foundation/Response.php
@@ -211,6 +211,11 @@ class Response
511 => 'Network Authentication Required', // RFC6585
];
+ /**
+ * Tracks headers already sent in informational responses.
+ */
+ private array $sentHeaders;
+
/**
* @param int $status The HTTP status code (200 "OK" by default)
*
@@ -326,21 +331,54 @@ public function prepare(Request $request): static
/**
* Sends HTTP headers.
*
+ * @param null|positive-int $statusCode The status code to use, override the statusCode property if set and not null
+ *
* @return $this
*/
- public function sendHeaders(): static
+ public function sendHeaders(/* int $statusCode = null */): static
{
// headers have already been sent by the developer
if (headers_sent()) {
return $this;
}
+ $statusCode = \func_num_args() > 0 ? func_get_arg(0) : null;
+ $informationalResponse = $statusCode >= 100 && $statusCode < 200;
+ if ($informationalResponse && !\function_exists('headers_send')) {
+ // skip informational responses if not supported by the SAPI
+ return $this;
+ }
+
// headers
foreach ($this->headers->allPreserveCaseWithoutCookies() as $name => $values) {
- $replace = 0 === strcasecmp($name, 'Content-Type');
- foreach ($values as $value) {
+ $newValues = $values;
+ $replace = false;
+
+ // As recommended by RFC 8297, PHP automatically copies headers from previous 103 responses, we need to deal with that if headers changed
+ if (103 === $statusCode) {
+ $previousValues = $this->sentHeaders[$name] ?? null;
+ if ($previousValues === $values) {
+ // Header already sent in a previous response, it will be automatically copied in this response by PHP
+ continue;
+ }
+
+ $replace = 0 === strcasecmp($name, 'Content-Type');
+
+ if (null !== $previousValues && array_diff($previousValues, $values)) {
+ header_remove($name);
+ $previousValues = null;
+ }
+
+ $newValues = null === $previousValues ? $values : array_diff($values, $previousValues);
+ }
+
+ foreach ($newValues as $value) {
header($name.': '.$value, $replace, $this->statusCode);
}
+
+ if ($informationalResponse) {
+ $this->sentHeaders[$name] = $values;
+ }
}
// cookies
@@ -348,8 +386,16 @@ public function sendHeaders(): static
header('Set-Cookie: '.$cookie, false, $this->statusCode);
}
+ if ($informationalResponse) {
+ headers_send($statusCode);
+
+ return $this;
+ }
+
+ $statusCode ??= $this->statusCode;
+
// status
- header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
+ header(sprintf('HTTP/%s %s %s', $this->version, $statusCode, $this->statusText), true, $statusCode);
return $this;
}
diff --git a/core/vendor/symfony/http-foundation/ResponseHeaderBag.php b/core/vendor/symfony/http-foundation/ResponseHeaderBag.php
index 9e8c5793a7..10450ca5e2 100644
--- a/core/vendor/symfony/http-foundation/ResponseHeaderBag.php
+++ b/core/vendor/symfony/http-foundation/ResponseHeaderBag.php
@@ -55,6 +55,9 @@ public function allPreserveCase(): array
return $headers;
}
+ /**
+ * @return array
+ */
public function allPreserveCaseWithoutCookies()
{
$headers = $this->allPreserveCase();
@@ -65,6 +68,9 @@ public function allPreserveCaseWithoutCookies()
return $headers;
}
+ /**
+ * @return void
+ */
public function replace(array $headers = [])
{
$this->headerNames = [];
@@ -97,6 +103,9 @@ public function all(string $key = null): array
return $headers;
}
+ /**
+ * @return void
+ */
public function set(string $key, string|array|null $values, bool $replace = true)
{
$uniqueKey = strtr($key, self::UPPER, self::LOWER);
@@ -125,6 +134,9 @@ public function set(string $key, string|array|null $values, bool $replace = true
}
}
+ /**
+ * @return void
+ */
public function remove(string $key)
{
$uniqueKey = strtr($key, self::UPPER, self::LOWER);
@@ -157,6 +169,9 @@ public function getCacheControlDirective(string $key): bool|string|null
return $this->computedCacheControl[$key] ?? null;
}
+ /**
+ * @return void
+ */
public function setCookie(Cookie $cookie)
{
$this->cookies[$cookie->getDomain()][$cookie->getPath()][$cookie->getName()] = $cookie;
@@ -165,6 +180,8 @@ public function setCookie(Cookie $cookie)
/**
* Removes a cookie from the array, but does not unset it in the browser.
+ *
+ * @return void
*/
public function removeCookie(string $name, ?string $path = '/', string $domain = null)
{
@@ -216,6 +233,8 @@ public function getCookies(string $format = self::COOKIES_FLAT): array
/**
* Clears a cookie in the browser.
+ *
+ * @return void
*/
public function clearCookie(string $name, ?string $path = '/', string $domain = null, bool $secure = false, bool $httpOnly = true, string $sameSite = null)
{
@@ -224,6 +243,8 @@ public function clearCookie(string $name, ?string $path = '/', string $domain =
/**
* @see HeaderUtils::makeDisposition()
+ *
+ * @return string
*/
public function makeDisposition(string $disposition, string $filename, string $filenameFallback = '')
{
diff --git a/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php b/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php
index 6659617579..ad5a6590a5 100644
--- a/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php
+++ b/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBag.php
@@ -36,11 +36,17 @@ public function getName(): string
return $this->name;
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->name = $name;
}
+ /**
+ * @return void
+ */
public function initialize(array &$attributes)
{
$this->attributes = &$attributes;
@@ -61,6 +67,9 @@ public function get(string $name, mixed $default = null): mixed
return \array_key_exists($name, $this->attributes) ? $this->attributes[$name] : $default;
}
+ /**
+ * @return void
+ */
public function set(string $name, mixed $value)
{
$this->attributes[$name] = $value;
@@ -71,6 +80,9 @@ public function all(): array
return $this->attributes;
}
+ /**
+ * @return void
+ */
public function replace(array $attributes)
{
$this->attributes = [];
diff --git a/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php b/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php
index 31a946444b..e8cd0b5a4d 100644
--- a/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php
+++ b/core/vendor/symfony/http-foundation/Session/Attribute/AttributeBagInterface.php
@@ -32,6 +32,8 @@ public function get(string $name, mixed $default = null): mixed;
/**
* Sets an attribute.
+ *
+ * @return void
*/
public function set(string $name, mixed $value);
@@ -42,6 +44,9 @@ public function set(string $name, mixed $value);
*/
public function all(): array;
+ /**
+ * @return void
+ */
public function replace(array $attributes);
/**
diff --git a/core/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php b/core/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php
index 00b1ac9486..80bbeda0f8 100644
--- a/core/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php
+++ b/core/vendor/symfony/http-foundation/Session/Flash/AutoExpireFlashBag.php
@@ -35,11 +35,17 @@ public function getName(): string
return $this->name;
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->name = $name;
}
+ /**
+ * @return void
+ */
public function initialize(array &$flashes)
{
$this->flashes = &$flashes;
@@ -51,6 +57,9 @@ public function initialize(array &$flashes)
$this->flashes['new'] = [];
}
+ /**
+ * @return void
+ */
public function add(string $type, mixed $message)
{
$this->flashes['new'][$type][] = $message;
@@ -90,11 +99,17 @@ public function all(): array
return $return;
}
+ /**
+ * @return void
+ */
public function setAll(array $messages)
{
$this->flashes['new'] = $messages;
}
+ /**
+ * @return void
+ */
public function set(string $type, string|array $messages)
{
$this->flashes['new'][$type] = (array) $messages;
diff --git a/core/vendor/symfony/http-foundation/Session/Flash/FlashBag.php b/core/vendor/symfony/http-foundation/Session/Flash/FlashBag.php
index a30d9528d1..659d59d186 100644
--- a/core/vendor/symfony/http-foundation/Session/Flash/FlashBag.php
+++ b/core/vendor/symfony/http-foundation/Session/Flash/FlashBag.php
@@ -35,16 +35,25 @@ public function getName(): string
return $this->name;
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->name = $name;
}
+ /**
+ * @return void
+ */
public function initialize(array &$flashes)
{
$this->flashes = &$flashes;
}
+ /**
+ * @return void
+ */
public function add(string $type, mixed $message)
{
$this->flashes[$type][] = $message;
@@ -81,11 +90,17 @@ public function all(): array
return $return;
}
+ /**
+ * @return void
+ */
public function set(string $type, string|array $messages)
{
$this->flashes[$type] = (array) $messages;
}
+ /**
+ * @return void
+ */
public function setAll(array $messages)
{
$this->flashes = $messages;
diff --git a/core/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php b/core/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php
index cd10a23f3c..bbcf7f8b7d 100644
--- a/core/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php
+++ b/core/vendor/symfony/http-foundation/Session/Flash/FlashBagInterface.php
@@ -22,11 +22,15 @@ interface FlashBagInterface extends SessionBagInterface
{
/**
* Adds a flash message for the given type.
+ *
+ * @return void
*/
public function add(string $type, mixed $message);
/**
* Registers one or more messages for a given type.
+ *
+ * @return void
*/
public function set(string $type, string|array $messages);
@@ -57,6 +61,8 @@ public function all(): array;
/**
* Sets all flash messages.
+ *
+ * @return void
*/
public function setAll(array $messages);
diff --git a/core/vendor/symfony/http-foundation/Session/Session.php b/core/vendor/symfony/http-foundation/Session/Session.php
index a55dde4821..b45be2f8c3 100644
--- a/core/vendor/symfony/http-foundation/Session/Session.php
+++ b/core/vendor/symfony/http-foundation/Session/Session.php
@@ -69,6 +69,9 @@ public function get(string $name, mixed $default = null): mixed
return $this->getAttributeBag()->get($name, $default);
}
+ /**
+ * @return void
+ */
public function set(string $name, mixed $value)
{
$this->getAttributeBag()->set($name, $value);
@@ -79,6 +82,9 @@ public function all(): array
return $this->getAttributeBag()->all();
}
+ /**
+ * @return void
+ */
public function replace(array $attributes)
{
$this->getAttributeBag()->replace($attributes);
@@ -89,6 +95,9 @@ public function remove(string $name): mixed
return $this->getAttributeBag()->remove($name);
}
+ /**
+ * @return void
+ */
public function clear()
{
$this->getAttributeBag()->clear();
@@ -154,6 +163,9 @@ public function migrate(bool $destroy = false, int $lifetime = null): bool
return $this->storage->regenerate($destroy, $lifetime);
}
+ /**
+ * @return void
+ */
public function save()
{
$this->storage->save();
@@ -164,6 +176,9 @@ public function getId(): string
return $this->storage->getId();
}
+ /**
+ * @return void
+ */
public function setId(string $id)
{
if ($this->storage->getId() !== $id) {
@@ -176,6 +191,9 @@ public function getName(): string
return $this->storage->getName();
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->storage->setName($name);
@@ -191,6 +209,9 @@ public function getMetadataBag(): MetadataBag
return $this->storage->getMetadataBag();
}
+ /**
+ * @return void
+ */
public function registerBag(SessionBagInterface $bag)
{
$this->storage->registerBag(new SessionBagProxy($bag, $this->data, $this->usageIndex, $this->usageReporter));
diff --git a/core/vendor/symfony/http-foundation/Session/SessionBagInterface.php b/core/vendor/symfony/http-foundation/Session/SessionBagInterface.php
index 821645d9b8..e1c2505549 100644
--- a/core/vendor/symfony/http-foundation/Session/SessionBagInterface.php
+++ b/core/vendor/symfony/http-foundation/Session/SessionBagInterface.php
@@ -25,6 +25,8 @@ public function getName(): string;
/**
* Initializes the Bag.
+ *
+ * @return void
*/
public function initialize(array &$array);
diff --git a/core/vendor/symfony/http-foundation/Session/SessionInterface.php b/core/vendor/symfony/http-foundation/Session/SessionInterface.php
index da2b3a37d6..534883d2d2 100644
--- a/core/vendor/symfony/http-foundation/Session/SessionInterface.php
+++ b/core/vendor/symfony/http-foundation/Session/SessionInterface.php
@@ -34,6 +34,8 @@ public function getId(): string;
/**
* Sets the session ID.
+ *
+ * @return void
*/
public function setId(string $id);
@@ -44,6 +46,8 @@ public function getName(): string;
/**
* Sets the session name.
+ *
+ * @return void
*/
public function setName(string $name);
@@ -78,6 +82,8 @@ public function migrate(bool $destroy = false, int $lifetime = null): bool;
* This method is generally not required for real sessions as
* the session will be automatically saved at the end of
* code execution.
+ *
+ * @return void
*/
public function save();
@@ -93,6 +99,8 @@ public function get(string $name, mixed $default = null): mixed;
/**
* Sets an attribute.
+ *
+ * @return void
*/
public function set(string $name, mixed $value);
@@ -103,6 +111,8 @@ public function all(): array;
/**
* Sets attributes.
+ *
+ * @return void
*/
public function replace(array $attributes);
@@ -115,6 +125,8 @@ public function remove(string $name): mixed;
/**
* Clears all attributes.
+ *
+ * @return void
*/
public function clear();
@@ -125,6 +137,8 @@ public function isStarted(): bool;
/**
* Registers a SessionBagInterface with the session.
+ *
+ * @return void
*/
public function registerBag(SessionBagInterface $bag);
diff --git a/core/vendor/symfony/http-foundation/Session/SessionUtils.php b/core/vendor/symfony/http-foundation/Session/SessionUtils.php
index b5bce4a884..504c5848e9 100644
--- a/core/vendor/symfony/http-foundation/Session/SessionUtils.php
+++ b/core/vendor/symfony/http-foundation/Session/SessionUtils.php
@@ -25,7 +25,7 @@ final class SessionUtils
* Finds the session header amongst the headers that are to be sent, removes it, and returns
* it so the caller can process it further.
*/
- public static function popSessionCookie(string $sessionName, string $sessionId): ?string
+ public static function popSessionCookie(string $sessionName, #[\SensitiveParameter] string $sessionId): ?string
{
$sessionCookie = null;
$sessionCookiePrefix = sprintf(' %s=', urlencode($sessionName));
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
index 88e513c5dd..288c24232c 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/AbstractSessionHandler.php
@@ -38,13 +38,13 @@ public function open(string $savePath, string $sessionName): bool
return true;
}
- abstract protected function doRead(string $sessionId): string;
+ abstract protected function doRead(#[\SensitiveParameter] string $sessionId): string;
- abstract protected function doWrite(string $sessionId, string $data): bool;
+ abstract protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool;
- abstract protected function doDestroy(string $sessionId): bool;
+ abstract protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool;
- public function validateId(string $sessionId): bool
+ public function validateId(#[\SensitiveParameter] string $sessionId): bool
{
$this->prefetchData = $this->read($sessionId);
$this->prefetchId = $sessionId;
@@ -52,7 +52,7 @@ public function validateId(string $sessionId): bool
return '' !== $this->prefetchData;
}
- public function read(string $sessionId): string
+ public function read(#[\SensitiveParameter] string $sessionId): string
{
if (isset($this->prefetchId)) {
$prefetchId = $this->prefetchId;
@@ -72,7 +72,7 @@ public function read(string $sessionId): string
return $data;
}
- public function write(string $sessionId, string $data): bool
+ public function write(#[\SensitiveParameter] string $sessionId, string $data): bool
{
// see https://github.com/igbinary/igbinary/issues/146
$this->igbinaryEmptyData ??= \function_exists('igbinary_serialize') ? igbinary_serialize([]) : '';
@@ -84,7 +84,7 @@ public function write(string $sessionId, string $data): bool
return $this->doWrite($sessionId, $data);
}
- public function destroy(string $sessionId): bool
+ public function destroy(#[\SensitiveParameter] string $sessionId): bool
{
if (!headers_sent() && filter_var(\ini_get('session.use_cookies'), \FILTER_VALIDATE_BOOL)) {
if (!isset($this->sessionName)) {
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php
index 9962fef3d6..1567f54332 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MarshallingSessionHandler.php
@@ -37,7 +37,7 @@ public function close(): bool
return $this->handler->close();
}
- public function destroy(string $sessionId): bool
+ public function destroy(#[\SensitiveParameter] string $sessionId): bool
{
return $this->handler->destroy($sessionId);
}
@@ -47,12 +47,12 @@ public function gc(int $maxlifetime): int|false
return $this->handler->gc($maxlifetime);
}
- public function read(string $sessionId): string
+ public function read(#[\SensitiveParameter] string $sessionId): string
{
return $this->marshaller->unmarshall($this->handler->read($sessionId));
}
- public function write(string $sessionId, string $data): bool
+ public function write(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$failed = [];
$marshalledData = $this->marshaller->marshall(['data' => $data], $failed);
@@ -64,12 +64,12 @@ public function write(string $sessionId, string $data): bool
return $this->handler->write($sessionId, $marshalledData['data']);
}
- public function validateId(string $sessionId): bool
+ public function validateId(#[\SensitiveParameter] string $sessionId): bool
{
return $this->handler->validateId($sessionId);
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->handler->updateTimestamp($sessionId, $data);
}
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
index 2bc29b459c..91a023ddbc 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MemcachedSessionHandler.php
@@ -59,19 +59,19 @@ public function close(): bool
return $this->memcached->quit();
}
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
return $this->memcached->get($this->prefix.$sessionId) ?: '';
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$this->memcached->touch($this->prefix.$sessionId, $this->getCompatibleTtl());
return true;
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->memcached->set($this->prefix.$sessionId, $data, $this->getCompatibleTtl());
}
@@ -89,7 +89,7 @@ private function getCompatibleTtl(): int
return $ttl;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
$result = $this->memcached->delete($this->prefix.$sessionId);
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php
index 1d42552368..8ed6a7b3fd 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MigratingSessionHandler.php
@@ -22,15 +22,8 @@
*/
class MigratingSessionHandler implements \SessionHandlerInterface, \SessionUpdateTimestampHandlerInterface
{
- /**
- * @var \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface
- */
- private \SessionHandlerInterface $currentHandler;
-
- /**
- * @var \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface
- */
- private \SessionHandlerInterface $writeOnlyHandler;
+ private \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface $currentHandler;
+ private \SessionHandlerInterface&\SessionUpdateTimestampHandlerInterface $writeOnlyHandler;
public function __construct(\SessionHandlerInterface $currentHandler, \SessionHandlerInterface $writeOnlyHandler)
{
@@ -53,7 +46,7 @@ public function close(): bool
return $result;
}
- public function destroy(string $sessionId): bool
+ public function destroy(#[\SensitiveParameter] string $sessionId): bool
{
$result = $this->currentHandler->destroy($sessionId);
$this->writeOnlyHandler->destroy($sessionId);
@@ -77,13 +70,13 @@ public function open(string $savePath, string $sessionName): bool
return $result;
}
- public function read(string $sessionId): string
+ public function read(#[\SensitiveParameter] string $sessionId): string
{
// No reading from new handler until switch-over
return $this->currentHandler->read($sessionId);
}
- public function write(string $sessionId, string $sessionData): bool
+ public function write(#[\SensitiveParameter] string $sessionId, string $sessionData): bool
{
$result = $this->currentHandler->write($sessionId, $sessionData);
$this->writeOnlyHandler->write($sessionId, $sessionData);
@@ -91,13 +84,13 @@ public function write(string $sessionId, string $sessionData): bool
return $result;
}
- public function validateId(string $sessionId): bool
+ public function validateId(#[\SensitiveParameter] string $sessionId): bool
{
// No reading from new handler until switch-over
return $this->currentHandler->validateId($sessionId);
}
- public function updateTimestamp(string $sessionId, string $sessionData): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $sessionData): bool
{
$result = $this->currentHandler->updateTimestamp($sessionId, $sessionData);
$this->writeOnlyHandler->updateTimestamp($sessionId, $sessionData);
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
index 63c609ae21..5ea5b4ae7d 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/MongoDbSessionHandler.php
@@ -84,7 +84,7 @@ public function close(): bool
return true;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
$this->getCollection()->deleteOne([
$this->options['id_field'] => $sessionId,
@@ -100,7 +100,7 @@ public function gc(int $maxlifetime): int|false
])->getDeletedCount();
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
$expiry = new UTCDateTime((time() + (int) $ttl) * 1000);
@@ -120,7 +120,7 @@ protected function doWrite(string $sessionId, string $data): bool
return true;
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
$expiry = new UTCDateTime((time() + (int) $ttl) * 1000);
@@ -136,7 +136,7 @@ public function updateTimestamp(string $sessionId, string $data): bool
return true;
}
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
$dbData = $this->getCollection()->findOne([
$this->options['id_field'] => $sessionId,
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
index 790ac2fedd..a77185e2eb 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/NullSessionHandler.php
@@ -23,27 +23,27 @@ public function close(): bool
return true;
}
- public function validateId(string $sessionId): bool
+ public function validateId(#[\SensitiveParameter] string $sessionId): bool
{
return true;
}
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
return '';
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return true;
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return true;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
return true;
}
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
index 06429b4ba0..65452a5207 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php
@@ -11,6 +11,9 @@
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
+use Doctrine\DBAL\Schema\Schema;
+use Doctrine\DBAL\Types\Types;
+
/**
* Session handler using a PDO connection to read and write data.
*
@@ -148,7 +151,7 @@ class PdoSessionHandler extends AbstractSessionHandler
*
* @throws \InvalidArgumentException When PDO error mode is not PDO::ERRMODE_EXCEPTION
*/
- public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
+ public function __construct(#[\SensitiveParameter] \PDO|string $pdoOrDsn = null, #[\SensitiveParameter] array $options = [])
{
if ($pdoOrDsn instanceof \PDO) {
if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
@@ -175,6 +178,56 @@ public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
$this->ttl = $options['ttl'] ?? null;
}
+ /**
+ * Adds the Table to the Schema if it doesn't exist.
+ */
+ public function configureSchema(Schema $schema, \Closure $isSameDatabase = null): void
+ {
+ if ($schema->hasTable($this->table) || ($isSameDatabase && !$isSameDatabase($this->getConnection()->exec(...)))) {
+ return;
+ }
+
+ $table = $schema->createTable($this->table);
+ switch ($this->driver) {
+ case 'mysql':
+ $table->addColumn($this->idCol, Types::BINARY)->setLength(128)->setNotnull(true);
+ $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
+ $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
+ $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
+ $table->addOption('collate', 'utf8mb4_bin');
+ $table->addOption('engine', 'InnoDB');
+ break;
+ case 'sqlite':
+ $table->addColumn($this->idCol, Types::TEXT)->setNotnull(true);
+ $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
+ $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
+ $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
+ break;
+ case 'pgsql':
+ $table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true);
+ $table->addColumn($this->dataCol, Types::BINARY)->setNotnull(true);
+ $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
+ $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
+ break;
+ case 'oci':
+ $table->addColumn($this->idCol, Types::STRING)->setLength(128)->setNotnull(true);
+ $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
+ $table->addColumn($this->lifetimeCol, Types::INTEGER)->setNotnull(true);
+ $table->addColumn($this->timeCol, Types::INTEGER)->setNotnull(true);
+ break;
+ case 'sqlsrv':
+ $table->addColumn($this->idCol, Types::TEXT)->setLength(128)->setNotnull(true);
+ $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true);
+ $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
+ $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true);
+ break;
+ default:
+ throw new \DomainException(sprintf('Creating the session table is currently not implemented for PDO driver "%s".', $this->driver));
+ }
+ $table->setPrimaryKey([$this->idCol]);
+ $table->addIndex([$this->lifetimeCol], $this->lifetimeCol.'_idx');
+ }
+
/**
* Creates the table to store sessions which can be called once for setup.
*
@@ -183,6 +236,8 @@ public function __construct(\PDO|string $pdoOrDsn = null, array $options = [])
* saved in a BLOB. One could also use a shorter inlined varbinary column
* if one was sure the data fits into it.
*
+ * @return void
+ *
* @throws \PDOException When the table already exists
* @throws \DomainException When an unsupported PDO driver is used
*/
@@ -207,7 +262,7 @@ public function createTable()
try {
$this->pdo->exec($sql);
- $this->pdo->exec("CREATE INDEX expiry ON $this->table ($this->lifetimeCol)");
+ $this->pdo->exec("CREATE INDEX {$this->lifetimeCol}_idx ON $this->table ($this->lifetimeCol)");
} catch (\PDOException $e) {
$this->rollback();
@@ -236,7 +291,7 @@ public function open(string $savePath, string $sessionName): bool
return parent::open($savePath, $sessionName);
}
- public function read(string $sessionId): string
+ public function read(#[\SensitiveParameter] string $sessionId): string
{
try {
return parent::read($sessionId);
@@ -256,7 +311,7 @@ public function gc(int $maxlifetime): int|false
return 0;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
// delete the record associated with this id
$sql = "DELETE FROM $this->table WHERE $this->idCol = :id";
@@ -274,7 +329,7 @@ protected function doDestroy(string $sessionId): bool
return true;
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$maxlifetime = (int) (($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime'));
@@ -317,7 +372,7 @@ protected function doWrite(string $sessionId, string $data): bool
return true;
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$expiry = time() + (int) (($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime'));
@@ -366,7 +421,7 @@ public function close(): bool
/**
* Lazy-connects to the database.
*/
- private function connect(string $dsn): void
+ private function connect(#[\SensitiveParameter] string $dsn): void
{
$this->pdo = new \PDO($dsn, $this->username, $this->password, $this->connectionOptions);
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
@@ -378,7 +433,7 @@ private function connect(string $dsn): void
*
* @todo implement missing support for oci DSN (which look totally different from other PDO ones)
*/
- private function buildDsnFromUrl(string $dsnOrUrl): string
+ private function buildDsnFromUrl(#[\SensitiveParameter] string $dsnOrUrl): string
{
// (pdo_)?sqlite3?:///... => (pdo_)?sqlite3?://localhost/... or else the URL will be invalid
$url = preg_replace('#^((?:pdo_)?sqlite3?):///#', '$1://localhost/', $dsnOrUrl);
@@ -561,7 +616,7 @@ private function rollback(): void
* We need to make sure we do not return session data that is already considered garbage according
* to the session.gc_maxlifetime setting because gc() is called after read() and only sometimes.
*/
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
if (self::LOCK_ADVISORY === $this->lockMode) {
$this->unlockStatements[] = $this->doAdvisoryLock($sessionId);
@@ -632,7 +687,7 @@ protected function doRead(string $sessionId): string
* - for oci using DBMS_LOCK.REQUEST
* - for sqlsrv using sp_getapplock with LockOwner = Session
*/
- private function doAdvisoryLock(string $sessionId): \PDOStatement
+ private function doAdvisoryLock(#[\SensitiveParameter] string $sessionId): \PDOStatement
{
switch ($this->driver) {
case 'mysql':
@@ -731,7 +786,7 @@ private function getSelectSql(): string
/**
* Returns an insert statement supported by the database for writing session data.
*/
- private function getInsertStatement(string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
+ private function getInsertStatement(#[\SensitiveParameter] string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
{
switch ($this->driver) {
case 'oci':
@@ -758,7 +813,7 @@ private function getInsertStatement(string $sessionId, string $sessionData, int
/**
* Returns an update statement supported by the database for writing session data.
*/
- private function getUpdateStatement(string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
+ private function getUpdateStatement(#[\SensitiveParameter] string $sessionId, string $sessionData, int $maxlifetime): \PDOStatement
{
switch ($this->driver) {
case 'oci':
@@ -785,7 +840,7 @@ private function getUpdateStatement(string $sessionId, string $sessionData, int
/**
* Returns a merge/upsert (i.e. insert or update) statement when supported by the database for writing session data.
*/
- private function getMergeStatement(string $sessionId, string $data, int $maxlifetime): ?\PDOStatement
+ private function getMergeStatement(#[\SensitiveParameter] string $sessionId, string $data, int $maxlifetime): ?\PDOStatement
{
switch (true) {
case 'mysql' === $this->driver:
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
index 38f488644d..b696eee4b7 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/RedisSessionHandler.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
use Predis\Response\ErrorInterface;
+use Relay\Relay;
/**
* Redis based session storage handler based on the Redis class
@@ -39,7 +40,7 @@ class RedisSessionHandler extends AbstractSessionHandler
* @throws \InvalidArgumentException When unsupported client or options are passed
*/
public function __construct(
- private \Redis|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis,
+ private \Redis|Relay|\RedisArray|\RedisCluster|\Predis\ClientInterface $redis,
array $options = [],
) {
if ($diff = array_diff(array_keys($options), ['prefix', 'ttl'])) {
@@ -50,12 +51,12 @@ public function __construct(
$this->ttl = $options['ttl'] ?? null;
}
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
return $this->redis->get($this->prefix.$sessionId) ?: '';
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
$result = $this->redis->setEx($this->prefix.$sessionId, (int) $ttl, $data);
@@ -63,7 +64,7 @@ protected function doWrite(string $sessionId, string $data): bool
return $result && !$result instanceof ErrorInterface;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
static $unlink = true;
@@ -93,7 +94,7 @@ public function gc(int $maxlifetime): int|false
return 0;
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
$ttl = ($this->ttl instanceof \Closure ? ($this->ttl)() : $this->ttl) ?? \ini_get('session.gc_maxlifetime');
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php
index e390c8feea..dbbe7dc880 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
use Doctrine\DBAL\DriverManager;
+use Relay\Relay;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
/**
@@ -32,6 +33,7 @@ public static function createHandler(object|string $connection, array $options =
switch (true) {
case $connection instanceof \Redis:
+ case $connection instanceof Relay:
case $connection instanceof \RedisArray:
case $connection instanceof \RedisCluster:
case $connection instanceof \Predis\ClientInterface:
@@ -54,7 +56,7 @@ public static function createHandler(object|string $connection, array $options =
case str_starts_with($connection, 'rediss:'):
case str_starts_with($connection, 'memcached:'):
if (!class_exists(AbstractAdapter::class)) {
- throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection));
+ throw new \InvalidArgumentException('Unsupported Redis or Memcached DSN. Try running "composer require symfony/cache".');
}
$handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class;
$connection = AbstractAdapter::createConnection($connection, ['lazy' => true]);
@@ -63,7 +65,7 @@ public static function createHandler(object|string $connection, array $options =
case str_starts_with($connection, 'pdo_oci://'):
if (!class_exists(DriverManager::class)) {
- throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require doctrine/dbal".', $connection));
+ throw new \InvalidArgumentException('Unsupported PDO OCI DSN. Try running "composer require doctrine/dbal".');
}
$connection = DriverManager::getConnection(['url' => $connection])->getWrappedConnection();
// no break;
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php b/core/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
index 1a16364815..1f86687447 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Handler/StrictSessionHandler.php
@@ -47,22 +47,22 @@ public function open(string $savePath, string $sessionName): bool
return $this->handler->open($savePath, $sessionName);
}
- protected function doRead(string $sessionId): string
+ protected function doRead(#[\SensitiveParameter] string $sessionId): string
{
return $this->handler->read($sessionId);
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->write($sessionId, $data);
}
- protected function doWrite(string $sessionId, string $data): bool
+ protected function doWrite(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->handler->write($sessionId, $data);
}
- public function destroy(string $sessionId): bool
+ public function destroy(#[\SensitiveParameter] string $sessionId): bool
{
$this->doDestroy = true;
$destroyed = parent::destroy($sessionId);
@@ -70,7 +70,7 @@ public function destroy(string $sessionId): bool
return $this->doDestroy ? $this->doDestroy($sessionId) : $destroyed;
}
- protected function doDestroy(string $sessionId): bool
+ protected function doDestroy(#[\SensitiveParameter] string $sessionId): bool
{
$this->doDestroy = false;
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php b/core/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
index 2c77f9db6c..ebe4b748ad 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/MetadataBag.php
@@ -51,6 +51,9 @@ public function __construct(string $storageKey = '_sf2_meta', int $updateThresho
$this->updateThreshold = $updateThreshold;
}
+ /**
+ * @return void
+ */
public function initialize(array &$array)
{
$this->meta = &$array;
@@ -82,6 +85,8 @@ public function getLifetime(): int
* will leave the system settings unchanged, 0 sets the cookie
* to expire with browser session. Time is in seconds, and is
* not a Unix timestamp.
+ *
+ * @return void
*/
public function stampNew(int $lifetime = null)
{
@@ -126,6 +131,8 @@ public function getName(): string
/**
* Sets name.
+ *
+ * @return void
*/
public function setName(string $name)
{
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php b/core/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
index 67fa0f95e0..d30b56d691 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/MockArraySessionStorage.php
@@ -68,6 +68,9 @@ public function __construct(string $name = 'MOCKSESSID', MetadataBag $metaBag =
$this->setMetadataBag($metaBag);
}
+ /**
+ * @return void
+ */
public function setSessionData(array $array)
{
$this->data = $array;
@@ -105,6 +108,9 @@ public function getId(): string
return $this->id;
}
+ /**
+ * @return void
+ */
public function setId(string $id)
{
if ($this->started) {
@@ -119,11 +125,17 @@ public function getName(): string
return $this->name;
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->name = $name;
}
+ /**
+ * @return void
+ */
public function save()
{
if (!$this->started || $this->closed) {
@@ -134,6 +146,9 @@ public function save()
$this->started = false;
}
+ /**
+ * @return void
+ */
public function clear()
{
// clear out the bags
@@ -148,6 +163,9 @@ public function clear()
$this->loadSession();
}
+ /**
+ * @return void
+ */
public function registerBag(SessionBagInterface $bag)
{
$this->bags[$bag->getName()] = $bag;
@@ -171,6 +189,9 @@ public function isStarted(): bool
return $this->started;
}
+ /**
+ * @return void
+ */
public function setMetadataBag(MetadataBag $bag = null)
{
if (1 > \func_num_args()) {
@@ -198,6 +219,9 @@ protected function generateId(): string
return hash('sha256', uniqid('ss_mock_', true));
}
+ /**
+ * @return void
+ */
protected function loadSession()
{
$bags = array_merge($this->bags, [$this->metadataBag]);
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php b/core/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
index 28771ad54e..95f69f2e13 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/MockFileSessionStorage.php
@@ -73,6 +73,9 @@ public function regenerate(bool $destroy = false, int $lifetime = null): bool
return parent::regenerate($destroy, $lifetime);
}
+ /**
+ * @return void
+ */
public function save()
{
if (!$this->started) {
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php b/core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
index 8b89478820..7c6b6f9296 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/NativeSessionStorage.php
@@ -183,6 +183,9 @@ public function getId(): string
return $this->saveHandler->getId();
}
+ /**
+ * @return void
+ */
public function setId(string $id)
{
$this->saveHandler->setId($id);
@@ -193,6 +196,9 @@ public function getName(): string
return $this->saveHandler->getName();
}
+ /**
+ * @return void
+ */
public function setName(string $name)
{
$this->saveHandler->setName($name);
@@ -222,6 +228,9 @@ public function regenerate(bool $destroy = false, int $lifetime = null): bool
return session_regenerate_id($destroy);
}
+ /**
+ * @return void
+ */
public function save()
{
// Store a copy so we can restore the bags in case the session was not left empty
@@ -261,6 +270,9 @@ public function save()
$this->started = false;
}
+ /**
+ * @return void
+ */
public function clear()
{
// clear out the bags
@@ -275,6 +287,9 @@ public function clear()
$this->loadSession();
}
+ /**
+ * @return void
+ */
public function registerBag(SessionBagInterface $bag)
{
if ($this->started) {
@@ -299,6 +314,9 @@ public function getBag(string $name): SessionBagInterface
return $this->bags[$name];
}
+ /**
+ * @return void
+ */
public function setMetadataBag(MetadataBag $metaBag = null)
{
if (1 > \func_num_args()) {
@@ -329,6 +347,8 @@ public function isStarted(): bool
* @param array $options Session ini directives [key => value]
*
* @see https://php.net/session.configuration
+ *
+ * @return void
*/
public function setOptions(array $options)
{
@@ -372,6 +392,8 @@ public function setOptions(array $options)
* @see https://php.net/sessionhandlerinterface
* @see https://php.net/sessionhandler
*
+ * @return void
+ *
* @throws \InvalidArgumentException
*/
public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandler = null)
@@ -404,6 +426,8 @@ public function setSaveHandler(AbstractProxy|\SessionHandlerInterface $saveHandl
* are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()).
* PHP takes the return value from the read() handler, unserializes it
* and populates $_SESSION with the result automatically.
+ *
+ * @return void
*/
protected function loadSession(array &$session = null)
{
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php b/core/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
index eed748f811..28cb3c3d05 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/PhpBridgeSessionStorage.php
@@ -41,6 +41,9 @@ public function start(): bool
return true;
}
+ /**
+ * @return void
+ */
public function clear()
{
// clear out the bags and nothing else that may be set
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php b/core/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
index 1845ee2c9e..2fcd06b10b 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Proxy/AbstractProxy.php
@@ -71,6 +71,8 @@ public function getId(): string
/**
* Sets the session ID.
*
+ * @return void
+ *
* @throws \LogicException
*/
public function setId(string $id)
@@ -93,6 +95,8 @@ public function getName(): string
/**
* Sets the session name.
*
+ * @return void
+ *
* @throws \LogicException
*/
public function setName(string $name)
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php b/core/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
index c292e58f05..7bf3f9ff1e 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/Proxy/SessionHandlerProxy.php
@@ -44,17 +44,17 @@ public function close(): bool
return $this->handler->close();
}
- public function read(string $sessionId): string|false
+ public function read(#[\SensitiveParameter] string $sessionId): string|false
{
return $this->handler->read($sessionId);
}
- public function write(string $sessionId, string $data): bool
+ public function write(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->handler->write($sessionId, $data);
}
- public function destroy(string $sessionId): bool
+ public function destroy(#[\SensitiveParameter] string $sessionId): bool
{
return $this->handler->destroy($sessionId);
}
@@ -64,12 +64,12 @@ public function gc(int $maxlifetime): int|false
return $this->handler->gc($maxlifetime);
}
- public function validateId(string $sessionId): bool
+ public function validateId(#[\SensitiveParameter] string $sessionId): bool
{
return !$this->handler instanceof \SessionUpdateTimestampHandlerInterface || $this->handler->validateId($sessionId);
}
- public function updateTimestamp(string $sessionId, string $data): bool
+ public function updateTimestamp(#[\SensitiveParameter] string $sessionId, string $data): bool
{
return $this->handler instanceof \SessionUpdateTimestampHandlerInterface ? $this->handler->updateTimestamp($sessionId, $data) : $this->write($sessionId, $data);
}
diff --git a/core/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php b/core/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
index 8bd62a43ae..ed2189e4e7 100644
--- a/core/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
+++ b/core/vendor/symfony/http-foundation/Session/Storage/SessionStorageInterface.php
@@ -40,6 +40,8 @@ public function getId(): string;
/**
* Sets the session ID.
+ *
+ * @return void
*/
public function setId(string $id);
@@ -50,6 +52,8 @@ public function getName(): string;
/**
* Sets the session name.
+ *
+ * @return void
*/
public function setName(string $name);
@@ -90,6 +94,8 @@ public function regenerate(bool $destroy = false, int $lifetime = null): bool;
* a real PHP session would interfere with testing, in which case
* it should actually persist the session data if required.
*
+ * @return void
+ *
* @throws \RuntimeException if the session is saved without being started, or if the session
* is already closed
*/
@@ -97,6 +103,8 @@ public function save();
/**
* Clear all session data in memory.
+ *
+ * @return void
*/
public function clear();
@@ -109,6 +117,8 @@ public function getBag(string $name): SessionBagInterface;
/**
* Registers a SessionBagInterface for use.
+ *
+ * @return void
*/
public function registerBag(SessionBagInterface $bag);
diff --git a/core/vendor/symfony/http-foundation/StreamedJsonResponse.php b/core/vendor/symfony/http-foundation/StreamedJsonResponse.php
new file mode 100644
index 0000000000..cf858a5eb7
--- /dev/null
+++ b/core/vendor/symfony/http-foundation/StreamedJsonResponse.php
@@ -0,0 +1,143 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpFoundation;
+
+/**
+ * StreamedJsonResponse represents a streamed HTTP response for JSON.
+ *
+ * A StreamedJsonResponse uses a structure and generics to create an
+ * efficient resource-saving JSON response.
+ *
+ * It is recommended to use flush() function after a specific number of items to directly stream the data.
+ *
+ * @see flush()
+ *
+ * @author Alexander Schranz
+ *
+ * Example usage:
+ *
+ * function loadArticles(): \Generator
+ * // some streamed loading
+ * yield ['title' => 'Article 1'];
+ * yield ['title' => 'Article 2'];
+ * yield ['title' => 'Article 3'];
+ * // recommended to use flush() after every specific number of items
+ * }),
+ *
+ * $response = new StreamedJsonResponse(
+ * // json structure with generators in which will be streamed
+ * [
+ * '_embedded' => [
+ * 'articles' => loadArticles(), // any generator which you want to stream as list of data
+ * ],
+ * ],
+ * );
+ */
+class StreamedJsonResponse extends StreamedResponse
+{
+ private const PLACEHOLDER = '__symfony_json__';
+
+ /**
+ * @param mixed[] $data JSON Data containing PHP generators which will be streamed as list of data
+ * @param int $status The HTTP status code (200 "OK" by default)
+ * @param array $headers An array of HTTP headers
+ * @param int $encodingOptions Flags for the json_encode() function
+ */
+ public function __construct(
+ private readonly array $data,
+ int $status = 200,
+ array $headers = [],
+ private int $encodingOptions = JsonResponse::DEFAULT_ENCODING_OPTIONS,
+ ) {
+ parent::__construct($this->stream(...), $status, $headers);
+
+ if (!$this->headers->get('Content-Type')) {
+ $this->headers->set('Content-Type', 'application/json');
+ }
+ }
+
+ private function stream(): void
+ {
+ $generators = [];
+ $structure = $this->data;
+
+ array_walk_recursive($structure, function (&$item, $key) use (&$generators) {
+ if (self::PLACEHOLDER === $key) {
+ // if the placeholder is already in the structure it should be replaced with a new one that explode
+ // works like expected for the structure
+ $generators[] = $key;
+ }
+
+ // generators should be used but for better DX all kind of Traversable and objects are supported
+ if (\is_object($item)) {
+ $generators[] = $item;
+ $item = self::PLACEHOLDER;
+ } elseif (self::PLACEHOLDER === $item) {
+ // if the placeholder is already in the structure it should be replaced with a new one that explode
+ // works like expected for the structure
+ $generators[] = $item;
+ }
+ });
+
+ $jsonEncodingOptions = \JSON_THROW_ON_ERROR | $this->encodingOptions;
+ $keyEncodingOptions = $jsonEncodingOptions & ~\JSON_NUMERIC_CHECK;
+
+ $jsonParts = explode('"'.self::PLACEHOLDER.'"', json_encode($structure, $jsonEncodingOptions));
+
+ foreach ($generators as $index => $generator) {
+ // send first and between parts of the structure
+ echo $jsonParts[$index];
+
+ if ($generator instanceof \JsonSerializable || !$generator instanceof \Traversable) {
+ // the placeholders, JsonSerializable and none traversable items in the structure are rendered here
+ echo json_encode($generator, $jsonEncodingOptions);
+
+ continue;
+ }
+
+ $isFirstItem = true;
+ $startTag = '[';
+
+ foreach ($generator as $key => $item) {
+ if ($isFirstItem) {
+ $isFirstItem = false;
+ // depending on the first elements key the generator is detected as a list or map
+ // we can not check for a whole list or map because that would hurt the performance
+ // of the streamed response which is the main goal of this response class
+ if (0 !== $key) {
+ $startTag = '{';
+ }
+
+ echo $startTag;
+ } else {
+ // if not first element of the generic, a separator is required between the elements
+ echo ',';
+ }
+
+ if ('{' === $startTag) {
+ echo json_encode((string) $key, $keyEncodingOptions).':';
+ }
+
+ echo json_encode($item, $jsonEncodingOptions);
+ }
+
+ if ($isFirstItem) { // indicates that the generator was empty
+ echo '[';
+ }
+
+ echo '[' === $startTag ? ']' : '}';
+ }
+
+ // send last part of the structure
+ echo $jsonParts[array_key_last($jsonParts)];
+ }
+}
diff --git a/core/vendor/symfony/http-foundation/StreamedResponse.php b/core/vendor/symfony/http-foundation/StreamedResponse.php
index 0bddcdc9bb..2c8ff15f36 100644
--- a/core/vendor/symfony/http-foundation/StreamedResponse.php
+++ b/core/vendor/symfony/http-foundation/StreamedResponse.php
@@ -59,17 +59,22 @@ public function setCallback(callable $callback): static
/**
* This method only sends the headers once.
*
+ * @param null|positive-int $statusCode The status code to use, override the statusCode property if set and not null
+ *
* @return $this
*/
- public function sendHeaders(): static
+ public function sendHeaders(/* int $statusCode = null */): static
{
if ($this->headersSent) {
return $this;
}
- $this->headersSent = true;
+ $statusCode = \func_num_args() > 0 ? func_get_arg(0) : null;
+ if ($statusCode < 100 || $statusCode >= 200) {
+ $this->headersSent = true;
+ }
- return parent::sendHeaders();
+ return parent::sendHeaders($statusCode);
}
/**
diff --git a/core/vendor/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php b/core/vendor/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php
index b3d375e4c3..417efc77a6 100644
--- a/core/vendor/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php
+++ b/core/vendor/symfony/http-foundation/Test/Constraint/ResponseCookieValueSame.php
@@ -69,9 +69,7 @@ protected function getCookie(Response $response): ?Cookie
{
$cookies = $response->headers->getCookies();
- $filteredCookies = array_filter($cookies, function (Cookie $cookie) {
- return $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain;
- });
+ $filteredCookies = array_filter($cookies, fn (Cookie $cookie) => $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain);
return reset($filteredCookies) ?: null;
}
diff --git a/core/vendor/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php b/core/vendor/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php
index 9b15aeae83..73393d386f 100644
--- a/core/vendor/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php
+++ b/core/vendor/symfony/http-foundation/Test/Constraint/ResponseHasCookie.php
@@ -61,9 +61,7 @@ private function getCookie(Response $response): ?Cookie
{
$cookies = $response->headers->getCookies();
- $filteredCookies = array_filter($cookies, function (Cookie $cookie) {
- return $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain;
- });
+ $filteredCookies = array_filter($cookies, fn (Cookie $cookie) => $cookie->getName() === $this->name && $cookie->getPath() === $this->path && $cookie->getDomain() === $this->domain);
return reset($filteredCookies) ?: null;
}
diff --git a/core/vendor/symfony/http-foundation/UrlHelper.php b/core/vendor/symfony/http-foundation/UrlHelper.php
index 42fcf0459a..d5641eff86 100644
--- a/core/vendor/symfony/http-foundation/UrlHelper.php
+++ b/core/vendor/symfony/http-foundation/UrlHelper.php
@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpFoundation;
use Symfony\Component\Routing\RequestContext;
+use Symfony\Component\Routing\RequestContextAwareInterface;
/**
* A helper service for manipulating URLs within and outside the request scope.
@@ -20,13 +21,11 @@
*/
final class UrlHelper
{
- private RequestStack $requestStack;
- private ?RequestContext $requestContext;
- public function __construct(RequestStack $requestStack, RequestContext $requestContext = null)
- {
- $this->requestStack = $requestStack;
- $this->requestContext = $requestContext;
+ public function __construct(
+ private RequestStack $requestStack,
+ private RequestContextAwareInterface|RequestContext|null $requestContext = null,
+ ) {
}
public function getAbsoluteUrl(string $path): string
@@ -73,28 +72,36 @@ public function getRelativePath(string $path): string
private function getAbsoluteUrlFromContext(string $path): string
{
- if (null === $this->requestContext || '' === $host = $this->requestContext->getHost()) {
+ if (null === $context = $this->requestContext) {
+ return $path;
+ }
+
+ if ($context instanceof RequestContextAwareInterface) {
+ $context = $context->getContext();
+ }
+
+ if ('' === $host = $context->getHost()) {
return $path;
}
- $scheme = $this->requestContext->getScheme();
+ $scheme = $context->getScheme();
$port = '';
- if ('http' === $scheme && 80 !== $this->requestContext->getHttpPort()) {
- $port = ':'.$this->requestContext->getHttpPort();
- } elseif ('https' === $scheme && 443 !== $this->requestContext->getHttpsPort()) {
- $port = ':'.$this->requestContext->getHttpsPort();
+ if ('http' === $scheme && 80 !== $context->getHttpPort()) {
+ $port = ':'.$context->getHttpPort();
+ } elseif ('https' === $scheme && 443 !== $context->getHttpsPort()) {
+ $port = ':'.$context->getHttpsPort();
}
if ('#' === $path[0]) {
- $queryString = $this->requestContext->getQueryString();
- $path = $this->requestContext->getPathInfo().($queryString ? '?'.$queryString : '').$path;
+ $queryString = $context->getQueryString();
+ $path = $context->getPathInfo().($queryString ? '?'.$queryString : '').$path;
} elseif ('?' === $path[0]) {
- $path = $this->requestContext->getPathInfo().$path;
+ $path = $context->getPathInfo().$path;
}
if ('/' !== $path[0]) {
- $path = rtrim($this->requestContext->getBaseUrl(), '/').'/'.$path;
+ $path = rtrim($context->getBaseUrl(), '/').'/'.$path;
}
return $scheme.'://'.$host.$port.$path;
diff --git a/core/vendor/symfony/http-foundation/composer.json b/core/vendor/symfony/http-foundation/composer.json
index e333a23b7a..248bcbb163 100644
--- a/core/vendor/symfony/http-foundation/composer.json
+++ b/core/vendor/symfony/http-foundation/composer.json
@@ -17,11 +17,13 @@
],
"require": {
"php": ">=8.1",
- "symfony/deprecation-contracts": "^2.1|^3",
- "symfony/polyfill-mbstring": "~1.1"
+ "symfony/deprecation-contracts": "^2.5|^3",
+ "symfony/polyfill-mbstring": "~1.1",
+ "symfony/polyfill-php83": "^1.27"
},
"require-dev": {
- "predis/predis": "~1.0",
+ "doctrine/dbal": "^2.13.1|^3.0",
+ "predis/predis": "^1.1|^2.0",
"symfony/cache": "^5.4|^6.0",
"symfony/dependency-injection": "^5.4|^6.0",
"symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4",
@@ -32,9 +34,6 @@
"conflict": {
"symfony/cache": "<6.2"
},
- "suggest" : {
- "symfony/mime": "To use the file extension guesser"
- },
"autoload": {
"psr-4": { "Symfony\\Component\\HttpFoundation\\": "" },
"exclude-from-classmap": [
diff --git a/core/vendor/symfony/http-kernel/Attribute/AsTargetedValueResolver.php b/core/vendor/symfony/http-kernel/Attribute/AsTargetedValueResolver.php
new file mode 100644
index 0000000000..c58f0e6dd5
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/AsTargetedValueResolver.php
@@ -0,0 +1,24 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+/**
+ * Service tag to autoconfigure targeted value resolvers.
+ */
+#[\Attribute(\Attribute::TARGET_CLASS)]
+class AsTargetedValueResolver
+{
+ public function __construct(
+ public readonly ?string $name = null,
+ ) {
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/MapDateTime.php b/core/vendor/symfony/http-kernel/Attribute/MapDateTime.php
index ce9f856855..bfe48a8090 100644
--- a/core/vendor/symfony/http-kernel/Attribute/MapDateTime.php
+++ b/core/vendor/symfony/http-kernel/Attribute/MapDateTime.php
@@ -11,14 +11,19 @@
namespace Symfony\Component\HttpKernel\Attribute;
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DateTimeValueResolver;
+
/**
* Controller parameter tag to configure DateTime arguments.
*/
#[\Attribute(\Attribute::TARGET_PARAMETER)]
-class MapDateTime
+class MapDateTime extends ValueResolver
{
public function __construct(
- public readonly ?string $format = null
+ public readonly ?string $format = null,
+ bool $disabled = false,
+ string $resolver = DateTimeValueResolver::class,
) {
+ parent::__construct($resolver, $disabled);
}
}
diff --git a/core/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php b/core/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php
new file mode 100644
index 0000000000..f83e331e41
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/MapQueryParameter.php
@@ -0,0 +1,38 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\QueryParameterValueResolver;
+
+/**
+ * Can be used to pass a query parameter to a controller argument.
+ *
+ * @author Ruud Kamphuis
+ */
+#[\Attribute(\Attribute::TARGET_PARAMETER)]
+final class MapQueryParameter extends ValueResolver
+{
+ /**
+ * @see https://php.net/filter.filters.validate for filter, flags and options
+ *
+ * @param string|null $name The name of the query parameter. If null, the name of the argument in the controller will be used.
+ */
+ public function __construct(
+ public ?string $name = null,
+ public ?int $filter = null,
+ public int $flags = 0,
+ public array $options = [],
+ string $resolver = QueryParameterValueResolver::class,
+ ) {
+ parent::__construct($resolver);
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/MapQueryString.php b/core/vendor/symfony/http-kernel/Attribute/MapQueryString.php
new file mode 100644
index 0000000000..6ba85e1bdd
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/MapQueryString.php
@@ -0,0 +1,35 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver;
+use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+
+/**
+ * Controller parameter tag to map the query string of the request to typed object and validate it.
+ *
+ * @author Konstantin Myakshin
+ */
+#[\Attribute(\Attribute::TARGET_PARAMETER)]
+class MapQueryString extends ValueResolver
+{
+ public ArgumentMetadata $metadata;
+
+ public function __construct(
+ public readonly array $serializationContext = [],
+ public readonly string|GroupSequence|array|null $validationGroups = null,
+ string $resolver = RequestPayloadValueResolver::class,
+ ) {
+ parent::__construct($resolver);
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php b/core/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php
new file mode 100644
index 0000000000..02c01fa40b
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/MapRequestPayload.php
@@ -0,0 +1,36 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestPayloadValueResolver;
+use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
+use Symfony\Component\Validator\Constraints\GroupSequence;
+
+/**
+ * Controller parameter tag to map the request content to typed object and validate it.
+ *
+ * @author Konstantin Myakshin
+ */
+#[\Attribute(\Attribute::TARGET_PARAMETER)]
+class MapRequestPayload extends ValueResolver
+{
+ public ArgumentMetadata $metadata;
+
+ public function __construct(
+ public readonly array|string|null $acceptFormat = null,
+ public readonly array $serializationContext = [],
+ public readonly string|GroupSequence|array|null $validationGroups = null,
+ string $resolver = RequestPayloadValueResolver::class,
+ ) {
+ parent::__construct($resolver);
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/ValueResolver.php b/core/vendor/symfony/http-kernel/Attribute/ValueResolver.php
new file mode 100644
index 0000000000..5875a27484
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/ValueResolver.php
@@ -0,0 +1,27 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
+
+#[\Attribute(\Attribute::TARGET_PARAMETER | \Attribute::IS_REPEATABLE)]
+class ValueResolver
+{
+ /**
+ * @param class-string|string $resolver
+ */
+ public function __construct(
+ public string $resolver,
+ public bool $disabled = false,
+ ) {
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/WithHttpStatus.php b/core/vendor/symfony/http-kernel/Attribute/WithHttpStatus.php
new file mode 100644
index 0000000000..718427aacc
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/WithHttpStatus.php
@@ -0,0 +1,28 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+/**
+ * @author Dejan Angelov
+ */
+#[\Attribute(\Attribute::TARGET_CLASS)]
+class WithHttpStatus
+{
+ /**
+ * @param array $headers
+ */
+ public function __construct(
+ public readonly int $statusCode,
+ public readonly array $headers = [],
+ ) {
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Attribute/WithLogLevel.php b/core/vendor/symfony/http-kernel/Attribute/WithLogLevel.php
new file mode 100644
index 0000000000..762b077043
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Attribute/WithLogLevel.php
@@ -0,0 +1,31 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Attribute;
+
+use Psr\Log\LogLevel;
+
+/**
+ * @author Dejan Angelov
+ */
+#[\Attribute(\Attribute::TARGET_CLASS)]
+final class WithLogLevel
+{
+ /**
+ * @param LogLevel::* $level
+ */
+ public function __construct(public readonly string $level)
+ {
+ if (!\defined('Psr\Log\LogLevel::'.strtoupper($this->level))) {
+ throw new \InvalidArgumentException(sprintf('Invalid log level "%s".', $this->level));
+ }
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Bundle/Bundle.php b/core/vendor/symfony/http-kernel/Bundle/Bundle.php
index 4d17cf5db3..2ddf55f2cb 100644
--- a/core/vendor/symfony/http-kernel/Bundle/Bundle.php
+++ b/core/vendor/symfony/http-kernel/Bundle/Bundle.php
@@ -31,10 +31,16 @@ abstract class Bundle implements BundleInterface
protected $path;
private string $namespace;
+ /**
+ * @return void
+ */
public function boot()
{
}
+ /**
+ * @return void
+ */
public function shutdown()
{
}
@@ -42,6 +48,8 @@ public function shutdown()
/**
* This method can be overridden to register compilation passes,
* other extensions, ...
+ *
+ * @return void
*/
public function build(ContainerBuilder $container)
{
@@ -110,6 +118,9 @@ final public function getName(): string
return $this->name;
}
+ /**
+ * @return void
+ */
public function registerCommands(Application $application)
{
}
@@ -132,7 +143,7 @@ protected function createContainerExtension(): ?ExtensionInterface
return class_exists($class = $this->getContainerExtensionClass()) ? new $class() : null;
}
- private function parseClassName()
+ private function parseClassName(): void
{
$pos = strrpos(static::class, '\\');
$this->namespace = false === $pos ? '' : substr(static::class, 0, $pos);
diff --git a/core/vendor/symfony/http-kernel/Bundle/BundleInterface.php b/core/vendor/symfony/http-kernel/Bundle/BundleInterface.php
index 5490632552..02cb9641db 100644
--- a/core/vendor/symfony/http-kernel/Bundle/BundleInterface.php
+++ b/core/vendor/symfony/http-kernel/Bundle/BundleInterface.php
@@ -24,11 +24,15 @@ interface BundleInterface extends ContainerAwareInterface
{
/**
* Boots the Bundle.
+ *
+ * @return void
*/
public function boot();
/**
* Shutdowns the Bundle.
+ *
+ * @return void
*/
public function shutdown();
@@ -36,6 +40,8 @@ public function shutdown();
* Builds the bundle.
*
* It is only ever called once when the cache is empty.
+ *
+ * @return void
*/
public function build(ContainerBuilder $container);
diff --git a/core/vendor/symfony/http-kernel/CHANGELOG.md b/core/vendor/symfony/http-kernel/CHANGELOG.md
index 2a5aad623b..8aceb90c86 100644
--- a/core/vendor/symfony/http-kernel/CHANGELOG.md
+++ b/core/vendor/symfony/http-kernel/CHANGELOG.md
@@ -1,6 +1,21 @@
CHANGELOG
=========
+6.3
+---
+
+ * Deprecate parameters `container.dumper.inline_factories` and `container.dumper.inline_class_loader`, use `.container.dumper.inline_factories` and `.container.dumper.inline_class_loader` instead
+ * `FileProfilerStorage` removes profiles automatically after two days
+ * Add `#[WithHttpStatus]` for defining status codes for exceptions
+ * Use an instance of `Psr\Clock\ClockInterface` to generate the current date time in `DateTimeValueResolver`
+ * Add `#[WithLogLevel]` for defining log levels for exceptions
+ * Add `skip_response_headers` to the `HttpCache` options
+ * Introduce targeted value resolvers with `#[ValueResolver]` and `#[AsTargetedValueResolver]`
+ * Add `#[MapRequestPayload]` to map and validate request payload from `Request::getContent()` or `Request::$request->all()` to typed objects
+ * Add `#[MapQueryString]` to map and validate request query string from `Request::$query->all()` to typed objects
+ * Add `#[MapQueryParameter]` to map and validate individual query parameters to controller arguments
+ * Collect data from every event dispatcher
+
6.2
---
diff --git a/core/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php b/core/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php
index 270f690e5b..5ca4265624 100644
--- a/core/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php
+++ b/core/vendor/symfony/http-kernel/CacheClearer/CacheClearerInterface.php
@@ -20,6 +20,8 @@ interface CacheClearerInterface
{
/**
* Clears any caches necessary.
+ *
+ * @return void
*/
public function clear(string $cacheDir);
}
diff --git a/core/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php b/core/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php
index 8ce77e2b74..0c541f21b8 100644
--- a/core/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php
+++ b/core/vendor/symfony/http-kernel/CacheClearer/ChainCacheClearer.php
@@ -30,7 +30,7 @@ public function __construct(iterable $clearers = [])
$this->clearers = $clearers;
}
- public function clear(string $cacheDir)
+ public function clear(string $cacheDir): void
{
foreach ($this->clearers as $clearer) {
$clearer->clear($cacheDir);
diff --git a/core/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php b/core/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php
index 054f77bc22..3c99b74af3 100644
--- a/core/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php
+++ b/core/vendor/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php
@@ -57,6 +57,9 @@ public function clearPool(string $name): bool
return $this->pools[$name]->clear();
}
+ /**
+ * @return void
+ */
public function clear(string $cacheDir)
{
foreach ($this->pools as $pool) {
diff --git a/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php b/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php
index aef42d62f4..f940ba4a72 100644
--- a/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php
+++ b/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmer.php
@@ -18,6 +18,9 @@
*/
abstract class CacheWarmer implements CacheWarmerInterface
{
+ /**
+ * @return void
+ */
protected function writeCacheFile(string $file, $content)
{
$tmpFile = @tempnam(\dirname($file), basename($file));
diff --git a/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php b/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php
index af0a2d13d1..3013292167 100644
--- a/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php
+++ b/core/vendor/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpKernel\CacheWarmer;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
/**
* Aggregates several cache warmers into a single one.
*
@@ -36,17 +38,17 @@ public function __construct(iterable $warmers = [], bool $debug = false, string
$this->deprecationLogsFilepath = $deprecationLogsFilepath;
}
- public function enableOptionalWarmers()
+ public function enableOptionalWarmers(): void
{
$this->optionalsEnabled = true;
}
- public function enableOnlyOptionalWarmers()
+ public function enableOnlyOptionalWarmers(): void
{
$this->onlyOptionalsEnabled = $this->optionalsEnabled = true;
}
- public function warmUp(string $cacheDir): array
+ public function warmUp(string $cacheDir, SymfonyStyle $io = null): array
{
if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) {
$collectedLogs = [];
@@ -93,7 +95,17 @@ public function warmUp(string $cacheDir): array
continue;
}
- $preload[] = array_values((array) $warmer->warmUp($cacheDir));
+ $start = microtime(true);
+ foreach ((array) $warmer->warmUp($cacheDir) as $item) {
+ if (is_dir($item) || (str_starts_with($item, \dirname($cacheDir)) && !is_file($item))) {
+ throw new \LogicException(sprintf('"%s::warmUp()" should return a list of files or classes but "%s" is none of them.', $warmer::class, $item));
+ }
+ $preload[] = $item;
+ }
+
+ if ($io?->isDebug()) {
+ $io->info(sprintf('"%s" completed in %0.2fms.', $warmer::class, 1000 * (microtime(true) - $start)));
+ }
}
} finally {
if ($collectDeprecations) {
@@ -110,7 +122,7 @@ public function warmUp(string $cacheDir): array
}
}
- return array_values(array_unique(array_merge([], ...$preload)));
+ return array_values(array_unique($preload));
}
public function isOptional(): bool
diff --git a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver.php b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver.php
index 52ac242141..3b0f89509f 100644
--- a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver.php
+++ b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver.php
@@ -11,7 +11,9 @@
namespace Symfony\Component\HttpKernel\Controller;
+use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Attribute\ValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\DefaultValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestAttributeValueResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\RequestValueResolver;
@@ -20,6 +22,8 @@
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\VariadicValueResolver;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactory;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadataFactoryInterface;
+use Symfony\Component\HttpKernel\Exception\ResolverNotFoundException;
+use Symfony\Contracts\Service\ServiceProviderInterface;
/**
* Responsible for resolving the arguments passed to an action.
@@ -30,14 +34,16 @@ final class ArgumentResolver implements ArgumentResolverInterface
{
private ArgumentMetadataFactoryInterface $argumentMetadataFactory;
private iterable $argumentValueResolvers;
+ private ?ContainerInterface $namedResolvers;
/**
* @param iterable $argumentValueResolvers
*/
- public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [])
+ public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [], ContainerInterface $namedResolvers = null)
{
$this->argumentMetadataFactory = $argumentMetadataFactory ?? new ArgumentMetadataFactory();
$this->argumentValueResolvers = $argumentValueResolvers ?: self::getDefaultArgumentValueResolvers();
+ $this->namedResolvers = $namedResolvers;
}
public function getArguments(Request $request, callable $controller, \ReflectionFunctionAbstract $reflector = null): array
@@ -45,10 +51,40 @@ public function getArguments(Request $request, callable $controller, \Reflection
$arguments = [];
foreach ($this->argumentMetadataFactory->createArgumentMetadata($controller, $reflector) as $metadata) {
- foreach ($this->argumentValueResolvers as $resolver) {
+ $argumentValueResolvers = $this->argumentValueResolvers;
+ $disabledResolvers = [];
+
+ if ($this->namedResolvers && $attributes = $metadata->getAttributesOfType(ValueResolver::class, $metadata::IS_INSTANCEOF)) {
+ $resolverName = null;
+ foreach ($attributes as $attribute) {
+ if ($attribute->disabled) {
+ $disabledResolvers[$attribute->resolver] = true;
+ } elseif ($resolverName) {
+ throw new \LogicException(sprintf('You can only pin one resolver per argument, but argument "$%s" of "%s()" has more.', $metadata->getName(), $this->getPrettyName($controller)));
+ } else {
+ $resolverName = $attribute->resolver;
+ }
+ }
+
+ if ($resolverName) {
+ if (!$this->namedResolvers->has($resolverName)) {
+ throw new ResolverNotFoundException($resolverName, $this->namedResolvers instanceof ServiceProviderInterface ? array_keys($this->namedResolvers->getProvidedServices()) : []);
+ }
+
+ $argumentValueResolvers = [
+ $this->namedResolvers->get($resolverName),
+ new DefaultValueResolver(),
+ ];
+ }
+ }
+
+ foreach ($argumentValueResolvers as $name => $resolver) {
if ((!$resolver instanceof ValueResolverInterface || $resolver instanceof TraceableValueResolver) && !$resolver->supports($request, $metadata)) {
continue;
}
+ if (isset($disabledResolvers[\is_int($name) ? $resolver::class : $name])) {
+ continue;
+ }
$count = 0;
foreach ($resolver->resolve($request, $metadata) as $argument) {
@@ -70,15 +106,7 @@ public function getArguments(Request $request, callable $controller, \Reflection
}
}
- $representative = $controller;
-
- if (\is_array($representative)) {
- $representative = sprintf('%s::%s()', \get_class($representative[0]), $representative[1]);
- } elseif (\is_object($representative)) {
- $representative = get_debug_type($representative);
- }
-
- throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or because there is a non optional argument after this one.', $representative, $metadata->getName()));
+ throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or there is a non-optional argument after this one.', $this->getPrettyName($controller), $metadata->getName()));
}
return $arguments;
@@ -97,4 +125,21 @@ public static function getDefaultArgumentValueResolvers(): iterable
new VariadicValueResolver(),
];
}
+
+ private function getPrettyName($controller): string
+ {
+ if (\is_array($controller)) {
+ if (\is_object($controller[0])) {
+ $controller[0] = get_debug_type($controller[0]);
+ }
+
+ return $controller[0].'::'.$controller[1];
+ }
+
+ if (\is_object($controller)) {
+ return get_debug_type($controller);
+ }
+
+ return $controller;
+ }
}
diff --git a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php
index 8fd7015ad0..0cfd42badc 100644
--- a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php
+++ b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+use Psr\Clock\ClockInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Attribute\MapDateTime;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
@@ -26,6 +27,11 @@
*/
final class DateTimeValueResolver implements ArgumentValueResolverInterface, ValueResolverInterface
{
+ public function __construct(
+ private readonly ?ClockInterface $clock = null,
+ ) {
+ }
+
/**
* @deprecated since Symfony 6.2, use resolve() instead
*/
@@ -45,12 +51,18 @@ public function resolve(Request $request, ArgumentMetadata $argument): array
$value = $request->attributes->get($argument->getName());
$class = \DateTimeInterface::class === $argument->getType() ? \DateTimeImmutable::class : $argument->getType();
- if ($value instanceof \DateTimeInterface) {
- return [$value instanceof $class ? $value : $class::createFromInterface($value)];
+ if (!$value) {
+ if ($argument->isNullable()) {
+ return [null];
+ }
+ if (!$this->clock) {
+ return [new $class()];
+ }
+ $value = $this->clock->now();
}
- if ($argument->isNullable() && !$value) {
- return [null];
+ if ($value instanceof \DateTimeInterface) {
+ return [$value instanceof $class ? $value : $class::createFromInterface($value)];
}
$format = null;
@@ -61,7 +73,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array
}
if (null !== $format) {
- $date = $class::createFromFormat($format, $value);
+ $date = $class::createFromFormat($format, $value, $this->clock?->now()->getTimeZone());
if (($class::getLastErrors() ?: ['warning_count' => 0])['warning_count']) {
$date = false;
@@ -71,7 +83,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array
$value = '@'.$value;
}
try {
- $date = new $class($value ?? 'now');
+ $date = new $class($value, $this->clock?->now()->getTimeZone());
} catch (\Exception) {
$date = false;
}
diff --git a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php
new file mode 100644
index 0000000000..f2e4bee812
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php
@@ -0,0 +1,100 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Attribute\MapQueryParameter;
+use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
+use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
+use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
+
+/**
+ * @author Ruud Kamphuis
+ * @author Nicolas Grekas
+ */
+final class QueryParameterValueResolver implements ValueResolverInterface
+{
+ public function resolve(Request $request, ArgumentMetadata $argument): array
+ {
+ if (!$attribute = $argument->getAttributesOfType(MapQueryParameter::class)[0] ?? null) {
+ return [];
+ }
+
+ $name = $attribute->name ?? $argument->getName();
+ if (!$request->query->has($name)) {
+ if ($argument->isNullable() || $argument->hasDefaultValue()) {
+ return [];
+ }
+
+ throw new NotFoundHttpException(sprintf('Missing query parameter "%s".', $name));
+ }
+
+ $value = $request->query->all()[$name];
+
+ if (null === $attribute->filter && 'array' === $argument->getType()) {
+ if (!$argument->isVariadic()) {
+ return [(array) $value];
+ }
+
+ $filtered = array_values(array_filter((array) $value, \is_array(...)));
+
+ if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
+ throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name));
+ }
+
+ return $filtered;
+ }
+
+ $options = [
+ 'flags' => $attribute->flags | \FILTER_NULL_ON_FAILURE,
+ 'options' => $attribute->options,
+ ];
+
+ if ('array' === $argument->getType() || $argument->isVariadic()) {
+ $value = (array) $value;
+ $options['flags'] |= \FILTER_REQUIRE_ARRAY;
+ } else {
+ $options['flags'] |= \FILTER_REQUIRE_SCALAR;
+ }
+
+ $filter = match ($argument->getType()) {
+ 'array' => \FILTER_DEFAULT,
+ 'string' => \FILTER_DEFAULT,
+ 'int' => \FILTER_VALIDATE_INT,
+ 'float' => \FILTER_VALIDATE_FLOAT,
+ 'bool' => \FILTER_VALIDATE_BOOL,
+ default => throw new \LogicException(sprintf('#[MapQueryParameter] cannot be used on controller argument "%s$%s" of type "%s"; one of array, string, int, float or bool should be used.', $argument->isVariadic() ? '...' : '', $argument->getName(), $argument->getType() ?? 'mixed'))
+ };
+
+ $value = filter_var($value, $attribute->filter ?? $filter, $options);
+
+ if (null === $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
+ throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name));
+ }
+
+ if (!\is_array($value)) {
+ return [$value];
+ }
+
+ $filtered = array_filter($value, static fn ($v) => null !== $v);
+
+ if ($argument->isVariadic()) {
+ $filtered = array_values($filtered);
+ }
+
+ if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) {
+ throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name));
+ }
+
+ return $argument->isVariadic() ? $filtered : [$filtered];
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php
new file mode 100644
index 0000000000..9ae65c7dfd
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php
@@ -0,0 +1,189 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Controller\ArgumentResolver;
+
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\Response;
+use Symfony\Component\HttpKernel\Attribute\MapQueryString;
+use Symfony\Component\HttpKernel\Attribute\MapRequestPayload;
+use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
+use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
+use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
+use Symfony\Component\HttpKernel\Exception\HttpException;
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\Serializer\Exception\NotEncodableValueException;
+use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
+use Symfony\Component\Serializer\Exception\UnsupportedFormatException;
+use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
+use Symfony\Component\Serializer\SerializerInterface;
+use Symfony\Component\Validator\ConstraintViolation;
+use Symfony\Component\Validator\ConstraintViolationList;
+use Symfony\Component\Validator\Exception\ValidationFailedException;
+use Symfony\Component\Validator\Validator\ValidatorInterface;
+use Symfony\Contracts\Translation\TranslatorInterface;
+
+/**
+ * @author Konstantin Myakshin
+ *
+ * @final
+ */
+class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscriberInterface
+{
+ /**
+ * @see \Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT
+ * @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS
+ */
+ private const CONTEXT_DENORMALIZE = [
+ 'disable_type_enforcement' => true,
+ 'collect_denormalization_errors' => true,
+ ];
+
+ /**
+ * @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS
+ */
+ private const CONTEXT_DESERIALIZE = [
+ 'collect_denormalization_errors' => true,
+ ];
+
+ public function __construct(
+ private readonly SerializerInterface&DenormalizerInterface $serializer,
+ private readonly ?ValidatorInterface $validator = null,
+ private readonly ?TranslatorInterface $translator = null,
+ ) {
+ }
+
+ public function resolve(Request $request, ArgumentMetadata $argument): iterable
+ {
+ $attribute = $argument->getAttributesOfType(MapQueryString::class, ArgumentMetadata::IS_INSTANCEOF)[0]
+ ?? $argument->getAttributesOfType(MapRequestPayload::class, ArgumentMetadata::IS_INSTANCEOF)[0]
+ ?? null;
+
+ if (!$attribute) {
+ return [];
+ }
+
+ $attribute->metadata = $argument;
+
+ return [$attribute];
+ }
+
+ public function onKernelControllerArguments(ControllerArgumentsEvent $event): void
+ {
+ $arguments = $event->getArguments();
+
+ foreach ($arguments as $i => $argument) {
+ if ($argument instanceof MapQueryString) {
+ $payloadMapper = 'mapQueryString';
+ $validationFailedCode = Response::HTTP_NOT_FOUND;
+ } elseif ($argument instanceof MapRequestPayload) {
+ $payloadMapper = 'mapRequestPayload';
+ $validationFailedCode = Response::HTTP_UNPROCESSABLE_ENTITY;
+ } else {
+ continue;
+ }
+ $request = $event->getRequest();
+
+ if (!$type = $argument->metadata->getType()) {
+ throw new \LogicException(sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->metadata->getName()));
+ }
+
+ if ($this->validator) {
+ $violations = new ConstraintViolationList();
+ try {
+ $payload = $this->$payloadMapper($request, $type, $argument);
+ } catch (PartialDenormalizationException $e) {
+ $trans = $this->translator ? $this->translator->trans(...) : fn ($m, $p) => strtr($m, $p);
+ foreach ($e->getErrors() as $error) {
+ $parameters = ['{{ type }}' => implode('|', $error->getExpectedTypes())];
+ if ($error->canUseMessageForUser()) {
+ $parameters['hint'] = $error->getMessage();
+ }
+ $template = 'This value should be of type {{ type }}.';
+ $message = $trans($template, $parameters, 'validators');
+ $violations->add(new ConstraintViolation($message, $template, $parameters, null, $error->getPath(), null));
+ }
+ $payload = $e->getData();
+ }
+
+ if (null !== $payload) {
+ $violations->addAll($this->validator->validate($payload, null, $argument->validationGroups ?? null));
+ }
+
+ if (\count($violations)) {
+ throw new HttpException($validationFailedCode, implode("\n", array_map(static fn ($e) => $e->getMessage(), iterator_to_array($violations))), new ValidationFailedException($payload, $violations));
+ }
+ } else {
+ try {
+ $payload = $this->$payloadMapper($request, $type, $argument);
+ } catch (PartialDenormalizationException $e) {
+ throw new HttpException($validationFailedCode, implode("\n", array_map(static fn ($e) => $e->getMessage(), $e->getErrors())), $e);
+ }
+ }
+
+ if (null === $payload && !$argument->metadata->isNullable()) {
+ throw new HttpException($validationFailedCode);
+ }
+
+ $arguments[$i] = $payload;
+ }
+
+ $event->setArguments($arguments);
+ }
+
+ public static function getSubscribedEvents(): array
+ {
+ return [
+ KernelEvents::CONTROLLER_ARGUMENTS => 'onKernelControllerArguments',
+ ];
+ }
+
+ private function mapQueryString(Request $request, string $type, MapQueryString $attribute): ?object
+ {
+ if (!$data = $request->query->all()) {
+ return null;
+ }
+
+ return $this->serializer->denormalize($data, $type, null, self::CONTEXT_DENORMALIZE + $attribute->serializationContext);
+ }
+
+ private function mapRequestPayload(Request $request, string $type, MapRequestPayload $attribute): ?object
+ {
+ if (null === $format = $request->getContentTypeFormat()) {
+ throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, 'Unsupported format.');
+ }
+
+ if ($attribute->acceptFormat && !\in_array($format, (array) $attribute->acceptFormat, true)) {
+ throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format, expects "%s", but "%s" given.', implode('", "', (array) $attribute->acceptFormat), $format));
+ }
+
+ if ($data = $request->request->all()) {
+ return $this->serializer->denormalize($data, $type, null, self::CONTEXT_DENORMALIZE + $attribute->serializationContext);
+ }
+
+ if ('' === $data = $request->getContent()) {
+ return null;
+ }
+
+ if ('form' === $format) {
+ throw new HttpException(Response::HTTP_BAD_REQUEST, 'Request payload contains invalid "form" data.');
+ }
+
+ try {
+ return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->serializationContext);
+ } catch (UnsupportedFormatException $e) {
+ throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format: "%s".', $format), $e);
+ } catch (NotEncodableValueException $e) {
+ throw new HttpException(Response::HTTP_BAD_REQUEST, sprintf('Request payload contains invalid "%s" data.', $format), $e);
+ }
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/TraceableValueResolver.php b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/TraceableValueResolver.php
index edc30e1806..0cb4703b29 100644
--- a/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/TraceableValueResolver.php
+++ b/core/vendor/symfony/http-kernel/Controller/ArgumentResolver/TraceableValueResolver.php
@@ -42,7 +42,7 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
return true;
}
- $method = \get_class($this->inner).'::'.__FUNCTION__;
+ $method = $this->inner::class.'::'.__FUNCTION__;
$this->stopwatch->start($method, 'controller.argument_value_resolver');
$return = $this->inner->supports($request, $argument);
@@ -54,7 +54,7 @@ public function supports(Request $request, ArgumentMetadata $argument): bool
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
- $method = \get_class($this->inner).'::'.__FUNCTION__;
+ $method = $this->inner::class.'::'.__FUNCTION__;
$this->stopwatch->start($method, 'controller.argument_value_resolver');
yield from $this->inner->resolve($request, $argument);
diff --git a/core/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php b/core/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php
index 6930738a28..1c9254e732 100644
--- a/core/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php
+++ b/core/vendor/symfony/http-kernel/Controller/ContainerControllerResolver.php
@@ -54,7 +54,7 @@ protected function instantiateController(string $class): object
throw new \InvalidArgumentException(sprintf('Controller "%s" does neither exist as service nor as class.', $class), 0, $e);
}
- private function throwExceptionIfControllerWasRemoved(string $controller, \Throwable $previous)
+ private function throwExceptionIfControllerWasRemoved(string $controller, \Throwable $previous): void
{
if ($this->container instanceof Container && isset($this->container->getRemovedIds()[$controller])) {
throw new \InvalidArgumentException(sprintf('Controller "%s" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?', $controller), 0, $previous);
diff --git a/core/vendor/symfony/http-kernel/Controller/ControllerResolver.php b/core/vendor/symfony/http-kernel/Controller/ControllerResolver.php
index 4a08041f33..b12ce8d35f 100644
--- a/core/vendor/symfony/http-kernel/Controller/ControllerResolver.php
+++ b/core/vendor/symfony/http-kernel/Controller/ControllerResolver.php
@@ -197,8 +197,6 @@ private function getClassMethodsWithoutMagicMethods($classOrObject): array
{
$methods = get_class_methods($classOrObject);
- return array_filter($methods, function (string $method) {
- return 0 !== strncmp($method, '__', 2);
- });
+ return array_filter($methods, fn (string $method) => 0 !== strncmp($method, '__', 2));
}
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php
index fda6a4eaaa..016ef2eceb 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/AjaxDataCollector.php
@@ -21,12 +21,12 @@
*/
class AjaxDataCollector extends DataCollector
{
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
// all collecting is done client side
}
- public function reset()
+ public function reset(): void
{
// all collecting is done client side
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
index d489b023aa..9873a9255a 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/ConfigDataCollector.php
@@ -29,7 +29,7 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
/**
* Sets the Kernel associated with this Request.
*/
- public function setKernel(KernelInterface $kernel = null)
+ public function setKernel(KernelInterface $kernel = null): void
{
if (1 > \func_num_args()) {
trigger_deprecation('symfony/http-kernel', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__);
@@ -38,7 +38,7 @@ public function setKernel(KernelInterface $kernel = null)
$this->kernel = $kernel;
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
$eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE);
$eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE);
@@ -76,12 +76,12 @@ public function collect(Request $request, Response $response, \Throwable $except
}
}
- public function reset()
+ public function reset(): void
{
$this->data = [];
}
- public function lateCollect()
+ public function lateCollect(): void
{
$this->data = $this->cloneVar($this->data);
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/DataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/DataCollector.php
index 3a3be3af49..698ed31397 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/DataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/DataCollector.php
@@ -89,14 +89,14 @@ public function __wakeup()
/**
* @internal to prevent implementing \Serializable
*/
- final protected function serialize()
+ final protected function serialize(): void
{
}
/**
* @internal to prevent implementing \Serializable
*/
- final protected function unserialize(string $data)
+ final protected function unserialize(string $data): void
{
}
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php b/core/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php
index 1cb865fd66..8df94ccb8f 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/DataCollectorInterface.php
@@ -24,6 +24,8 @@ interface DataCollectorInterface extends ResetInterface
{
/**
* Collects data for the given Request and Response.
+ *
+ * @return void
*/
public function collect(Request $request, Response $response, \Throwable $exception = null);
diff --git a/core/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php
index 48ad9acb6d..d52b02b773 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/DumpDataCollector.php
@@ -68,32 +68,37 @@ public function __clone()
$this->clonesIndex = ++$this->clonesCount;
}
- public function dump(Data $data)
+ public function dump(Data $data): ?string
{
$this->stopwatch?->start('dump');
['name' => $name, 'file' => $file, 'line' => $line, 'file_excerpt' => $fileExcerpt] = $this->sourceContextProvider->getContext();
- if ($this->dumper instanceof Connection) {
- if (!$this->dumper->write($data)) {
- $this->isCollected = false;
- }
- } elseif ($this->dumper) {
- $this->doDump($this->dumper, $data, $name, $file, $line);
- } else {
+ if (!$this->dumper || $this->dumper instanceof Connection && !$this->dumper->write($data)) {
$this->isCollected = false;
}
+ $context = $data->getContext();
+ $label = $context['label'] ?? '';
+ unset($context['label']);
+ $data = $data->withContext($context);
+
+ if ($this->dumper && !$this->dumper instanceof Connection) {
+ $this->doDump($this->dumper, $data, $name, $file, $line, $label);
+ }
+
if (!$this->dataCount) {
$this->data = [];
}
- $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
+ $this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt', 'label');
++$this->dataCount;
$this->stopwatch?->stop('dump');
+
+ return null;
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
if (!$this->dataCount) {
$this->data = [];
@@ -123,12 +128,12 @@ public function collect(Request $request, Response $response, \Throwable $except
}
foreach ($this->data as $dump) {
- $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line']);
+ $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line'], $dump['label'] ?? '');
}
}
}
- public function reset()
+ public function reset(): void
{
$this->stopwatch?->reset();
$this->data = [];
@@ -240,7 +245,7 @@ public function __destruct()
foreach ($this->data as $i => $dump) {
$this->data[$i] = null;
- $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line']);
+ $this->doDump($dumper, $dump['data'], $dump['name'], $dump['file'], $dump['line'], $dump['label'] ?? '');
}
$this->data = [];
@@ -248,10 +253,12 @@ public function __destruct()
}
}
- private function doDump(DataDumperInterface $dumper, Data $data, string $name, string $file, int $line)
+ private function doDump(DataDumperInterface $dumper, Data $data, string $name, string $file, int $line, string $label): void
{
if ($dumper instanceof CliDumper) {
- $contextDumper = function ($name, $file, $line, $fmt) {
+ $contextDumper = function ($name, $file, $line, $fmt, $label) {
+ $this->line = '' !== $label ? $this->style('meta', $label).' in ' : '';
+
if ($this instanceof HtmlDumper) {
if ($file) {
$s = $this->style('meta', '%s');
@@ -265,17 +272,17 @@ private function doDump(DataDumperInterface $dumper, Data $data, string $name, s
} else {
$name = $this->style('meta', $name);
}
- $this->line = $name.' on line '.$this->style('meta', $line).':';
+ $this->line .= $name.' on line '.$this->style('meta', $line).':';
} else {
- $this->line = $this->style('meta', $name).' on line '.$this->style('meta', $line).':';
+ $this->line .= $this->style('meta', $name).' on line '.$this->style('meta', $line).':';
}
$this->dumpLine(0);
};
$contextDumper = $contextDumper->bindTo($dumper, $dumper);
- $contextDumper($name, $file, $line, $this->fileLinkFormat);
+ $contextDumper($name, $file, $line, $this->fileLinkFormat, $label);
} else {
$cloner = new VarCloner();
- $dumper->dump($cloner->cloneVar($name.' on line '.$line.':'));
+ $dumper->dump($cloner->cloneVar(('' !== $label ? $label.' in ' : '').$name.' on line '.$line.':'));
}
$dumper->dump($data);
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php
index 0c122e6cff..8c0eefdf39 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/EventDataCollector.php
@@ -28,76 +28,92 @@
*/
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
{
- private ?EventDispatcherInterface $dispatcher;
- private ?RequestStack $requestStack;
+ /** @var iterable */
+ private iterable $dispatchers;
private ?Request $currentRequest = null;
- public function __construct(EventDispatcherInterface $dispatcher = null, RequestStack $requestStack = null)
- {
- $this->dispatcher = $dispatcher;
+ /**
+ * @param iterable|EventDispatcherInterface|null $dispatchers
+ */
+ public function __construct(
+ iterable|EventDispatcherInterface $dispatchers = null,
+ private ?RequestStack $requestStack = null,
+ private string $defaultDispatcher = 'event_dispatcher',
+ ) {
+ if ($dispatchers instanceof EventDispatcherInterface) {
+ $dispatchers = [$this->defaultDispatcher => $dispatchers];
+ }
+ $this->dispatchers = $dispatchers ?? [];
$this->requestStack = $requestStack;
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
$this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
- $this->data = [
- 'called_listeners' => [],
- 'not_called_listeners' => [],
- 'orphaned_events' => [],
- ];
+ $this->data = [];
}
- public function reset()
+ public function reset(): void
{
$this->data = [];
- if ($this->dispatcher instanceof ResetInterface) {
- $this->dispatcher->reset();
+ foreach ($this->dispatchers as $dispatcher) {
+ if ($dispatcher instanceof ResetInterface) {
+ $dispatcher->reset();
+ }
}
}
- public function lateCollect()
+ public function lateCollect(): void
{
- if ($this->dispatcher instanceof TraceableEventDispatcher) {
- $this->setCalledListeners($this->dispatcher->getCalledListeners($this->currentRequest));
- $this->setNotCalledListeners($this->dispatcher->getNotCalledListeners($this->currentRequest));
- $this->setOrphanedEvents($this->dispatcher->getOrphanedEvents($this->currentRequest));
+ foreach ($this->dispatchers as $name => $dispatcher) {
+ if (!$dispatcher instanceof TraceableEventDispatcher) {
+ continue;
+ }
+
+ $this->setCalledListeners($dispatcher->getCalledListeners($this->currentRequest), $name);
+ $this->setNotCalledListeners($dispatcher->getNotCalledListeners($this->currentRequest), $name);
+ $this->setOrphanedEvents($dispatcher->getOrphanedEvents($this->currentRequest), $name);
}
$this->data = $this->cloneVar($this->data);
}
+ public function getData(): array|Data
+ {
+ return $this->data;
+ }
+
/**
* @see TraceableEventDispatcher
*/
- public function setCalledListeners(array $listeners)
+ public function setCalledListeners(array $listeners, string $dispatcher = null): void
{
- $this->data['called_listeners'] = $listeners;
+ $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] = $listeners;
}
/**
* @see TraceableEventDispatcher
*/
- public function getCalledListeners(): array|Data
+ public function getCalledListeners(string $dispatcher = null): array|Data
{
- return $this->data['called_listeners'];
+ return $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] ?? [];
}
/**
* @see TraceableEventDispatcher
*/
- public function setNotCalledListeners(array $listeners)
+ public function setNotCalledListeners(array $listeners, string $dispatcher = null): void
{
- $this->data['not_called_listeners'] = $listeners;
+ $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] = $listeners;
}
/**
* @see TraceableEventDispatcher
*/
- public function getNotCalledListeners(): array|Data
+ public function getNotCalledListeners(string $dispatcher = null): array|Data
{
- return $this->data['not_called_listeners'];
+ return $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] ?? [];
}
/**
@@ -105,17 +121,17 @@ public function getNotCalledListeners(): array|Data
*
* @see TraceableEventDispatcher
*/
- public function setOrphanedEvents(array $events)
+ public function setOrphanedEvents(array $events, string $dispatcher = null): void
{
- $this->data['orphaned_events'] = $events;
+ $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] = $events;
}
/**
* @see TraceableEventDispatcher
*/
- public function getOrphanedEvents(): array|Data
+ public function getOrphanedEvents(string $dispatcher = null): array|Data
{
- return $this->data['orphaned_events'];
+ return $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] ?? [];
}
public function getName(): string
diff --git a/core/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php
index dbe24b414e..bcd7f238be 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/ExceptionDataCollector.php
@@ -22,16 +22,16 @@
*/
class ExceptionDataCollector extends DataCollector
{
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
if (null !== $exception) {
$this->data = [
- 'exception' => FlattenException::createFromThrowable($exception),
+ 'exception' => FlattenException::createWithDataRepresentation($exception),
];
}
}
- public function reset()
+ public function reset(): void
{
$this->data = [];
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php b/core/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php
index 012332de47..efa1a4f737 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/LateDataCollectorInterface.php
@@ -20,6 +20,8 @@ interface LateDataCollectorInterface
{
/**
* Collects data as late as possible.
+ *
+ * @return void
*/
public function lateCollect();
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php
index 661b84e0ad..d10dd365ad 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/LoggerDataCollector.php
@@ -40,12 +40,12 @@ public function __construct(object $logger = null, string $containerPathPrefix =
$this->requestStack = $requestStack;
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
$this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null;
}
- public function reset()
+ public function reset(): void
{
if (isset($this->logger)) {
$this->logger->clear();
@@ -53,7 +53,7 @@ public function reset()
$this->data = [];
}
- public function lateCollect()
+ public function lateCollect(): void
{
if (isset($this->logger)) {
$containerDeprecationLogs = $this->getContainerDeprecationLogs();
@@ -110,9 +110,7 @@ public function getProcessedLogs()
}
// sort logs from oldest to newest
- usort($logs, static function ($logA, $logB) {
- return $logA['timestamp'] <=> $logB['timestamp'];
- });
+ usort($logs, static fn ($logA, $logB) => $logA['timestamp'] <=> $logB['timestamp']);
return $this->processedLogs = $logs;
}
@@ -229,7 +227,7 @@ private function getContainerCompilerLogs(string $compilerLogsFilepath = null):
return $logs;
}
- private function sanitizeLogs(array $logs)
+ private function sanitizeLogs(array $logs): array
{
$sanitizedLogs = [];
$silencedLogs = [];
@@ -261,7 +259,7 @@ private function sanitizeLogs(array $logs)
continue;
}
- $errorId = md5("{$exception->getSeverity()}/{$exception->getLine()}/{$exception->getFile()}\0{$message}", true);
+ $errorId = hash('xxh128', "{$exception->getSeverity()}/{$exception->getLine()}/{$exception->getFile()}\0{$message}", true);
if (isset($sanitizedLogs[$errorId])) {
++$sanitizedLogs[$errorId]['errorCount'];
diff --git a/core/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php
index 474b5bf3fe..8b88943675 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/MemoryDataCollector.php
@@ -26,12 +26,12 @@ public function __construct()
$this->reset();
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
$this->updateMemoryUsage();
}
- public function reset()
+ public function reset(): void
{
$this->data = [
'memory' => 0,
@@ -39,7 +39,7 @@ public function reset()
];
}
- public function lateCollect()
+ public function lateCollect(): void
{
$this->updateMemoryUsage();
}
@@ -54,7 +54,7 @@ public function getMemoryLimit(): int|float
return $this->data['memory_limit'];
}
- public function updateMemoryUsage()
+ public function updateMemoryUsage(): void
{
$this->data['memory'] = memory_get_peak_usage(true);
}
diff --git a/core/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php
index aa505783bb..094683ccce 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/RequestDataCollector.php
@@ -44,7 +44,7 @@ public function __construct(RequestStack $requestStack = null)
$this->requestStack = $requestStack;
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
// attributes are serialized and as they can be anything, they need to be converted to strings.
$attributes = [];
@@ -136,7 +136,7 @@ public function collect(Request $request, Response $response, \Throwable $except
continue;
}
if ('request_headers' === $key || 'response_headers' === $key) {
- $this->data[$key] = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value);
+ $this->data[$key] = array_map(fn ($v) => isset($v[0]) && !isset($v[1]) ? $v[0] : $v, $value);
}
}
@@ -173,12 +173,12 @@ public function collect(Request $request, Response $response, \Throwable $except
}
}
- public function lateCollect()
+ public function lateCollect(): void
{
$this->data = $this->cloneVar($this->data);
}
- public function reset()
+ public function reset(): void
{
$this->data = [];
$this->controllers = new \SplObjectStorage();
@@ -195,46 +195,73 @@ public function getPathInfo()
return $this->data['path_info'];
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestRequest()
{
return new ParameterBag($this->data['request_request']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestQuery()
{
return new ParameterBag($this->data['request_query']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestFiles()
{
return new ParameterBag($this->data['request_files']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestHeaders()
{
return new ParameterBag($this->data['request_headers']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestServer(bool $raw = false)
{
return new ParameterBag($this->data['request_server']->getValue($raw));
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestCookies(bool $raw = false)
{
return new ParameterBag($this->data['request_cookies']->getValue($raw));
}
+ /**
+ * @return ParameterBag
+ */
public function getRequestAttributes()
{
return new ParameterBag($this->data['request_attributes']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getResponseHeaders()
{
return new ParameterBag($this->data['response_headers']->getValue());
}
+ /**
+ * @return ParameterBag
+ */
public function getResponseCookies()
{
return new ParameterBag($this->data['response_cookies']->getValue());
@@ -270,11 +297,17 @@ public function getContent()
return $this->data['content'];
}
+ /**
+ * @return bool
+ */
public function isJsonRequest()
{
return 1 === preg_match('{^application/(?:\w+\++)*json$}i', $this->data['request_headers']['content-type']);
}
+ /**
+ * @return string|null
+ */
public function getPrettyJson()
{
$decoded = json_decode($this->getContent());
@@ -307,6 +340,9 @@ public function getLocale()
return $this->data['locale'];
}
+ /**
+ * @return ParameterBag
+ */
public function getDotenvVars()
{
return new ParameterBag($this->data['dotenv_vars']->getValue());
@@ -364,12 +400,12 @@ public function getForwardToken()
return $this->data['forward_token'] ?? null;
}
- public function onKernelController(ControllerEvent $event)
+ public function onKernelController(ControllerEvent $event): void
{
$this->controllers[$event->getRequest()] = $event->getController();
}
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest()) {
return;
diff --git a/core/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php
index 3c9f2142f4..444138da70 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/RouterDataCollector.php
@@ -34,7 +34,7 @@ public function __construct()
/**
* @final
*/
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
if ($response instanceof RedirectResponse) {
$this->data['redirect'] = true;
@@ -48,6 +48,9 @@ public function collect(Request $request, Response $response, \Throwable $except
unset($this->controllers[$request]);
}
+ /**
+ * @return void
+ */
public function reset()
{
$this->controllers = new \SplObjectStorage();
@@ -59,6 +62,9 @@ public function reset()
];
}
+ /**
+ * @return string
+ */
protected function guessRoute(Request $request, string|object|array $controller)
{
return 'n/a';
@@ -66,6 +72,8 @@ protected function guessRoute(Request $request, string|object|array $controller)
/**
* Remembers the controller associated to each request.
+ *
+ * @return void
*/
public function onKernelController(ControllerEvent $event)
{
diff --git a/core/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php b/core/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php
index 71bf255d01..a8b7ead940 100644
--- a/core/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php
+++ b/core/vendor/symfony/http-kernel/DataCollector/TimeDataCollector.php
@@ -34,7 +34,7 @@ public function __construct(KernelInterface $kernel = null, Stopwatch $stopwatch
$this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0];
}
- public function collect(Request $request, Response $response, \Throwable $exception = null)
+ public function collect(Request $request, Response $response, \Throwable $exception = null): void
{
if (null !== $this->kernel) {
$startTime = $this->kernel->getStartTime();
@@ -50,14 +50,14 @@ public function collect(Request $request, Response $response, \Throwable $except
];
}
- public function reset()
+ public function reset(): void
{
$this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0];
$this->stopwatch?->reset();
}
- public function lateCollect()
+ public function lateCollect(): void
{
if (null !== $this->stopwatch && isset($this->data['token'])) {
$this->setEvents($this->stopwatch->getSectionEvents($this->data['token']));
@@ -68,7 +68,7 @@ public function lateCollect()
/**
* @param StopwatchEvent[] $events The request events
*/
- public function setEvents(array $events)
+ public function setEvents(array $events): void
{
foreach ($events as $event) {
$event->ensureStopped();
diff --git a/core/vendor/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php b/core/vendor/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php
new file mode 100644
index 0000000000..49f188c22d
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php
@@ -0,0 +1,107 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Debug;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\ErrorHandler\ErrorHandler;
+
+/**
+ * Configures the error handler.
+ *
+ * @final
+ *
+ * @internal
+ */
+class ErrorHandlerConfigurator
+{
+ private ?LoggerInterface $logger;
+ private ?LoggerInterface $deprecationLogger;
+ private array|int|null $levels;
+ private ?int $throwAt;
+ private bool $scream;
+ private bool $scope;
+
+ /**
+ * @param array|int|null $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
+ * @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value
+ * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
+ * @param bool $scope Enables/disables scoping mode
+ */
+ public function __construct(LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, LoggerInterface $deprecationLogger = null)
+ {
+ $this->logger = $logger;
+ $this->levels = $levels ?? \E_ALL;
+ $this->throwAt = \is_int($throwAt) ? $throwAt : (null === $throwAt ? null : ($throwAt ? \E_ALL : null));
+ $this->scream = $scream;
+ $this->scope = $scope;
+ $this->deprecationLogger = $deprecationLogger;
+ }
+
+ /**
+ * Configures the error handler.
+ */
+ public function configure(ErrorHandler $handler): void
+ {
+ if ($this->logger || $this->deprecationLogger) {
+ $this->setDefaultLoggers($handler);
+ if (\is_array($this->levels)) {
+ $levels = 0;
+ foreach ($this->levels as $type => $log) {
+ $levels |= $type;
+ }
+ } else {
+ $levels = $this->levels;
+ }
+
+ if ($this->scream) {
+ $handler->screamAt($levels);
+ }
+ if ($this->scope) {
+ $handler->scopeAt($levels & ~\E_USER_DEPRECATED & ~\E_DEPRECATED);
+ } else {
+ $handler->scopeAt(0, true);
+ }
+ $this->logger = $this->deprecationLogger = $this->levels = null;
+ }
+ if (null !== $this->throwAt) {
+ $handler->throwAt($this->throwAt, true);
+ }
+ }
+
+ private function setDefaultLoggers(ErrorHandler $handler): void
+ {
+ if (\is_array($this->levels)) {
+ $levelsDeprecatedOnly = [];
+ $levelsWithoutDeprecated = [];
+ foreach ($this->levels as $type => $log) {
+ if (\E_DEPRECATED == $type || \E_USER_DEPRECATED == $type) {
+ $levelsDeprecatedOnly[$type] = $log;
+ } else {
+ $levelsWithoutDeprecated[$type] = $log;
+ }
+ }
+ } else {
+ $levelsDeprecatedOnly = $this->levels & (\E_DEPRECATED | \E_USER_DEPRECATED);
+ $levelsWithoutDeprecated = $this->levels & ~\E_DEPRECATED & ~\E_USER_DEPRECATED;
+ }
+
+ $defaultLoggerLevels = $this->levels;
+ if ($this->deprecationLogger && $levelsDeprecatedOnly) {
+ $handler->setDefaultLogger($this->deprecationLogger, $levelsDeprecatedOnly);
+ $defaultLoggerLevels = $levelsWithoutDeprecated;
+ }
+
+ if ($this->logger && $defaultLoggerLevels) {
+ $handler->setDefaultLogger($this->logger, $defaultLoggerLevels);
+ }
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php b/core/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php
index 4eaeeb1513..fcb100859f 100644
--- a/core/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php
+++ b/core/vendor/symfony/http-kernel/Debug/FileLinkFormatter.php
@@ -37,8 +37,9 @@ public function __construct(string|array $fileLinkFormat = null, RequestStack $r
{
$fileLinkFormat ??= $_ENV['SYMFONY_IDE'] ?? $_SERVER['SYMFONY_IDE'] ?? '';
- if (!\is_array($fileLinkFormat) && $fileLinkFormat = (ErrorRendererInterface::IDE_LINK_FORMATS[$fileLinkFormat] ?? $fileLinkFormat) ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: false) {
- $i = strpos($f = $fileLinkFormat, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
+ if (!\is_array($f = $fileLinkFormat)) {
+ $f = (ErrorRendererInterface::IDE_LINK_FORMATS[$f] ?? $f) ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format') ?: 'file://%f#L%l';
+ $i = strpos($f, '&', max(strrpos($f, '%f'), strrpos($f, '%l'))) ?: \strlen($f);
$fileLinkFormat = [substr($f, 0, $i)] + preg_split('/&([^>]++)>/', substr($f, $i), -1, \PREG_SPLIT_DELIM_CAPTURE);
}
@@ -48,7 +49,10 @@ public function __construct(string|array $fileLinkFormat = null, RequestStack $r
$this->urlFormat = $urlFormat;
}
- public function format(string $file, int $line)
+ /**
+ * @return string|false
+ */
+ public function format(string $file, int $line): string|bool
{
if ($fmt = $this->getFileLinkFormat()) {
for ($i = 1; isset($fmt[$i]); ++$i) {
diff --git a/core/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php b/core/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php
index dff3bc9474..4f6c34bc74 100644
--- a/core/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php
+++ b/core/vendor/symfony/http-kernel/Debug/TraceableEventDispatcher.php
@@ -23,6 +23,9 @@
*/
class TraceableEventDispatcher extends BaseTraceableEventDispatcher
{
+ /**
+ * @return void
+ */
protected function beforeDispatch(string $eventName, object $event)
{
switch ($eventName) {
@@ -55,6 +58,9 @@ protected function beforeDispatch(string $eventName, object $event)
}
}
+ /**
+ * @return void
+ */
protected function afterDispatch(string $eventName, object $event)
{
switch ($eventName) {
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php b/core/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
index 9b691d26ef..1924b1ddb0 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/AddAnnotatedClassesToCachePass.php
@@ -31,6 +31,9 @@ public function __construct(Kernel $kernel)
$this->kernel = $kernel;
}
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
$annotatedClasses = [];
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php b/core/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php
index 8401dd4e8c..12d468cf04 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/ConfigurableExtension.php
@@ -27,13 +27,15 @@
*/
abstract class ConfigurableExtension extends Extension
{
- final public function load(array $configs, ContainerBuilder $container)
+ final public function load(array $configs, ContainerBuilder $container): void
{
$this->loadInternal($this->processConfiguration($this->getConfiguration($configs, $container), $configs), $container);
}
/**
* Configures the passed container according to the merged configuration.
+ *
+ * @return void
*/
abstract protected function loadInternal(array $mergedConfig, ContainerBuilder $container);
}
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php
index 281a778295..d3b157418e 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/ControllerArgumentValueResolverPass.php
@@ -12,6 +12,8 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
+use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
+use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -28,26 +30,44 @@ class ControllerArgumentValueResolverPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('argument_resolver')) {
return;
}
- $resolvers = $this->findAndSortTaggedServices('controller.argument_value_resolver', $container);
+ $definitions = $container->getDefinitions();
+ $namedResolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.targeted_value_resolver', 'name', needsIndexes: true), $container);
+ $resolvers = $this->findAndSortTaggedServices(new TaggedIteratorArgument('controller.argument_value_resolver', 'name', needsIndexes: true), $container);
+
+ foreach ($resolvers as $name => $resolver) {
+ if ($definitions[(string) $resolver]->hasTag('controller.targeted_value_resolver')) {
+ unset($resolvers[$name]);
+ } else {
+ $namedResolvers[$name] ??= clone $resolver;
+ }
+ }
if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class) && $container->has('debug.stopwatch')) {
- foreach ($resolvers as $resolverReference) {
- $id = (string) $resolverReference;
- $container->register("debug.$id", TraceableValueResolver::class)
- ->setDecoratedService($id)
- ->setArguments([new Reference("debug.$id.inner"), new Reference('debug.stopwatch')]);
+ foreach ($resolvers as $name => $resolver) {
+ $resolvers[$name] = new Reference('.debug.value_resolver.'.$resolver);
+ $container->register('.debug.value_resolver.'.$resolver, TraceableValueResolver::class)
+ ->setArguments([$resolver, new Reference('debug.stopwatch')]);
+ }
+ foreach ($namedResolvers as $name => $resolver) {
+ $namedResolvers[$name] = new Reference('.debug.value_resolver.'.$resolver);
+ $container->register('.debug.value_resolver.'.$resolver, TraceableValueResolver::class)
+ ->setArguments([$resolver, new Reference('debug.stopwatch')]);
}
}
$container
->getDefinition('argument_resolver')
- ->replaceArgument(1, new IteratorArgument($resolvers))
+ ->replaceArgument(1, new IteratorArgument(array_values($resolvers)))
+ ->setArgument(2, new ServiceLocatorArgument($namedResolvers))
;
}
}
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/Extension.php b/core/vendor/symfony/http-kernel/DependencyInjection/Extension.php
index c8d546e9d9..d72efa1724 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/Extension.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/Extension.php
@@ -34,6 +34,8 @@ public function getAnnotatedClassesToCompile(): array
* Adds annotated classes to the class cache.
*
* @param array $annotatedClasses An array of class patterns
+ *
+ * @return void
*/
public function addAnnotatedClassesToCompile(array $annotatedClasses)
{
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php
index ced62ae380..f41d58b81b 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php
@@ -25,6 +25,9 @@
*/
class FragmentRendererPass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('fragment.handler')) {
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php
index d780645f1e..2b6cb00793 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/LoggerPass.php
@@ -25,6 +25,9 @@
*/
class LoggerPass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
$container->setAlias(LoggerInterface::class, 'logger')
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php
index c0bc6eccf2..cec23e1970 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/MergeExtensionConfigurationPass.php
@@ -31,6 +31,9 @@ public function __construct(array $extensions)
$this->extensions = $extensions;
}
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
foreach ($this->extensions as $extension) {
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php
index c31fb35d71..d0e05340d8 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php
@@ -33,6 +33,9 @@
*/
class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('argument_resolver.service') && !$container->hasDefinition('argument_resolver.not_tagged_controller')) {
@@ -143,7 +146,7 @@ public function process(ContainerBuilder $container)
$args[$p->name] = $bindingValue;
continue;
- } elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class)) && (!$type || '\\' !== $target[0]))) {
+ } elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)) && (!$type || '\\' !== $target[0]))) {
continue;
} elseif (is_subclass_of($type, \UnitEnum::class)) {
// do not attempt to register enum typed arguments if not already present in bindings
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php
index 2141a510d6..2a01365bd3 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/RegisterLocaleAwareServicesPass.php
@@ -23,6 +23,9 @@
*/
class RegisterLocaleAwareServicesPass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('locale_aware_listener')) {
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php b/core/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php
index cbc92355d6..7a21fe0e59 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php
@@ -21,6 +21,9 @@
*/
class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
$controllerLocator = $container->findDefinition('argument_resolver.controller_locator');
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php b/core/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php
index 8418b4da4a..da9f8d6320 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/ResettableServicePass.php
@@ -23,6 +23,9 @@
*/
class ResettableServicePass implements CompilerPassInterface
{
+ /**
+ * @return void
+ */
public function process(ContainerBuilder $container)
{
if (!$container->has('services_resetter')) {
diff --git a/core/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php b/core/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php
index e7be3b88e7..b38ab5658d 100644
--- a/core/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php
+++ b/core/vendor/symfony/http-kernel/DependencyInjection/ServicesResetter.php
@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
+use ProxyManager\Proxy\LazyLoadingInterface;
+use Symfony\Component\VarExporter\LazyObjectInterface;
use Symfony\Contracts\Service\ResetInterface;
/**
@@ -36,9 +38,17 @@ public function __construct(\Traversable $resettableServices, array $resetMethod
$this->resetMethods = $resetMethods;
}
- public function reset()
+ public function reset(): void
{
foreach ($this->resettableServices as $id => $service) {
+ if ($service instanceof LazyObjectInterface && !$service->isLazyObjectInitialized(true)) {
+ continue;
+ }
+
+ if ($service instanceof LazyLoadingInterface && !$service->isProxyInitialized()) {
+ continue;
+ }
+
foreach ((array) $this->resetMethods[$id] as $resetMethod) {
if ('?' === $resetMethod[0] && !method_exists($service, $resetMethod = substr($resetMethod, 1))) {
continue;
diff --git a/core/vendor/symfony/http-kernel/Event/ControllerArgumentsEvent.php b/core/vendor/symfony/http-kernel/Event/ControllerArgumentsEvent.php
index 0af39671e6..64063abf25 100644
--- a/core/vendor/symfony/http-kernel/Event/ControllerArgumentsEvent.php
+++ b/core/vendor/symfony/http-kernel/Event/ControllerArgumentsEvent.php
@@ -63,7 +63,7 @@ public function getArguments(): array
return $this->arguments;
}
- public function setArguments(array $arguments)
+ public function setArguments(array $arguments): void
{
$this->arguments = $arguments;
unset($this->namedArguments);
diff --git a/core/vendor/symfony/http-kernel/Event/ControllerEvent.php b/core/vendor/symfony/http-kernel/Event/ControllerEvent.php
index b012263b93..d07d886db0 100644
--- a/core/vendor/symfony/http-kernel/Event/ControllerEvent.php
+++ b/core/vendor/symfony/http-kernel/Event/ControllerEvent.php
@@ -69,7 +69,7 @@ public function setController(callable $controller, array $attributes = null): v
if (\is_array($controller) && method_exists(...$controller)) {
$this->controllerReflector = new \ReflectionMethod(...$controller);
- } elseif (\is_string($controller) && false !== $i = strpos($controller, '::')) {
+ } elseif (\is_string($controller) && str_contains($controller, '::')) {
$this->controllerReflector = new \ReflectionMethod($controller);
} else {
$this->controllerReflector = new \ReflectionFunction($controller(...));
diff --git a/core/vendor/symfony/http-kernel/Event/RequestEvent.php b/core/vendor/symfony/http-kernel/Event/RequestEvent.php
index c7cfcc1e13..b81a79b780 100644
--- a/core/vendor/symfony/http-kernel/Event/RequestEvent.php
+++ b/core/vendor/symfony/http-kernel/Event/RequestEvent.php
@@ -36,6 +36,8 @@ public function getResponse(): ?Response
/**
* Sets a response and stops event propagation.
+ *
+ * @return void
*/
public function setResponse(Response $response)
{
diff --git a/core/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php b/core/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php
index c85e839230..ec27eaec12 100644
--- a/core/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/AbstractSessionListener.php
@@ -57,7 +57,7 @@ public function __construct(ContainerInterface $container = null, bool $debug =
$this->sessionOptions = $sessionOptions;
}
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
@@ -65,9 +65,10 @@ public function onKernelRequest(RequestEvent $event)
$request = $event->getRequest();
if (!$request->hasSession()) {
- // This variable prevents calling `$this->getSession()` twice in case the Request (and the below factory) is cloned
- $sess = null;
- $request->setSessionFactory(function () use (&$sess, $request) {
+ $request->setSessionFactory(function () use ($request) {
+ // Prevent calling `$this->getSession()` twice in case the Request (and the below factory) is cloned
+ static $sess;
+
if (!$sess) {
$sess = $this->getSession();
$request->setSession($sess);
@@ -89,7 +90,7 @@ public function onKernelRequest(RequestEvent $event)
}
}
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest() || (!$this->container->has('initialized_session') && !$event->getRequest()->hasSession())) {
return;
diff --git a/core/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php b/core/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php
index c3fc3fb657..d4ef3fe498 100644
--- a/core/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/AddRequestFormatsListener.php
@@ -34,7 +34,7 @@ public function __construct(array $formats)
/**
* Adds request formats.
*/
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
foreach ($this->formats as $format => $mimeTypes) {
diff --git a/core/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php b/core/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php
index 2230b8f699..723e758cd0 100644
--- a/core/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/CacheAttributeListener.php
@@ -46,6 +46,8 @@ public function __construct(
/**
* Handles HTTP validation headers.
+ *
+ * @return void
*/
public function onKernelControllerArguments(ControllerArgumentsEvent $event)
{
@@ -90,6 +92,8 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event)
/**
* Modifies the response to apply HTTP cache headers when needed.
+ *
+ * @return void
*/
public function onKernelResponse(ResponseEvent $event)
{
diff --git a/core/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php b/core/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php
index 4f9ceb73e3..e3e8924928 100644
--- a/core/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/DebugHandlersListener.php
@@ -11,7 +11,6 @@
namespace Symfony\Component\HttpKernel\EventListener;
-use Psr\Log\LoggerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
@@ -21,7 +20,7 @@
use Symfony\Component\HttpKernel\KernelEvents;
/**
- * Configures errors and exceptions handlers.
+ * Sets an exception handler.
*
* @author Nicolas Grekas
*
@@ -33,41 +32,25 @@ class DebugHandlersListener implements EventSubscriberInterface
{
private string|object|null $earlyHandler;
private ?\Closure $exceptionHandler;
- private ?LoggerInterface $logger;
- private ?LoggerInterface $deprecationLogger;
- private array|int|null $levels;
- private ?int $throwAt;
- private bool $scream;
- private bool $scope;
private bool $firstCall = true;
private bool $hasTerminatedWithException = false;
/**
- * @param callable|null $exceptionHandler A handler that must support \Throwable instances that will be called on Exception
- * @param array|int|null $levels An array map of E_* to LogLevel::* or an integer bit field of E_* constants
- * @param int|null $throwAt Thrown errors in a bit field of E_* constants, or null to keep the current value
- * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged
- * @param bool $scope Enables/disables scoping mode
+ * @param callable|null $exceptionHandler A handler that must support \Throwable instances that will be called on Exception
*/
- public function __construct(callable $exceptionHandler = null, LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, LoggerInterface $deprecationLogger = null)
+ public function __construct(callable $exceptionHandler = null)
{
$handler = set_exception_handler('is_int');
$this->earlyHandler = \is_array($handler) ? $handler[0] : null;
restore_exception_handler();
$this->exceptionHandler = null === $exceptionHandler ? null : $exceptionHandler(...);
- $this->logger = $logger;
- $this->levels = $levels ?? \E_ALL;
- $this->throwAt = \is_int($throwAt) ? $throwAt : (null === $throwAt ? null : ($throwAt ? \E_ALL : null));
- $this->scream = $scream;
- $this->scope = $scope;
- $this->deprecationLogger = $deprecationLogger;
}
/**
* Configures the error handler.
*/
- public function configure(object $event = null)
+ public function configure(object $event = null): void
{
if ($event instanceof ConsoleEvent && !\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
return;
@@ -77,40 +60,6 @@ public function configure(object $event = null)
}
$this->firstCall = $this->hasTerminatedWithException = false;
- $handler = set_exception_handler('is_int');
- $handler = \is_array($handler) ? $handler[0] : null;
- restore_exception_handler();
-
- if (!$handler instanceof ErrorHandler) {
- $handler = $this->earlyHandler;
- }
-
- if ($handler instanceof ErrorHandler) {
- if ($this->logger || $this->deprecationLogger) {
- $this->setDefaultLoggers($handler);
- if (\is_array($this->levels)) {
- $levels = 0;
- foreach ($this->levels as $type => $log) {
- $levels |= $type;
- }
- } else {
- $levels = $this->levels;
- }
-
- if ($this->scream) {
- $handler->screamAt($levels);
- }
- if ($this->scope) {
- $handler->scopeAt($levels & ~\E_USER_DEPRECATED & ~\E_DEPRECATED);
- } else {
- $handler->scopeAt(0, true);
- }
- $this->logger = $this->deprecationLogger = $this->levels = null;
- }
- if (null !== $this->throwAt) {
- $handler->throwAt($this->throwAt, true);
- }
- }
if (!$this->exceptionHandler) {
if ($event instanceof KernelEvent) {
if (method_exists($kernel = $event->getKernel(), 'terminateWithException')) {
@@ -136,6 +85,14 @@ public function configure(object $event = null)
}
}
if ($this->exceptionHandler) {
+ $handler = set_exception_handler('is_int');
+ $handler = \is_array($handler) ? $handler[0] : null;
+ restore_exception_handler();
+
+ if (!$handler instanceof ErrorHandler) {
+ $handler = $this->earlyHandler;
+ }
+
if ($handler instanceof ErrorHandler) {
$handler->setExceptionHandler($this->exceptionHandler);
}
@@ -143,34 +100,6 @@ public function configure(object $event = null)
}
}
- private function setDefaultLoggers(ErrorHandler $handler): void
- {
- if (\is_array($this->levels)) {
- $levelsDeprecatedOnly = [];
- $levelsWithoutDeprecated = [];
- foreach ($this->levels as $type => $log) {
- if (\E_DEPRECATED == $type || \E_USER_DEPRECATED == $type) {
- $levelsDeprecatedOnly[$type] = $log;
- } else {
- $levelsWithoutDeprecated[$type] = $log;
- }
- }
- } else {
- $levelsDeprecatedOnly = $this->levels & (\E_DEPRECATED | \E_USER_DEPRECATED);
- $levelsWithoutDeprecated = $this->levels & ~\E_DEPRECATED & ~\E_USER_DEPRECATED;
- }
-
- $defaultLoggerLevels = $this->levels;
- if ($this->deprecationLogger && $levelsDeprecatedOnly) {
- $handler->setDefaultLogger($this->deprecationLogger, $levelsDeprecatedOnly);
- $defaultLoggerLevels = $levelsWithoutDeprecated;
- }
-
- if ($this->logger && $defaultLoggerLevels) {
- $handler->setDefaultLogger($this->logger, $defaultLoggerLevels);
- }
- }
-
public static function getSubscribedEvents(): array
{
$events = [KernelEvents::REQUEST => ['configure', 2048]];
diff --git a/core/vendor/symfony/http-kernel/EventListener/DumpListener.php b/core/vendor/symfony/http-kernel/EventListener/DumpListener.php
index 151f96ea7e..b10bd37f43 100644
--- a/core/vendor/symfony/http-kernel/EventListener/DumpListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/DumpListener.php
@@ -36,14 +36,20 @@ public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper
$this->connection = $connection;
}
+ /**
+ * @return void
+ */
public function configure()
{
$cloner = $this->cloner;
$dumper = $this->dumper;
$connection = $this->connection;
- VarDumper::setHandler(static function ($var) use ($cloner, $dumper, $connection) {
+ VarDumper::setHandler(static function ($var, string $label = null) use ($cloner, $dumper, $connection) {
$data = $cloner->cloneVar($var);
+ if (null !== $label) {
+ $data = $data->withContext(['label' => $label]);
+ }
if (!$connection || !$connection->write($data)) {
$dumper->dump($data);
diff --git a/core/vendor/symfony/http-kernel/EventListener/ErrorListener.php b/core/vendor/symfony/http-kernel/EventListener/ErrorListener.php
index dd61050520..cc6936cfda 100644
--- a/core/vendor/symfony/http-kernel/EventListener/ErrorListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/ErrorListener.php
@@ -12,9 +12,12 @@
namespace Symfony\Component\HttpKernel\EventListener;
use Psr\Log\LoggerInterface;
+use Psr\Log\LogLevel;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpKernel\Attribute\WithHttpStatus;
+use Symfony\Component\HttpKernel\Attribute\WithLogLevel;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
@@ -48,17 +51,13 @@ public function __construct(string|object|array|null $controller, LoggerInterfac
$this->exceptionsMapping = $exceptionsMapping;
}
+ /**
+ * @return void
+ */
public function logKernelException(ExceptionEvent $event)
{
$throwable = $event->getThrowable();
- $logLevel = null;
-
- foreach ($this->exceptionsMapping as $class => $config) {
- if ($throwable instanceof $class && $config['log_level']) {
- $logLevel = $config['log_level'];
- break;
- }
- }
+ $logLevel = $this->resolveLogLevel($throwable);
foreach ($this->exceptionsMapping as $class => $config) {
if (!$throwable instanceof $class || !$config['status_code']) {
@@ -72,11 +71,30 @@ public function logKernelException(ExceptionEvent $event)
break;
}
+ // There's no specific status code defined in the configuration for this exception
+ if (!$throwable instanceof HttpExceptionInterface) {
+ $class = new \ReflectionClass($throwable);
+
+ do {
+ if ($attributes = $class->getAttributes(WithHttpStatus::class, \ReflectionAttribute::IS_INSTANCEOF)) {
+ /** @var WithHttpStatus $instance */
+ $instance = $attributes[0]->newInstance();
+
+ $throwable = new HttpException($instance->statusCode, $throwable->getMessage(), $throwable, $instance->headers);
+ $event->setThrowable($throwable);
+ break;
+ }
+ } while ($class = $class->getParentClass());
+ }
+
$e = FlattenException::createFromThrowable($throwable);
$this->logException($throwable, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()), $logLevel);
}
+ /**
+ * @return void
+ */
public function onKernelException(ExceptionEvent $event)
{
if (null === $this->controller) {
@@ -120,6 +138,9 @@ public function removeCspHeader(ResponseEvent $event): void
}
}
+ /**
+ * @return void
+ */
public function onControllerArguments(ControllerArgumentsEvent $event)
{
$e = $event->getRequest()->attributes->get('exception');
@@ -155,15 +176,42 @@ public static function getSubscribedEvents(): array
*/
protected function logException(\Throwable $exception, string $message, string $logLevel = null): void
{
- if (null !== $this->logger) {
- if (null !== $logLevel) {
- $this->logger->log($logLevel, $message, ['exception' => $exception]);
- } elseif (!$exception instanceof HttpExceptionInterface || $exception->getStatusCode() >= 500) {
- $this->logger->critical($message, ['exception' => $exception]);
- } else {
- $this->logger->error($message, ['exception' => $exception]);
+ if (null === $this->logger) {
+ return;
+ }
+
+ $logLevel ??= $this->resolveLogLevel($exception);
+
+ $this->logger->log($logLevel, $message, ['exception' => $exception]);
+ }
+
+ /**
+ * Resolves the level to be used when logging the exception.
+ */
+ private function resolveLogLevel(\Throwable $throwable): string
+ {
+ foreach ($this->exceptionsMapping as $class => $config) {
+ if ($throwable instanceof $class && $config['log_level']) {
+ return $config['log_level'];
+ }
+ }
+
+ $class = new \ReflectionClass($throwable);
+
+ do {
+ if ($attributes = $class->getAttributes(WithLogLevel::class)) {
+ /** @var WithLogLevel $instance */
+ $instance = $attributes[0]->newInstance();
+
+ return $instance->level;
}
+ } while ($class = $class->getParentClass());
+
+ if (!$throwable instanceof HttpExceptionInterface || $throwable->getStatusCode() >= 500) {
+ return LogLevel::CRITICAL;
}
+
+ return LogLevel::ERROR;
}
/**
diff --git a/core/vendor/symfony/http-kernel/EventListener/FragmentListener.php b/core/vendor/symfony/http-kernel/EventListener/FragmentListener.php
index 5c2fb09623..6392d699ff 100644
--- a/core/vendor/symfony/http-kernel/EventListener/FragmentListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/FragmentListener.php
@@ -50,7 +50,7 @@ public function __construct(UriSigner $signer, string $fragmentPath = '/_fragmen
*
* @throws AccessDeniedHttpException if the request does not come from a trusted IP
*/
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
@@ -75,7 +75,7 @@ public function onKernelRequest(RequestEvent $event)
$request->query->remove('_path');
}
- protected function validateRequest(Request $request)
+ protected function validateRequest(Request $request): void
{
// is the Request safe?
if (!$request->isMethodSafe()) {
diff --git a/core/vendor/symfony/http-kernel/EventListener/LocaleListener.php b/core/vendor/symfony/http-kernel/EventListener/LocaleListener.php
index 2502fa4be9..4516048be7 100644
--- a/core/vendor/symfony/http-kernel/EventListener/LocaleListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/LocaleListener.php
@@ -44,12 +44,12 @@ public function __construct(RequestStack $requestStack, string $defaultLocale =
$this->enabledLocales = $enabledLocales;
}
- public function setDefaultLocale(KernelEvent $event)
+ public function setDefaultLocale(KernelEvent $event): void
{
$event->getRequest()->setDefaultLocale($this->defaultLocale);
}
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
@@ -57,14 +57,14 @@ public function onKernelRequest(RequestEvent $event)
$this->setRouterContext($request);
}
- public function onKernelFinishRequest(FinishRequestEvent $event)
+ public function onKernelFinishRequest(FinishRequestEvent $event): void
{
if (null !== $parentRequest = $this->requestStack->getParentRequest()) {
$this->setRouterContext($parentRequest);
}
}
- private function setLocale(Request $request)
+ private function setLocale(Request $request): void
{
if ($locale = $request->attributes->get('_locale')) {
$request->setLocale($locale);
@@ -76,7 +76,7 @@ private function setLocale(Request $request)
}
}
- private function setRouterContext(Request $request)
+ private function setRouterContext(Request $request): void
{
$this->router?->getContext()->setParameter('_locale', $request->getLocale());
}
diff --git a/core/vendor/symfony/http-kernel/EventListener/ProfilerListener.php b/core/vendor/symfony/http-kernel/EventListener/ProfilerListener.php
index d63c0493d7..716d939fd0 100644
--- a/core/vendor/symfony/http-kernel/EventListener/ProfilerListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/ProfilerListener.php
@@ -63,7 +63,7 @@ public function __construct(Profiler $profiler, RequestStack $requestStack, Requ
/**
* Handles the onKernelException event.
*/
- public function onKernelException(ExceptionEvent $event)
+ public function onKernelException(ExceptionEvent $event): void
{
if ($this->onlyMainRequests && !$event->isMainRequest()) {
return;
@@ -75,7 +75,7 @@ public function onKernelException(ExceptionEvent $event)
/**
* Handles the onKernelResponse event.
*/
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if ($this->onlyMainRequests && !$event->isMainRequest()) {
return;
@@ -119,7 +119,7 @@ public function onKernelResponse(ResponseEvent $event)
$this->parents[$request] = $this->requestStack->getParentRequest();
}
- public function onKernelTerminate(TerminateEvent $event)
+ public function onKernelTerminate(TerminateEvent $event): void
{
// attach children to parents
foreach ($this->profiles as $request) {
diff --git a/core/vendor/symfony/http-kernel/EventListener/ResponseListener.php b/core/vendor/symfony/http-kernel/EventListener/ResponseListener.php
index 435fd31d1b..5825e16e44 100644
--- a/core/vendor/symfony/http-kernel/EventListener/ResponseListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/ResponseListener.php
@@ -36,7 +36,7 @@ public function __construct(string $charset, bool $addContentLanguageHeader = fa
/**
* Filters the Response.
*/
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest()) {
return;
diff --git a/core/vendor/symfony/http-kernel/EventListener/RouterListener.php b/core/vendor/symfony/http-kernel/EventListener/RouterListener.php
index 72be3e6e78..bb393c7799 100644
--- a/core/vendor/symfony/http-kernel/EventListener/RouterListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/RouterListener.php
@@ -67,7 +67,7 @@ public function __construct(UrlMatcherInterface|RequestMatcherInterface $matcher
$this->debug = $debug;
}
- private function setCurrentRequest(?Request $request)
+ private function setCurrentRequest(?Request $request): void
{
if (null !== $request) {
try {
@@ -82,12 +82,12 @@ private function setCurrentRequest(?Request $request)
* After a sub-request is done, we need to reset the routing context to the parent request so that the URL generator
* operates on the correct context again.
*/
- public function onKernelFinishRequest()
+ public function onKernelFinishRequest(): void
{
$this->setCurrentRequest($this->requestStack->getParentRequest());
}
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
$request = $event->getRequest();
@@ -132,7 +132,7 @@ public function onKernelRequest(RequestEvent $event)
}
}
- public function onKernelException(ExceptionEvent $event)
+ public function onKernelException(ExceptionEvent $event): void
{
if (!$this->debug || !($e = $event->getThrowable()) instanceof NotFoundHttpException) {
return;
diff --git a/core/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php b/core/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php
index c0b74fdf0e..312d5ee23b 100644
--- a/core/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/StreamedResponseListener.php
@@ -33,7 +33,7 @@ class StreamedResponseListener implements EventSubscriberInterface
/**
* Filters the Response.
*/
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest()) {
return;
diff --git a/core/vendor/symfony/http-kernel/EventListener/SurrogateListener.php b/core/vendor/symfony/http-kernel/EventListener/SurrogateListener.php
index 3d1be0f2e1..17bdf2b392 100644
--- a/core/vendor/symfony/http-kernel/EventListener/SurrogateListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/SurrogateListener.php
@@ -36,7 +36,7 @@ public function __construct(SurrogateInterface $surrogate = null)
/**
* Filters the Response.
*/
- public function onKernelResponse(ResponseEvent $event)
+ public function onKernelResponse(ResponseEvent $event): void
{
if (!$event->isMainRequest()) {
return;
diff --git a/core/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php b/core/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php
index e2501c5777..187633d5d4 100644
--- a/core/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php
+++ b/core/vendor/symfony/http-kernel/EventListener/ValidateRequestListener.php
@@ -27,7 +27,7 @@ class ValidateRequestListener implements EventSubscriberInterface
/**
* Performs the validation.
*/
- public function onKernelRequest(RequestEvent $event)
+ public function onKernelRequest(RequestEvent $event): void
{
if (!$event->isMainRequest()) {
return;
diff --git a/core/vendor/symfony/http-kernel/Exception/HttpException.php b/core/vendor/symfony/http-kernel/Exception/HttpException.php
index 418271065a..e12abce004 100644
--- a/core/vendor/symfony/http-kernel/Exception/HttpException.php
+++ b/core/vendor/symfony/http-kernel/Exception/HttpException.php
@@ -39,6 +39,9 @@ public function getHeaders(): array
return $this->headers;
}
+ /**
+ * @return void
+ */
public function setHeaders(array $headers)
{
$this->headers = $headers;
diff --git a/core/vendor/symfony/http-kernel/Exception/ResolverNotFoundException.php b/core/vendor/symfony/http-kernel/Exception/ResolverNotFoundException.php
new file mode 100644
index 0000000000..6d9fb8a01f
--- /dev/null
+++ b/core/vendor/symfony/http-kernel/Exception/ResolverNotFoundException.php
@@ -0,0 +1,33 @@
+
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\HttpKernel\Exception;
+
+class ResolverNotFoundException extends \RuntimeException
+{
+ /**
+ * @param string[] $alternatives
+ */
+ public function __construct(string $name, array $alternatives = [])
+ {
+ $msg = sprintf('You have requested a non-existent resolver "%s".', $name);
+ if ($alternatives) {
+ if (1 === \count($alternatives)) {
+ $msg .= ' Did you mean this: "';
+ } else {
+ $msg .= ' Did you mean one of these: "';
+ }
+ $msg .= implode('", "', $alternatives).'"?';
+ }
+
+ parent::__construct($msg);
+ }
+}
diff --git a/core/vendor/symfony/http-kernel/Fragment/FragmentHandler.php b/core/vendor/symfony/http-kernel/Fragment/FragmentHandler.php
index dfc03db42d..62b21e6d4e 100644
--- a/core/vendor/symfony/http-kernel/Fragment/FragmentHandler.php
+++ b/core/vendor/symfony/http-kernel/Fragment/FragmentHandler.php
@@ -48,6 +48,8 @@ public function __construct(RequestStack $requestStack, array $renderers = [], b
/**
* Adds a renderer.
+ *
+ * @return void
*/
public function addRenderer(FragmentRendererInterface $renderer)
{
diff --git a/core/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php b/core/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php
index 0e53768ee9..d563182f96 100644
--- a/core/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php
+++ b/core/vendor/symfony/http-kernel/Fragment/InlineFragmentRenderer.php
@@ -103,6 +103,9 @@ public function render(string|ControllerReference $uri, Request $request, array
}
}
+ /**
+ * @return Request
+ */
protected function createSubRequest(string $uri, Request $request)
{
$cookies = $request->cookies->all();
@@ -127,6 +130,9 @@ protected function createSubRequest(string $uri, Request $request)
if ($request->getDefaultLocale() !== $request->getLocale()) {
$subRequest->setLocale($request->getLocale());
}
+ if ($request->attributes->has('_stateless')) {
+ $subRequest->attributes->set('_stateless', $request->attributes->get('_stateless'));
+ }
return $subRequest;
}
diff --git a/core/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php b/core/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php
index 416b670417..47027233a7 100644
--- a/core/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php
+++ b/core/vendor/symfony/http-kernel/Fragment/RoutableFragmentRenderer.php
@@ -31,6 +31,8 @@ abstract class RoutableFragmentRenderer implements FragmentRendererInterface
* Sets the fragment path that triggers the fragment listener.
*
* @see FragmentListener
+ *
+ * @return void
*/
public function setFragmentPath(string $path)
{
diff --git a/core/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php b/core/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php
index ca01a9240b..95518bed2b 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/AbstractSurrogate.php
@@ -24,6 +24,10 @@
abstract class AbstractSurrogate implements SurrogateInterface
{
protected $contentTypes;
+
+ /**
+ * @deprecated since Symfony 6.3
+ */
protected $phpEscapeMap = [
['', '<%', '', '', '', ''],
@@ -55,6 +59,9 @@ public function hasSurrogateCapability(Request $request): bool
return str_contains($value, sprintf('%s/1.0', strtoupper($this->getName())));
}
+ /**
+ * @return void
+ */
public function addSurrogateCapability(Request $request)
{
$current = $request->headers->get('Surrogate-Capability');
@@ -101,6 +108,8 @@ public function handle(HttpCache $cache, string $uri, string $alt, bool $ignoreE
/**
* Remove the Surrogate from the Surrogate-Control header.
+ *
+ * @return void
*/
protected function removeFromControl(Response $response)
{
@@ -119,4 +128,15 @@ protected function removeFromControl(Response $response)
$response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value));
}
}
+
+ protected static function generateBodyEvalBoundary(): string
+ {
+ static $cookie;
+ $cookie = hash('xxh128', $cookie ?? $cookie = random_bytes(16), true);
+ $boundary = base64_encode($cookie);
+
+ \assert(HttpCache::BODY_EVAL_BOUNDARY_LENGTH === \strlen($boundary));
+
+ return $boundary;
+ }
}
diff --git a/core/vendor/symfony/http-kernel/HttpCache/Esi.php b/core/vendor/symfony/http-kernel/HttpCache/Esi.php
index 9e7c3f898a..5db840a802 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/Esi.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/Esi.php
@@ -32,6 +32,9 @@ public function getName(): string
return 'esi';
}
+ /**
+ * @return void
+ */
public function addSurrogateControl(Response $response)
{
if (str_contains($response->getContent(), '.*?#s', '', $content);
$content = preg_replace('#]+>#s', '', $content);
+ $boundary = self::generateBodyEvalBoundary();
$chunks = preg_split('##', $content, -1, \PREG_SPLIT_DELIM_CAPTURE);
- $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
$i = 1;
while (isset($chunks[$i])) {
@@ -86,16 +89,10 @@ public function process(Request $request, Response $response): Response
throw new \RuntimeException('Unable to process an ESI tag without a "src" attribute.');
}
- $chunks[$i] = sprintf('surrogate->handle($this, %s, %s, %s) ?>'."\n",
- var_export($options['src'], true),
- var_export($options['alt'] ?? '', true),
- isset($options['onerror']) && 'continue' === $options['onerror'] ? 'true' : 'false'
- );
- ++$i;
- $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]);
- ++$i;
+ $chunks[$i] = $boundary.$options['src']."\n".($options['alt'] ?? '')."\n".('continue' === ($options['onerror'] ?? ''))."\n";
+ $i += 2;
}
- $content = implode('', $chunks);
+ $content = $boundary.implode('', $chunks).$boundary;
$response->setContent($content);
$response->headers->set('X-Body-Eval', 'ESI');
diff --git a/core/vendor/symfony/http-kernel/HttpCache/HttpCache.php b/core/vendor/symfony/http-kernel/HttpCache/HttpCache.php
index f77a99e0ff..eabacfec62 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/HttpCache.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/HttpCache.php
@@ -29,6 +29,8 @@
*/
class HttpCache implements HttpKernelInterface, TerminableInterface
{
+ public const BODY_EVAL_BOUNDARY_LENGTH = 24;
+
private HttpKernelInterface $kernel;
private StoreInterface $store;
private Request $request;
@@ -60,6 +62,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
* on responses that don't explicitly state whether the response is
* public or private via a Cache-Control directive. (default: Authorization and Cookie)
*
+ * * skip_response_headers Set of response headers that are never cached even if a response is cacheable (public).
+ * (default: Set-Cookie)
+ *
* * allow_reload Specifies whether the client can force a cache reload by including a
* Cache-Control "no-cache" directive in the request. Set it to ``true``
* for compliance with RFC 2616. (default: false)
@@ -97,6 +102,7 @@ public function __construct(HttpKernelInterface $kernel, StoreInterface $store,
'debug' => false,
'default_ttl' => 0,
'private_headers' => ['Authorization', 'Cookie'],
+ 'skip_response_headers' => ['Set-Cookie'],
'allow_reload' => false,
'allow_revalidate' => false,
'stale_while_revalidate' => 2,
@@ -127,7 +133,7 @@ public function getTraces(): array
return $this->traces;
}
- private function addTraces(Response $response)
+ private function addTraces(Response $response): void
{
$traceString = null;
@@ -236,6 +242,9 @@ public function handle(Request $request, int $type = HttpKernelInterface::MAIN_R
return $response;
}
+ /**
+ * @return void
+ */
public function terminate(Request $request, Response $response)
{
// Do not call any listeners in case of a cache hit.
@@ -586,13 +595,24 @@ protected function lock(Request $request, Response $entry): bool
/**
* Writes the Response to the cache.
*
+ * @return void
+ *
* @throws \Exception
*/
protected function store(Request $request, Response $response)
{
try {
- $this->store->write($request, $response);
+ $restoreHeaders = [];
+ foreach ($this->options['skip_response_headers'] as $header) {
+ if (!$response->headers->has($header)) {
+ continue;
+ }
+
+ $restoreHeaders[$header] = $response->headers->all($header);
+ $response->headers->remove($header);
+ }
+ $this->store->write($request, $response);
$this->record($request, 'store');
$response->headers->set('Age', $response->getAge());
@@ -602,6 +622,10 @@ protected function store(Request $request, Response $response)
if ($this->options['debug']) {
throw $e;
}
+ } finally {
+ foreach ($restoreHeaders as $header => $values) {
+ $response->headers->set($header, $values);
+ }
}
// now that the response is cached, release the lock
@@ -611,15 +635,25 @@ protected function store(Request $request, Response $response)
/**
* Restores the Response body.
*/
- private function restoreResponseBody(Request $request, Response $response)
+ private function restoreResponseBody(Request $request, Response $response): void
{
if ($response->headers->has('X-Body-Eval')) {
+ \assert(self::BODY_EVAL_BOUNDARY_LENGTH === 24);
+
ob_start();
- if ($response->headers->has('X-Body-File')) {
- include $response->headers->get('X-Body-File');
- } else {
- eval('; ?>'.$response->getContent().'getContent();
+ $boundary = substr($content, 0, 24);
+ $j = strpos($content, $boundary, 24);
+ echo substr($content, 24, $j - 24);
+ $i = $j + 24;
+
+ while (false !== $j = strpos($content, $boundary, $i)) {
+ [$uri, $alt, $ignoreErrors, $part] = explode("\n", substr($content, $i, $j - $i), 4);
+ $i = $j + 24;
+
+ echo $this->surrogate->handle($this, $uri, $alt, $ignoreErrors);
+ echo $part;
}
$response->setContent(ob_get_clean());
@@ -640,6 +674,9 @@ private function restoreResponseBody(Request $request, Response $response)
$response->headers->remove('X-Body-File');
}
+ /**
+ * @return void
+ */
protected function processResponseBody(Request $request, Response $response)
{
if ($this->surrogate?->needsParsing($response)) {
@@ -671,7 +708,7 @@ private function isPrivateRequest(Request $request): bool
/**
* Records that an event took place.
*/
- private function record(Request $request, string $event)
+ private function record(Request $request, string $event): void
{
$this->traces[$this->getTraceKey($request)][] = $event;
}
diff --git a/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php b/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php
index 0c9f10823a..57b5d21961 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php
@@ -54,6 +54,9 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
'expires' => null,
];
+ /**
+ * @return void
+ */
public function add(Response $response)
{
++$this->embeddedResponses;
@@ -95,6 +98,9 @@ public function add(Response $response)
}
}
+ /**
+ * @return void
+ */
public function update(Response $response)
{
// if we have no embedded Response, do nothing
@@ -148,7 +154,7 @@ public function update(Response $response)
if (is_numeric($this->ageDirectives['expires'])) {
$date = clone $response->getDate();
- $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds');
+ $date = $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds');
$response->setExpires($date);
}
}
@@ -209,7 +215,7 @@ private function willMakeFinalResponseUncacheable(Response $response): bool
* as cacheable in a public (shared) cache, but did not provide an explicit lifetime that would serve
* as an upper bound. In this case, we can proceed and possibly keep the directive on the final response.
*/
- private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable)
+ private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable): void
{
if (null === $value) {
if ($isHeuristicallyCacheable) {
diff --git a/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php b/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php
index e282299aee..33c8bd9412 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/ResponseCacheStrategyInterface.php
@@ -27,11 +27,15 @@ interface ResponseCacheStrategyInterface
{
/**
* Adds a Response.
+ *
+ * @return void
*/
public function add(Response $response);
/**
* Updates the Response HTTP headers based on the embedded Responses.
+ *
+ * @return void
*/
public function update(Response $response);
}
diff --git a/core/vendor/symfony/http-kernel/HttpCache/Ssi.php b/core/vendor/symfony/http-kernel/HttpCache/Ssi.php
index 4bd1cef0a7..b17c90ac60 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/Ssi.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/Ssi.php
@@ -26,6 +26,9 @@ public function getName(): string
return 'ssi';
}
+ /**
+ * @return void
+ */
public function addSurrogateControl(Response $response)
{
if (str_contains($response->getContent(), '#', $content, -1, \PREG_SPLIT_DELIM_CAPTURE);
- $chunks[0] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[0]);
$i = 1;
while (isset($chunks[$i])) {
@@ -68,14 +70,10 @@ public function process(Request $request, Response $response): Response
throw new \RuntimeException('Unable to process an SSI tag without a "virtual" attribute.');
}
- $chunks[$i] = sprintf('surrogate->handle($this, %s, \'\', false) ?>'."\n",
- var_export($options['virtual'], true)
- );
- ++$i;
- $chunks[$i] = str_replace($this->phpEscapeMap[0], $this->phpEscapeMap[1], $chunks[$i]);
- ++$i;
+ $chunks[$i] = $boundary.$options['virtual']."\n\n\n";
+ $i += 2;
}
- $content = implode('', $chunks);
+ $content = $boundary.implode('', $chunks).$boundary;
$response->setContent($content);
$response->headers->set('X-Body-Eval', 'SSI');
diff --git a/core/vendor/symfony/http-kernel/HttpCache/Store.php b/core/vendor/symfony/http-kernel/HttpCache/Store.php
index b21cb45874..3f21e383f4 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/Store.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/Store.php
@@ -55,6 +55,8 @@ public function __construct(string $root, array $options = [])
/**
* Cleanups storage.
+ *
+ * @return void
*/
public function cleanup()
{
@@ -247,6 +249,8 @@ protected function generateContentDigest(Response $response): string
/**
* Invalidates all cache entries that match the request.
*
+ * @return void
+ *
* @throws \RuntimeException
*/
public function invalidate(Request $request)
@@ -413,6 +417,9 @@ private function save(string $key, string $data, bool $overwrite = true): bool
return true;
}
+ /**
+ * @return string
+ */
public function getPath(string $key)
{
return $this->root.\DIRECTORY_SEPARATOR.substr($key, 0, 2).\DIRECTORY_SEPARATOR.substr($key, 2, 2).\DIRECTORY_SEPARATOR.substr($key, 4, 2).\DIRECTORY_SEPARATOR.substr($key, 6);
@@ -467,15 +474,25 @@ private function persistResponse(Response $response): array
/**
* Restores a Response from the HTTP headers and body.
*/
- private function restoreResponse(array $headers, string $path = null): Response
+ private function restoreResponse(array $headers, string $path = null): ?Response
{
$status = $headers['X-Status'][0];
unset($headers['X-Status']);
+ $content = null;
if (null !== $path) {
$headers['X-Body-File'] = [$path];
+ unset($headers['x-body-file']);
+
+ if ($headers['X-Body-Eval'] ?? $headers['x-body-eval'] ?? false) {
+ $content = file_get_contents($path);
+ \assert(HttpCache::BODY_EVAL_BOUNDARY_LENGTH === 24);
+ if (48 > \strlen($content) || substr($content, -24) !== substr($content, 0, 24)) {
+ return null;
+ }
+ }
}
- return new Response($path, $status, $headers);
+ return new Response($content, $status, $headers);
}
}
diff --git a/core/vendor/symfony/http-kernel/HttpCache/StoreInterface.php b/core/vendor/symfony/http-kernel/HttpCache/StoreInterface.php
index 0cf8921cd1..b73cb7a9e6 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/StoreInterface.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/StoreInterface.php
@@ -41,6 +41,8 @@ public function write(Request $request, Response $response): string;
/**
* Invalidates all cache entries that match the request.
+ *
+ * @return void
*/
public function invalidate(Request $request);
@@ -74,6 +76,8 @@ public function purge(string $url): bool;
/**
* Cleanups storage.
+ *
+ * @return void
*/
public function cleanup();
}
diff --git a/core/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php b/core/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php
index 6e9b17b316..e444458f73 100644
--- a/core/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php
+++ b/core/vendor/symfony/http-kernel/HttpCache/SurrogateInterface.php
@@ -33,6 +33,8 @@ public function hasSurrogateCapability(Request $request): bool;
/**
* Adds Surrogate-capability to the given Request.
+ *
+ * @return void
*/
public function addSurrogateCapability(Request $request);
@@ -40,6 +42,8 @@ public function addSurrogateCapability(Request $request);
* Adds HTTP headers to specify that the Response needs to be parsed for Surrogate.
*
* This method only adds an Surrogate HTTP header if the Response has some Surrogate tags.
+ *
+ * @return void
*/
public function addSurrogateControl(Response $response);
diff --git a/core/vendor/symfony/http-kernel/HttpKernel.php b/core/vendor/symfony/http-kernel/HttpKernel.php
index 7f5c592506..794a55dc18 100644
--- a/core/vendor/symfony/http-kernel/HttpKernel.php
+++ b/core/vendor/symfony/http-kernel/HttpKernel.php
@@ -92,6 +92,9 @@ public function handle(Request $request, int $type = HttpKernelInterface::MAIN_R
}
}
+ /**
+ * @return void
+ */
public function terminate(Request $request, Response $response)
{
$this->dispatcher->dispatch(new TerminateEvent($this, $request, $response), KernelEvents::TERMINATE);
@@ -100,7 +103,7 @@ public function terminate(Request $request, Response $response)
/**
* @internal
*/
- public function terminateWithException(\Throwable $exception, Request $request = null)
+ public function terminateWithException(\Throwable $exception, Request $request = null): void
{
if (!$request ??= $this->requestStack->getMainRequest()) {
throw $exception;
@@ -207,7 +210,7 @@ private function filterResponse(Response $response, Request $request, int $type)
* operations such as {@link RequestStack::getParentRequest()} can lead to
* weird results.
*/
- private function finishRequest(Request $request, int $type)
+ private function finishRequest(Request $request, int $type): void
{
$this->dispatcher->dispatch(new FinishRequestEvent($this, $request, $type), KernelEvents::FINISH_REQUEST);
}
diff --git a/core/vendor/symfony/http-kernel/HttpKernelBrowser.php b/core/vendor/symfony/http-kernel/HttpKernelBrowser.php
index 0938617169..0f3630e7fe 100644
--- a/core/vendor/symfony/http-kernel/HttpKernelBrowser.php
+++ b/core/vendor/symfony/http-kernel/HttpKernelBrowser.php
@@ -47,6 +47,8 @@ public function __construct(HttpKernelInterface $kernel, array $server = [], His
/**
* Sets whether to catch exceptions when the kernel is handling a request.
+ *
+ * @return void
*/
public function catchExceptions(bool $catchExceptions)
{
@@ -110,6 +112,9 @@ protected function getScript(object $request)
return $code.$this->getHandleScript();
}
+ /**
+ * @return string
+ */
protected function getHandleScript()
{
return <<<'EOF'
diff --git a/core/vendor/symfony/http-kernel/Kernel.php b/core/vendor/symfony/http-kernel/Kernel.php
index e9694e978e..c98705163d 100644
--- a/core/vendor/symfony/http-kernel/Kernel.php
+++ b/core/vendor/symfony/http-kernel/Kernel.php
@@ -17,6 +17,7 @@
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
+use Symfony\Component\DependencyInjection\Compiler\RemoveBuildParametersPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
@@ -75,15 +76,15 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
private static array $freshCache = [];
- public const VERSION = '6.2.10';
- public const VERSION_ID = 60210;
+ public const VERSION = '6.3.0';
+ public const VERSION_ID = 60300;
public const MAJOR_VERSION = 6;
- public const MINOR_VERSION = 2;
- public const RELEASE_VERSION = 10;
+ public const MINOR_VERSION = 3;
+ public const RELEASE_VERSION = 0;
public const EXTRA_VERSION = '';
- public const END_OF_MAINTENANCE = '07/2023';
- public const END_OF_LIFE = '07/2023';
+ public const END_OF_MAINTENANCE = '01/2024';
+ public const END_OF_LIFE = '01/2024';
public function __construct(string $environment, bool $debug)
{
@@ -102,6 +103,9 @@ public function __clone()
$this->resetServices = false;
}
+ /**
+ * @return void
+ */
public function boot()
{
if (true === $this->booted) {
@@ -130,6 +134,9 @@ public function boot()
$this->booted = true;
}
+ /**
+ * @return void
+ */
public function reboot(?string $warmupDir)
{
$this->shutdown();
@@ -137,6 +144,9 @@ public function reboot(?string $warmupDir)
$this->boot();
}
+ /**
+ * @return void
+ */
public function terminate(Request $request, Response $response)
{
if (false === $this->booted) {
@@ -148,6 +158,9 @@ public function terminate(Request $request, Response $response)
}
}
+ /**
+ * @return void
+ */
public function shutdown()
{
if (false === $this->booted) {
@@ -280,7 +293,7 @@ public function getContainer(): ContainerInterface
/**
* @internal
*/
- public function setAnnotatedClassCache(array $annotatedClasses)
+ public function setAnnotatedClassCache(array $annotatedClasses): void
{
file_put_contents(($this->warmupDir ?: $this->getBuildDir()).'/annotations.map', sprintf('container = include $cachePath)) {
$this->container = null;
- } elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
+ } elseif (!$oldContainer || $this->container::class !== $oldContainer->name) {
flock($lock, \LOCK_UN);
fclose($lock);
$this->container->set('kernel', $this);
@@ -504,7 +523,7 @@ protected function initializeContainer()
$this->container = require $cachePath;
$this->container->set('kernel', $this);
- if ($oldContainer && \get_class($this->container) !== $oldContainer->name) {
+ if ($oldContainer && $this->container::class !== $oldContainer->name) {
// Because concurrent requests might still be using them,
// old container files are not removed immediately,
// but on a next dump of the container.
@@ -526,7 +545,7 @@ protected function initializeContainer()
$preload = array_merge($preload, (array) $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')));
}
- if ($preload && method_exists(Preloader::class, 'append') && file_exists($preloadFile = $buildDir.'/'.$class.'.preload.php')) {
+ if ($preload && file_exists($preloadFile = $buildDir.'/'.$class.'.preload.php')) {
Preloader::append($preloadFile, $preload);
}
}
@@ -591,6 +610,8 @@ protected function buildContainer(): ContainerBuilder
/**
* Prepares the ContainerBuilder before it is compiled.
+ *
+ * @return void
*/
protected function prepareContainer(ContainerBuilder $container)
{
@@ -642,18 +663,45 @@ protected function getContainerBuilder(): ContainerBuilder
*
* @param string $class The name of the class to generate
* @param string $baseClass The name of the container's base class
+ *
+ * @return void
*/
protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, string $class, string $baseClass)
{
// cache the container
$dumper = new PhpDumper($container);
+ $buildParameters = [];
+ foreach ($container->getCompilerPassConfig()->getPasses() as $pass) {
+ if ($pass instanceof RemoveBuildParametersPass) {
+ $buildParameters = array_merge($buildParameters, $pass->getRemovedParameters());
+ }
+ }
+
+ $inlineFactories = false;
+ if (isset($buildParameters['.container.dumper.inline_factories'])) {
+ $inlineFactories = $buildParameters['.container.dumper.inline_factories'];
+ } elseif ($container->hasParameter('container.dumper.inline_factories')) {
+ trigger_deprecation('symfony/http-kernel', '6.3', 'Parameter "%s" is deprecated, use ".%1$s" instead.', 'container.dumper.inline_factories');
+ $inlineFactories = $container->getParameter('container.dumper.inline_factories');
+ }
+
+ $inlineClassLoader = $this->debug;
+ if (isset($buildParameters['.container.dumper.inline_class_loader'])) {
+ $inlineClassLoader = $buildParameters['.container.dumper.inline_class_loader'];
+ } elseif ($container->hasParameter('container.dumper.inline_class_loader')) {
+ trigger_deprecation('symfony/http-kernel', '6.3', 'Parameter "%s" is deprecated, use ".%1$s" instead.', 'container.dumper.inline_class_loader');
+ $inlineClassLoader = $container->getParameter('container.dumper.inline_class_loader');
+ }
+
$content = $dumper->dump([
'class' => $class,
'base_class' => $baseClass,
'file' => $cache->getPath(),
'as_files' => true,
'debug' => $this->debug,
+ 'inline_factories' => $inlineFactories,
+ 'inline_class_loader' => $inlineClassLoader,
'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(),
'preload_classes' => array_map('get_class', $this->bundles),
]);
diff --git a/core/vendor/symfony/http-kernel/KernelInterface.php b/core/vendor/symfony/http-kernel/KernelInterface.php
index 0959febf14..14a053ab30 100644
--- a/core/vendor/symfony/http-kernel/KernelInterface.php
+++ b/core/vendor/symfony/http-kernel/KernelInterface.php
@@ -33,11 +33,15 @@ public function registerBundles(): iterable;
/**
* Loads the container configuration.
+ *
+ * @return void
*/
public function registerContainerConfiguration(LoaderInterface $loader);
/**
* Boots the current kernel.
+ *
+ * @return void
*/
public function boot();
@@ -45,6 +49,8 @@ public function boot();
* Shutdowns the kernel.
*
* This method is mainly useful when doing functional testing.
+ *
+ * @return void
*/
public function shutdown();
diff --git a/core/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php b/core/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php
index 84452ae71f..1940c80a90 100644
--- a/core/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php
+++ b/core/vendor/symfony/http-kernel/Log/DebugLoggerInterface.php
@@ -44,6 +44,8 @@ public function countErrors(Request $request = null);
/**
* Removes all log records.
+ *
+ * @return void
*/
public function clear();
}
diff --git a/core/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php b/core/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php
index d3c801de5b..0fdbfc44ba 100644
--- a/core/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php
+++ b/core/vendor/symfony/http-kernel/Profiler/FileProfilerStorage.php
@@ -87,6 +87,9 @@ public function find(?string $ip, ?string $url, ?int $limit, ?string $method, in
return array_values($result);
}
+ /**
+ * @return void
+ */
public function purge()
{
$flags = \FilesystemIterator::SKIP_DOTS;
@@ -127,9 +130,7 @@ public function write(Profile $profile): bool
// when there are errors in sub-requests, the parent and/or children tokens
// may equal the profile token, resulting in infinite loops
$parentToken = $profile->getParentToken() !== $profileToken ? $profile->getParentToken() : null;
- $childrenToken = array_filter(array_map(function (Profile $p) use ($profileToken) {
- return $profileToken !== $p->getToken() ? $p->getToken() : null;
- }, $profile->getChildren()));
+ $childrenToken = array_filter(array_map(fn (Profile $p) => $profileToken !== $p->getToken() ? $p->getToken() : null, $profile->getChildren()));
// Store profile
$data = [
@@ -165,11 +166,15 @@ public function write(Profile $profile): bool
$profile->getIp(),
$profile->getMethod(),
$profile->getUrl(),
- $profile->getTime(),
+ $profile->getTime() ?: time(),
$profile->getParentToken(),
$profile->getStatusCode(),
]);
fclose($file);
+
+ if (1 === mt_rand(1, 10)) {
+ $this->removeExpiredProfiles();
+ }
}
return true;
@@ -240,6 +245,9 @@ protected function readLineFromFile($file): mixed
return '' === $line ? null : $line;
}
+ /**
+ * @return Profile
+ */
protected function createProfileFromData(string $token, array $data, Profile $parent = null)
{
$profile = new Profile($token);
@@ -289,4 +297,29 @@ private function doRead($token, Profile $profile = null): ?Profile
return $this->createProfileFromData($token, $data, $profile);
}
+
+ private function removeExpiredProfiles(): void
+ {
+ $minimalProfileTimestamp = time() - 2 * 86400;
+ $file = $this->getIndexFilename();
+ $handle = fopen($file, 'r');
+
+ if ($offset = is_file($file.'.offset') ? (int) file_get_contents($file.'.offset') : 0) {
+ fseek($handle, $offset);
+ }
+
+ while ($line = fgets($handle)) {
+ [$csvToken, , , , $csvTime] = str_getcsv($line);
+
+ if ($csvTime >= $minimalProfileTimestamp) {
+ break;
+ }
+
+ @unlink($this->getFilename($csvToken));
+ $offset += \strlen($line);
+ }
+ fclose($handle);
+
+ file_put_contents($file.'.offset', $offset);
+ }
}
diff --git a/core/vendor/symfony/http-kernel/Profiler/Profile.php b/core/vendor/symfony/http-kernel/Profiler/Profile.php
index 5ca2d96009..8de1468ac6 100644
--- a/core/vendor/symfony/http-kernel/Profiler/Profile.php
+++ b/core/vendor/symfony/http-kernel/Profiler/Profile.php
@@ -44,6 +44,9 @@ public function __construct(string $token)
$this->token = $token;
}
+ /**
+ * @return void
+ */
public function setToken(string $token)
{
$this->token = $token;
@@ -59,6 +62,8 @@ public function getToken(): string
/**
* Sets the parent token.
+ *
+ * @return void
*/
public function setParent(self $parent)
{
@@ -89,6 +94,9 @@ public function getIp(): ?string
return $this->ip;
}
+ /**
+ * @return void
+ */
public function setIp(?string $ip)
{
$this->ip = $ip;
@@ -102,6 +110,9 @@ public function getMethod(): ?string
return $this->method;
}
+ /**
+ * @return void
+ */
public function setMethod(string $method)
{
$this->method = $method;
@@ -115,6 +126,9 @@ public function getUrl(): ?string
return $this->url;
}
+ /**
+ * @return void
+ */
public function setUrl(?string $url)
{
$this->url = $url;
@@ -125,11 +139,17 @@ public function getTime(): int
return $this->time ?? 0;
}
+ /**
+ * @return void
+ */
public function setTime(int $time)
{
$this->time = $time;
}
+ /**
+ * @return void
+ */
public function setStatusCode(int $statusCode)
{
$this->statusCode = $statusCode;
@@ -154,6 +174,8 @@ public function getChildren(): array
* Sets children profiler.
*
* @param Profile[] $children
+ *
+ * @return void
*/
public function setChildren(array $children)
{
@@ -165,6 +187,8 @@ public function setChildren(array $children)
/**
* Adds the child token.
+ *
+ * @return void
*/
public function addChild(self $child)
{
@@ -211,6 +235,8 @@ public function getCollectors(): array
* Sets the Collectors associated with this profile.
*
* @param DataCollectorInterface[] $collectors
+ *
+ * @return void
*/
public function setCollectors(array $collectors)
{
@@ -222,6 +248,8 @@ public function setCollectors(array $collectors)
/**
* Adds a Collector.
+ *
+ * @return void
*/
public function addCollector(DataCollectorInterface $collector)
{
diff --git a/core/vendor/symfony/http-kernel/Profiler/Profiler.php b/core/vendor/symfony/http-kernel/Profiler/Profiler.php
index 2bcabdfea4..58508e5b48 100644
--- a/core/vendor/symfony/http-kernel/Profiler/Profiler.php
+++ b/core/vendor/symfony/http-kernel/Profiler/Profiler.php
@@ -46,6 +46,8 @@ public function __construct(ProfilerStorageInterface $storage, LoggerInterface $
/**
* Disables the profiler.
+ *
+ * @return void
*/
public function disable()
{
@@ -54,6 +56,8 @@ public function disable()
/**
* Enables the profiler.
+ *
+ * @return void
*/
public function enable()
{
@@ -98,7 +102,7 @@ public function saveProfile(Profile $profile): bool
}
if (!($ret = $this->storage->write($profile)) && null !== $this->logger) {
- $this->logger->warning('Unable to store the profiler information.', ['configured_storage' => \get_class($this->storage)]);
+ $this->logger->warning('Unable to store the profiler information.', ['configured_storage' => $this->storage::class]);
}
return $ret;
@@ -106,6 +110,8 @@ public function saveProfile(Profile $profile): bool
/**
* Purges all data from the storage.
+ *
+ * @return void
*/
public function purge()
{
@@ -162,6 +168,9 @@ public function collect(Request $request, Response $response, \Throwable $except
return $profile;
}
+ /**
+ * @return void
+ */
public function reset()
{
foreach ($this->collectors as $collector) {
@@ -182,6 +191,8 @@ public function all(): array
* Sets the Collectors associated with this profiler.
*
* @param DataCollectorInterface[] $collectors An array of collectors
+ *
+ * @return void
*/
public function set(array $collectors = [])
{
@@ -193,6 +204,8 @@ public function set(array $collectors = [])
/**
* Adds a Collector.
+ *
+ * @return void
*/
public function add(DataCollectorInterface $collector)
{
diff --git a/core/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php b/core/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php
index 95d72f46b3..247e51fce9 100644
--- a/core/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php
+++ b/core/vendor/symfony/http-kernel/Profiler/ProfilerStorageInterface.php
@@ -49,6 +49,8 @@ public function write(Profile $profile): bool;
/**
* Purges all data from the database.
+ *
+ * @return void
*/
public function purge();
}
diff --git a/core/vendor/symfony/http-kernel/RebootableInterface.php b/core/vendor/symfony/http-kernel/RebootableInterface.php
index e257237da9..e973f55400 100644
--- a/core/vendor/symfony/http-kernel/RebootableInterface.php
+++ b/core/vendor/symfony/http-kernel/RebootableInterface.php
@@ -25,6 +25,8 @@ interface RebootableInterface
* while building the container. Use the %kernel.build_dir% parameter instead.
*
* @param string|null $warmupDir pass null to reboot in the regular build directory
+ *
+ * @return void
*/
public function reboot(?string $warmupDir);
}
diff --git a/core/vendor/symfony/http-kernel/Resources/welcome.html.php b/core/vendor/symfony/http-kernel/Resources/welcome.html.php
index 44d962d503..2670ce1ab8 100644
--- a/core/vendor/symfony/http-kernel/Resources/welcome.html.php
+++ b/core/vendor/symfony/http-kernel/Resources/welcome.html.php
@@ -7,8 +7,8 @@
'.$this->dumpHeader;
}
+ /**
+ * @return void
+ */
public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
{
if ('' === $str && isset($cursor->attr['img-data'], $cursor->attr['content-type'])) {
@@ -788,6 +804,9 @@ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut)
}
}
+ /**
+ * @return void
+ */
public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild)
{
if (Cursor::HASH_OBJECT === $type) {
@@ -816,6 +835,9 @@ public function enterHash(Cursor $cursor, int $type, string|int|null $class, boo
}
}
+ /**
+ * @return void
+ */
public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut)
{
$this->dumpEllipsis($cursor, $hasChild, $cut);
@@ -827,7 +849,7 @@ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, boo
protected function style(string $style, string $value, array $attr = []): string
{
- if ('' === $value) {
+ if ('' === $value && ('label' !== $style || !isset($attr['file']) && !isset($attr['href']))) {
return '';
}
@@ -862,7 +884,6 @@ protected function style(string $style, string $value, array $attr = []): string
} elseif ('private' === $style) {
$style .= sprintf(' title="Private property defined in class:
`%s`"', esc($this->utf8Encode($attr['class'])));
}
- $map = static::$controlCharsMap;
if (isset($attr['ellipsis'])) {
$class = 'sf-dump-ellipsis';
@@ -881,6 +902,7 @@ protected function style(string $style, string $value, array $attr = []): string
}
}
+ $map = static::$controlCharsMap;
$v = "".preg_replace_callback(static::$controlCharsRx, function ($c) use ($map) {
$s = $b = '%s', esc($this->utf8Encode($attr['href'])), $target, $v);
}
if (isset($attr['lang'])) {
$v = sprintf('%s
', esc($attr['lang']), $v);
}
+ if ('label' === $style) {
+ $v .= ' ';
+ }
return $v;
}
+ /**
+ * @return void
+ */
protected function dumpLine(int $depth, bool $endOfValue = false)
{
if (-1 === $this->lastDepth) {
@@ -944,7 +981,7 @@ protected function dumpLine(int $depth, bool $endOfValue = false)
AbstractDumper::dumpLine($depth);
}
- private function getSourceLink(string $file, int $line)
+ private function getSourceLink(string $file, int $line): string|false
{
$options = $this->extraDisplayOptions + $this->displayOptions;
@@ -956,7 +993,7 @@ private function getSourceLink(string $file, int $line)
}
}
-function esc(string $str)
+function esc(string $str): string
{
return htmlspecialchars($str, \ENT_QUOTES, 'UTF-8');
}
diff --git a/core/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/core/vendor/symfony/var-dumper/Dumper/ServerDumper.php
index f2c891b6a1..98c2149330 100644
--- a/core/vendor/symfony/var-dumper/Dumper/ServerDumper.php
+++ b/core/vendor/symfony/var-dumper/Dumper/ServerDumper.php
@@ -41,10 +41,15 @@ public function getContextProviders(): array
return $this->connection->getContextProviders();
}
+ /**
+ * @return string|null
+ */
public function dump(Data $data)
{
if (!$this->connection->write($data) && $this->wrappedDumper) {
- $this->wrappedDumper->dump($data);
+ return $this->wrappedDumper->dump($data);
}
+
+ return null;
}
}
diff --git a/core/vendor/symfony/var-dumper/Resources/functions/dump.php b/core/vendor/symfony/var-dumper/Resources/functions/dump.php
index 6221a4d182..a0e5addff1 100644
--- a/core/vendor/symfony/var-dumper/Resources/functions/dump.php
+++ b/core/vendor/symfony/var-dumper/Resources/functions/dump.php
@@ -9,40 +9,52 @@
* file that was distributed with this source code.
*/
+use Symfony\Component\VarDumper\Caster\ScalarStub;
use Symfony\Component\VarDumper\VarDumper;
if (!function_exists('dump')) {
/**
* @author Nicolas Grekas
+ * @author Alexandre Daubois
*/
- function dump(mixed $var, mixed ...$moreVars): mixed
+ function dump(mixed ...$vars): mixed
{
- VarDumper::dump($var);
+ if (!$vars) {
+ VarDumper::dump(new ScalarStub('🐛'));
- foreach ($moreVars as $v) {
- VarDumper::dump($v);
+ return null;
}
- if (1 < func_num_args()) {
- return func_get_args();
+ if (array_key_exists(0, $vars) && 1 === count($vars)) {
+ VarDumper::dump($vars[0]);
+ $k = 0;
+ } else {
+ foreach ($vars as $k => $v) {
+ VarDumper::dump($v, is_int($k) ? 1 + $k : $k);
+ }
}
- return $var;
+ if (1 < count($vars)) {
+ return $vars;
+ }
+
+ return $vars[$k];
}
}
if (!function_exists('dd')) {
- /**
- * @return never
- */
- function dd(...$vars): void
+ function dd(mixed ...$vars): never
{
if (!in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && !headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
- foreach ($vars as $v) {
- VarDumper::dump($v);
+ if (array_key_exists(0, $vars) && 1 === count($vars)) {
+ VarDumper::dump($vars[0]);
+ } else {
+ foreach ($vars as $k => $v) {
+ VarDumper::dump($v, is_int($k) ? 1 + $k : $k);
+ }
}
exit(1);
diff --git a/core/vendor/symfony/var-dumper/Server/Connection.php b/core/vendor/symfony/var-dumper/Server/Connection.php
index c68408678f..3c0f36864f 100644
--- a/core/vendor/symfony/var-dumper/Server/Connection.php
+++ b/core/vendor/symfony/var-dumper/Server/Connection.php
@@ -62,7 +62,7 @@ public function write(Data $data): bool
$context = array_filter($context);
$encodedPayload = base64_encode(serialize([$data, $context]))."\n";
- set_error_handler([self::class, 'nullErrorHandler']);
+ set_error_handler(fn () => true);
try {
if (-1 !== stream_socket_sendto($this->socket, $encodedPayload)) {
return true;
@@ -82,16 +82,14 @@ public function write(Data $data): bool
return false;
}
- private static function nullErrorHandler(int $t, string $m)
- {
- // no-op
- }
-
+ /**
+ * @return resource|null
+ */
private function createSocket()
{
- set_error_handler([self::class, 'nullErrorHandler']);
+ set_error_handler(fn () => true);
try {
- return stream_socket_client($this->host, $errno, $errstr, 3);
+ return stream_socket_client($this->host, $errno, $errstr, 3) ?: null;
} finally {
restore_error_handler();
}
diff --git a/core/vendor/symfony/var-dumper/VarDumper.php b/core/vendor/symfony/var-dumper/VarDumper.php
index 840bfd6496..2e1dad116c 100644
--- a/core/vendor/symfony/var-dumper/VarDumper.php
+++ b/core/vendor/symfony/var-dumper/VarDumper.php
@@ -37,13 +37,19 @@ class VarDumper
*/
private static $handler;
- public static function dump(mixed $var)
+ /**
+ * @param string|null $label
+ *
+ * @return mixed
+ */
+ public static function dump(mixed $var/* , string $label = null */)
{
+ $label = 2 <= \func_num_args() ? func_get_arg(1) : null;
if (null === self::$handler) {
self::register();
}
- return (self::$handler)($var);
+ return (self::$handler)($var, $label);
}
public static function setHandler(callable $callable = null): ?callable
@@ -90,8 +96,14 @@ private static function register(): void
$dumper = new ContextualizedDumper($dumper, [new SourceContextProvider()]);
}
- self::$handler = function ($var) use ($cloner, $dumper) {
- $dumper->dump($cloner->cloneVar($var));
+ self::$handler = function ($var, string $label = null) use ($cloner, $dumper) {
+ $var = $cloner->cloneVar($var);
+
+ if (null !== $label) {
+ $var = $var->withContext(['label' => $label]);
+ }
+
+ $dumper->dump($var);
};
}
diff --git a/core/vendor/symfony/var-dumper/composer.json b/core/vendor/symfony/var-dumper/composer.json
index 71ec64c0de..e9967f0e52 100644
--- a/core/vendor/symfony/var-dumper/composer.json
+++ b/core/vendor/symfony/var-dumper/composer.json
@@ -27,14 +27,8 @@
"twig/twig": "^2.13|^3.0.4"
},
"conflict": {
- "phpunit/phpunit": "<5.4.3",
"symfony/console": "<5.4"
},
- "suggest": {
- "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).",
- "ext-intl": "To show region name in time zone dump",
- "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script"
- },
"autoload": {
"files": [ "Resources/functions/dump.php" ],
"psr-4": { "Symfony\\Component\\VarDumper\\": "" },
diff --git a/core/vendor/voku/portable-ascii/.whitesource b/core/vendor/voku/portable-ascii/.whitesource
deleted file mode 100644
index 55b922e8c1..0000000000
--- a/core/vendor/voku/portable-ascii/.whitesource
+++ /dev/null
@@ -1,12 +0,0 @@
-{
- "scanSettings": {
- "baseBranches": []
- },
- "checkRunSettings": {
- "vulnerableCheckRunConclusionLevel": "failure",
- "displayMode": "diff"
- },
- "issueSettings": {
- "minSeverityLevel": "LOW"
- }
-}
\ No newline at end of file
diff --git a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php
index d51f557a1d..68c3f9d254 100644
--- a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php
+++ b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_by_languages.php
@@ -1060,9 +1060,9 @@
'Я' => 'Ya',
'я' => 'ya',
],
- // Russian - Passport (2013), ICAO
+ // Russian - GOST 7.79-2000(B)
// -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1
- 'ru__passport_2013' => [
+ 'ru__gost_2000_b' => [
'А' => 'A',
'а' => 'a',
'Б' => 'B',
@@ -1075,8 +1075,8 @@
'д' => 'd',
'Е' => 'E',
'е' => 'e',
- 'Ё' => 'E',
- 'ё' => 'e',
+ 'Ё' => 'Yo',
+ 'ё' => 'yo',
'Ж' => 'Zh',
'ж' => 'zh',
'З' => 'Z',
@@ -1107,42 +1107,42 @@
'у' => 'u',
'Ф' => 'F',
'ф' => 'f',
- 'Х' => 'Kh',
- 'х' => 'kh',
- 'Ц' => 'Ts',
- 'ц' => 'ts',
+ 'Х' => 'X',
+ 'х' => 'x',
+ 'Ц' => 'Cz',
+ 'ц' => 'cz',
'Ч' => 'Ch',
'ч' => 'ch',
'ш' => 'sh',
'Ш' => 'Sh',
- 'Щ' => 'Shch',
- 'щ' => 'shch',
- 'Ъ' => 'Ie',
- 'ъ' => 'ie',
- 'Ы' => 'Y',
- 'ы' => 'y',
+ 'Щ' => 'Shh',
+ 'щ' => 'shh',
+ 'Ъ' => '',
+ 'ъ' => '',
+ 'Ы' => 'Y\'',
+ 'ы' => 'y\'',
'Ь' => '',
'ь' => '',
- 'Э' => 'E',
- 'э' => 'e',
- 'Ю' => 'Iu',
- 'ю' => 'iu',
- 'Я' => 'Ia',
- 'я' => 'ia',
- 'І' => '',
- 'і' => '',
- 'Ѳ' => '',
- 'ѳ' => '',
- 'Ѣ' => '',
- 'ѣ' => '',
- 'Ѵ' => '',
- 'ѵ' => '',
+ 'Э' => 'E\'',
+ 'э' => 'e\'',
+ 'Ю' => 'Yu',
+ 'ю' => 'yu',
+ 'Я' => 'Ya',
+ 'я' => 'ya',
+ 'І' => 'I',
+ 'і' => 'i',
+ 'Ѳ' => 'Fh',
+ 'ѳ' => 'fh',
+ 'Ѣ' => 'Ye',
+ 'ѣ' => 'ye',
+ 'Ѵ' => 'Yh',
+ 'ѵ' => 'yh',
'Є' => '',
'є' => '',
'Ѥ' => '',
'ѥ' => '',
- 'Ѕ' => '',
- 'ѕ' => '',
+ 'Ѕ' => 'Js',
+ 'ѕ' => 'js',
'Ꙋ' => '',
'ꙋ' => '',
'Ѡ' => '',
@@ -1162,9 +1162,9 @@
'Ѱ' => '',
'ѱ' => '',
],
- // Russian - GOST 7.79-2000(B)
+ // Russian - Passport (2013), ICAO
// -> https://en.m.wikipedia.org/wiki/Romanization_of_Russian#content-collapsible-block-1
- 'ru__gost_2000_b' => [
+ 'ru__passport_2013' => [
'А' => 'A',
'а' => 'a',
'Б' => 'B',
@@ -1177,8 +1177,8 @@
'д' => 'd',
'Е' => 'E',
'е' => 'e',
- 'Ё' => 'Yo',
- 'ё' => 'yo',
+ 'Ё' => 'E',
+ 'ё' => 'e',
'Ж' => 'Zh',
'ж' => 'zh',
'З' => 'Z',
@@ -1209,42 +1209,42 @@
'у' => 'u',
'Ф' => 'F',
'ф' => 'f',
- 'Х' => 'X',
- 'х' => 'x',
- 'Ц' => 'Cz',
- 'ц' => 'cz',
+ 'Х' => 'Kh',
+ 'х' => 'kh',
+ 'Ц' => 'Ts',
+ 'ц' => 'ts',
'Ч' => 'Ch',
'ч' => 'ch',
'ш' => 'sh',
'Ш' => 'Sh',
- 'Щ' => 'Shh',
- 'щ' => 'shh',
- 'Ъ' => '',
- 'ъ' => '',
- 'Ы' => 'Y\'',
- 'ы' => 'y\'',
+ 'Щ' => 'Shch',
+ 'щ' => 'shch',
+ 'Ъ' => 'Ie',
+ 'ъ' => 'ie',
+ 'Ы' => 'Y',
+ 'ы' => 'y',
'Ь' => '',
'ь' => '',
- 'Э' => 'E\'',
- 'э' => 'e\'',
- 'Ю' => 'Yu',
- 'ю' => 'yu',
- 'Я' => 'Ya',
- 'я' => 'ya',
- 'І' => 'I',
- 'і' => 'i',
- 'Ѳ' => 'Fh',
- 'ѳ' => 'fh',
- 'Ѣ' => 'Ye',
- 'ѣ' => 'ye',
- 'Ѵ' => 'Yh',
- 'ѵ' => 'yh',
+ 'Э' => 'E',
+ 'э' => 'e',
+ 'Ю' => 'Iu',
+ 'ю' => 'iu',
+ 'Я' => 'Ia',
+ 'я' => 'ia',
+ 'І' => '',
+ 'і' => '',
+ 'Ѳ' => '',
+ 'ѳ' => '',
+ 'Ѣ' => '',
+ 'ѣ' => '',
+ 'Ѵ' => '',
+ 'ѵ' => '',
'Є' => '',
'є' => '',
'Ѥ' => '',
'ѥ' => '',
- 'Ѕ' => 'Js',
- 'ѕ' => 'js',
+ 'Ѕ' => '',
+ 'ѕ' => '',
'Ꙋ' => '',
'ꙋ' => '',
'Ѡ' => '',
@@ -1265,15 +1265,32 @@
'ѱ' => '',
],
// Ukrainian
+ // -> https://zakon.rada.gov.ua/laws/show/55-2010-%D0%BF?lang=en
'uk' => [
+ 'Г' => 'H',
+ 'г' => 'h',
+ 'Ґ' => 'G',
+ 'ґ' => 'g',
'Є' => 'Ye',
'є' => 'ye',
+ 'И' => 'Y',
+ 'и' => 'y',
'І' => 'I',
'і' => 'i',
'Ї' => 'Yi',
'ї' => 'yi',
- 'Ґ' => 'G',
- 'ґ' => 'g',
+ 'Й' => 'Y',
+ 'й' => 'y',
+ 'Х' => 'Kh',
+ 'х' => 'kh',
+ 'Ц' => 'Ts',
+ 'ц' => 'ts',
+ 'Ч' => 'Ch',
+ 'ч' => 'ch',
+ 'Ш' => 'Sh',
+ 'ш' => 'sh',
+ 'Щ' => 'Shch',
+ 'щ' => 'shch',
],
// Kazakh
'kk' => [
@@ -1602,10 +1619,10 @@
'fa' => [
'ا' => 'a',
'ب' => 'b',
- 'پ' => 'b',
+ 'پ' => 'p',
'ت' => 't',
'ث' => 's',
- 'ج' => 'g',
+ 'ج' => 'j',
'چ' => 'ch',
'ح' => 'h',
'خ' => 'kh',
@@ -2555,6 +2572,8 @@
'j̄' => 'j',
'J̃' => 'J',
'j̃' => 'j',
+ 'Й' => 'i',
+ 'й' => 'i',
'ĸ' => 'k',
'Ĺ' => 'L',
'Ľ' => 'L',
@@ -2810,6 +2829,8 @@
'ȳ' => 'y',
'Ỹ' => 'Y',
'ỹ' => 'y',
+ 'Щ' => 'Shh',
+ 'щ' => 'shh',
'Ź' => 'Z',
'ź' => 'z',
'Z̀' => 'Z',
diff --git a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php
index 426d84a4dc..afe31ae2cc 100644
--- a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php
+++ b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_extras_by_languages.php
@@ -199,8 +199,8 @@
'&' => ' i ',
'+' => ' plus ',
],
- // Russian - Passport (2013), ICAO
- 'ru__passport_2013' => [
+ // Russian - GOST 7.79-2000(B)
+ 'ru__gost_2000_b' => [
'=' => ' ravnyj ',
'%' => ' procent ',
'∑' => ' summa ',
@@ -210,8 +210,8 @@
'&' => ' i ',
'+' => ' plus ',
],
- // Russian - GOST 7.79-2000(B)
- 'ru__gost_2000_b' => [
+ // Russian - Passport (2013), ICAO
+ 'ru__passport_2013' => [
'=' => ' ravnyj ',
'%' => ' procent ',
'∑' => ' summa ',
diff --git a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php
index a6345f2138..da81ae2366 100644
--- a/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php
+++ b/core/vendor/voku/portable-ascii/src/voku/helper/data/ascii_language_max_key.php
@@ -31,8 +31,8 @@
'fi' => 1,
'ka' => 1,
'ru' => 1,
- 'ru__passport_2013' => 1,
'ru__gost_2000_b' => 1,
+ 'ru__passport_2013' => 1,
'uk' => 1,
'kk' => 1,
'cs' => 1,