composer update

This commit is contained in:
2019-06-23 10:14:30 +00:00
parent a56db5ea2b
commit ec4506ebf4
790 changed files with 35767 additions and 7663 deletions

View File

@@ -1,6 +1,31 @@
CHANGELOG
=========
4.3.0
-----
* renamed `Client` to `HttpKernelBrowser`
* `KernelInterface` doesn't extend `Serializable` anymore
* deprecated the `Kernel::serialize()` and `unserialize()` methods
* increased the priority of `Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener`
* made `Symfony\Component\HttpKernel\EventListener\LocaleListener` set the default locale early
* deprecated `TranslatorListener` in favor of `LocaleAwareListener`
* added the registration of all `LocaleAwareInterface` implementations into the `LocaleAwareListener`
* made `FileLinkFormatter` final and not implement `Serializable` anymore
* the base `DataCollector` doesn't implement `Serializable` anymore, you should
store all the serialized state in the data property instead
* `DumpDataCollector` has been marked as `final`
* added an event listener to prevent search engines from indexing applications in debug mode.
* renamed `FilterControllerArgumentsEvent` to `ControllerArgumentsEvent`
* renamed `FilterControllerEvent` to `ControllerEvent`
* renamed `FilterResponseEvent` to `ResponseEvent`
* renamed `GetResponseEvent` to `RequestEvent`
* renamed `GetResponseForControllerResultEvent` to `ViewEvent`
* renamed `GetResponseForExceptionEvent` to `ExceptionEvent`
* renamed `PostResponseEvent` to `TerminateEvent`
* added `HttpClientKernel` for handling requests with an `HttpClientInterface` instance
* added `trace_header` and `trace_level` configuration options to `HttpCache`
4.2.0
-----

View File

@@ -11,194 +11,8 @@
namespace Symfony\Component\HttpKernel;
use Symfony\Component\BrowserKit\Client as BaseClient;
use Symfony\Component\BrowserKit\CookieJar;
use Symfony\Component\BrowserKit\History;
use Symfony\Component\BrowserKit\Request as DomRequest;
use Symfony\Component\BrowserKit\Response as DomResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" instead.', Client::class, HttpKernelBrowser::class), E_USER_DEPRECATED);
/**
* Client simulates a browser and makes requests to a Kernel object.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @method Request getRequest() A Request instance
* @method Response getResponse() A Response instance
*/
class Client extends BaseClient
class Client extends HttpKernelBrowser
{
protected $kernel;
private $catchExceptions = true;
/**
* @param HttpKernelInterface $kernel An HttpKernel instance
* @param array $server The server parameters (equivalent of $_SERVER)
* @param History $history A History instance to store the browser history
* @param CookieJar $cookieJar A CookieJar instance to store the cookies
*/
public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null)
{
// These class properties must be set before calling the parent constructor, as it may depend on it.
$this->kernel = $kernel;
$this->followRedirects = false;
parent::__construct($server, $history, $cookieJar);
}
/**
* Sets whether to catch exceptions when the kernel is handling a request.
*
* @param bool $catchExceptions Whether to catch exceptions
*/
public function catchExceptions($catchExceptions)
{
$this->catchExceptions = $catchExceptions;
}
/**
* Makes a request.
*
* @return Response A Response instance
*/
protected function doRequest($request)
{
$response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $this->catchExceptions);
if ($this->kernel instanceof TerminableInterface) {
$this->kernel->terminate($request, $response);
}
return $response;
}
/**
* Returns the script to execute when the request must be insulated.
*
* @return string
*/
protected function getScript($request)
{
$kernel = var_export(serialize($this->kernel), true);
$request = var_export(serialize($request), true);
$errorReporting = error_reporting();
$requires = '';
foreach (get_declared_classes() as $class) {
if (0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$file = \dirname(\dirname($r->getFileName())).'/autoload.php';
if (file_exists($file)) {
$requires .= 'require_once '.var_export($file, true).";\n";
}
}
}
if (!$requires) {
throw new \RuntimeException('Composer autoloader not found.');
}
$code = <<<EOF
<?php
error_reporting($errorReporting);
$requires
\$kernel = unserialize($kernel);
\$request = unserialize($request);
EOF;
return $code.$this->getHandleScript();
}
protected function getHandleScript()
{
return <<<'EOF'
$response = $kernel->handle($request);
if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
$kernel->terminate($request, $response);
}
echo serialize($response);
EOF;
}
/**
* Converts the BrowserKit request to a HttpKernel request.
*
* @return Request A Request instance
*/
protected function filterRequest(DomRequest $request)
{
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
$httpRequest->files->set($key, $value);
}
return $httpRequest;
}
/**
* Filters an array of files.
*
* This method created test instances of UploadedFile so that the move()
* method can be called on those instances.
*
* If the size of a file is greater than the allowed size (from php.ini) then
* an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
*
* @see UploadedFile
*
* @return array An array with all uploaded files marked as already moved
*/
protected function filterFiles(array $files)
{
$filtered = [];
foreach ($files as $key => $value) {
if (\is_array($value)) {
$filtered[$key] = $this->filterFiles($value);
} elseif ($value instanceof UploadedFile) {
if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
$filtered[$key] = new UploadedFile(
'',
$value->getClientOriginalName(),
$value->getClientMimeType(),
UPLOAD_ERR_INI_SIZE,
true
);
} else {
$filtered[$key] = new UploadedFile(
$value->getPathname(),
$value->getClientOriginalName(),
$value->getClientMimeType(),
$value->getError(),
true
);
}
}
}
return $filtered;
}
/**
* Converts the HttpKernel response to a BrowserKit response.
*
* @return DomResponse A DomResponse instance
*/
protected function filterResponse($response)
{
// this is needed to support StreamedResponse
ob_start();
$response->sendContent();
$content = ob_get_clean();
return new DomResponse($content, $response->getStatusCode(), $response->headers->all());
}
}

View File

@@ -0,0 +1,81 @@
<?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\HttpKernel\Controller\ArgumentResolver;
use Psr\Container\ContainerInterface;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentValueResolverInterface;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
/**
* Provides an intuitive error message when controller fails because it is not registered as a service.
*
* @author Simeon Kolev <simeon.kolev9@gmail.com>
*/
final class NotTaggedControllerValueResolver implements ArgumentValueResolverInterface
{
private $container;
public function __construct(ContainerInterface $container)
{
$this->container = $container;
}
/**
* {@inheritdoc}
*/
public function supports(Request $request, ArgumentMetadata $argument)
{
$controller = $request->attributes->get('_controller');
if (\is_array($controller) && \is_callable($controller, true) && \is_string($controller[0])) {
$controller = $controller[0].'::'.$controller[1];
} elseif (!\is_string($controller) || '' === $controller) {
return false;
}
if ('\\' === $controller[0]) {
$controller = ltrim($controller, '\\');
}
if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) {
$controller = substr($controller, 0, $i).strtolower(substr($controller, $i));
}
return false === $this->container->has($controller);
}
/**
* {@inheritdoc}
*/
public function resolve(Request $request, ArgumentMetadata $argument)
{
if (\is_array($controller = $request->attributes->get('_controller'))) {
$controller = $controller[0].'::'.$controller[1];
}
if ('\\' === $controller[0]) {
$controller = ltrim($controller, '\\');
}
if (!$this->container->has($controller)) {
$i = strrpos($controller, ':');
$controller = substr($controller, 0, $i).strtolower(substr($controller, $i));
}
$what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller);
$message = sprintf('Could not resolve %s, maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?', $what);
throw new RuntimeException($message);
}
}

View File

@@ -29,7 +29,7 @@ interface ControllerResolverInterface
* As several resolvers can exist for a single application, a resolver must
* return false when it is not able to determine the controller.
*
* The resolver must only throw an exception when it should be able to load
* The resolver must only throw an exception when it should be able to load a
* controller but cannot because of some errors made by the developer.
*
* @return callable|false A PHP callable representing the Controller,

View File

@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\VarDumper\Caster\CutStub;
use Symfony\Component\VarDumper\Caster\ReflectionCaster;
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
use Symfony\Component\VarDumper\Cloner\Data;
use Symfony\Component\VarDumper\Cloner\Stub;
@@ -25,7 +26,7 @@ use Symfony\Component\VarDumper\Cloner\VarCloner;
* @author Fabien Potencier <fabien@symfony.com>
* @author Bernhard Schussek <bschussek@symfony.com>
*/
abstract class DataCollector implements DataCollectorInterface, \Serializable
abstract class DataCollector implements DataCollectorInterface
{
protected $data = [];
@@ -34,16 +35,26 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
*/
private $cloner;
/**
* @deprecated since Symfony 4.3, store all the serialized state in the data property instead
*/
public function serialize()
{
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3, store all the serialized state in the data property instead.', __METHOD__), E_USER_DEPRECATED);
$trace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT, 2);
$isCalledFromOverridingMethod = isset($trace[1]['function'], $trace[1]['object']) && 'serialize' === $trace[1]['function'] && $this === $trace[1]['object'];
return $isCalledFromOverridingMethod ? $this->data : serialize($this->data);
}
/**
* @deprecated since Symfony 4.3, store all the serialized state in the data property instead
*/
public function unserialize($data)
{
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3, store all the serialized state in the data property instead.', __METHOD__), E_USER_DEPRECATED);
$this->data = \is_array($data) ? $data : unserialize($data);
}
@@ -79,7 +90,7 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
*/
protected function getCasters()
{
return [
$casters = [
'*' => function ($v, array $a, Stub $s, $isNested) {
if (!$v instanceof Stub) {
foreach ($a as $k => $v) {
@@ -92,5 +103,29 @@ abstract class DataCollector implements DataCollectorInterface, \Serializable
return $a;
},
];
if (method_exists(ReflectionCaster::class, 'unsetClosureFileInfo')) {
$casters += ReflectionCaster::UNSET_CLOSURE_FILE_INFO;
}
return $casters;
}
public function __sleep()
{
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3, store all the serialized state in the "data" property instead.', $c), E_USER_DEPRECATED);
$this->data = $this->serialize();
}
return ['data'];
}
public function __wakeup()
{
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'unserialize'))->getDeclaringClass()->name) {
@trigger_error(sprintf('Implementing the "%s::unserialize()" method is deprecated since Symfony 4.3, store all the serialized state in the "data" property instead.', $c), E_USER_DEPRECATED);
$this->unserialize($this->data);
}
}
}

View File

