composer update

This commit is contained in:
2020-05-10 09:29:56 +00:00
parent c6f807ebad
commit 8e93eececf
919 changed files with 11790 additions and 7005 deletions

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -36,7 +36,6 @@ use Symfony\Component\Console\Input\InputAwareInterface;
use Symfony\Component\Console\Input\InputDefinition;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\StreamableInputInterface;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Console\Output\OutputInterface;
@@ -600,7 +599,7 @@ class Application implements ResetInterface
$exact = \in_array($namespace, $namespaces, true);
if (\count($namespaces) > 1 && !$exact) {
throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
throw new NamespaceNotFoundException(sprintf("The namespace \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))), array_values($namespaces));
}
return $exact ? $namespace : reset($namespaces);
@@ -673,8 +672,13 @@ class Application implements ResetInterface
// filter out aliases for commands which are already on the list
if (\count($commands) > 1) {
$commandList = $this->commandLoader ? array_merge(array_flip($this->commandLoader->getNames()), $this->commands) : $this->commands;
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use ($commandList, $commands, &$aliases) {
$commandName = $commandList[$nameOrAlias] instanceof Command ? $commandList[$nameOrAlias]->getName() : $nameOrAlias;
$commands = array_unique(array_filter($commands, function ($nameOrAlias) use (&$commandList, $commands, &$aliases) {
if (!$commandList[$nameOrAlias] instanceof Command) {
$commandList[$nameOrAlias] = $this->commandLoader->get($nameOrAlias);
}
$commandName = $commandList[$nameOrAlias]->getName();
$aliases[$nameOrAlias] = $commandName;
return $commandName === $nameOrAlias || !\in_array($commandName, $commands);
@@ -689,10 +693,6 @@ class Application implements ResetInterface
$maxLen = max(Helper::strlen($abbrev), $maxLen);
}
$abbrevs = array_map(function ($cmd) use ($commandList, $usableWidth, $maxLen, &$commands) {
if (!$commandList[$cmd] instanceof Command) {
$commandList[$cmd] = $this->commandLoader->get($cmd);
}
if ($commandList[$cmd]->isHidden()) {
unset($commands[array_search($cmd, $commands)]);
@@ -707,7 +707,7 @@ class Application implements ResetInterface
if (\count($commands) > 1) {
$suggestions = $this->getAbbreviationSuggestions(array_filter($abbrevs));
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s", $name, $suggestions), array_values($commands));
throw new CommandNotFoundException(sprintf("Command \"%s\" is ambiguous.\nDid you mean one of these?\n%s.", $name, $suggestions), array_values($commands));
}
}
@@ -804,7 +804,7 @@ class Application implements ResetInterface
public function renderThrowable(\Throwable $e, OutputInterface $output): void
{
if (__CLASS__ !== \get_class($this) && __CLASS__ === (new \ReflectionMethod($this, 'renderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'renderException'))->getDeclaringClass()->getName()) {
if (__CLASS__ !== static::class && __CLASS__ === (new \ReflectionMethod($this, 'renderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'renderException'))->getDeclaringClass()->getName()) {
@trigger_error(sprintf('The "%s::renderException()" method is deprecated since Symfony 4.4, use "renderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
if (!$e instanceof \Exception) {
@@ -843,7 +843,7 @@ class Application implements ResetInterface
protected function doRenderThrowable(\Throwable $e, OutputInterface $output): void
{
if (__CLASS__ !== \get_class($this) && __CLASS__ === (new \ReflectionMethod($this, 'doRenderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'doRenderException'))->getDeclaringClass()->getName()) {
if (__CLASS__ !== static::class && __CLASS__ === (new \ReflectionMethod($this, 'doRenderThrowable'))->getDeclaringClass()->getName() && __CLASS__ !== (new \ReflectionMethod($this, 'doRenderException'))->getDeclaringClass()->getName()) {
@trigger_error(sprintf('The "%s::doRenderException()" method is deprecated since Symfony 4.4, use "doRenderThrowable()" instead.', __CLASS__), E_USER_DEPRECATED);
if (!$e instanceof \Exception) {
@@ -872,7 +872,7 @@ class Application implements ResetInterface
}
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
}, $message);
}
@@ -946,16 +946,6 @@ class Application implements ResetInterface
if (true === $input->hasParameterOption(['--no-interaction', '-n'], true)) {
$input->setInteractive(false);
} elseif (\function_exists('posix_isatty')) {
$inputStream = null;
if ($input instanceof StreamableInputInterface) {
$inputStream = $input->getStream();
}
if (!@posix_isatty($inputStream) && false === getenv('SHELL_INTERACTIVE')) {
$input->setInteractive(false);
}
}
switch ($shellVerbosity = (int) getenv('SHELL_VERBOSITY')) {

View File

@@ -55,7 +55,7 @@ class Command
*/
public static function getDefaultName()
{
$class = \get_called_class();
$class = static::class;
$r = new \ReflectionProperty($class, 'defaultName');
return $class === $r->class ? static::$defaultName : null;
@@ -255,7 +255,7 @@ class Command
$statusCode = $this->execute($input, $output);
if (!\is_int($statusCode)) {
@trigger_error(sprintf('Return value of "%s::execute()" should always be of the type int since Symfony 4.4, %s returned.', \get_class($this), \gettype($statusCode)), E_USER_DEPRECATED);
@trigger_error(sprintf('Return value of "%s::execute()" should always be of the type int since Symfony 4.4, %s returned.', static::class, \gettype($statusCode)), E_USER_DEPRECATED);
}
}
@@ -344,7 +344,7 @@ class Command
public function getDefinition()
{
if (null === $this->definition) {
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', \get_class($this)));
throw new LogicException(sprintf('Command class "%s" is not correctly initialized. You probably forgot to call the parent constructor.', static::class));
}
return $this->definition;
@@ -559,7 +559,7 @@ class Command
public function setAliases($aliases)
{
if (!\is_array($aliases) && !$aliases instanceof \Traversable) {
throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable');
throw new InvalidArgumentException('$aliases must be an array or an instance of \Traversable.');
}
foreach ($aliases as $alias) {

View File

@@ -77,7 +77,7 @@ class ApplicationDescription
public function getCommand(string $name): Command
{
if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {
throw new CommandNotFoundException(sprintf('Command %s does not exist.', $name));
throw new CommandNotFoundException(sprintf('Command "%s" does not exist.', $name));
}
return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];

View File

@@ -0,0 +1,21 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Console\Exception;
/**
* Represents failure to read input from stdin.
*
* @author Gabriel Ostrolucký <gabriel.ostrolucky@gmail.com>
*/
class MissingInputException extends RuntimeException implements ExceptionInterface
{
}

View File

@@ -115,7 +115,7 @@ class OutputFormatter implements WrappableOutputFormatterInterface
public function getStyle($name)
{
if (!$this->hasStyle($name)) {
throw new InvalidArgumentException(sprintf('Undefined style: %s', $name));
throw new InvalidArgumentException(sprintf('Undefined style: "%s".', $name));
}
return $this->styles[strtolower($name)];

View File

@@ -87,7 +87,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
}
if (!isset(static::$availableForegroundColors[$color])) {
throw new InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors))));
throw new InvalidArgumentException(sprintf('Invalid foreground color specified: "%s". Expected one of (%s).', $color, implode(', ', array_keys(static::$availableForegroundColors))));
}
$this->foreground = static::$availableForegroundColors[$color];
@@ -105,7 +105,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
}
if (!isset(static::$availableBackgroundColors[$color])) {
throw new InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors))));
throw new InvalidArgumentException(sprintf('Invalid background color specified: "%s". Expected one of (%s).', $color, implode(', ', array_keys(static::$availableBackgroundColors))));
}
$this->background = static::$availableBackgroundColors[$color];
@@ -122,7 +122,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
public function setOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, implode(', ', array_keys(static::$availableOptions))));
}
if (!\in_array(static::$availableOptions[$option], $this->options)) {
@@ -136,7 +136,7 @@ class OutputFormatterStyle implements OutputFormatterStyleInterface
public function unsetOption($option)
{
if (!isset(static::$availableOptions[$option])) {
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));
throw new InvalidArgumentException(sprintf('Invalid option specified: "%s". Expected one of (%s).', $option, implode(', ', array_keys(static::$availableOptions))));
}
$pos = array_search(static::$availableOptions[$option], $this->options);

View File

@@ -54,12 +54,12 @@ class FormatterHelper extends Helper
foreach ($messages as $message) {
$message = OutputFormatter::escape($message);
$lines[] = sprintf($large ? ' %s ' : ' %s ', $message);
$len = max($this->strlen($message) + ($large ? 4 : 2), $len);
$len = max(self::strlen($message) + ($large ? 4 : 2), $len);
}
$messages = $large ? [str_repeat(' ', $len)] : [];
for ($i = 0; isset($lines[$i]); ++$i) {
$messages[] = $lines[$i].str_repeat(' ', $len - $this->strlen($lines[$i]));
$messages[] = $lines[$i].str_repeat(' ', $len - self::strlen($lines[$i]));
}
if ($large) {
$messages[] = str_repeat(' ', $len);
@@ -83,17 +83,13 @@ class FormatterHelper extends Helper
*/
public function truncate($message, $length, $suffix = '...')
{
$computedLength = $length - $this->strlen($suffix);
$computedLength = $length - self::strlen($suffix);
if ($computedLength > $this->strlen($message)) {
if ($computedLength > self::strlen($message)) {
return $message;
}
if (false === $encoding = mb_detect_encoding($message, null, true)) {
return substr($message, 0, $length).$suffix;
}
return mb_substr($message, 0, $length, $encoding).$suffix;
return self::substr($message, 0, $length).$suffix;
}
/**

View File

@@ -11,6 +11,7 @@
namespace Symfony\Component\Console\Helper;
use Symfony\Component\Console\Exception\MissingInputException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatter;
use Symfony\Component\Console\Formatter\OutputFormatterStyle;
@@ -48,44 +49,32 @@ class QuestionHelper extends Helper
}
if (!$input->isInteractive()) {
$default = $question->getDefault();
if (null === $default) {
return $default;
}
if ($validator = $question->getValidator()) {
return \call_user_func($question->getValidator(), $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
if (!$question->isMultiselect()) {
return isset($choices[$default]) ? $choices[$default] : $default;
}
$default = explode(',', $default);
foreach ($default as $k => $v) {
$v = $question->isTrimmable() ? trim($v) : $v;
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
}
}
return $default;
return $this->getDefaultAnswer($question);
}
if ($input instanceof StreamableInputInterface && $stream = $input->getStream()) {
$this->inputStream = $stream;
}
if (!$question->getValidator()) {
return $this->doAsk($output, $question);
try {
if (!$question->getValidator()) {
return $this->doAsk($output, $question);
}
$interviewer = function () use ($output, $question) {
return $this->doAsk($output, $question);
};
return $this->validateAttempts($interviewer, $output, $question);
} catch (MissingInputException $exception) {
$input->setInteractive(false);
if (null === $fallbackOutput = $this->getDefaultAnswer($question)) {
throw $exception;
}
return $fallbackOutput;
}
$interviewer = function () use ($output, $question) {
return $this->doAsk($output, $question);
};
return $this->validateAttempts($interviewer, $output, $question);
}
/**
@@ -134,7 +123,7 @@ class QuestionHelper extends Helper
if (false === $ret) {
$ret = fgets($inputStream, 4096);
if (false === $ret) {
throw new RuntimeException('Aborted.');
throw new MissingInputException('Aborted.');
}
if ($question->isTrimmable()) {
$ret = trim($ret);
@@ -158,6 +147,36 @@ class QuestionHelper extends Helper
return $ret;
}
/**
* @return mixed
*/
private function getDefaultAnswer(Question $question)
{
$default = $question->getDefault();
if (null === $default) {
return $default;
}
if ($validator = $question->getValidator()) {
return \call_user_func($question->getValidator(), $default);
} elseif ($question instanceof ChoiceQuestion) {
$choices = $question->getChoices();
if (!$question->isMultiselect()) {
return isset($choices[$default]) ? $choices[$default] : $default;
}
$default = explode(',', $default);
foreach ($default as $k => $v) {
$v = $question->isTrimmable() ? trim($v) : $v;
$default[$k] = isset($choices[$v]) ? $choices[$v] : $v;
}
}
return $default;
}
/**
* Outputs the question prompt.
*/
@@ -166,15 +185,9 @@ class QuestionHelper extends Helper
$message = $question->getQuestion();
if ($question instanceof ChoiceQuestion) {
$maxWidth = max(array_map([$this, 'strlen'], array_keys($question->getChoices())));
$messages = (array) $question->getQuestion();
foreach ($question->getChoices() as $key => $value) {
$width = $maxWidth - $this->strlen($key);
$messages[] = ' [<info>'.$key.str_repeat(' ', $width).'</info>] '.$value;
}
$output->writeln($messages);
$output->writeln(array_merge([
$question->getQuestion(),
], $this->formatChoiceQuestionChoices($question, 'info')));
$message = $question->getPrompt();
}
@@ -182,6 +195,26 @@ class QuestionHelper extends Helper
$output->write($message);
}
/**
* @param string $tag
*
* @return string[]
*/
protected function formatChoiceQuestionChoices(ChoiceQuestion $question, $tag)
{
$messages = [];
$maxWidth = max(array_map('self::strlen', array_keys($choices = $question->getChoices())));
foreach ($choices as $key => $value) {
$padding = str_repeat(' ', $maxWidth - self::strlen($key));
$messages[] = sprintf(" [<$tag>%s$padding</$tag>] %s", $key, $value);
}
return $messages;
}
/**
* Outputs an error message.
*/
@@ -226,7 +259,7 @@ class QuestionHelper extends Helper
// as opposed to fgets(), fread() returns an empty string when the stream content is empty, not false.
if (false === $c || ('' === $ret && '' === $c && null === $question->getDefault())) {
shell_exec(sprintf('stty %s', $sttyMode));
throw new RuntimeException('Aborted.');
throw new MissingInputException('Aborted.');
} elseif ("\177" === $c) { // Backspace Character
if (0 === $numMatches && 0 !== $i) {
--$i;
@@ -392,7 +425,7 @@ class QuestionHelper extends Helper
shell_exec(sprintf('stty %s', $sttyMode));
if (false === $value) {
throw new RuntimeException('Aborted.');
throw new MissingInputException('Aborted.');
}
if ($trimmable) {
$value = trim($value);

View File

@@ -68,15 +68,15 @@ class SymfonyQuestionHelper extends QuestionHelper
$output->writeln($text);
if ($question instanceof ChoiceQuestion) {
$width = max(array_map('strlen', array_keys($question->getChoices())));
$prompt = ' > ';
foreach ($question->getChoices() as $key => $value) {
$output->writeln(sprintf(" [<comment>%-${width}s</comment>] %s", $key, $value));
}
if ($question instanceof ChoiceQuestion) {
$output->writeln($this->formatChoiceQuestionChoices($question, 'comment'));
$prompt = $question->getPrompt();
}
$output->write(' > ');
$output->write($prompt);
}
/**

View File

@@ -601,7 +601,9 @@ class Table
++$numberOfRows; // Add row for header separator
}
++$numberOfRows; // Add row for footer separator
if (\count($this->rows) > 0) {
++$numberOfRows; // Add row for footer separator
}
return $numberOfRows;
}
@@ -616,7 +618,7 @@ class Table
$unmergedRows = [];
foreach ($rows[$line] as $column => $cell) {
if (null !== $cell && !$cell instanceof TableCell && !is_scalar($cell) && !(\is_object($cell) && method_exists($cell, '__toString'))) {
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing __toString, %s given.', \gettype($cell)));
throw new InvalidArgumentException(sprintf('A cell must be a TableCell, a scalar or an object implementing "__toString()", "%s" given.', \gettype($cell)));
}
if ($cell instanceof TableCell && $cell->getRowspan() > 1) {
$nbLines = $cell->getRowspan() - 1;

View File

@@ -58,7 +58,7 @@ class TableStyle
public function setPaddingChar($paddingChar)
{
if (!$paddingChar) {
throw new LogicException('The padding char must not be empty');
throw new LogicException('The padding char must not be empty.');
}
$this->paddingChar = $paddingChar;

View File

@@ -57,7 +57,7 @@ class StringInput extends ArgvInput
$tokens[] = stripcslashes($match[1]);
} else {
// should never happen
throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ..."', substr($input, $cursor, 10)));
throw new InvalidArgumentException(sprintf('Unable to parse input near "... %s ...".', substr($input, $cursor, 10)));
}
$cursor += \strlen($match[0]);

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -12,7 +12,6 @@
namespace Symfony\Component\Console\Output;
use Symfony\Component\Console\Exception\InvalidArgumentException;
use Symfony\Component\Console\Exception\RuntimeException;
use Symfony\Component\Console\Formatter\OutputFormatterInterface;
/**
@@ -74,10 +73,7 @@ class StreamOutput extends Output
$message .= PHP_EOL;
}
if (false === @fwrite($this->stream, $message)) {
// should never happen
throw new RuntimeException('Unable to write output.');
}
@fwrite($this->stream, $message);
fflush($this->stream);
}

View File

@@ -156,7 +156,7 @@ class ChoiceQuestion extends Question
}
if (\count($results) > 1) {
throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));
throw new InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of "%s".', implode('" or "', $results)));
}
$result = array_search($value, $choices);

View File

@@ -7,7 +7,7 @@ interfaces.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/console/index.html)
* [Documentation](https://symfony.com/doc/current/components/console.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View File

@@ -295,7 +295,7 @@ class SymfonyStyle extends OutputStyle
{
if (null !== $default) {
$values = array_flip($choices);
$default = $values[$default];
$default = isset($values[$default]) ? $values[$default] : $default;
}
return $this->askQuestion(new ChoiceQuestion($question, $choices, $default));

View File

@@ -59,19 +59,12 @@ class ApplicationTester
$this->input->setInteractive($options['interactive']);
}
$shellInteractive = getenv('SHELL_INTERACTIVE');
if ($this->inputs) {
$this->input->setStream(self::createStream($this->inputs));
putenv('SHELL_INTERACTIVE=1');
}
$this->initOutput($options);
$this->statusCode = $this->application->run($this->input, $this->output);
putenv($shellInteractive ? "SHELL_INTERACTIVE=$shellInteractive" : 'SHELL_INTERACTIVE');
return $this->statusCode;
return $this->statusCode = $this->application->run($this->input, $this->output);
}
}

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -31,7 +31,7 @@ abstract class AbstractNode implements NodeInterface
public function getNodeName(): string
{
if (null === $this->nodeName) {
$this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', \get_called_class());
$this->nodeName = preg_replace('~.*\\\\([^\\\\]+)Node$~', '$1', static::class);
}
return $this->nodeName;

View File

@@ -55,7 +55,7 @@ class StringHandler implements HandlerInterface
$match = $reader->findPattern($this->patterns->getQuotedStringPattern($quote));
if (!$match) {
throw new InternalErrorException(sprintf('Should have found at least an empty match at %s.', $reader->getPosition()));
throw new InternalErrorException(sprintf('Should have found at least an empty match at %d.', $reader->getPosition()));
}
// check unclosed strings

View File

@@ -53,7 +53,7 @@ class FunctionExtension extends AbstractExtension
try {
list($a, $b) = Parser::parseSeries($function->getArguments());
} catch (SyntaxErrorException $e) {
throw new ExpressionErrorException(sprintf('Invalid series: %s', implode(', ', $function->getArguments())), 0, $e);
throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
}
$xpath->addStarPrefix();

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -391,7 +391,7 @@ class DebugClassLoader
foreach ($matches as list(, $parameterType, $parameterName)) {
if (!isset($definedParameters[$parameterName])) {
$parameterType = trim($parameterType);
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its parent class "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, $method->class);
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($class) ? 'interface' : 'parent class', $method->class);
}
}
}

View File

@@ -226,14 +226,14 @@ class ErrorHandler
if (!\is_array($log)) {
$log = [$log];
} elseif (!\array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
throw new \InvalidArgumentException('No logger provided.');
}
if (null === $log[0]) {
$this->loggedErrors &= ~$type;
} elseif ($log[0] instanceof LoggerInterface) {
$this->loggedErrors |= $type;
} else {
throw new \InvalidArgumentException('Invalid logger provided');
throw new \InvalidArgumentException('Invalid logger provided.');
}
$this->loggers[$type] = $log + $prev[$type];
@@ -499,7 +499,7 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404) && !\defined('HHVM_VERSION')) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
@@ -511,7 +511,7 @@ class ErrorHandler
} finally {
$this->isRecursive = false;
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404) && !\defined('HHVM_VERSION')) {
set_error_handler($currentErrorHandler);
}
}

View File

@@ -180,7 +180,7 @@ class FlattenException
public function setMessage($message)
{
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
}, $message);
}

View File

@@ -256,7 +256,11 @@ EOF
foreach ($e['trace'] as $trace) {
$content .= '<tr><td>';
if ($trace['function']) {
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>(<span class="trace-arguments">%s</span>)', $this->formatClass($trace['class']), $trace['type'], $trace['function'], $this->formatArgs($trace['args']));
$content .= sprintf('at <span class="trace-class">%s</span><span class="trace-type">%s</span><span class="trace-method">%s</span>', $this->formatClass($trace['class']), $trace['type'], $trace['function']);
if (isset($trace['args'])) {
$content .= sprintf('(<span class="trace-arguments">%s</span>)', $this->formatArgs($trace['args']));
}
}
if (isset($trace['file']) && isset($trace['line'])) {
$content .= $this->formatPath($trace['file'], $trace['line']);

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,12 +1,29 @@
Debug Component
===============
**CAUTION**: this component is deprecated since Symfony 4.4. Instead, use the
[ErrorHandler component](https://github.com/symfony/symfony/tree/master/src/Symfony/Component/ErrorHandler).
-----
The Debug component provides tools to ease debugging PHP code.
Getting Started
---------------
```
$ composer install symfony/debug
```
```php
use Symfony\Component\Debug\Debug;
Debug::enable();
```
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/debug/index.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -29,8 +29,13 @@ class Debug
ini_set('display_errors', 1);
}
@ini_set('zend.assertions', 1);
ini_set('assert.active', 1);
ini_set('assert.warning', 0);
ini_set('assert.exception', 1);
DebugClassLoader::enable();
return ErrorHandler::register(new ErrorHandler(new BufferingLogger()));
return ErrorHandler::register(new ErrorHandler(new BufferingLogger(), true));
}
}

View File

@@ -11,7 +11,8 @@
namespace Symfony\Component\ErrorHandler;
use Doctrine\Common\Persistence\Proxy;
use Doctrine\Common\Persistence\Proxy as LegacyProxy;
use Doctrine\Persistence\Proxy;
use PHPUnit\Framework\MockObject\Matcher\StatelessInvocation;
use PHPUnit\Framework\MockObject\MockObject;
use Prophecy\Prophecy\ProphecySubjectInterface;
@@ -298,6 +299,7 @@ class DebugClassLoader
&& !is_subclass_of($symbols[$i], ProphecySubjectInterface::class)
&& !is_subclass_of($symbols[$i], Proxy::class)
&& !is_subclass_of($symbols[$i], ProxyInterface::class)
&& !is_subclass_of($symbols[$i], LegacyProxy::class)
) {
$loader->checkClass($symbols[$i]);
}
@@ -426,17 +428,17 @@ class DebugClassLoader
}
}
if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+(?:[\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) {
if ($refl->isInterface() && false !== strpos($doc, 'method') && preg_match_all('#\n \* @method\s+(static\s+)?+([\w\|&\[\]\\\]+\s+)?(\w+(?:\s*\([^\)]*\))?)+(.+?([[:punct:]]\s*)?)?(?=\r?\n \*(?: @|/$|\r?\n))#', $doc, $notice, PREG_SET_ORDER)) {
foreach ($notice as $method) {
$static = '' !== $method[1];
$name = $method[2];
$description = $method[3] ?? null;
$static = '' !== $method[1] && !empty($method[2]);
$name = $method[3];
$description = $method[4] ?? null;
if (false === strpos($name, '(')) {
$name .= '()';
}
if (null !== $description) {
$description = trim($description);
if (!isset($method[4])) {
if (!isset($method[5])) {
$description .= '.';
}
}
@@ -605,7 +607,7 @@ class DebugClassLoader
if ($canAddReturnType && 'docblock' === $this->patchTypes['force'] && false === strpos($method->getFileName(), \DIRECTORY_SEPARATOR.'vendor'.\DIRECTORY_SEPARATOR)) {
$this->patchMethod($method, $returnType, $declaringFile, $normalizedType);
} elseif ('' !== $declaringClass && $this->patchTypes['deprecations']) {
$deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in child class "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, $className);
$deprecations[] = sprintf('Method "%s::%s()" will return "%s" as of its next major version. Doing the same in %s "%s" will be required when upgrading.', $declaringClass, $method->name, $normalizedType, interface_exists($declaringClass) ? 'implementation' : 'child class', $className);
}
}
}
@@ -662,7 +664,7 @@ class DebugClassLoader
foreach ($matches as list(, $parameterType, $parameterName)) {
if (!isset($definedParameters[$parameterName])) {
$parameterType = trim($parameterType);
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its parent class "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, $className);
self::$annotatedParameters[$class][$method->name][$parameterName] = sprintf('The "%%s::%s()" method will require a new "%s$%s" argument in the next major version of its %s "%s", not defining it is deprecated.', $method->name, $parameterType ? $parameterType.' ' : '', $parameterName, interface_exists($className) ? 'interface' : 'parent class', $className);
}
}
}

View File

@@ -92,6 +92,7 @@ class ErrorHandler
private $screamedErrors = 0x55; // E_ERROR + E_CORE_ERROR + E_COMPILE_ERROR + E_PARSE
private $loggedErrors = 0;
private $traceReflector;
private $debug;
private $isRecursive = 0;
private $isRoot = false;
@@ -180,7 +181,7 @@ class ErrorHandler
}
}
public function __construct(BufferingLogger $bootstrappingLogger = null)
public function __construct(BufferingLogger $bootstrappingLogger = null, bool $debug = false)
{
if ($bootstrappingLogger) {
$this->bootstrappingLogger = $bootstrappingLogger;
@@ -188,6 +189,7 @@ class ErrorHandler
}
$this->traceReflector = new \ReflectionProperty('Exception', 'trace');
$this->traceReflector->setAccessible(true);
$this->debug = $debug;
}
/**
@@ -244,14 +246,14 @@ class ErrorHandler
if (!\is_array($log)) {
$log = [$log];
} elseif (!\array_key_exists(0, $log)) {
throw new \InvalidArgumentException('No logger provided');
throw new \InvalidArgumentException('No logger provided.');
}
if (null === $log[0]) {
$this->loggedErrors &= ~$type;
} elseif ($log[0] instanceof LoggerInterface) {
$this->loggedErrors |= $type;
} else {
throw new \InvalidArgumentException('Invalid logger provided');
throw new \InvalidArgumentException('Invalid logger provided.');
}
$this->loggers[$type] = $log + $prev[$type];
@@ -411,6 +413,11 @@ class ErrorHandler
$throw = $this->thrownErrors & $type & $level;
$type &= $level | $this->screamedErrors;
// Never throw on warnings triggered by assert()
if (E_WARNING === $type && 'a' === $message[0] && 0 === strncmp($message, 'assert(): ', 10)) {
$throw = 0;
}
if (!$type || (!$log && !$throw)) {
return !$silenced && $type && $log;
}
@@ -512,7 +519,7 @@ class ErrorHandler
if ($this->isRecursive) {
$log = 0;
} else {
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
$currentErrorHandler = set_error_handler('var_dump');
restore_error_handler();
}
@@ -524,7 +531,7 @@ class ErrorHandler
} finally {
$this->isRecursive = false;
if (!\defined('HHVM_VERSION')) {
if (\PHP_VERSION_ID < (\PHP_VERSION_ID < 70400 ? 70316 : 70404)) {
set_error_handler($currentErrorHandler);
}
}
@@ -697,7 +704,7 @@ class ErrorHandler
*/
private function renderException(\Throwable $exception): void
{
$renderer = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliErrorRenderer() : new HtmlErrorRenderer(0 !== $this->scopedErrors);
$renderer = \in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) ? new CliErrorRenderer() : new HtmlErrorRenderer($this->debug);
$exception = $renderer->render($exception);
@@ -761,7 +768,7 @@ class ErrorHandler
*/
private function parseAnonymousClass(string $message): string
{
return preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', static function ($m) {
return preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', static function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
}, $message);
}

View File

@@ -15,6 +15,9 @@ use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
// Help opcache.preload discover always-needed symbols
class_exists(CliDumper::class);
/**
* @author Nicolas Grekas <p@tchwork.com>
*/

View File

@@ -46,11 +46,11 @@ class HtmlErrorRenderer implements ErrorRendererInterface
public function __construct($debug = false, string $charset = null, $fileLinkFormat = null, string $projectDir = null, $outputBuffer = '', LoggerInterface $logger = null)
{
if (!\is_bool($debug) && !\is_callable($debug)) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be a boolean or a callable, %s given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a boolean or a callable, "%s" given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
}
if (!\is_string($outputBuffer) && !\is_callable($outputBuffer)) {
throw new \TypeError(sprintf('Argument 5 passed to %s() must be a string or a callable, %s given.', __METHOD__, \is_object($outputBuffer) ? \get_class($outputBuffer) : \gettype($outputBuffer)));
throw new \TypeError(sprintf('Argument 5 passed to "%s()" must be a string or a callable, "%s" given.', __METHOD__, \is_object($outputBuffer) ? \get_class($outputBuffer) : \gettype($outputBuffer)));
}
$this->debug = $debug;

View File

@@ -12,6 +12,7 @@
namespace Symfony\Component\ErrorHandler\ErrorRenderer;
use Symfony\Component\ErrorHandler\Exception\FlattenException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
use Symfony\Component\Serializer\SerializerInterface;
@@ -30,16 +31,17 @@ class SerializerErrorRenderer implements ErrorRendererInterface
/**
* @param string|callable(FlattenException) $format The format as a string or a callable that should return it
* formats not supported by Request::getMimeTypes() should be given as mime types
* @param bool|callable $debug The debugging mode as a boolean or a callable that should return it
*/
public function __construct(SerializerInterface $serializer, $format, ErrorRendererInterface $fallbackErrorRenderer = null, $debug = false)
{
if (!\is_string($format) && !\is_callable($format)) {
throw new \TypeError(sprintf('Argument 2 passed to %s() must be a string or a callable, %s given.', __METHOD__, \is_object($format) ? \get_class($format) : \gettype($format)));
throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be a string or a callable, "%s" given.', __METHOD__, \is_object($format) ? \get_class($format) : \gettype($format)));
}
if (!\is_bool($debug) && !\is_callable($debug)) {
throw new \TypeError(sprintf('Argument 4 passed to %s() must be a boolean or a callable, %s given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
throw new \TypeError(sprintf('Argument 4 passed to "%s()" must be a boolean or a callable, "%s" given.', __METHOD__, \is_object($debug) ? \get_class($debug) : \gettype($debug)));
}
$this->serializer = $serializer;
@@ -57,11 +59,16 @@ class SerializerErrorRenderer implements ErrorRendererInterface
try {
$format = \is_string($this->format) ? $this->format : ($this->format)($flattenException);
$headers = [
'Content-Type' => Request::getMimeTypes($format)[0] ?? $format,
'Vary' => 'Accept',
];
return $flattenException->setAsString($this->serializer->serialize($flattenException, $format, [
'exception' => $exception,
'debug' => \is_bool($this->debug) ? $this->debug : ($this->debug)($exception),
]));
]))
->setHeaders($flattenException->getHeaders() + $headers);
} catch (NotEncodableValueException $e) {
return $this->fallbackErrorRenderer->render($exception);
}

View File

@@ -196,7 +196,7 @@ class FlattenException extends LegacyFlattenException
public function setMessage($message): self
{
if (false !== strpos($message, "class@anonymous\0")) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php0x?[0-9a-fA-F]++/', function ($m) {
$message = preg_replace_callback('/class@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', function ($m) {
return class_exists($m[0], false) ? get_parent_class($m[0]).'@anonymous' : $m[0];
}, $message);
}
@@ -206,7 +206,10 @@ class FlattenException extends LegacyFlattenException
return $this;
}
public function getCode(): int
/**
* @return int|string int most of the time (might be a string with PDOException)
*/
public function getCode()
{
return $this->code;
}

View File

@@ -1,4 +1,4 @@
Copyright (c) 2019 Fabien Potencier
Copyright (c) 2019-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -5,7 +5,7 @@
<?php } ?>
<?php if ('compact' !== $style && $trace['function']) { ?>
<span class="trace-class"><?= $this->abbrClass($trace['class']); ?></span><?php if ($trace['type']) { ?><span class="trace-type"><?= $trace['type']; ?></span><?php } ?><span class="trace-method"><?= $trace['function']; ?></span><span class="trace-arguments">(<?= $this->formatArgs($trace['args']); ?>)</span>
<span class="trace-class"><?= $this->abbrClass($trace['class']); ?></span><?php if ($trace['type']) { ?><span class="trace-type"><?= $trace['type']; ?></span><?php } ?><span class="trace-method"><?= $trace['function']; ?></span><?php if (isset($trace['args'])) { ?><span class="trace-arguments">(<?= $this->formatArgs($trace['args']); ?>)</span><?php } ?>
<?php } ?>
<?php if ($trace['file']) { ?>

View File

@@ -20,15 +20,15 @@
<?php if ($exception['trace']) { ?>
<pre class="stacktrace">
<?php
echo $exception['class'].":\n";
echo $this->escape($exception['class']).":\n";
if ($exception['message']) {
echo $exception['message']."\n";
echo $this->escape($exception['message'])."\n";
}
foreach ($exception['trace'] as $trace) {
echo "\n ";
if ($trace['function']) {
echo 'at '.$trace['class'].$trace['type'].$trace['function'].'('.$this->formatArgsAsText($trace['args']).')';
echo $this->escape('at '.$trace['class'].$trace['type'].$trace['function']).'('.(isset($trace['args']) ? $this->formatArgsAsText($trace['args']) : '').')';
}
if ($trace['file'] && $trace['line']) {
echo($trace['function'] ? "\n (" : 'at ').strtr(strip_tags($this->formatFile($trace['file'], $trace['line'])), [' at line '.$trace['line'] => '']).':'.$trace['line'].($trace['function'] ? ')' : '');

View File

@@ -18,7 +18,7 @@
"require": {
"php": "^7.1.3",
"psr/log": "~1.0",
"symfony/debug": "^4.4",
"symfony/debug": "^4.4.5",
"symfony/var-dumper": "^4.4|^5.0"
},
"require-dev": {

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -151,7 +151,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
$eventName = $swap;
if (!$event instanceof Event) {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an instance of %s, %s given.', EventDispatcherInterface::class, Event::class, \is_object($event) ? \get_class($event) : \gettype($event)));
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an instance of "%s", "%s" given.', EventDispatcherInterface::class, Event::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}
}

View File

@@ -38,7 +38,7 @@ class EventDispatcher implements EventDispatcherInterface
public function __construct()
{
if (__CLASS__ === \get_class($this)) {
if (__CLASS__ === static::class) {
$this->optimized = [];
}
}
@@ -60,7 +60,7 @@ class EventDispatcher implements EventDispatcherInterface
$event = $eventName ?? new Event();
$eventName = $swap;
} else {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, %s given.', EventDispatcherInterface::class, \is_object($event) ? \get_class($event) : \gettype($event)));
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, "%s" given.', EventDispatcherInterface::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}
if (null !== $this->optimized && null !== $eventName) {
@@ -274,7 +274,7 @@ class EventDispatcher implements EventDispatcherInterface
$this->sorted[$eventName] = [];
foreach ($this->listeners[$eventName] as &$listeners) {
foreach ($listeners as $k => $listener) {
foreach ($listeners as $k => &$listener) {
if (\is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure && 2 >= \count($listener)) {
$listener[0] = $listener[0]();
$listener[1] = $listener[1] ?? '__invoke';

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -65,7 +65,7 @@ final class LegacyEventDispatcherProxy implements EventDispatcherInterface
$event = $eventName ?? new Event();
$eventName = $swap;
} else {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, %s given.', ContractsEventDispatcherInterface::class, \is_object($event) ? \get_class($event) : \gettype($event)));
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, "%s" given.', ContractsEventDispatcherInterface::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}
$listeners = $this->getListeners($eventName);

View File

@@ -8,7 +8,7 @@ them.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/event_dispatcher/index.html)
* [Documentation](https://symfony.com/doc/current/components/event_dispatcher.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -440,7 +440,7 @@ class Finder implements \IteratorAggregate, \Countable
*/
public function sortByName(/* bool $useNaturalSort = false */)
{
if (\func_num_args() < 1 && __CLASS__ !== \get_class($this) && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
if (\func_num_args() < 1 && __CLASS__ !== static::class && __CLASS__ !== (new \ReflectionMethod($this, __FUNCTION__))->getDeclaringClass()->getName() && !$this instanceof \PHPUnit\Framework\MockObject\MockObject && !$this instanceof \Prophecy\Prophecy\ProphecySubjectInterface) {
@trigger_error(sprintf('The "%s()" method will have a new "bool $useNaturalSort = false" argument in version 5.0, not defining it is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$useNaturalSort = 0 < \func_num_args() && func_get_arg(0);
@@ -797,6 +797,10 @@ class Finder implements \IteratorAggregate, \Countable
*/
private function normalizeDir(string $dir): string
{
if ('/' === $dir) {
return $dir;
}
$dir = rtrim($dir, '/'.\DIRECTORY_SEPARATOR);
if (preg_match('#^(ssh2\.)?s?ftp://#', $dir)) {

View File

@@ -70,7 +70,11 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
}
$subPathname .= $this->getFilename();
return new SplFileInfo($this->rootPath.$this->directorySeparator.$subPathname, $this->subPath, $subPathname);
if ('/' !== $basePath = $this->rootPath) {
$basePath .= $this->directorySeparator;
}
return new SplFileInfo($basePath.$subPathname, $this->subPath, $subPathname);
}
/**

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -11,6 +11,9 @@
namespace Symfony\Component\HttpFoundation;
// Help opcache.preload discover always-needed symbols
class_exists(AcceptHeaderItem::class);
/**
* Represents an Accept-* header.
*

View File

@@ -217,7 +217,7 @@ class BinaryFileResponse extends Response
}
if ('x-accel-redirect' === strtolower($type)) {
// Do X-Accel-Mapping substitutions.
// @link http://wiki.nginx.org/X-accel#X-Accel-Redirect
// @link https://www.nginx.com/resources/wiki/start/topics/examples/x-accel/#x-accel-redirect
$parts = HeaderUtils::split($request->headers->get('X-Accel-Mapping', ''), ',=');
foreach ($parts as $part) {
list($pathPrefix, $location) = $part;

View File

@@ -91,7 +91,7 @@ class File extends \SplFileInfo
$renamed = rename($this->getPathname(), $target);
restore_error_handler();
if (!$renamed) {
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
}
@chmod($target, 0666 & ~umask());
@@ -106,10 +106,10 @@ class File extends \SplFileInfo
{
if (!is_dir($directory)) {
if (false === @mkdir($directory, 0777, true) && !is_dir($directory)) {
throw new FileException(sprintf('Unable to create the "%s" directory', $directory));
throw new FileException(sprintf('Unable to create the "%s" directory.', $directory));
}
} elseif (!is_writable($directory)) {
throw new FileException(sprintf('Unable to write in the "%s" directory', $directory));
throw new FileException(sprintf('Unable to write in the "%s" directory.', $directory));
}
$target = rtrim($directory, '/\\').\DIRECTORY_SEPARATOR.(null === $name ? $this->getBasename() : $this->getName($name));

View File

@@ -130,7 +130,7 @@ class MimeTypeGuesser implements MimeTypeGuesserInterface
}
if (2 === \count($this->guessers) && !FileBinaryMimeTypeGuesser::isSupported() && !FileinfoMimeTypeGuesser::isSupported()) {
throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?)');
throw new \LogicException('Unable to guess the mime type as no guessers are available (Did you enable the php_fileinfo extension?).');
}
return null;

View File

@@ -208,7 +208,7 @@ class UploadedFile extends File
$moved = move_uploaded_file($this->getPathname(), $target);
restore_error_handler();
if (!$moved) {
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s)', $this->getPathname(), $target, strip_tags($error)));
throw new FileException(sprintf('Could not move the file "%s" to "%s" (%s).', $this->getPathname(), $target, strip_tags($error)));
}
@chmod($target, 0666 & ~umask());

View File

@@ -219,7 +219,7 @@ class HeaderBag implements \IteratorAggregate, \Countable
}
if (false === $date = \DateTime::createFromFormat(DATE_RFC2822, $value)) {
throw new \RuntimeException(sprintf('The %s HTTP header is not parseable (%s).', $key, $value));
throw new \RuntimeException(sprintf('The "%s" HTTP header is not parseable (%s).', $key, $value));
}
return $date;

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -7,7 +7,7 @@ specification.
Resources
---------
* [Documentation](https://symfony.com/doc/current/components/http_foundation/index.html)
* [Documentation](https://symfony.com/doc/current/components/http_foundation.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)

View File

@@ -47,7 +47,7 @@ class RedirectResponse extends Response
throw new \InvalidArgumentException(sprintf('The HTTP status code is not a redirect ("%s" given).', $status));
}
if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, \CASE_LOWER))) {
if (301 == $status && !\array_key_exists('cache-control', array_change_key_case($headers, CASE_LOWER))) {
$this->headers->remove('cache-control');
}
}

View File

@@ -15,6 +15,14 @@ use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
// Help opcache.preload discover always-needed symbols
class_exists(AcceptHeader::class);
class_exists(FileBag::class);
class_exists(HeaderBag::class);
class_exists(HeaderUtils::class);
class_exists(ParameterBag::class);
class_exists(ServerBag::class);
/**
* Request represents an HTTP request.
*
@@ -725,7 +733,7 @@ class Request
if (null === $session) {
@trigger_error(sprintf('Calling "%s()" when no session has been set is deprecated since Symfony 4.1 and will throw an exception in 5.0. Use "hasSession()" instead.', __METHOD__), E_USER_DEPRECATED);
// throw new \BadMethodCallException('Session has not been set');
// throw new \BadMethodCallException('Session has not been set.');
}
return $session;
@@ -1582,24 +1590,23 @@ class Request
* Gets the preferred format for the response by inspecting, in the following order:
* * the request format set using setRequestFormat
* * the values of the Accept HTTP header
* * the content type of the body of the request.
*
* Note that if you use this method, you should send the "Vary: Accept" header
* in the response to prevent any issues with intermediary HTTP caches.
*/
public function getPreferredFormat(?string $default = 'html'): ?string
{
if (null !== $this->preferredFormat) {
if (null !== $this->preferredFormat || null !== $this->preferredFormat = $this->getRequestFormat(null)) {
return $this->preferredFormat;
}
$preferredFormat = null;
foreach ($this->getAcceptableContentTypes() as $contentType) {
if ($preferredFormat = $this->getFormat($contentType)) {
break;
foreach ($this->getAcceptableContentTypes() as $mimeType) {
if ($this->preferredFormat = $this->getFormat($mimeType)) {
return $this->preferredFormat;
}
}
$this->preferredFormat = $this->getRequestFormat($preferredFormat ?: $this->getContentType());
return $this->preferredFormat ?: $default;
return $default;
}
/**

View File

@@ -11,6 +11,9 @@
namespace Symfony\Component\HttpFoundation;
// Help opcache.preload discover always-needed symbols
class_exists(ResponseHeaderBag::class);
/**
* Response represents an HTTP response.
*
@@ -267,10 +270,12 @@ class Response
$this->setContent(null);
$headers->remove('Content-Type');
$headers->remove('Content-Length');
// prevent PHP from sending the Content-Type header based on default_mimetype
ini_set('default_mimetype', '');
} else {
// Content-type based on the Request
if (!$headers->has('Content-Type')) {
$format = $request->getPreferredFormat();
$format = $request->getRequestFormat(null);
if (null !== $format && $mimeType = $request->getMimeType($format)) {
$headers->set('Content-Type', $mimeType);
}
@@ -628,7 +633,7 @@ class Response
}
/**
* Returns true if the response must be revalidated by caches.
* Returns true if the response must be revalidated by shared caches once it has become stale.
*
* This method indicates that the response must not be served stale by a
* cache in any circumstance without first revalidating with the origin.

View File

@@ -252,10 +252,13 @@ class ResponseHeaderBag extends HeaderBag
* @param string $domain
* @param bool $secure
* @param bool $httpOnly
* @param string $sameSite
*/
public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true)
public function clearCookie($name, $path = '/', $domain = null, $secure = false, $httpOnly = true/*, $sameSite = null*/)
{
$this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly, false, null));
$sameSite = \func_num_args() > 5 ? func_get_arg(5) : null;
$this->setCookie(new Cookie($name, null, 1, $path, $domain, $secure, $httpOnly, false, $sameSite));
}
/**
@@ -276,13 +279,13 @@ class ResponseHeaderBag extends HeaderBag
*/
protected function computeCacheControlValue()
{
if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
return 'no-cache, private';
}
if (!$this->cacheControl) {
if ($this->has('Last-Modified') || $this->has('Expires')) {
return 'private, must-revalidate'; // allows for heuristic expiration (RFC 7234 Section 4.2.2) in the case of "Last-Modified"
}
// conservative by default
return 'private, must-revalidate';
return 'no-cache, private';
}
$header = $this->getCacheControlHeader();

View File

@@ -18,6 +18,11 @@ use Symfony\Component\HttpFoundation\Session\Flash\FlashBagInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpFoundation\Session\Storage\SessionStorageInterface;
// Help opcache.preload discover always-needed symbols
class_exists(AttributeBag::class);
class_exists(FlashBag::class);
class_exists(SessionBagProxy::class);
/**
* @author Fabien Potencier <fabien@symfony.com>
* @author Drak <drak@zikula.org>

View File

@@ -71,6 +71,15 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess
$this->prefetchData = $this->read($sessionId);
$this->prefetchId = $sessionId;
if (\PHP_VERSION_ID < 70317 || (70400 <= \PHP_VERSION_ID && \PHP_VERSION_ID < 70405)) {
// work around https://bugs.php.net/79413
foreach (debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS) as $frame) {
if (!isset($frame['class']) && isset($frame['function']) && \in_array($frame['function'], ['session_regenerate_id', 'session_create_id'], true)) {
return '' === $this->prefetchData;
}
}
}
return '' !== $this->prefetchData;
}
@@ -121,7 +130,7 @@ abstract class AbstractSessionHandler implements \SessionHandlerInterface, \Sess
{
if (!headers_sent() && filter_var(ini_get('session.use_cookies'), FILTER_VALIDATE_BOOLEAN)) {
if (!$this->sessionName) {
throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', \get_class($this)));
throw new \LogicException(sprintf('Session name cannot be empty, did you forget to call "parent::open()" in "%s"?.', static::class));
}
$cookie = SessionUtils::popSessionCookie($this->sessionName, $sessionId);

View File

@@ -47,7 +47,7 @@ class MemcachedSessionHandler extends AbstractSessionHandler
$this->memcached = $memcached;
if ($diff = array_diff(array_keys($options), ['prefix', 'expiretime'])) {
throw new \InvalidArgumentException(sprintf('The following options are not supported "%s"', implode(', ', $diff)));
throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff)));
}
$this->ttl = isset($options['expiretime']) ? (int) $options['expiretime'] : 86400;

View File

@@ -66,7 +66,7 @@ class MongoDbSessionHandler extends AbstractSessionHandler
public function __construct(\MongoDB\Client $mongo, array $options)
{
if (!isset($options['database']) || !isset($options['collection'])) {
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler');
throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
}
$this->mongo = $mongo;

View File

@@ -38,7 +38,7 @@ class NativeFileSessionHandler extends \SessionHandler
if ($count = substr_count($savePath, ';')) {
if ($count > 2) {
throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'', $savePath));
throw new \InvalidArgumentException(sprintf('Invalid argument $savePath \'%s\'.', $savePath));
}
// characters after last ';' are the path
@@ -46,7 +46,7 @@ class NativeFileSessionHandler extends \SessionHandler
}
if ($baseDir && !is_dir($baseDir) && !@mkdir($baseDir, 0777, true) && !is_dir($baseDir)) {
throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $baseDir));
throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s".', $baseDir));
}
ini_set('session.save_path', $savePath);

View File

@@ -174,7 +174,7 @@ class PdoSessionHandler extends AbstractSessionHandler
{
if ($pdoOrDsn instanceof \PDO) {
if (\PDO::ERRMODE_EXCEPTION !== $pdoOrDsn->getAttribute(\PDO::ATTR_ERRMODE)) {
throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION))', __CLASS__));
throw new \InvalidArgumentException(sprintf('"%s" requires PDO error mode attribute be set to throw Exceptions (i.e. $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)).', __CLASS__));
}
$this->pdo = $pdoOrDsn;
@@ -219,7 +219,7 @@ class PdoSessionHandler extends AbstractSessionHandler
// - trailing space removal
// - case-insensitivity
// - language processing like é == e
$sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8_bin, ENGINE = InnoDB";
$sql = "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB";
break;
case 'sqlite':
$sql = "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)";
@@ -468,7 +468,7 @@ class PdoSessionHandler extends AbstractSessionHandler
}
if (!isset($params['scheme'])) {
throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler');
throw new \InvalidArgumentException('URLs without scheme are not supported to configure the PdoSessionHandler.');
}
$driverAliasMap = [
@@ -871,10 +871,10 @@ class PdoSessionHandler extends AbstractSessionHandler
$mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB);
$mergeStmt->bindValue(4, time() + $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(4, time(), \PDO::PARAM_INT);
$mergeStmt->bindParam(5, $data, \PDO::PARAM_LOB);
$mergeStmt->bindValue(6, time() + $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(6, time(), \PDO::PARAM_INT);
$mergeStmt->bindValue(5, time(), \PDO::PARAM_INT);
$mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB);
$mergeStmt->bindValue(7, time() + $maxlifetime, \PDO::PARAM_INT);
$mergeStmt->bindValue(8, time(), \PDO::PARAM_INT);
} else {
$mergeStmt->bindParam(':id', $sessionId, \PDO::PARAM_STR);
$mergeStmt->bindParam(':data', $data, \PDO::PARAM_LOB);

View File

@@ -54,16 +54,16 @@ class RedisSessionHandler extends AbstractSessionHandler
!$redis instanceof RedisProxy &&
!$redis instanceof RedisClusterProxy
) {
throw new \InvalidArgumentException(sprintf('%s() expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, %s given', __METHOD__, \is_object($redis) ? \get_class($redis) : \gettype($redis)));
throw new \InvalidArgumentException(sprintf('"%s()" expects parameter 1 to be Redis, RedisArray, RedisCluster or Predis\ClientInterface, "%s" given.', __METHOD__, \is_object($redis) ? \get_class($redis) : \gettype($redis)));
}
if ($diff = array_diff(array_keys($options), ['prefix', 'ttl'])) {
throw new \InvalidArgumentException(sprintf('The following options are not supported "%s"', implode(', ', $diff)));
throw new \InvalidArgumentException(sprintf('The following options are not supported "%s".', implode(', ', $diff)));
}
$this->redis = $redis;
$this->prefix = $options['prefix'] ?? 'sf_s';
$this->ttl = $options['ttl'] ?? (int) ini_get('session.gc_maxlifetime');
$this->ttl = $options['ttl'] ?? null;
}
/**
@@ -79,7 +79,7 @@ class RedisSessionHandler extends AbstractSessionHandler
*/
protected function doWrite($sessionId, $data): bool
{
$result = $this->redis->setEx($this->prefix.$sessionId, $this->ttl, $data);
$result = $this->redis->setEx($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')), $data);
return $result && !$result instanceof ErrorInterface;
}
@@ -115,6 +115,6 @@ class RedisSessionHandler extends AbstractSessionHandler
*/
public function updateTimestamp($sessionId, $data)
{
return (bool) $this->redis->expire($this->prefix.$sessionId, $this->ttl);
return (bool) $this->redis->expire($this->prefix.$sessionId, (int) ($this->ttl ?? ini_get('session.gc_maxlifetime')));
}
}

View File

@@ -27,7 +27,7 @@ class SessionHandlerFactory
public static function createHandler($connection): AbstractSessionHandler
{
if (!\is_string($connection) && !\is_object($connection)) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be a string or a connection object, %s given.', __METHOD__, \gettype($connection)));
throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be a string or a connection object, "%s" given.', __METHOD__, \gettype($connection)));
}
switch (true) {
@@ -46,17 +46,17 @@ class SessionHandlerFactory
return new PdoSessionHandler($connection);
case !\is_string($connection):
throw new \InvalidArgumentException(sprintf('Unsupported Connection: %s.', \get_class($connection)));
throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', \get_class($connection)));
case 0 === strpos($connection, 'file://'):
return new StrictSessionHandler(new NativeFileSessionHandler(substr($connection, 7)));
case 0 === strpos($connection, 'redis://'):
case 0 === strpos($connection, 'rediss://'):
case 0 === strpos($connection, 'memcached://'):
case 0 === strpos($connection, 'redis:'):
case 0 === strpos($connection, 'rediss:'):
case 0 === strpos($connection, 'memcached:'):
if (!class_exists(AbstractAdapter::class)) {
throw new InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection));
throw new \InvalidArgumentException(sprintf('Unsupported DSN "%s". Try running "composer require symfony/cache".', $connection));
}
$handlerClass = 0 === strpos($connection, 'memcached://') ? MemcachedSessionHandler::class : RedisSessionHandler::class;
$handlerClass = 0 === strpos($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class;
$connection = AbstractAdapter::createConnection($connection, ['lazy' => true]);
return new $handlerClass($connection);
@@ -80,6 +80,6 @@ class SessionHandlerFactory
return new PdoSessionHandler($connection);
}
throw new \InvalidArgumentException(sprintf('Unsupported Connection: %s.', $connection));
throw new \InvalidArgumentException(sprintf('Unsupported Connection: "%s".', $connection));
}
}

View File

@@ -148,7 +148,7 @@ class MockArraySessionStorage implements SessionStorageInterface
public function save()
{
if (!$this->started || $this->closed) {
throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
throw new \RuntimeException('Trying to save a session that was not started yet or was already closed.');
}
// nothing to do since we don't persist the session data
$this->closed = false;
@@ -186,7 +186,7 @@ class MockArraySessionStorage implements SessionStorageInterface
public function getBag($name)
{
if (!isset($this->bags[$name])) {
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name));
}
if (!$this->started) {

View File

@@ -37,7 +37,7 @@ class MockFileSessionStorage extends MockArraySessionStorage
}
if (!is_dir($savePath) && !@mkdir($savePath, 0777, true) && !is_dir($savePath)) {
throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s"', $savePath));
throw new \RuntimeException(sprintf('Session Storage was not able to create directory "%s".', $savePath));
}
$this->savePath = $savePath;
@@ -87,7 +87,7 @@ class MockFileSessionStorage extends MockArraySessionStorage
public function save()
{
if (!$this->started) {
throw new \RuntimeException('Trying to save a session that was not started yet or was already closed');
throw new \RuntimeException('Trying to save a session that was not started yet or was already closed.');
}
$data = $this->data;

View File

@@ -17,6 +17,11 @@ use Symfony\Component\HttpFoundation\Session\Storage\Handler\StrictSessionHandle
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy;
use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy;
// Help opcache.preload discover always-needed symbols
class_exists(MetadataBag::class);
class_exists(StrictSessionHandler::class);
class_exists(SessionHandlerProxy::class);
/**
* This provides a base class for session attribute storage.
*
@@ -139,7 +144,7 @@ class NativeSessionStorage implements SessionStorageInterface
return true;
}
if (\PHP_SESSION_ACTIVE === session_status()) {
if (PHP_SESSION_ACTIVE === session_status()) {
throw new \RuntimeException('Failed to start the session: already started by PHP.');
}
@@ -149,7 +154,7 @@ class NativeSessionStorage implements SessionStorageInterface
// ok to try and start the session
if (!session_start()) {
throw new \RuntimeException('Failed to start the session');
throw new \RuntimeException('Failed to start the session.');
}
if (null !== $this->emulateSameSite) {
@@ -202,7 +207,7 @@ class NativeSessionStorage implements SessionStorageInterface
public function regenerate($destroy = false, $lifetime = null)
{
// Cannot regenerate the session ID for non-active sessions.
if (\PHP_SESSION_ACTIVE !== session_status()) {
if (PHP_SESSION_ACTIVE !== session_status()) {
return false;
}
@@ -210,8 +215,10 @@ class NativeSessionStorage implements SessionStorageInterface
return false;
}
if (null !== $lifetime) {
if (null !== $lifetime && $lifetime != ini_get('session.cookie_lifetime')) {
$this->save();
ini_set('session.cookie_lifetime', $lifetime);
$this->start();
}
if ($destroy) {
@@ -220,10 +227,6 @@ class NativeSessionStorage implements SessionStorageInterface
$isRegenerated = session_regenerate_id($destroy);
// The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it.
// @see https://bugs.php.net/70013
$this->loadSession();
if (null !== $this->emulateSameSite) {
$originalCookie = SessionUtils::popSessionCookie(session_name(), session_id());
if (null !== $originalCookie) {
@@ -311,7 +314,7 @@ class NativeSessionStorage implements SessionStorageInterface
public function getBag($name)
{
if (!isset($this->bags[$name])) {
throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name));
throw new \InvalidArgumentException(sprintf('The SessionBagInterface "%s" is not registered.', $name));
}
if (!$this->started && $this->saveHandler->isActive()) {
@@ -362,7 +365,7 @@ class NativeSessionStorage implements SessionStorageInterface
*/
public function setOptions(array $options)
{
if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
if (headers_sent() || PHP_SESSION_ACTIVE === session_status()) {
return;
}
@@ -401,13 +404,11 @@ class NativeSessionStorage implements SessionStorageInterface
* ini_set('session.save_path', '/tmp');
*
* or pass in a \SessionHandler instance which configures session.save_handler in the
* constructor, for a template see NativeFileSessionHandler or use handlers in
* composer package drak/native-session
* constructor, for a template see NativeFileSessionHandler.
*
* @see https://php.net/session-set-save-handler
* @see https://php.net/sessionhandlerinterface
* @see https://php.net/sessionhandler
* @see https://github.com/zikula/NativeSession
*
* @param AbstractProxy|\SessionHandlerInterface|null $saveHandler
*
@@ -429,7 +430,7 @@ class NativeSessionStorage implements SessionStorageInterface
}
$this->saveHandler = $saveHandler;
if (headers_sent() || \PHP_SESSION_ACTIVE === session_status()) {
if (headers_sent() || PHP_SESSION_ACTIVE === session_status()) {
return;
}

View File

@@ -65,7 +65,7 @@ abstract class AbstractProxy
*/
public function isActive()
{
return \PHP_SESSION_ACTIVE === session_status();
return PHP_SESSION_ACTIVE === session_status();
}
/**
@@ -88,7 +88,7 @@ abstract class AbstractProxy
public function setId($id)
{
if ($this->isActive()) {
throw new \LogicException('Cannot change the ID of an active session');
throw new \LogicException('Cannot change the ID of an active session.');
}
session_id($id);
@@ -114,7 +114,7 @@ abstract class AbstractProxy
public function setName($name)
{
if ($this->isActive()) {
throw new \LogicException('Cannot change the name of an active session');
throw new \LogicException('Cannot change the name of an active session.');
}
session_name($name);

View File

@@ -1,3 +0,0 @@
/Tests export-ignore
/phpunit.xml.dist export-ignore
/.gitignore export-ignore

View File

@@ -69,7 +69,7 @@ abstract class Bundle implements BundleInterface
if (null !== $extension) {
if (!$extension instanceof ExtensionInterface) {
throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', \get_class($extension)));
throw new \LogicException(sprintf('Extension "%s" must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', \get_class($extension)));
}
// check naming convention

View File

@@ -31,7 +31,7 @@ class Psr6CacheClearer implements CacheClearerInterface
public function getPool($name)
{
if (!$this->hasPool($name)) {
throw new \InvalidArgumentException(sprintf('Cache pool not found: %s.', $name));
throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name));
}
return $this->pools[$name];
@@ -40,7 +40,7 @@ class Psr6CacheClearer implements CacheClearerInterface
public function clearPool($name)
{
if (!isset($this->pools[$name])) {
throw new \InvalidArgumentException(sprintf('Cache pool not found: %s.', $name));
throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name));
}
return $this->pools[$name]->clear();

View File

@@ -65,20 +65,24 @@ class FileLocator extends BaseFileLocator
|| (\strlen($file) > 3 && ctype_alpha($file[0]) && ':' === $file[1] && ('\\' === $file[2] || '/' === $file[2]))
|| null !== parse_url($file, PHP_URL_SCHEME)
)) {
$deprecation = false;
// no need to trigger deprecations when the loaded file is given as absolute path
foreach ($this->paths as $deprecatedPath) {
if (\is_array($locations)) {
foreach ($locations as $location) {
if (0 === strpos($location, $deprecatedPath) && (null === $currentPath || false === strpos($location, $currentPath))) {
@trigger_error(sprintf('Loading the file "%s" from the global resource directory "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $file, $deprecatedPath), E_USER_DEPRECATED);
}
foreach ((array) $locations as $location) {
if (null !== $currentPath && 0 === strpos($location, $currentPath)) {
return $locations;
}
} else {
if (0 === strpos($locations, $deprecatedPath) && (null === $currentPath || false === strpos($locations, $currentPath))) {
@trigger_error(sprintf('Loading the file "%s" from the global resource directory "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $file, $deprecatedPath), E_USER_DEPRECATED);
if (0 === strpos($location, $deprecatedPath) && (null === $currentPath || false === strpos($location, $currentPath))) {
$deprecation = sprintf('Loading the file "%s" from the global resource directory "%s" is deprecated since Symfony 4.4 and will be removed in 5.0.', $file, $deprecatedPath);
}
}
}
if ($deprecation) {
@trigger_error($deprecation, E_USER_DEPRECATED);
}
}
return $locations;

View File

@@ -62,7 +62,7 @@ final class ArgumentResolver implements ArgumentResolverInterface
}
if (!$atLeastOne) {
throw new \InvalidArgumentException(sprintf('%s::resolve() must yield at least one value.', \get_class($resolver)));
throw new \InvalidArgumentException(sprintf('"%s::resolve()" must yield at least one value.', \get_class($resolver)));
}
// continue to the next controller argument

View File

@@ -64,7 +64,7 @@ class ContainerControllerResolver extends ControllerResolver
throw new \InvalidArgumentException(sprintf('Controller "%s" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?', $class), 0, $e);
}
throw new \InvalidArgumentException(sprintf('Controller "%s" does neither exist as service nor as class', $class), 0, $e);
throw new \InvalidArgumentException(sprintf('Controller "%s" does neither exist as service nor as class.', $class), 0, $e);
}
private function throwExceptionIfControllerWasRemoved(string $controller, \Throwable $previous)

View File

@@ -64,7 +64,7 @@ class ControllerResolver implements ControllerResolverInterface
}
if (!\is_callable($controller)) {
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $this->getControllerError($controller)));
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($controller), $request->getPathInfo()));
}
return $controller;
@@ -72,7 +72,7 @@ class ControllerResolver implements ControllerResolverInterface
if (\is_object($controller)) {
if (!\is_callable($controller)) {
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $this->getControllerError($controller)));
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($controller), $request->getPathInfo()));
}
return $controller;
@@ -85,11 +85,11 @@ class ControllerResolver implements ControllerResolverInterface
try {
$callable = $this->createController($controller);
} catch (\InvalidArgumentException $e) {
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $e->getMessage()));
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$e->getMessage(), $request->getPathInfo()), 0, $e);
}
if (!\is_callable($callable)) {
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable. %s', $request->getPathInfo(), $this->getControllerError($callable)));
throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: '.$this->getControllerError($callable), $request->getPathInfo()));
}
return $callable;

View File

@@ -99,7 +99,7 @@ class ArgumentMetadata
public function getDefaultValue()
{
if (!$this->hasDefaultValue) {
throw new \LogicException(sprintf('Argument $%s does not have a default value. Use %s::hasDefaultValue() to avoid this exception.', $this->name, __CLASS__));
throw new \LogicException(sprintf('Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.', $this->name, __CLASS__));
}
return $this->defaultValue;

View File

@@ -198,7 +198,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$dumper = new HtmlDumper($data, $this->charset);
$dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]);
} else {
throw new \InvalidArgumentException(sprintf('Invalid dump format: %s', $format));
throw new \InvalidArgumentException(sprintf('Invalid dump format: "%s".', $format));
}
$dumps = [];

View File

@@ -179,7 +179,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
continue;
}
$message = $log['message'];
$message = '_'.$log['message'];
$exception = $log['context']['exception'];
if ($exception instanceof SilencedErrorContext) {

View File

@@ -15,6 +15,7 @@ use Psr\Log\LoggerInterface;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\Console\Event\ConsoleEvent;
use Symfony\Component\Console\Output\ConsoleOutputInterface;
use Symfony\Component\Debug\ErrorHandler as LegacyErrorHandler;
use Symfony\Component\Debug\Exception\FatalThrowableError;
use Symfony\Component\ErrorHandler\ErrorHandler;
use Symfony\Component\EventDispatcher\Event;
@@ -66,6 +67,9 @@ class DebugHandlersListener implements EventSubscriberInterface
*/
public function configure(Event $event = null)
{
if ($event instanceof ConsoleEvent && !\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true)) {
return;
}
if (!$event instanceof KernelEvent ? !$this->firstCall : !$event->isMasterRequest()) {
return;
}
@@ -76,7 +80,7 @@ class DebugHandlersListener implements EventSubscriberInterface
restore_exception_handler();
if ($this->logger || null !== $this->throwAt) {
if ($handler instanceof ErrorHandler) {
if ($handler instanceof ErrorHandler || $handler instanceof LegacyErrorHandler) {
if ($this->logger) {
$handler->setDefaultLogger($this->logger, $this->levels);
if (\is_array($this->levels)) {
@@ -135,7 +139,7 @@ class DebugHandlersListener implements EventSubscriberInterface
}
}
if ($this->exceptionHandler) {
if ($handler instanceof ErrorHandler) {
if ($handler instanceof ErrorHandler || $handler instanceof LegacyErrorHandler) {
$handler->setExceptionHandler($this->exceptionHandler);
}
$this->exceptionHandler = null;
@@ -146,7 +150,7 @@ class DebugHandlersListener implements EventSubscriberInterface
{
$events = [KernelEvents::REQUEST => ['configure', 2048]];
if ('cli' === \PHP_SAPI && \defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) {
if (\defined('Symfony\Component\Console\ConsoleEvents::COMMAND')) {
$events[ConsoleEvents::COMMAND] = ['configure', 2048];
}

View File

@@ -40,7 +40,7 @@ class TranslatorListener implements EventSubscriberInterface
public function __construct($translator, RequestStack $requestStack)
{
if (!$translator instanceof TranslatorInterface && !$translator instanceof LocaleAwareInterface) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, LocaleAwareInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be an instance of "%s", "%s" given.', __METHOD__, LocaleAwareInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
}
$this->translator = $translator;
$this->requestStack = $requestStack;

View File

@@ -98,7 +98,7 @@ class FragmentHandler
protected function deliver(Response $response)
{
if (!$response->isSuccessful()) {
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $this->requestStack->getCurrentRequest()->getUri(), $response->getStatusCode()));
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $this->requestStack->getCurrentRequest()->getUri(), $response->getStatusCode()));
}
if (!$response instanceof StreamedResponse) {

View File

@@ -57,7 +57,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
public function setTemplating($templating)
{
if (null !== $templating && !$templating instanceof EngineInterface && !$templating instanceof Environment) {
throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of Twig\Environment or Symfony\Component\Templating\EngineInterface');
throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of Twig\Environment or Symfony\Component\Templating\EngineInterface.');
}
if ($templating instanceof EngineInterface) {

View File

@@ -96,7 +96,7 @@ abstract class AbstractSurrogate implements SurrogateInterface
$response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true);
if (!$response->isSuccessful()) {
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %s).', $subRequest->getUri(), $response->getStatusCode()));
throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $subRequest->getUri(), $response->getStatusCode()));
}
return $response->getContent();

View File

@@ -350,6 +350,10 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
return $this->validate($request, $entry, $catch);
}
if ($entry->headers->hasCacheControlDirective('no-cache')) {
return $this->validate($request, $entry, $catch);
}
$this->record($request, 'fresh');
$entry->headers->set('Age', $entry->getAge());
@@ -472,13 +476,37 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
// always a "master" request (as the real master request can be in cache)
$response = SubRequestHandler::handle($this->kernel, $request, HttpKernelInterface::MASTER_REQUEST, $catch);
// we don't implement the stale-if-error on Requests, which is nonetheless part of the RFC
if (null !== $entry && \in_array($response->getStatusCode(), [500, 502, 503, 504])) {
/*
* Support stale-if-error given on Responses or as a config option.
* RFC 7234 summarizes in Section 4.2.4 (but also mentions with the individual
* Cache-Control directives) that
*
* A cache MUST NOT generate a stale response if it is prohibited by an
* explicit in-protocol directive (e.g., by a "no-store" or "no-cache"
* cache directive, a "must-revalidate" cache-response-directive, or an
* applicable "s-maxage" or "proxy-revalidate" cache-response-directive;
* see Section 5.2.2).
*
* https://tools.ietf.org/html/rfc7234#section-4.2.4
*
* We deviate from this in one detail, namely that we *do* serve entries in the
* stale-if-error case even if they have a `s-maxage` Cache-Control directive.
*/
if (null !== $entry
&& \in_array($response->getStatusCode(), [500, 502, 503, 504])
&& !$entry->headers->hasCacheControlDirective('no-cache')
&& !$entry->mustRevalidate()
) {
if (null === $age = $entry->headers->getCacheControlDirective('stale-if-error')) {
$age = $this->options['stale_if_error'];
}
if (abs($entry->getTtl()) < $age) {
/*
* stale-if-error gives the (extra) time that the Response may be used *after* it has become stale.
* So we compare the time the $entry has been sitting in the cache already with the
* time it was fresh plus the allowed grace period.
*/
if ($entry->getAge() <= $entry->getMaxAge() + $age) {
$this->record($request, 'stale-if-error');
return $entry;

View File

@@ -110,8 +110,6 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
$response->headers->set('Age', $this->age);
if ($this->isNotCacheableResponseEmbedded) {
$response->setExpires($response->getDate());
if ($this->flagDirectives['no-store']) {
$response->headers->set('Cache-Control', 'no-cache, no-store, must-revalidate');
} else {

View File

@@ -21,6 +21,9 @@ use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Component\Mime\Part\TextPart;
use Symfony\Contracts\HttpClient\HttpClientInterface;
// Help opcache.preload discover always-needed symbols
class_exists(ResponseHeaderBag::class);
/**
* An implementation of a Symfony HTTP kernel using a "real" HTTP client.
*

View File

@@ -33,6 +33,18 @@ use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
// Help opcache.preload discover always-needed symbols
class_exists(LegacyEventDispatcherProxy::class);
class_exists(ControllerArgumentsEvent::class);
class_exists(ControllerEvent::class);
class_exists(ExceptionEvent::class);
class_exists(FinishRequestEvent::class);
class_exists(RequestEvent::class);
class_exists(ResponseEvent::class);
class_exists(TerminateEvent::class);
class_exists(ViewEvent::class);
class_exists(KernelEvents::class);
/**
* HttpKernel notifies events to convert a Request object to a Response one.
*

View File

@@ -76,11 +76,11 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private static $freshCache = [];
const VERSION = '4.4.1';
const VERSION_ID = 40401;
const VERSION = '4.4.8';
const VERSION_ID = 40408;
const MAJOR_VERSION = 4;
const MINOR_VERSION = 4;
const RELEASE_VERSION = 1;
const RELEASE_VERSION = 8;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '11/2022';
@@ -228,10 +228,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
public function getBundle($name)
{
if (!isset($this->bundles[$name])) {
$class = \get_class($this);
$class = static::class;
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, $class));
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, $class));
}
return $this->bundles[$name];
@@ -449,7 +449,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
foreach ($this->registerBundles() as $bundle) {
$name = $bundle->getName();
if (isset($this->bundles[$name])) {
throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s"', $name));
throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s".', $name));
}
$this->bundles[$name] = $bundle;
}
@@ -473,7 +473,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
protected function getContainerClass()
{
$class = \get_class($this);
$class = static::class;
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).str_replace('.', '_', ContainerBuilder::hash($class)) : $class;
$class = $this->name.str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container';
@@ -510,7 +510,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
$cachePath = $cache->getPath();
// Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors
$errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
$errorLevel = error_reporting(E_ALL ^ E_WARNING);
try {
if (file_exists($cachePath) && \is_object($this->container = include $cachePath)
@@ -530,47 +530,20 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
try {
is_dir($cacheDir) ?: mkdir($cacheDir, 0777, true);
if ($lock = fopen($cachePath, 'w')) {
chmod($cachePath, 0666 & ~umask());
if ($lock = fopen($cachePath.'.lock', 'w')) {
flock($lock, LOCK_EX | LOCK_NB, $wouldBlock);
if (!flock($lock, $wouldBlock ? LOCK_SH : LOCK_EX)) {
fclose($lock);
} else {
$cache = new class($cachePath, $this->debug) extends ConfigCache {
public $lock;
$lock = null;
} elseif (!\is_object($this->container = include $cachePath)) {
$this->container = null;
} elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
flock($lock, LOCK_UN);
fclose($lock);
$this->container->set('kernel', $this);
public function write($content, array $metadata = null)
{
rewind($this->lock);
ftruncate($this->lock, 0);
fwrite($this->lock, $content);
if (null !== $metadata) {
file_put_contents($this->getPath().'.meta', serialize($metadata));
@chmod($this->getPath().'.meta', 0666 & ~umask());
}
if (\function_exists('opcache_invalidate') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN)) {
opcache_invalidate($this->getPath(), true);
}
}
public function __destruct()
{
flock($this->lock, LOCK_UN);
fclose($this->lock);
}
};
$cache->lock = $lock;
if (!\is_object($this->container = include $cachePath)) {
$this->container = null;
} elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
$this->container->set('kernel', $this);
return;
}
return;
}
}
} catch (\Throwable $e) {
@@ -634,7 +607,12 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
}
$this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
unset($cache);
if ($lock) {
flock($lock, LOCK_UN);
fclose($lock);
}
$this->container = require $cachePath;
$this->container->set('kernel', $this);
@@ -710,10 +688,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
foreach (['cache' => $this->warmupDir ?: $this->getCacheDir(), 'logs' => $this->getLogDir()] as $name => $dir) {
if (!is_dir($dir)) {
if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf("Unable to create the %s directory (%s)\n", $name, $dir));
throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir));
}
} elseif (!is_writable($dir)) {
throw new \RuntimeException(sprintf("Unable to write in the %s directory (%s)\n", $name, $dir));
throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir));
}
}
@@ -802,6 +780,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
'as_files' => true,
'debug' => $this->debug,
'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(),
'preload_classes' => array_map('get_class', $this->bundles),
]);
$rootCode = array_pop($content);

View File

@@ -1,4 +1,4 @@
Copyright (c) 2004-2019 Fabien Potencier
Copyright (c) 2004-2020 Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -79,7 +79,7 @@ class Logger extends AbstractLogger
}
$formatter = $this->formatter;
fwrite($this->handle, $formatter($level, $message, $context));
@fwrite($this->handle, $formatter($level, $message, $context));
}
private function format(string $level, string $message, array $context): string
@@ -101,6 +101,6 @@ class Logger extends AbstractLogger
$message = strtr($message, $replacements);
}
return sprintf('%s [%s] %s', date(\DateTime::RFC3339), $level, $message).\PHP_EOL;
return sprintf('%s [%s] %s', date(\DateTime::RFC3339), $level, $message).PHP_EOL;
}
}

Some files were not shown because too many files have changed in this diff Show More