@@ -25,6 +25,8 @@ use Symfony\Component\VarDumper\Server\Connection;
/**
* @author Nicolas Grekas <p@tchwork.com>
*
* @final since Symfony 4.3
*/
class DumpDataCollector extends DataCollector implements DataDumperInterface
{
@@ -85,6 +87,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$this->isCollected = false;
}
if (!$this->dataCount) {
$this->data = [];
}
$this->data[] = compact('data', 'name', 'file', 'line', 'fileExcerpt');
++$this->dataCount;
@@ -95,6 +100,10 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
public function collect(Request $request, Response $response, \Exception $exception = null)
{
if (!$this->dataCount) {
$this->data = [];
}
// Sub-requests and programmatic calls stay in the collected profile.
if ($this->dumper || ($this->requestStack && $this->requestStack->getMasterRequest() !== $request) || $request->isXmlHttpRequest() || $request->headers->has('Origin')) {
return;
@@ -113,6 +122,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]);
} else {
$dumper = new CliDumper('php://output', $this->charset);
if (method_exists($dumper, 'setDisplayOptions')) {
$dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]);
}
}
foreach ($this->data as $dump) {
@@ -133,28 +145,38 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$this->clonesIndex = 0;
}
public function serialize()
/**
* @internal
*/
public function __sleep()
{
if (!$this->dataCount) {
$this->data = [];
}
if ($this->clonesCount !== $this->clonesIndex) {
return 'a:0:{}';
return [];
}
$this->data[] = $this->fileLinkFormat;
$this->data[] = $this->charset;
$ser = serialize($this->data);
$this->data = [];
$this->dataCount = 0;
$this->isCollected = true;
return $ser;
return parent::__sleep();
}
public function unserialize($data)
/**
* @internal
*/
public function __wakeup()
{
$this->data = unserialize($data);
parent::__wakeup();
$charset = array_pop($this->data);
$fileLinkFormat = array_pop($this->data);
$this->dataCount = \count($this->data);
self::__construct($this->stopwatch, $fileLinkFormat, $charset);
}
@@ -175,6 +197,10 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
}
$dumps = [];
if (!$this->dataCount) {
return $this->data = [];
}
foreach ($this->data as $dump) {
$dumper->dump($dump['data']->withMaxDepth($maxDepthLimit)->withMaxItemsPerDepth($maxItemsPerDepth));
$dump['data'] = stream_get_contents($data, -1, 0);
@@ -193,7 +219,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
public function __destruct()
{
if (0 === $this->clonesCount-- && !$this->isCollected && $this->data) {
if (0 === $this->clonesCount-- && !$this->isCollected && $this->dataCount) {
$this->clonesCount = 0;
$this->isCollected = true;
@@ -215,6 +241,9 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
$dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]);
} else {
$dumper = new CliDumper('php://output', $this->charset);
if (method_exists($dumper, 'setDisplayOptions')) {
$dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]);
}
}
foreach ($this->data as $i => $dump) {

View File

@@ -13,9 +13,10 @@ namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use Symfony\Contracts\Service\ResetInterface;
/**
@@ -26,10 +27,13 @@ use Symfony\Contracts\Service\ResetInterface;
class EventDataCollector extends DataCollector implements LateDataCollectorInterface
{
protected $dispatcher;
private $requestStack;
private $currentRequest;
public function __construct(EventDispatcherInterface $dispatcher = null)
public function __construct(EventDispatcherInterface $dispatcher = null, RequestStack $requestStack = null)
{
$this->dispatcher = $dispatcher;
$this->requestStack = $requestStack;
}
/**
@@ -37,6 +41,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
*/
public function collect(Request $request, Response $response, \Exception $exception = null)
{
$this->currentRequest = $this->requestStack && $this->requestStack->getMasterRequest() !== $request ? $request : null;
$this->data = [
'called_listeners' => [],
'not_called_listeners' => [],
@@ -56,12 +61,12 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
public function lateCollect()
{
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
$this->setCalledListeners($this->dispatcher->getCalledListeners());
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners());
$this->setCalledListeners($this->dispatcher->getCalledListeners($this->currentRequest));
$this->setNotCalledListeners($this->dispatcher->getNotCalledListeners($this->currentRequest));
}
if ($this->dispatcher instanceof TraceableEventDispatcher) {
$this->setOrphanedEvents($this->dispatcher->getOrphanedEvents());
$this->setOrphanedEvents($this->dispatcher->getOrphanedEvents($this->currentRequest));
}
$this->data = $this->cloneVar($this->data);

View File

@@ -66,7 +66,9 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
if (null !== $this->logger) {
$containerDeprecationLogs = $this->getContainerDeprecationLogs();
$this->data = $this->computeErrorsCount($containerDeprecationLogs);
$this->data['compiler_logs'] = $this->getContainerCompilerLogs();
// get compiler logs later (only when they are needed) to improve performance
$this->data['compiler_logs'] = [];
$this->data['compiler_logs_filepath'] = $this->containerPathPrefix.'Compiler.log';
$this->data['logs'] = $this->sanitizeLogs(array_merge($this->logger->getLogs($this->currentRequest), $containerDeprecationLogs));
$this->data = $this->cloneVar($this->data);
}
@@ -110,7 +112,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
public function getCompilerLogs()
{
return isset($this->data['compiler_logs']) ? $this->data['compiler_logs'] : [];
return $this->cloneVar($this->getContainerCompilerLogs($this->data['compiler_logs_filepath'] ?? null));
}
/**
@@ -147,14 +149,14 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
return $logs;
}
private function getContainerCompilerLogs()
private function getContainerCompilerLogs(?string $compilerLogsFilepath = null): array
{
if (null === $this->containerPathPrefix || !file_exists($file = $this->containerPathPrefix.'Compiler.log')) {
if (!file_exists($compilerLogsFilepath)) {
return [];
}
$logs = [];
foreach (file($file, FILE_IGNORE_NEW_LINES) as $log) {
foreach (file($compilerLogsFilepath, FILE_IGNORE_NEW_LINES) as $log) {
$log = explode(': ', $log, 2);
if (!isset($log[1]) || !preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $log[0])) {
$log = ['Unknown Compiler Pass', implode(': ', $log)];

View File

@@ -252,6 +252,18 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
return $this->data['content'];
}
public function isJsonRequest()
{
return 1 === preg_match('{^application/(?:\w+\++)*json$}i', $this->data['request_headers']['content-type']);
}
public function getPrettyJson()
{
$decoded = json_decode($this->getContent());
return JSON_ERROR_NONE === json_last_error() ? json_encode($decoded, JSON_PRETTY_PRINT) : null;
}
public function getContentType()
{
return $this->data['content_type'];
@@ -338,11 +350,17 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
return isset($this->data['forward_token']) ? $this->data['forward_token'] : null;
}
/**
* @final since Symfony 4.3
*/
public function onKernelController(FilterControllerEvent $event)
{
$this->controllers[$event->getRequest()] = $event->getController();
}
/**
* @final since Symfony 4.3
*/
public function onKernelResponse(FilterResponseEvent $event)
{
if (!$event->isMasterRequest()) {

View File

@@ -17,8 +17,6 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
/**
* RouterDataCollector.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class RouterDataCollector extends DataCollector
@@ -68,6 +66,8 @@ class RouterDataCollector extends DataCollector
/**
* Remembers the controller associated to each request.
*
* @final since Symfony 4.3
*/
public function onKernelController(FilterControllerEvent $event)
{

View File

@@ -20,8 +20,10 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
* Formats debug file links.
*
* @author Jérémy Romey <jeremy@free-agent.fr>
*
* @final since Symfony 4.3
*/
class FileLinkFormatter implements \Serializable
class FileLinkFormatter
{
private $fileLinkFormat;
private $requestStack;
@@ -64,17 +66,11 @@ class FileLinkFormatter implements \Serializable
/**
* @internal
*/
public function serialize()
public function __sleep(): array
{
return serialize($this->getFileLinkFormat());
}
$this->getFileLinkFormat();
/**
* @internal
*/
public function unserialize($serialized)
{
$this->fileLinkFormat = unserialize($serialized, ['allowed_classes' => false]);
return ['fileLinkFormat'];
}
/**
@@ -91,21 +87,17 @@ class FileLinkFormatter implements \Serializable
private function getFileLinkFormat()
{
if ($this->fileLinkFormat) {
return $this->fileLinkFormat;
}
if ($this->requestStack && $this->baseDir && $this->urlFormat) {
$request = $this->requestStack->getMasterRequest();
if ($request instanceof Request) {
if ($this->urlFormat instanceof \Closure && !$this->urlFormat = ($this->urlFormat)()) {
return;
}
return [
if ($request instanceof Request && (!$this->urlFormat instanceof \Closure || $this->urlFormat = ($this->urlFormat)())) {
$this->fileLinkFormat = [
$request->getSchemeAndHttpHost().$request->getBasePath().$this->urlFormat,
$this->baseDir.\DIRECTORY_SEPARATOR, '',
];
}
}
return $this->fileLinkFormat;
}
}

View File

@@ -12,7 +12,6 @@
namespace Symfony\Component\HttpKernel\Debug;
use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcher as BaseTraceableEventDispatcher;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpKernel\KernelEvents;
/**
@@ -27,7 +26,7 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
/**
* {@inheritdoc}
*/
protected function preDispatch($eventName, Event $event)
protected function beforeDispatch(string $eventName, $event)
{
switch ($eventName) {
case KernelEvents::REQUEST:
@@ -58,7 +57,7 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher
/**
* {@inheritdoc}
*/
protected function postDispatch($eventName, Event $event)
protected function afterDispatch(string $eventName, $event)
{
switch ($eventName) {
case KernelEvents::CONTROLLER_ARGUMENTS:

View File

@@ -34,17 +34,19 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
private $resolverServiceId;
private $controllerTag;
private $controllerLocator;
private $notTaggedControllerResolverServiceId;
public function __construct(string $resolverServiceId = 'argument_resolver.service', string $controllerTag = 'controller.service_arguments', string $controllerLocator = 'argument_resolver.controller_locator')
public function __construct(string $resolverServiceId = 'argument_resolver.service', string $controllerTag = 'controller.service_arguments', string $controllerLocator = 'argument_resolver.controller_locator', string $notTaggedControllerResolverServiceId = 'argument_resolver.not_tagged_controller')
{
$this->resolverServiceId = $resolverServiceId;
$this->controllerTag = $controllerTag;
$this->controllerLocator = $controllerLocator;
$this->notTaggedControllerResolverServiceId = $notTaggedControllerResolverServiceId;
}
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition($this->resolverServiceId)) {
if (false === $container->hasDefinition($this->resolverServiceId) && false === $container->hasDefinition($this->notTaggedControllerResolverServiceId)) {
return;
}
@@ -137,8 +139,8 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
} elseif (isset($bindings[$bindingName = $type.' $'.$p->name]) || isset($bindings[$bindingName = '$'.$p->name]) || isset($bindings[$bindingName = $type])) {
$binding = $bindings[$bindingName];
list($bindingValue, $bindingId) = $binding->getValues();
$binding->setValues([$bindingValue, $bindingId, true]);
list($bindingValue, $bindingId, , $bindingType, $bindingFile) = $binding->getValues();
$binding->setValues([$bindingValue, $bindingId, true, $bindingType, $bindingFile]);
if (!$bindingValue instanceof Reference) {
$args[$p->name] = new Reference('.value.'.$container->hash($bindingValue));
@@ -181,8 +183,17 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
}
}
$container->getDefinition($this->resolverServiceId)
->replaceArgument(0, $controllerLocatorRef = ServiceLocatorTagPass::register($container, $controllers));
$controllerLocatorRef = ServiceLocatorTagPass::register($container, $controllers);
if ($container->hasDefinition($this->resolverServiceId)) {
$container->getDefinition($this->resolverServiceId)
->replaceArgument(0, $controllerLocatorRef);
}
if ($container->hasDefinition($this->notTaggedControllerResolverServiceId)) {
$container->getDefinition($this->notTaggedControllerResolverServiceId)
->replaceArgument(0, $controllerLocatorRef);
}
$container->setAlias($this->controllerLocator, (string) $controllerLocatorRef);
}

View File

@@ -0,0 +1,58 @@
<?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\HttpKernel\DependencyInjection;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Register all services that have the "kernel.locale_aware" tag into the listener.
*
* @author Pierre Bobiet <pierrebobiet@gmail.com>
*/
class RegisterLocaleAwareServicesPass implements CompilerPassInterface
{
private $listenerServiceId;
private $localeAwareTag;
public function __construct(string $listenerServiceId = 'locale_aware_listener', string $localeAwareTag = 'kernel.locale_aware')
{
$this->listenerServiceId = $listenerServiceId;
$this->localeAwareTag = $localeAwareTag;
}
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition($this->listenerServiceId)) {
return;
}
$services = [];
foreach ($container->findTaggedServiceIds($this->localeAwareTag) as $id => $tags) {
$services[] = new Reference($id);
}
if (!$services) {
$container->removeDefinition($this->listenerServiceId);
return;
}
$container
->getDefinition($this->listenerServiceId)
->setArgument(0, new IteratorArgument($services))
;
}
}

View File

@@ -0,0 +1,28 @@
<?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\HttpKernel\Event;
/**
* Allows filtering of controller arguments.
*
* You can call getController() to retrieve the controller and getArguments
* to retrieve the current arguments. With setArguments() you can replace
* arguments that are used to call the controller.
*
* Arguments set in the event must be compatible with the signature of the
* controller.
*
* @author Christophe Coevoet <stof@notk.org>
*/
class ControllerArgumentsEvent extends FilterControllerArgumentsEvent
{
}

View File

@@ -0,0 +1,27 @@
<?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\HttpKernel\Event;
/**
* Allows filtering of a controller callable.
*
* You can call getController() to retrieve the current controller. With
* setController() you can set a new controller that is used in the processing
* of the request.
*
* Controllers should be callables.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ControllerEvent extends FilterControllerEvent
{
}

View File

@@ -0,0 +1,29 @@
<?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\HttpKernel\Event;
/**
* Allows to create a response for a thrown exception.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* You can also call setException() to replace the thrown exception. This
* exception will be thrown if no response is set during processing of this
* event.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ExceptionEvent extends GetResponseForExceptionEvent
{
}

View File

@@ -15,18 +15,9 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows filtering of controller arguments.
*
* You can call getController() to retrieve the controller and getArguments
* to retrieve the current arguments. With setArguments() you can replace
* arguments that are used to call the controller.
*
* Arguments set in the event must be compatible with the signature of the
* controller.
*
* @author Christophe Coevoet <stof@notk.org>
* @deprecated since Symfony 4.3, use ControllerArgumentsEvent instead
*/
class FilterControllerArgumentsEvent extends FilterControllerEvent
class FilterControllerArgumentsEvent extends ControllerEvent
{
private $arguments;

View File

@@ -15,15 +15,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows filtering of a controller callable.
*
* You can call getController() to retrieve the current controller. With
* setController() you can set a new controller that is used in the processing
* of the request.
*
* Controllers should be callables.
*
* @author Bernhard Schussek <bschussek@gmail.com>
* @deprecated since Symfony 4.3, use ControllerEvent instead
*/
class FilterControllerEvent extends KernelEvent
{

View File

@@ -16,13 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows to filter a Response object.
*
* You can call getResponse() to retrieve the current response. With
* setResponse() you can set a new response that will be returned to the
* browser.
*
* @author Bernhard Schussek <bschussek@gmail.com>
* @deprecated since Symfony 4.3, use ResponseEvent instead
*/
class FilterResponseEvent extends KernelEvent
{

View File

@@ -14,13 +14,7 @@ namespace Symfony\Component\HttpKernel\Event;
use Symfony\Component\HttpFoundation\Response;
/**
* Allows to create a response for a request.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* @author Bernhard Schussek <bschussek@gmail.com>
* @deprecated since Symfony 4.3, use RequestEvent instead
*/
class GetResponseEvent extends KernelEvent
{

View File

@@ -15,15 +15,9 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows to create a response for the return value of a controller.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* @author Bernhard Schussek <bschussek@gmail.com>
* @deprecated since Symfony 4.3, use ViewEvent instead
*/
class GetResponseForControllerResultEvent extends GetResponseEvent
class GetResponseForControllerResultEvent extends RequestEvent
{
/**
* The return value of the controller.

View File

@@ -15,19 +15,9 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows to create a response for a thrown exception.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* You can also call setException() to replace the thrown exception. This
* exception will be thrown if no response is set during processing of this
* event.
*
* @author Bernhard Schussek <bschussek@gmail.com>
* @deprecated since Symfony 4.3, use ExceptionEvent instead
*/
class GetResponseForExceptionEvent extends GetResponseEvent
class GetResponseForExceptionEvent extends RequestEvent
{
/**
* The exception object.

View File

@@ -16,12 +16,7 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\HttpKernelInterface;
/**
* Allows to execute logic after a response was sent.
*
* Since it's only triggered on master requests, the `getRequestType()` method
* will always return the value of `HttpKernelInterface::MASTER_REQUEST`.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
* @deprecated since Symfony 4.3, use TerminateEvent instead
*/
class PostResponseEvent extends KernelEvent
{

View File

@@ -0,0 +1,25 @@
<?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\HttpKernel\Event;
/**
* Allows to create a response for a request.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class RequestEvent extends GetResponseEvent
{
}

View File

@@ -0,0 +1,25 @@
<?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\HttpKernel\Event;
/**
* Allows to filter a Response object.
*
* You can call getResponse() to retrieve the current response. With
* setResponse() you can set a new response that will be returned to the
* browser.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ResponseEvent extends FilterResponseEvent
{
}

View File

@@ -0,0 +1,24 @@
<?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\HttpKernel\Event;
/**
* Allows to execute logic after a response was sent.
*
* Since it's only triggered on master requests, the `getRequestType()` method
* will always return the value of `HttpKernelInterface::MASTER_REQUEST`.
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class TerminateEvent extends PostResponseEvent
{
}

View File

@@ -0,0 +1,25 @@
<?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\HttpKernel\Event;
/**
* Allows to create a response for the return value of a controller.
*
* Call setResponse() to set the response that will be returned for the
* current request. The propagation of this event is stopped as soon as a
* response is set.
*
* @author Bernhard Schussek <bschussek@gmail.com>
*/
class ViewEvent extends GetResponseForControllerResultEvent
{
}

View File

@@ -32,6 +32,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
*
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
* @author Tobias Schultze <http://tobion.de>
*
* @internal since Symfony 4.3
*/
abstract class AbstractSessionListener implements EventSubscriberInterface
{

View File

@@ -26,6 +26,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
*
* @author Bulat Shakirzyanov <mallluhuct@gmail.com>
* @author Fabien Potencier <fabien@symfony.com>
*
* @internal since Symfony 4.3
*/
abstract class AbstractTestSessionListener implements EventSubscriberInterface
{

View File

@@ -19,6 +19,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
* Adds configured formats to each request.
*
* @author Gildas Quemener <gildas.quemener@gmail.com>
*
* @final since Symfony 4.3
*/
class AddRequestFormatsListener implements EventSubscriberInterface
{
@@ -45,6 +47,6 @@ class AddRequestFormatsListener implements EventSubscriberInterface
*/
public static function getSubscribedEvents()
{
return [KernelEvents::REQUEST => ['onKernelRequest', 1]];
return [KernelEvents::REQUEST => ['onKernelRequest', 100]];
}
}

View File

@@ -0,0 +1,43 @@
<?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\HttpKernel\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Ensures that the application is not indexed by search engines.
*
* @author Gary PEGEOT <garypegeot@gmail.com>
*/
class DisallowRobotsIndexingListener implements EventSubscriberInterface
{
private const HEADER_NAME = 'X-Robots-Tag';
public function onResponse(ResponseEvent $event): void
{
if (!$event->getResponse()->headers->has(static::HEADER_NAME)) {
$event->getResponse()->headers->set(static::HEADER_NAME, 'noindex');
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return [
KernelEvents::RESPONSE => ['onResponse', -255],
];
}
}

View File

@@ -18,7 +18,6 @@ use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -26,9 +25,9 @@ use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
/**
* ExceptionListener.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class ExceptionListener implements EventSubscriberInterface
{
@@ -55,6 +54,10 @@ class ExceptionListener implements EventSubscriberInterface
$this->logException($event->getException(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
}
/**
* @param string $eventName
* @param EventDispatcherInterface $eventDispatcher
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
if (null === $this->controller) {
@@ -96,7 +99,7 @@ class ExceptionListener implements EventSubscriberInterface
$event->setResponse($response);
if ($this->debug && $eventDispatcher instanceof EventDispatcherInterface) {
$cspRemovalListener = function (FilterResponseEvent $event) use (&$cspRemovalListener, $eventDispatcher) {
$cspRemovalListener = function ($event) use (&$cspRemovalListener, $eventDispatcher) {
$event->getResponse()->headers->remove('Content-Security-Policy');
$eventDispatcher->removeListener(KernelEvents::RESPONSE, $cspRemovalListener);
};

View File

@@ -24,10 +24,12 @@ use Symfony\Component\HttpKernel\UriSigner;
* All URL paths starting with /_fragment are handled as
* content fragments by this listener.
*
* If throws an AccessDeniedHttpException exception if the request
* Throws an AccessDeniedHttpException exception if the request
* is not signed or if it is not an internal sub-request.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class FragmentListener implements EventSubscriberInterface
{

View File

@@ -0,0 +1,76 @@
<?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\HttpKernel\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\Translation\LocaleAwareInterface;
/**
* Pass the current locale to the provided services.
*
* @author Pierre Bobiet <pierrebobiet@gmail.com>
*/
class LocaleAwareListener implements EventSubscriberInterface
{
private $localeAwareServices;
private $requestStack;
/**
* @param LocaleAwareInterface[] $localeAwareServices
*/
public function __construct(iterable $localeAwareServices, RequestStack $requestStack)
{
$this->localeAwareServices = $localeAwareServices;
$this->requestStack = $requestStack;
}
public function onKernelRequest(RequestEvent $event): void
{
$this->setLocale($event->getRequest()->getLocale(), $event->getRequest()->getDefaultLocale());
}
public function onKernelFinishRequest(FinishRequestEvent $event): void
{
if (null === $parentRequest = $this->requestStack->getParentRequest()) {
$this->setLocale($event->getRequest()->getDefaultLocale());
return;
}
$this->setLocale($parentRequest->getLocale(), $parentRequest->getDefaultLocale());
}
public static function getSubscribedEvents()
{
return [
// must be registered after the Locale listener
KernelEvents::REQUEST => [['onKernelRequest', 15]],
KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', -15]],
];
}
private function setLocale(string $locale, ?string $defaultLocale = null): void
{
foreach ($this->localeAwareServices as $service) {
try {
$service->setLocale($locale);
} catch (\InvalidArgumentException $e) {
$service->setLocale($defaultLocale);
}
}
}
}

View File

@@ -16,6 +16,7 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\KernelEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RequestContextAwareInterface;
@@ -23,6 +24,8 @@ use Symfony\Component\Routing\RequestContextAwareInterface;
* Initializes the locale based on the current request.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class LocaleListener implements EventSubscriberInterface
{
@@ -42,10 +45,14 @@ class LocaleListener implements EventSubscriberInterface
$this->router = $router;
}
public function setDefaultLocale(KernelEvent $event)
{
$event->getRequest()->setDefaultLocale($this->defaultLocale);
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$request->setDefaultLocale($this->defaultLocale);
$this->setLocale($request);
$this->setRouterContext($request);
@@ -75,8 +82,11 @@ class LocaleListener implements EventSubscriberInterface
public static function getSubscribedEvents()
{
return [
// must be registered after the Router to have access to the _locale
KernelEvents::REQUEST => [['onKernelRequest', 16]],
KernelEvents::REQUEST => [
['setDefaultLocale', 100],
// must be registered after the Router to have access to the _locale
['onKernelRequest', 16],
],
KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]],
];
}

View File

@@ -24,6 +24,8 @@ use Symfony\Component\HttpKernel\Profiler\Profiler;
* ProfilerListener collects data for the current request by listening to the kernel events.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class ProfilerListener implements EventSubscriberInterface
{

View File

@@ -19,6 +19,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
* ResponseListener fixes the Response headers based on the Request.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class ResponseListener implements EventSubscriberInterface
{

View File

@@ -37,6 +37,8 @@ use Symfony\Component\Routing\RequestContextAwareInterface;
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Yonel Ceruto <yonelceruto@gmail.com>
*
* @final since Symfony 4.3
*/
class RouterListener implements EventSubscriberInterface
{

View File

@@ -21,6 +21,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
* to the client.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class StreamedResponseListener implements EventSubscriberInterface
{

View File

@@ -21,6 +21,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
* SurrogateListener adds a Surrogate-Control HTTP header when the Response needs to be parsed for Surrogates.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3
*/
class SurrogateListener implements EventSubscriberInterface
{

View File

@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpKernel\EventListener;
@trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3 and will be removed in 5.0, use LocaleAwareListener instead.', TranslatorListener::class), E_USER_DEPRECATED);
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -24,6 +26,8 @@ use Symfony\Contracts\Translation\LocaleAwareInterface;
* Synchronizes the locale between the request and the translator.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated since Symfony 4.3, use LocaleAwareListener instead
*/
class TranslatorListener implements EventSubscriberInterface
{

View File

@@ -19,6 +19,8 @@ use Symfony\Component\HttpKernel\KernelEvents;
* Validates Requests.
*
* @author Magnus Nordlander <magnus@fervo.se>
*
* @final since Symfony 4.3
*/
class ValidateRequestListener implements EventSubscriberInterface
{

View File

@@ -19,11 +19,11 @@ class AccessDeniedHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(403, $message, $previous, $headers, $code);
}

View File

@@ -18,11 +18,11 @@ class BadRequestHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(400, $message, $previous, $headers, $code);
}

View File

@@ -18,11 +18,11 @@ class ConflictHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(409, $message, $previous, $headers, $code);
}

View File

@@ -67,9 +67,15 @@ class ControllerDoesNotReturnResponseException extends \LogicException
if (\is_object($controller)) {
$r = new \ReflectionClass($controller);
try {
$line = $r->getMethod('__invoke')->getEndLine();
} catch (\ReflectionException $e) {
$line = $r->getEndLine();
}
return [
'file' => $r->getFileName(),
'line' => $r->getEndLine(),
'line' => $line,
];
}

View File

@@ -18,11 +18,11 @@ class GoneHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(410, $message, $previous, $headers, $code);
}

View File

@@ -21,7 +21,7 @@ class HttpException extends \RuntimeException implements HttpExceptionInterface
private $statusCode;
private $headers;
public function __construct(int $statusCode, string $message = null, \Exception $previous = null, array $headers = [], ?int $code = 0)
public function __construct(int $statusCode, string $message = null, \Throwable $previous = null, array $headers = [], ?int $code = 0)
{
$this->statusCode = $statusCode;
$this->headers = $headers;

View File

@@ -18,11 +18,11 @@ class LengthRequiredHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(411, $message, $previous, $headers, $code);
}

View File

@@ -19,11 +19,11 @@ class MethodNotAllowedHttpException extends HttpException
/**
* @param array $allow An array of allowed methods
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(array $allow, string $message = null, \Exception $previous = null, ?int $code = 0, array $headers = [])
public function __construct(array $allow, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
$headers['Allow'] = strtoupper(implode(', ', $allow));

View File

@@ -18,11 +18,11 @@ class NotAcceptableHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(406, $message, $previous, $headers, $code);
}

View File

@@ -18,11 +18,11 @@ class NotFoundHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(404, $message, $previous, $headers, $code);
}

View File

@@ -18,11 +18,11 @@ class PreconditionFailedHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(412, $message, $previous, $headers, $code);
}

View File

@@ -20,11 +20,11 @@ class PreconditionRequiredHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(428, $message, $previous, $headers, $code);
}

View File

@@ -19,11 +19,11 @@ class ServiceUnavailableHttpException extends HttpException
/**
* @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct($retryAfter = null, string $message = null, \Exception $previous = null, ?int $code = 0, array $headers = [])
public function __construct($retryAfter = null, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
if ($retryAfter) {
$headers['Retry-After'] = $retryAfter;

View File

@@ -21,11 +21,11 @@ class TooManyRequestsHttpException extends HttpException
/**
* @param int|string $retryAfter The number of seconds or HTTP-date after which the request may be retried
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct($retryAfter = null, string $message = null, \Exception $previous = null, ?int $code = 0, array $headers = [])
public function __construct($retryAfter = null, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
if ($retryAfter) {
$headers['Retry-After'] = $retryAfter;

View File

@@ -19,11 +19,11 @@ class UnauthorizedHttpException extends HttpException
/**
* @param string $challenge WWW-Authenticate challenge string
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $challenge, string $message = null, \Exception $previous = null, ?int $code = 0, array $headers = [])
public function __construct(string $challenge, string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
$headers['WWW-Authenticate'] = $challenge;

View File

@@ -18,11 +18,11 @@ class UnprocessableEntityHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(422, $message, $previous, $headers, $code);
}

View File

@@ -18,11 +18,11 @@ class UnsupportedMediaTypeHttpException extends HttpException
{
/**
* @param string $message The internal exception message
* @param \Exception $previous The previous exception
* @param \Throwable $previous The previous exception
* @param int $code The internal exception code
* @param array $headers
*/
public function __construct(string $message = null, \Exception $previous = null, int $code = 0, array $headers = [])
public function __construct(string $message = null, \Throwable $previous = null, int $code = 0, array $headers = [])
{
parent::__construct(415, $message, $previous, $headers, $code);
}

View File

@@ -59,6 +59,10 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
throw new \InvalidArgumentException('The hinclude rendering strategy needs an instance of Twig\Environment or Symfony\Component\Templating\EngineInterface');
}
if ($templating instanceof EngineInterface) {
@trigger_error(sprintf('Using a "%s" instance for "%s" is deprecated since version 4.3; use a \Twig\Environment instance instead.', EngineInterface::class, __CLASS__), E_USER_DEPRECATED);
}
$this->templating = $templating;
}

View File

@@ -11,14 +11,15 @@
namespace Symfony\Component\HttpKernel\Fragment;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ControllerReference;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\HttpCache\SubRequestHandler;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* Implements the inline rendering strategy where the Request is rendered by the current HTTP kernel.
@@ -33,7 +34,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
public function __construct(HttpKernelInterface $kernel, EventDispatcherInterface $dispatcher = null)
{
$this->kernel = $kernel;
$this->dispatcher = $dispatcher;
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
}
/**
@@ -82,9 +83,9 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
// we dispatch the exception event to trigger the logging
// the response that comes back is ignored
if (isset($options['ignore_errors']) && $options['ignore_errors'] && $this->dispatcher) {
$event = new GetResponseForExceptionEvent($this->kernel, $request, HttpKernelInterface::SUB_REQUEST, $e);
$event = new ExceptionEvent($this->kernel, $request, HttpKernelInterface::SUB_REQUEST, $e);
$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
$this->dispatcher->dispatch($event, KernelEvents::EXCEPTION);
}
// let's clean up the output buffers that were created by the sub-request

View File

@@ -40,7 +40,14 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
*
* The available options are:
*
* * debug: If true, the traces are added as a HTTP header to ease debugging
* * debug If true, exceptions are thrown when things go wrong. Otherwise, the cache
* will try to carry on and deliver a meaningful response.
*
* * trace_level May be one of 'none', 'short' and 'full'. For 'short', a concise trace of the
* master request will be added as an HTTP header. 'full' will add traces for all
* requests (including ESI subrequests). (default: 'full' if in debug; 'none' otherwise)
*
* * trace_header Header name to use for traces. (default: X-Symfony-Cache)
*
* * default_ttl The number of seconds that a cache entry should be considered
* fresh when no explicit freshness information is provided in
@@ -87,7 +94,13 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
'allow_revalidate' => false,
'stale_while_revalidate' => 2,
'stale_if_error' => 60,
'trace_level' => 'none',
'trace_header' => 'X-Symfony-Cache',
], $options);
if (!isset($options['trace_level']) && $this->options['debug']) {
$this->options['trace_level'] = 'full';
}
}
/**
@@ -110,6 +123,23 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
return $this->traces;
}
private function addTraces(Response $response)
{
$traceString = null;
if ('full' === $this->options['trace_level']) {
$traceString = $this->getLog();
}
if ('short' === $this->options['trace_level'] && $masterId = array_key_first($this->traces)) {
$traceString = implode('/', $this->traces[$masterId]);
}
if (null !== $traceString) {
$response->headers->add([$this->options['trace_header'] => $traceString]);
}
}
/**
* Returns a log message for the events of the last request processing.
*
@@ -194,8 +224,8 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$this->restoreResponseBody($request, $response);
if (HttpKernelInterface::MASTER_REQUEST === $type && $this->options['debug']) {
$response->headers->set('X-Symfony-Cache', $this->getLog());
if (HttpKernelInterface::MASTER_REQUEST === $type) {
$this->addTraces($response);
}
if (null !== $this->surrogate) {

View File

@@ -0,0 +1,106 @@
<?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\HttpKernel;
use Symfony\Component\HttpClient\HttpClient;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\Mime\Part\AbstractPart;
use Symfony\Component\Mime\Part\DataPart;
use Symfony\Component\Mime\Part\Multipart\FormDataPart;
use Symfony\Component\Mime\Part\TextPart;
use Symfony\Contracts\HttpClient\HttpClientInterface;
/**
* An implementation of a Symfony HTTP kernel using a "real" HTTP client.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
final class HttpClientKernel implements HttpKernelInterface
{
private $client;
public function __construct(HttpClientInterface $client = null)
{
if (!class_exists(HttpClient::class)) {
throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__));
}
$this->client = $client ?? HttpClient::create();
}
public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
{
$headers = $this->getHeaders($request);
$body = '';
if (null !== $part = $this->getBody($request)) {
$headers = array_merge($headers, $part->getPreparedHeaders()->toArray());
$body = $part->bodyToIterable();
}
$response = $this->client->request($request->getMethod(), $request->getUri(), [
'headers' => $headers,
'body' => $body,
'max_redirects' => 0,
] + $request->attributes->get('http_client_options', []));
$response = new Response($response->getContent(!$catch), $response->getStatusCode(), $response->getHeaders(!$catch));
$response->headers = new class($response->headers->all()) extends ResponseHeaderBag {
protected function computeCacheControlValue()
{
return $this->getCacheControlHeader(); // preserve the original value
}
};
return $response;
}
private function getBody(Request $request): ?AbstractPart
{
if (\in_array($request->getMethod(), ['GET', 'HEAD'])) {
return null;
}
if (!class_exists(AbstractPart::class)) {
throw new \LogicException('You cannot pass non-empty bodies as the Mime component is not installed. Try running "composer require symfony/mime".');
}
if ($content = $request->getContent()) {
return new TextPart($content, 'utf-8', 'plain', '8bit');
}
$fields = $request->request->all();
foreach ($request->files->all() as $name => $file) {
$fields[$name] = DataPart::fromPath($file->getPathname(), $file->getClientOriginalName(), $file->getClientMimeType());
}
return new FormDataPart($fields);
}
private function getHeaders(Request $request): array
{
$headers = [];
foreach ($request->headers as $key => $value) {
$headers[$key] = $value;
}
$cookies = [];
foreach ($request->cookies->all() as $name => $value) {
$cookies[] = $name.'='.$value;
}
if ($cookies) {
$headers['cookie'] = implode('; ', $cookies);
}
return $headers;
}
}

View File

@@ -11,7 +11,7 @@
namespace Symfony\Component\HttpKernel;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\HttpFoundation\Exception\RequestExceptionInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -19,18 +19,19 @@ use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\Event\ViewEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
/**
* HttpKernel notifies events to convert a Request object to a Response one.
@@ -46,7 +47,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null)
{
$this->dispatcher = $dispatcher;
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
$this->resolver = $resolver;
$this->requestStack = $requestStack ?: new RequestStack();
$this->argumentResolver = $argumentResolver;
@@ -84,7 +85,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
*/
public function terminate(Request $request, Response $response)
{
$this->dispatcher->dispatch(KernelEvents::TERMINATE, new PostResponseEvent($this, $request, $response));
$this->dispatcher->dispatch(new TerminateEvent($this, $request, $response), KernelEvents::TERMINATE);
}
/**
@@ -122,8 +123,8 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
$this->requestStack->push($request);
// request
$event = new GetResponseEvent($this, $request, $type);
$this->dispatcher->dispatch(KernelEvents::REQUEST, $event);
$event = new RequestEvent($this, $request, $type);
$this->dispatcher->dispatch($event, KernelEvents::REQUEST);
if ($event->hasResponse()) {
return $this->filterResponse($event->getResponse(), $request, $type);
@@ -134,15 +135,15 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo()));
}
$event = new FilterControllerEvent($this, $controller, $request, $type);
$this->dispatcher->dispatch(KernelEvents::CONTROLLER, $event);
$event = new ControllerEvent($this, $controller, $request, $type);
$this->dispatcher->dispatch($event, KernelEvents::CONTROLLER);
$controller = $event->getController();
// controller arguments
$arguments = $this->argumentResolver->getArguments($request, $controller);
$event = new FilterControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
$this->dispatcher->dispatch(KernelEvents::CONTROLLER_ARGUMENTS, $event);
$event = new ControllerArgumentsEvent($this, $controller, $arguments, $request, $type);
$this->dispatcher->dispatch($event, KernelEvents::CONTROLLER_ARGUMENTS);
$controller = $event->getController();
$arguments = $event->getArguments();
@@ -151,8 +152,8 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
// view
if (!$response instanceof Response) {
$event = new GetResponseForControllerResultEvent($this, $request, $type, $response);
$this->dispatcher->dispatch(KernelEvents::VIEW, $event);
$event = new ViewEvent($this, $request, $type, $response);
$this->dispatcher->dispatch($event, KernelEvents::VIEW);
if ($event->hasResponse()) {
$response = $event->getResponse();
@@ -184,9 +185,9 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
*/
private function filterResponse(Response $response, Request $request, int $type)
{
$event = new FilterResponseEvent($this, $request, $type, $response);
$event = new ResponseEvent($this, $request, $type, $response);
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$this->dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->finishRequest($request, $type);
@@ -202,7 +203,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
*/
private function finishRequest(Request $request, int $type)
{
$this->dispatcher->dispatch(KernelEvents::FINISH_REQUEST, new FinishRequestEvent($this, $request, $type));
$this->dispatcher->dispatch(new FinishRequestEvent($this, $request, $type), KernelEvents::FINISH_REQUEST);
$this->requestStack->pop();
}
@@ -217,8 +218,8 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
*/
private function handleException(\Exception $e, Request $request, int $type): Response
{
$event = new GetResponseForExceptionEvent($this, $request, $type, $e);
$this->dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
$event = new ExceptionEvent($this, $request, $type, $e);
$this->dispatcher->dispatch($event, KernelEvents::EXCEPTION);
// a listener might have replaced the exception
$e = $event->getException();

View File

@@ -0,0 +1,204 @@
<?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\HttpKernel;
use Symfony\Component\BrowserKit\AbstractBrowser;
use Symfony\Component\BrowserKit\CookieJar;
use Symfony\Component\BrowserKit\History;
use Symfony\Component\BrowserKit\Request as DomRequest;
use Symfony\Component\BrowserKit\Response as DomResponse;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Client simulates a browser and makes requests to an HttpKernel instance.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @method Request getRequest() A Request instance
* @method Response getResponse() A Response instance
*/
class HttpKernelBrowser extends AbstractBrowser
{
protected $kernel;
private $catchExceptions = true;
/**
* @param HttpKernelInterface $kernel An HttpKernel instance
* @param array $server The server parameters (equivalent of $_SERVER)
* @param History $history A History instance to store the browser history
* @param CookieJar $cookieJar A CookieJar instance to store the cookies
*/
public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null)
{
// These class properties must be set before calling the parent constructor, as it may depend on it.
$this->kernel = $kernel;
$this->followRedirects = false;
parent::__construct($server, $history, $cookieJar);
}
/**
* Sets whether to catch exceptions when the kernel is handling a request.
*
* @param bool $catchExceptions Whether to catch exceptions
*/
public function catchExceptions($catchExceptions)
{
$this->catchExceptions = $catchExceptions;
}
/**
* Makes a request.
*
* @return Response A Response instance
*/
protected function doRequest($request)
{
$response = $this->kernel->handle($request, HttpKernelInterface::MASTER_REQUEST, $this->catchExceptions);
if ($this->kernel instanceof TerminableInterface) {
$this->kernel->terminate($request, $response);
}
return $response;
}
/**
* Returns the script to execute when the request must be insulated.
*
* @return string
*/
protected function getScript($request)
{
$kernel = var_export(serialize($this->kernel), true);
$request = var_export(serialize($request), true);
$errorReporting = error_reporting();
$requires = '';
foreach (get_declared_classes() as $class) {
if (0 === strpos($class, 'ComposerAutoloaderInit')) {
$r = new \ReflectionClass($class);
$file = \dirname(\dirname($r->getFileName())).'/autoload.php';
if (file_exists($file)) {
$requires .= 'require_once '.var_export($file, true).";\n";
}
}
}
if (!$requires) {
throw new \RuntimeException('Composer autoloader not found.');
}
$code = <<<EOF
<?php
error_reporting($errorReporting);
$requires
\$kernel = unserialize($kernel);
\$request = unserialize($request);
EOF;
return $code.$this->getHandleScript();
}
protected function getHandleScript()
{
return <<<'EOF'
$response = $kernel->handle($request);
if ($kernel instanceof Symfony\Component\HttpKernel\TerminableInterface) {
$kernel->terminate($request, $response);
}
echo serialize($response);
EOF;
}
/**
* Converts the BrowserKit request to a HttpKernel request.
*
* @return Request A Request instance
*/
protected function filterRequest(DomRequest $request)
{
$httpRequest = Request::create($request->getUri(), $request->getMethod(), $request->getParameters(), $request->getCookies(), $request->getFiles(), $request->getServer(), $request->getContent());
foreach ($this->filterFiles($httpRequest->files->all()) as $key => $value) {
$httpRequest->files->set($key, $value);
}
return $httpRequest;
}
/**
* Filters an array of files.
*
* This method created test instances of UploadedFile so that the move()
* method can be called on those instances.
*
* If the size of a file is greater than the allowed size (from php.ini) then
* an invalid UploadedFile is returned with an error set to UPLOAD_ERR_INI_SIZE.
*
* @see UploadedFile
*
* @return array An array with all uploaded files marked as already moved
*/
protected function filterFiles(array $files)
{
$filtered = [];
foreach ($files as $key => $value) {
if (\is_array($value)) {
$filtered[$key] = $this->filterFiles($value);
} elseif ($value instanceof UploadedFile) {
if ($value->isValid() && $value->getSize() > UploadedFile::getMaxFilesize()) {
$filtered[$key] = new UploadedFile(
'',
$value->getClientOriginalName(),
$value->getClientMimeType(),
UPLOAD_ERR_INI_SIZE,
true
);
} else {
$filtered[$key] = new UploadedFile(
$value->getPathname(),
$value->getClientOriginalName(),
$value->getClientMimeType(),
$value->getError(),
true
);
}
}
}
return $filtered;
}
/**
* Converts the HttpKernel response to a BrowserKit response.
*
* @return DomResponse A DomResponse instance
*/
protected function filterResponse($response)
{
// this is needed to support StreamedResponse
ob_start();
$response->sendContent();
$content = ob_get_clean();
return new DomResponse($content, $response->getStatusCode(), $response->headers->all());
}
}

View File

@@ -73,15 +73,15 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private $requestStackSize = 0;
private $resetServices = false;
const VERSION = '4.2.8';
const VERSION_ID = 40208;
const VERSION = '4.3.0';
const VERSION_ID = 40300;
const MAJOR_VERSION = 4;
const MINOR_VERSION = 2;
const RELEASE_VERSION = 8;
const MINOR_VERSION = 3;
const RELEASE_VERSION = 0;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '07/2019';
const END_OF_LIFE = '01/2020';
const END_OF_MAINTENANCE = '01/2020';
const END_OF_LIFE = '07/2020';
public function __construct(string $environment, bool $debug)
{
@@ -442,14 +442,21 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
/**
* Gets the container class.
*
* @throws \InvalidArgumentException If the generated classname is invalid
*
* @return string The container class
*/
protected function getContainerClass()
{
$class = \get_class($this);
$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';
return $this->name.str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container';
if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) {
throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment));
}
return $class;
}
/**
@@ -826,22 +833,54 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
$output .= $rawChunk;
// PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
unset($tokens, $rawChunk);
gc_mem_caches();
return $output;
}
/**
* @deprecated since Symfony 4.3
*/
public function serialize()
{
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED);
return serialize([$this->environment, $this->debug]);
}
/**
* @deprecated since Symfony 4.3
*/
public function unserialize($data)
{
@trigger_error(sprintf('The "%s" method is deprecated since Symfony 4.3.', __METHOD__), E_USER_DEPRECATED);
list($environment, $debug) = unserialize($data, ['allowed_classes' => false]);
$this->__construct($environment, $debug);
}
public function __sleep()
{
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3.', $c), E_USER_DEPRECATED);
$this->serialized = $this->serialize();
return ['serialized'];
}
return ['environment', 'debug'];
}
public function __wakeup()
{
if (__CLASS__ !== $c = (new \ReflectionMethod($this, 'serialize'))->getDeclaringClass()->name) {
@trigger_error(sprintf('Implementing the "%s::serialize()" method is deprecated since Symfony 4.3.', $c), E_USER_DEPRECATED);
$this->unserialize($this->serialized);
unset($this->serialized);
return;
}
$this->__construct($this->environment, $this->debug);
}
}

View File

@@ -25,7 +25,7 @@ final class KernelEvents
* This event allows you to create a response for a request before any
* other code in the framework is executed.
*
* @Event("Symfony\Component\HttpKernel\Event\GetResponseEvent")
* @Event("Symfony\Component\HttpKernel\Event\RequestEvent")
*/
const REQUEST = 'kernel.request';
@@ -35,7 +35,7 @@ final class KernelEvents
* This event allows you to create a response for a thrown exception or
* to modify the thrown exception.
*
* @Event("Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent")
* @Event("Symfony\Component\HttpKernel\Event\ExceptionEvent")
*/
const EXCEPTION = 'kernel.exception';
@@ -46,7 +46,7 @@ final class KernelEvents
* This event allows you to create a response for the return value of the
* controller.
*
* @Event("Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent")
* @Event("Symfony\Component\HttpKernel\Event\ViewEvent")
*/
const VIEW = 'kernel.view';
@@ -57,7 +57,7 @@ final class KernelEvents
* This event allows you to change the controller that will handle the
* request.
*
* @Event("Symfony\Component\HttpKernel\Event\FilterControllerEvent")
* @Event("Symfony\Component\HttpKernel\Event\ControllerEvent")
*/
const CONTROLLER = 'kernel.controller';
@@ -67,7 +67,7 @@ final class KernelEvents
* This event allows you to change the arguments that will be passed to
* the controller.
*
* @Event("Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent")
* @Event("Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent")
*/
const CONTROLLER_ARGUMENTS = 'kernel.controller_arguments';
@@ -78,7 +78,7 @@ final class KernelEvents
* This event allows you to modify or replace the response that will be
* replied.
*
* @Event("Symfony\Component\HttpKernel\Event\FilterResponseEvent")
* @Event("Symfony\Component\HttpKernel\Event\ResponseEvent")
*/
const RESPONSE = 'kernel.response';
@@ -87,7 +87,7 @@ final class KernelEvents
*
* This event allows you to run expensive post-response jobs.
*
* @Event("Symfony\Component\HttpKernel\Event\PostResponseEvent")
* @Event("Symfony\Component\HttpKernel\Event\TerminateEvent")
*/
const TERMINATE = 'kernel.terminate';

View File

@@ -24,7 +24,7 @@ use Symfony\Component\HttpKernel\Bundle\BundleInterface;
*
* @method string getProjectDir() Gets the project dir (path of the project's composer file) - not defining it is deprecated since Symfony 4.2
*/
interface KernelInterface extends HttpKernelInterface, \Serializable
interface KernelInterface extends HttpKernelInterface
{
/**
* Returns an array of bundles to register.

View File

@@ -30,7 +30,7 @@ class FileLocatorTest extends TestCase
$kernel
->expects($this->never())
->method('locateResource');
$this->{method_exists($this, $_ = 'expectException') ? $_ : 'setExpectedException'}('LogicException');
$this->expectException('LogicException');
$locator->locate('/some/path');
}

View File

@@ -0,0 +1,117 @@
<?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\HttpKernel\Tests\Controller\ArgumentResolver;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ServiceLocator;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver\NotTaggedControllerValueResolver;
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
class NotTaggedControllerValueResolverTest extends TestCase
{
public function testDoSupportWhenControllerDoNotExists()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => 'my_controller']);
$this->assertTrue($resolver->supports($request, $argument));
}
public function testDoNotSupportWhenControllerExists()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([
'App\\Controller\\Mine::method' => function () {
return new ServiceLocator([
'dummy' => function () {
return new \stdClass();
},
]);
},
]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => 'App\\Controller\\Mine::method']);
$this->assertFalse($resolver->supports($request, $argument));
}
public function testDoNotSupportEmptyController()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => '']);
$this->assertFalse($resolver->supports($request, $argument));
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Could not resolve argument $dummy of "App\Controller\Mine::method()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
*/
public function testController()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => 'App\\Controller\\Mine::method']);
$this->assertTrue($resolver->supports($request, $argument));
$resolver->resolve($request, $argument);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Could not resolve argument $dummy of "App\Controller\Mine::method()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
*/
public function testControllerWithATrailingBackSlash()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => '\\App\\Controller\\Mine::method']);
$this->assertTrue($resolver->supports($request, $argument));
$resolver->resolve($request, $argument);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Could not resolve argument $dummy of "App\Controller\Mine::method()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
*/
public function testControllerWithMethodNameStartUppercase()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => 'App\\Controller\\Mine::Method']);
$this->assertTrue($resolver->supports($request, $argument));
$resolver->resolve($request, $argument);
}
/**
* @expectedException \Symfony\Component\DependencyInjection\Exception\RuntimeException
* @expectedExceptionMessage Could not resolve argument $dummy of "App\Controller\Mine::method()", maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?
*/
public function testControllerNameIsAnArray()
{
$resolver = new NotTaggedControllerValueResolver(new ServiceLocator([]));
$argument = new ArgumentMetadata('dummy', \stdClass::class, false, false, null);
$request = $this->requestWithAttributes(['_controller' => ['App\\Controller\\Mine', 'method']]);
$this->assertTrue($resolver->supports($request, $argument));
$resolver->resolve($request, $argument);
}
private function requestWithAttributes(array $attributes)
{
$request = Request::create('/');
foreach ($attributes as $name => $value) {
$request->attributes->set($name, $value);
}
return $request;
}
}

View File

@@ -52,9 +52,9 @@ class DumpDataCollectorTest extends TestCase
];
$this->assertEquals($xDump, $dump);
$this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize());
$this->assertStringMatchesFormat('%a;a:%d:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', serialize($collector));
$this->assertSame(0, $collector->getDumpsCount());
$this->assertSame('a:2:{i:0;b:0;i:1;s:5:"UTF-8";}', $collector->serialize());
$this->assertSame("O:60:\"Symfony\Component\HttpKernel\DataCollector\DumpDataCollector\":1:{s:7:\"\0*\0data\";a:2:{i:0;b:0;i:1;s:5:\"UTF-8\";}}", serialize($collector));
}
public function testDumpWithServerConnection()
@@ -72,7 +72,7 @@ class DumpDataCollectorTest extends TestCase
ob_start();
$collector->collect(new Request(), new Response());
$this->assertEmpty(ob_get_clean());
$this->assertStringMatchesFormat('a:3:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', $collector->serialize());
$this->assertStringMatchesFormat('%a;a:%d:{i:0;a:5:{s:4:"data";%c:39:"Symfony\Component\VarDumper\Cloner\Data":%a', serialize($collector));
}
public function testCollectDefault()
@@ -90,7 +90,7 @@ class DumpDataCollectorTest extends TestCase
$this->assertSame("DumpDataCollectorTest.php on line {$line}:\n123\n", $output);
$this->assertSame(1, $collector->getDumpsCount());
$collector->serialize();
serialize($collector);
}
public function testCollectHtml()
@@ -118,7 +118,7 @@ EOTXT;
$this->assertSame($xOutput, trim($output));
$this->assertSame(1, $collector->getDumpsCount());
$collector->serialize();
serialize($collector);
}
public function testFlush()

View File

@@ -22,8 +22,8 @@ use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface;
use Symfony\Component\HttpKernel\DataCollector\RequestDataCollector;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -206,7 +206,7 @@ class RequestDataCollectorTest extends TestCase
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$c = new RequestDataCollector();
$c->onKernelResponse(new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $this->createResponse()));
$c->onKernelResponse(new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $this->createResponse()));
$this->assertTrue($request->attributes->get('_redirected'));
}
@@ -290,7 +290,7 @@ class RequestDataCollectorTest extends TestCase
{
$resolver = $this->getMockBuilder('Symfony\\Component\\HttpKernel\\Controller\\ControllerResolverInterface')->getMock();
$httpKernel = new HttpKernel(new EventDispatcher(), $resolver, null, $this->getMockBuilder(ArgumentResolverInterface::class)->getMock());
$event = new FilterControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new ControllerEvent($httpKernel, $controller, $request, HttpKernelInterface::MASTER_REQUEST);
$collector->onKernelController($event);
}
@@ -333,4 +333,58 @@ class RequestDataCollectorTest extends TestCase
throw new \InvalidArgumentException(sprintf('Cookie named "%s" is not in response', $name));
}
/**
* @dataProvider provideJsonContentTypes
*/
public function testIsJson($contentType, $expected)
{
$response = $this->createResponse();
$request = $this->createRequest();
$request->headers->set('Content-Type', $contentType);
$c = new RequestDataCollector();
$c->collect($request, $response);
$this->assertSame($expected, $c->isJsonRequest());
}
public function provideJsonContentTypes()
{
return [
['text/csv', false],
['application/json', true],
['application/JSON', true],
['application/hal+json', true],
['application/xml+json', true],
['application/xml', false],
['', false],
];
}
/**
* @dataProvider providePrettyJson
*/
public function testGetPrettyJsonValidity($content, $expected)
{
$response = $this->createResponse();
$request = Request::create('/', 'POST', [], [], [], [], $content);
$c = new RequestDataCollector();
$c->collect($request, $response);
$this->assertSame($expected, $c->getPrettyJson());
}
public function providePrettyJson()
{
return [
['null', 'null'],
['{ "foo": "bar" }', '{
"foo": "bar"
}'],
['{ "abc" }', null],
['', null],
];
}
}

View File

@@ -34,18 +34,6 @@ class FileLinkFormatterTest extends TestCase
$this->assertSame("debug://open?url=file://$file&line=3", $sut->format($file, 3));
}
public function testWhenFileLinkFormatAndRequest()
{
$file = __DIR__.\DIRECTORY_SEPARATOR.'file.php';
$requestStack = new RequestStack();
$request = new Request();
$requestStack->push($request);
$sut = new FileLinkFormatter('debug://open?url=file://%f&line=%l', $requestStack, __DIR__, '/_profiler/open?file=%f&line=%l#line%l');
$this->assertSame("debug://open?url=file://$file&line=3", $sut->format($file, 3));
}
public function testWhenNoFileLinkFormatAndRequest()
{
$file = __DIR__.\DIRECTORY_SEPARATOR.'file.php';

View File

@@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel\Tests\Debug;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -89,10 +90,10 @@ class TraceableEventDispatcherTest extends TestCase
$called2 = true;
});
});
$dispatcher->dispatch('my-event');
$dispatcher->dispatch(new Event(), 'my-event');
$this->assertTrue($called1);
$this->assertFalse($called2);
$dispatcher->dispatch('my-event');
$dispatcher->dispatch(new Event(), 'my-event');
$this->assertTrue($called2);
}
@@ -104,7 +105,7 @@ class TraceableEventDispatcherTest extends TestCase
};
$eventDispatcher->addListener('foo', $listener1);
$eventDispatcher->addListener('foo', function () {});
$eventDispatcher->dispatch('foo');
$eventDispatcher->dispatch(new Event(), 'foo');
$this->assertCount(1, $eventDispatcher->getListeners('foo'), 'expected listener1 to be removed');
}

View File

@@ -376,6 +376,19 @@ class RegisterControllerArgumentLocatorsPassTest extends TestCase
$this->assertInstanceOf(ServiceClosureArgument::class, $locator['someArg']);
$this->assertEquals(new Reference('parent'), $locator['someArg']->getValues()[0]);
}
public function testNotTaggedControllerServiceReceivesLocatorArgument()
{
$container = new ContainerBuilder();
$resolver = $container->register('argument_resolver.not_tagged_controller')->addArgument([]);
$pass = new RegisterControllerArgumentLocatorsPass();
$pass->process($container);
$locatorArgument = $container->getDefinition('argument_resolver.not_tagged_controller')->getArgument(0);
$this->assertInstanceOf(Reference::class, $locatorArgument);
}
}
class RegisterTestController

View File

@@ -0,0 +1,59 @@
<?php
namespace Symfony\Component\HttpKernel\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\RegisterLocaleAwareServicesPass;
use Symfony\Component\HttpKernel\EventListener\LocaleAwareListener;
use Symfony\Contracts\Translation\LocaleAwareInterface;
class RegisterLocaleAwareServicesPassTest extends TestCase
{
public function testCompilerPass()
{
$container = new ContainerBuilder();
$container->register('locale_aware_listener', LocaleAwareListener::class)
->setPublic(true)
->setArguments([null, null]);
$container->register('some_locale_aware_service', LocaleAwareInterface::class)
->setPublic(true)
->addTag('kernel.locale_aware');
$container->register('another_locale_aware_service', LocaleAwareInterface::class)
->setPublic(true)
->addTag('kernel.locale_aware');
$container->addCompilerPass(new RegisterLocaleAwareServicesPass());
$container->compile();
$this->assertEquals(
[
new IteratorArgument([
0 => new Reference('some_locale_aware_service'),
1 => new Reference('another_locale_aware_service'),
]),
null,
],
$container->getDefinition('locale_aware_listener')->getArguments()
);
}
public function testListenerUnregisteredWhenNoLocaleAwareServices()
{
$container = new ContainerBuilder();
$container->register('locale_aware_listener', LocaleAwareListener::class)
->setPublic(true)
->setArguments([null, null]);
$container->addCompilerPass(new RegisterLocaleAwareServicesPass());
$container->compile();
$this->assertFalse($container->hasDefinition('locale_aware_listener'));
}
}

View File

@@ -0,0 +1,17 @@
<?php
namespace Symfony\Component\HttpKernel\Tests\Event;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Tests\TestHttpKernel;
class ControllerArgumentsEventTest extends TestCase
{
public function testControllerArgumentsEvent()
{
$filterController = new ControllerArgumentsEvent(new TestHttpKernel(), function () {}, ['test'], new Request(), 1);
$this->assertEquals($filterController->getArguments(), ['test']);
}
}

View File

@@ -13,14 +13,14 @@ namespace Symfony\Component\HttpKernel\Tests\Event;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Tests\TestHttpKernel;
class GetResponseForExceptionEventTest extends TestCase
class ExceptionEventTest extends TestCase
{
public function testAllowSuccessfulResponseIsFalseByDefault()
{
$event = new GetResponseForExceptionEvent(new TestHttpKernel(), new Request(), 1, new \Exception());
$event = new ExceptionEvent(new TestHttpKernel(), new Request(), 1, new \Exception());
$this->assertFalse($event->isAllowingCustomResponseCode());
}

View File

@@ -1,17 +0,0 @@
<?php
namespace Symfony\Component\HttpKernel\Tests\Event;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Tests\TestHttpKernel;
class FilterControllerArgumentsEventTest extends TestCase
{
public function testFilterControllerArgumentsEvent()
{
$filterController = new FilterControllerArgumentsEvent(new TestHttpKernel(), function () {}, ['test'], new Request(), 1);
$this->assertEquals($filterController->getArguments(), ['test']);
}
}

View File

@@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\AddRequestFormatsListener;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -46,7 +47,7 @@ class AddRequestFormatsListenerTest extends TestCase
public function testRegisteredEvent()
{
$this->assertEquals(
[KernelEvents::REQUEST => ['onKernelRequest', 1]],
[KernelEvents::REQUEST => ['onKernelRequest', 100]],
AddRequestFormatsListener::getSubscribedEvents()
);
}
@@ -54,7 +55,7 @@ class AddRequestFormatsListenerTest extends TestCase
public function testSetAdditionalFormats()
{
$request = $this->getRequestMock();
$event = $this->getGetResponseEventMock($request);
$event = $this->getRequestEventMock($request);
$request->expects($this->once())
->method('setFormat')
@@ -68,10 +69,10 @@ class AddRequestFormatsListenerTest extends TestCase
return $this->getMockBuilder('Symfony\Component\HttpFoundation\Request')->getMock();
}
protected function getGetResponseEventMock(Request $request)
protected function getRequestEventMock(Request $request)
{
$event = $this
->getMockBuilder('Symfony\Component\HttpKernel\Event\GetResponseEvent')
->getMockBuilder(RequestEvent::class)
->disableOriginalConstructor()
->getMock();

View File

@@ -112,7 +112,7 @@ class DebugHandlersListenerTest extends TestCase
set_error_handler([$eHandler, 'handleError']);
set_exception_handler([$eHandler, 'handleException']);
try {
$dispatcher->dispatch(ConsoleEvents::COMMAND, $event);
$dispatcher->dispatch($event, ConsoleEvents::COMMAND);
} catch (\Exception $exception) {
}
restore_exception_handler();

View File

@@ -0,0 +1,47 @@
<?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\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\DisallowRobotsIndexingListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelInterface;
class DisallowRobotsIndexingListenerTest extends TestCase
{
/**
* @dataProvider provideResponses
*/
public function testInvoke(?string $expected, Response $response): void
{
$listener = new DisallowRobotsIndexingListener();
$event = new ResponseEvent($this->createMock(HttpKernelInterface::class), $this->createMock(Request::class), KernelInterface::MASTER_REQUEST, $response);
$listener->onResponse($event);
$this->assertSame($expected, $response->headers->get('X-Robots-Tag'), 'Header doesn\'t match expectations');
}
public function provideResponses(): iterable
{
yield 'No header' => ['noindex', new Response()];
yield 'Header already set' => [
'something else',
new Response('', 204, ['X-Robots-Tag' => 'something else']),
];
}
}

View File

@@ -15,8 +15,8 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -103,8 +103,8 @@ class ExceptionListenerTest extends TestCase
$request = new Request();
$exception = new \Exception('foo');
$event = new GetResponseForExceptionEvent(new TestKernel(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
$event2 = new GetResponseForExceptionEvent(new TestKernelThatThrowsException(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
$event = new ExceptionEvent(new TestKernel(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
$event2 = new ExceptionEvent(new TestKernelThatThrowsException(), $request, HttpKernelInterface::MASTER_REQUEST, $exception);
return [
[$event, $event2],
@@ -123,7 +123,7 @@ class ExceptionListenerTest extends TestCase
$request = Request::create('/');
$request->setRequestFormat('xml');
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$event = new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$listener->onKernelException($event);
$response = $event->getResponse();
@@ -143,14 +143,14 @@ class ExceptionListenerTest extends TestCase
$dispatcher->addSubscriber($listener);
$request = Request::create('/');
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$dispatcher->dispatch(KernelEvents::EXCEPTION, $event);
$event = new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$dispatcher->dispatch($event, KernelEvents::EXCEPTION);
$response = new Response('', 200, ['content-security-policy' => "style-src 'self'"]);
$this->assertTrue($response->headers->has('content-security-policy'));
$event = new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertFalse($response->headers->has('content-security-policy'), 'CSP header has been removed');
$this->assertFalse($dispatcher->hasListeners(KernelEvents::RESPONSE), 'CSP removal listener has been removed');
@@ -166,7 +166,7 @@ class ExceptionListenerTest extends TestCase
return $controller();
}));
$request = Request::create('/');
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$event = new ExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$listener->onKernelException($event);
$this->assertNull($event->getResponse());

View File

@@ -13,7 +13,7 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\FragmentListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\UriSigner;
@@ -25,7 +25,7 @@ class FragmentListenerTest extends TestCase
$request = Request::create('http://example.com/foo?_path=foo%3Dbar%26_controller%3Dfoo');
$listener = new FragmentListener(new UriSigner('foo'));
$event = $this->createGetResponseEvent($request);
$event = $this->createRequestEvent($request);
$expected = $request->attributes->all();
@@ -41,7 +41,7 @@ class FragmentListenerTest extends TestCase
$request->attributes->set('_controller', 'bar');
$listener = new FragmentListener(new UriSigner('foo'));
$event = $this->createGetResponseEvent($request, HttpKernelInterface::SUB_REQUEST);
$event = $this->createRequestEvent($request, HttpKernelInterface::SUB_REQUEST);
$expected = $request->attributes->all();
@@ -58,7 +58,7 @@ class FragmentListenerTest extends TestCase
$request = Request::create('http://example.com/_fragment', 'POST');
$listener = new FragmentListener(new UriSigner('foo'));
$event = $this->createGetResponseEvent($request);
$event = $this->createRequestEvent($request);
$listener->onKernelRequest($event);
}
@@ -71,7 +71,7 @@ class FragmentListenerTest extends TestCase
$request = Request::create('http://example.com/_fragment', 'GET', [], [], [], ['REMOTE_ADDR' => '10.0.0.1']);
$listener = new FragmentListener(new UriSigner('foo'));
$event = $this->createGetResponseEvent($request);
$event = $this->createRequestEvent($request);
$listener->onKernelRequest($event);
}
@@ -82,7 +82,7 @@ class FragmentListenerTest extends TestCase
$request = Request::create($signer->sign('http://example.com/_fragment?_path=foo%3Dbar%26_controller%3Dfoo'), 'GET', [], [], [], ['REMOTE_ADDR' => '10.0.0.1']);
$listener = new FragmentListener($signer);
$event = $this->createGetResponseEvent($request);
$event = $this->createRequestEvent($request);
$listener->onKernelRequest($event);
@@ -95,7 +95,7 @@ class FragmentListenerTest extends TestCase
$request = Request::create('http://example.com/_fragment?_path=foo%3Dbar%26_controller%3Dfoo');
$listener = new FragmentListener(new UriSigner('foo'));
$event = $this->createGetResponseEvent($request, HttpKernelInterface::SUB_REQUEST);
$event = $this->createRequestEvent($request, HttpKernelInterface::SUB_REQUEST);
$listener->onKernelRequest($event);
@@ -108,15 +108,15 @@ class FragmentListenerTest extends TestCase
$request = Request::create($signer->sign('http://example.com/_fragment?_path=foo%3Dbar'), 'GET', [], [], [], ['REMOTE_ADDR' => '10.0.0.1']);
$listener = new FragmentListener($signer);
$event = $this->createGetResponseEvent($request);
$event = $this->createRequestEvent($request);
$listener->onKernelRequest($event);
$this->assertFalse($request->query->has('_path'));
}
private function createGetResponseEvent(Request $request, $requestType = HttpKernelInterface::MASTER_REQUEST)
private function createRequestEvent(Request $request, $requestType = HttpKernelInterface::MASTER_REQUEST)
{
return new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, $requestType);
return new RequestEvent($this->getMockBuilder(HttpKernelInterface::class)->getMock(), $request, $requestType);
}
}

View File

@@ -0,0 +1,119 @@
<?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\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\LocaleAwareListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Contracts\Translation\LocaleAwareInterface;
class LocaleAwareListenerTest extends TestCase
{
private $listener;
private $localeAwareService;
private $requestStack;
protected function setUp()
{
$this->localeAwareService = $this->getMockBuilder(LocaleAwareInterface::class)->getMock();
$this->requestStack = new RequestStack();
$this->listener = new LocaleAwareListener(new \ArrayIterator([$this->localeAwareService]), $this->requestStack);
}
public function testLocaleIsSetInOnKernelRequest()
{
$this->localeAwareService
->expects($this->once())
->method('setLocale')
->with($this->equalTo('fr'));
$event = new RequestEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
}
public function testDefaultLocaleIsUsedOnExceptionsInOnKernelRequest()
{
$this->localeAwareService
->expects($this->at(0))
->method('setLocale')
->will($this->throwException(new \InvalidArgumentException()));
$this->localeAwareService
->expects($this->at(1))
->method('setLocale')
->with($this->equalTo('en'));
$event = new RequestEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
}
public function testLocaleIsSetInOnKernelFinishRequestWhenParentRequestExists()
{
$this->localeAwareService
->expects($this->once())
->method('setLocale')
->with($this->equalTo('fr'));
$this->requestStack->push($this->createRequest('fr'));
$this->requestStack->push($subRequest = $this->createRequest('de'));
$event = new FinishRequestEvent($this->createHttpKernel(), $subRequest, HttpKernelInterface::SUB_REQUEST);
$this->listener->onKernelFinishRequest($event);
}
public function testLocaleIsSetToDefaultOnKernelFinishRequestWhenParentRequestDoesNotExist()
{
$this->localeAwareService
->expects($this->once())
->method('setLocale')
->with($this->equalTo('en'));
$this->requestStack->push($subRequest = $this->createRequest('de'));
$event = new FinishRequestEvent($this->createHttpKernel(), $subRequest, HttpKernelInterface::SUB_REQUEST);
$this->listener->onKernelFinishRequest($event);
}
public function testDefaultLocaleIsUsedOnExceptionsInOnKernelFinishRequest()
{
$this->localeAwareService
->expects($this->at(0))
->method('setLocale')
->will($this->throwException(new \InvalidArgumentException()));
$this->localeAwareService
->expects($this->at(1))
->method('setLocale')
->with($this->equalTo('en'));
$this->requestStack->push($this->createRequest('fr'));
$this->requestStack->push($subRequest = $this->createRequest('de'));
$event = new FinishRequestEvent($this->createHttpKernel(), $subRequest, HttpKernelInterface::SUB_REQUEST);
$this->listener->onKernelFinishRequest($event);
}
private function createHttpKernel()
{
return $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
}
private function createRequest($locale)
{
$request = new Request();
$request->setLocale($locale);
return $request;
}
}

View File

@@ -12,10 +12,12 @@
namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\LocaleListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class LocaleListenerTest extends TestCase
{
@@ -26,12 +28,28 @@ class LocaleListenerTest extends TestCase
$this->requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->disableOriginalConstructor()->getMock();
}
public function testDefaultLocaleWithoutSession()
public function testIsAnEventSubscriber()
{
$this->assertInstanceOf(EventSubscriberInterface::class, new LocaleListener($this->requestStack));
}
public function testRegisteredEvent()
{
$this->assertEquals(
[
KernelEvents::REQUEST => [['setDefaultLocale', 100], ['onKernelRequest', 16]],
KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]],
],
LocaleListener::getSubscribedEvents()
);
}
public function testDefaultLocale()
{
$listener = new LocaleListener($this->requestStack, 'fr');
$event = $this->getEvent($request = Request::create('/'));
$listener->onKernelRequest($event);
$listener->setDefaultLocale($event);
$this->assertEquals('fr', $request->getLocale());
}
@@ -95,8 +113,8 @@ class LocaleListenerTest extends TestCase
$this->assertEquals('de', $request->getLocale());
}
private function getEvent(Request $request)
private function getEvent(Request $request): RequestEvent
{
return new GetResponseEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
return new RequestEvent($this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock(), $request, HttpKernelInterface::MASTER_REQUEST);
}
}

View File

@@ -13,9 +13,9 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\Event\TerminateEvent;
use Symfony\Component\HttpKernel\EventListener\ProfilerListener;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Kernel;
@@ -59,12 +59,12 @@ class ProfilerListenerTest extends TestCase
$listener = new ProfilerListener($profiler, $requestStack, null, $onlyException);
// master request
$listener->onKernelResponse(new FilterResponseEvent($kernel, $masterRequest, Kernel::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, $masterRequest, Kernel::MASTER_REQUEST, $response));
// sub request
$listener->onKernelException(new GetResponseForExceptionEvent($kernel, $subRequest, Kernel::SUB_REQUEST, new HttpException(404)));
$listener->onKernelResponse(new FilterResponseEvent($kernel, $subRequest, Kernel::SUB_REQUEST, $response));
$listener->onKernelException(new ExceptionEvent($kernel, $subRequest, Kernel::SUB_REQUEST, new HttpException(404)));
$listener->onKernelResponse(new ResponseEvent($kernel, $subRequest, Kernel::SUB_REQUEST, $response));
$listener->onKernelTerminate(new PostResponseEvent($kernel, $masterRequest, $response));
$listener->onKernelTerminate(new TerminateEvent($kernel, $masterRequest, $response));
}
}

View File

@@ -15,7 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\ResponseListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -45,8 +45,8 @@ class ResponseListenerTest extends TestCase
{
$response = new Response('foo');
$event = new FilterResponseEvent($this->kernel, new Request(), HttpKernelInterface::SUB_REQUEST, $response);
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($this->kernel, new Request(), HttpKernelInterface::SUB_REQUEST, $response);
$this->dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('', $event->getResponse()->headers->get('content-type'));
}
@@ -58,8 +58,8 @@ class ResponseListenerTest extends TestCase
$response = new Response('foo');
$event = new FilterResponseEvent($this->kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($this->kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('ISO-8859-15', $response->getCharset());
}
@@ -72,8 +72,8 @@ class ResponseListenerTest extends TestCase
$response = new Response('foo');
$response->setCharset('ISO-8859-1');
$event = new FilterResponseEvent($this->kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($this->kernel, Request::create('/'), HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('ISO-8859-1', $response->getCharset());
}
@@ -87,8 +87,8 @@ class ResponseListenerTest extends TestCase
$request = Request::create('/');
$request->setRequestFormat('application/json');
$event = new FilterResponseEvent($this->kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($this->kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response);
$this->dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('ISO-8859-15', $response->getCharset());
}

View File

@@ -18,7 +18,7 @@ use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Controller\ArgumentResolver;
use Symfony\Component\HttpKernel\Controller\ControllerResolver;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\ExceptionListener;
use Symfony\Component\HttpKernel\EventListener\RouterListener;
use Symfony\Component\HttpKernel\EventListener\ValidateRequestListener;
@@ -52,7 +52,7 @@ class RouterListenerTest extends TestCase
->will($this->returnValue($context));
$listener = new RouterListener($urlMatcher, $this->requestStack);
$event = $this->createGetResponseEventForUri($uri);
$event = $this->createRequestEventForUri($uri);
$listener->onKernelRequest($event);
$this->assertEquals($expectedHttpPort, $context->getHttpPort());
@@ -70,13 +70,13 @@ class RouterListenerTest extends TestCase
];
}
private function createGetResponseEventForUri(string $uri): GetResponseEvent
private function createRequestEventForUri(string $uri): RequestEvent
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create($uri);
$request->attributes->set('_controller', null); // Prevents going in to routing process
return new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
return new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
}
/**
@@ -89,9 +89,9 @@ class RouterListenerTest extends TestCase
public function testRequestMatcher()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('http://localhost/');
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
$requestMatcher->expects($this->once())
@@ -105,9 +105,9 @@ class RouterListenerTest extends TestCase
public function testSubRequestWithDifferentMethod()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('http://localhost/', 'post');
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();
$requestMatcher->expects($this->any())
@@ -121,9 +121,9 @@ class RouterListenerTest extends TestCase
$listener->onKernelRequest($event);
// sub-request with another HTTP method
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('http://localhost/', 'get');
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::SUB_REQUEST);
$listener->onKernelRequest($event);
@@ -145,11 +145,11 @@ class RouterListenerTest extends TestCase
->method('info')
->with($this->equalTo($log), $this->equalTo($parameters));
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('http://localhost/');
$listener = new RouterListener($requestMatcher, $this->requestStack, new RequestContext(), $logger);
$listener->onKernelRequest(new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
}
public function getLoggingParameterData()
@@ -209,9 +209,9 @@ class RouterListenerTest extends TestCase
*/
public function testRequestWithBadHost()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('http://bad host %22/');
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$requestMatcher = $this->getMockBuilder('Symfony\Component\Routing\Matcher\RequestMatcherInterface')->getMock();

View File

@@ -15,7 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\SaveSessionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -27,7 +27,7 @@ class SaveSessionListenerTest extends TestCase
public function testOnlyTriggeredOnMasterRequest()
{
$listener = new SaveSessionListener();
$event = $this->getMockBuilder(FilterResponseEvent::class)->disableOriginalConstructor()->getMock();
$event = $this->getMockBuilder(ResponseEvent::class)->disableOriginalConstructor()->getMock();
$event->expects($this->once())->method('isMasterRequest')->willReturn(false);
$event->expects($this->never())->method('getRequest');
@@ -47,6 +47,6 @@ class SaveSessionListenerTest extends TestCase
$request = new Request();
$request->setSession($session);
$response = new Response();
$listener->onKernelResponse(new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response));
}
}

View File

@@ -19,9 +19,9 @@ use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\AbstractSessionListener;
use Symfony\Component\HttpKernel\EventListener\SessionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -31,7 +31,7 @@ class SessionListenerTest extends TestCase
public function testOnlyTriggeredOnMasterRequest()
{
$listener = $this->getMockForAbstractClass(AbstractSessionListener::class);
$event = $this->getMockBuilder(GetResponseEvent::class)->disableOriginalConstructor()->getMock();
$event = $this->getMockBuilder(RequestEvent::class)->disableOriginalConstructor()->getMock();
$event->expects($this->once())->method('isMasterRequest')->willReturn(false);
$event->expects($this->never())->method('getRequest');
@@ -57,7 +57,7 @@ class SessionListenerTest extends TestCase
$request = new Request();
$listener = new SessionListener($container);
$event = $this->getMockBuilder(GetResponseEvent::class)->disableOriginalConstructor()->getMock();
$event = $this->getMockBuilder(RequestEvent::class)->disableOriginalConstructor()->getMock();
$event->expects($this->once())->method('isMasterRequest')->willReturn(true);
$event->expects($this->once())->method('getRequest')->willReturn($request);
@@ -79,10 +79,10 @@ class SessionListenerTest extends TestCase
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
$request = new Request();
$listener->onKernelRequest(new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$response = new Response();
$listener->onKernelResponse(new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$this->assertTrue($response->headers->hasCacheControlDirective('private'));
$this->assertTrue($response->headers->hasCacheControlDirective('must-revalidate'));
@@ -102,12 +102,12 @@ class SessionListenerTest extends TestCase
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
$request = new Request();
$listener->onKernelRequest(new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$response = new Response();
$response->setSharedMaxAge(60);
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
$listener->onKernelResponse(new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
@@ -128,7 +128,7 @@ class SessionListenerTest extends TestCase
]);
$listener = new SessionListener($container);
$listener->onKernelResponse(new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response));
$this->assertTrue($response->headers->hasCacheControlDirective('public'));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
$this->assertFalse($response->headers->hasCacheControlDirective('must-revalidate'));
@@ -151,20 +151,20 @@ class SessionListenerTest extends TestCase
$request = new Request();
$response = new Response();
$response->setCache(['public' => true, 'max_age' => '30']);
$listener->onKernelRequest(new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelRequest(new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
$this->assertTrue($request->hasSession());
$subRequest = clone $request;
$this->assertSame($request->getSession(), $subRequest->getSession());
$listener->onKernelRequest(new GetResponseEvent($kernel, $subRequest, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelResponse(new FilterResponseEvent($kernel, $subRequest, HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelRequest(new RequestEvent($kernel, $subRequest, HttpKernelInterface::MASTER_REQUEST));
$listener->onKernelResponse(new ResponseEvent($kernel, $subRequest, HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onFinishRequest(new FinishRequestEvent($kernel, $subRequest, HttpKernelInterface::MASTER_REQUEST));
$this->assertFalse($response->headers->hasCacheControlDirective('private'));
$this->assertFalse($response->headers->hasCacheControlDirective('must-revalidate'));
$this->assertSame('30', $response->headers->getCacheControlDirective('max-age'));
$listener->onKernelResponse(new FilterResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response));
$listener->onKernelResponse(new ResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, $response));
$this->assertTrue($response->headers->hasCacheControlDirective('private'));
$this->assertTrue($response->headers->hasCacheControlDirective('must-revalidate'));

View File

@@ -15,7 +15,7 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\SurrogateListener;
use Symfony\Component\HttpKernel\HttpCache\Esi;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -31,8 +31,8 @@ class SurrogateListenerTest extends TestCase
$listener = new SurrogateListener(new Esi());
$dispatcher->addListener(KernelEvents::RESPONSE, [$listener, 'onKernelResponse']);
$event = new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::SUB_REQUEST, $response);
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($kernel, new Request(), HttpKernelInterface::SUB_REQUEST, $response);
$dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('', $event->getResponse()->headers->get('Surrogate-Control'));
}
@@ -45,8 +45,8 @@ class SurrogateListenerTest extends TestCase
$listener = new SurrogateListener(new Esi());
$dispatcher->addListener(KernelEvents::RESPONSE, [$listener, 'onKernelResponse']);
$event = new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('content="ESI/1.0"', $event->getResponse()->headers->get('Surrogate-Control'));
}
@@ -59,8 +59,8 @@ class SurrogateListenerTest extends TestCase
$listener = new SurrogateListener(new Esi());
$dispatcher->addListener(KernelEvents::RESPONSE, [$listener, 'onKernelResponse']);
$event = new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch(KernelEvents::RESPONSE, $event);
$event = new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, $response);
$dispatcher->dispatch($event, KernelEvents::RESPONSE);
$this->assertEquals('', $event->getResponse()->headers->get('Surrogate-Control'));
}

View File

@@ -15,8 +15,8 @@ use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Event\ResponseEvent;
use Symfony\Component\HttpKernel\EventListener\SessionListener;
use Symfony\Component\HttpKernel\EventListener\TestSessionListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -95,9 +95,9 @@ class TestSessionListenerTest extends TestCase
$this->sessionIsEmpty();
$this->fixSessionId('456');
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('/', 'GET', [], ['MOCKSESSID' => '123']);
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
$response = $this->filterResponse(new Request(), HttpKernelInterface::MASTER_REQUEST);
@@ -114,9 +114,9 @@ class TestSessionListenerTest extends TestCase
$this->sessionIsEmpty();
$this->fixSessionId('456');
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$request = Request::create('/', 'GET', [], ['MOCKSESSID' => '123']);
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
$response = new Response('', 200, ['Set-Cookie' => $existing]);
@@ -145,8 +145,8 @@ class TestSessionListenerTest extends TestCase
public function testDoesNotThrowIfRequestDoesNotHaveASession()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$event = new FilterResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, new Response());
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$event = new ResponseEvent($kernel, new Request(), HttpKernelInterface::MASTER_REQUEST, new Response());
$this->listener->onKernelResponse($event);
@@ -157,8 +157,8 @@ class TestSessionListenerTest extends TestCase
{
$request->setSession($this->session);
$response = $response ?: new Response();
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();
$event = new FilterResponseEvent($kernel, $request, $type, $response);
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$event = new ResponseEvent($kernel, $request, $type, $response);
$this->listener->onKernelResponse($event);

View File

@@ -14,11 +14,14 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\TranslatorListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Contracts\Translation\LocaleAwareInterface;
/**
* @group legacy
*/
class TranslatorListenerTest extends TestCase
{
private $listener;
@@ -39,7 +42,7 @@ class TranslatorListenerTest extends TestCase
->method('setLocale')
->with($this->equalTo('fr'));
$event = new GetResponseEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
}
@@ -54,7 +57,7 @@ class TranslatorListenerTest extends TestCase
->method('setLocale')
->with($this->equalTo('en'));
$event = new GetResponseEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($this->createHttpKernel(), $this->createRequest('fr'), HttpKernelInterface::MASTER_REQUEST);
$this->listener->onKernelRequest($event);
}

View File

@@ -14,7 +14,7 @@ namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\EventListener\ValidateRequestListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\KernelEvents;
@@ -41,8 +41,8 @@ class ValidateRequestListenerTest extends TestCase
$request->headers->set('X_FORWARDED_FOR', '3.3.3.3');
$dispatcher->addListener(KernelEvents::REQUEST, [new ValidateRequestListener(), 'onKernelRequest']);
$event = new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$event = new RequestEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$dispatcher->dispatch(KernelEvents::REQUEST, $event);
$dispatcher->dispatch($event, KernelEvents::REQUEST);
}
}

View File

@@ -6,8 +6,8 @@ use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
class AccessDeniedHttpExceptionTest extends HttpExceptionTest
{
protected function createException()
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
return new AccessDeniedHttpException();
return new AccessDeniedHttpException($message, $previous, $code, $headers);
}
}

View File

@@ -6,8 +6,8 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
class BadRequestHttpExceptionTest extends HttpExceptionTest
{
protected function createException()
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
return new BadRequestHttpException();
return new BadRequestHttpException($message, $previous, $code, $headers);
}
}

View File

@@ -6,8 +6,8 @@ use Symfony\Component\HttpKernel\Exception\ConflictHttpException;
class ConflictHttpExceptionTest extends HttpExceptionTest
{
protected function createException()
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
return new ConflictHttpException();
return new ConflictHttpException($message, $previous, $code, $headers);
}
}

View File

@@ -6,8 +6,8 @@ use Symfony\Component\HttpKernel\Exception\GoneHttpException;
class GoneHttpExceptionTest extends HttpExceptionTest
{
protected function createException()
protected function createException(string $message = null, \Throwable $previous = null, ?int $code = 0, array $headers = [])
{
return new GoneHttpException();
return new GoneHttpException($message, $previous, $code, $headers);
}
}

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