composer update

This commit is contained in:
Manish Verma
2018-12-05 10:50:52 +05:30
parent 9eabcacfa7
commit 4addd1e9c6
3328 changed files with 156676 additions and 138988 deletions

View File

@@ -33,23 +33,21 @@ abstract class Bundle implements BundleInterface
private $namespace;
/**
* Boots the Bundle.
* {@inheritdoc}
*/
public function boot()
{
}
/**
* Shutdowns the Bundle.
* {@inheritdoc}
*/
public function shutdown()
{
}
/**
* Builds the bundle.
*
* It is only ever called once when the cache is empty.
* {@inheritdoc}
*
* This method can be overridden to register compilation passes,
* other extensions, ...
@@ -80,10 +78,7 @@ abstract class Bundle implements BundleInterface
$expectedAlias = Container::underscore($basename);
if ($expectedAlias != $extension->getAlias()) {
throw new \LogicException(sprintf(
'Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.',
$expectedAlias, $extension->getAlias()
));
throw new \LogicException(sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', $expectedAlias, $extension->getAlias()));
}
$this->extension = $extension;
@@ -98,9 +93,7 @@ abstract class Bundle implements BundleInterface
}
/**
* Gets the Bundle namespace.
*
* @return string The Bundle namespace
* {@inheritdoc}
*/
public function getNamespace()
{
@@ -112,9 +105,7 @@ abstract class Bundle implements BundleInterface
}
/**
* Gets the Bundle directory path.
*
* @return string The Bundle absolute path
* {@inheritdoc}
*/
public function getPath()
{

View File

@@ -1,12 +1,21 @@
CHANGELOG
=========
4.2.0
-----
* deprecated `KernelInterface::getRootDir()` and the `kernel.root_dir` parameter
* deprecated `KernelInterface::getName()` and the `kernel.name` parameter
* deprecated the first and second constructor argument of `ConfigDataCollector`
* deprecated `ConfigDataCollector::getApplicationName()`
* deprecated `ConfigDataCollector::getApplicationVersion()`
4.1.0
-----
* added orphaned events support to `EventDataCollector`
* `ExceptionListener` now logs exceptions at priority `0` (previously logged at `-128`)
* Deprecated `service:action` syntax with a single colon to reference controllers. Use `service::method` instead.
* Added support for using `service::method` to reference controllers, making it consistent with other cases. It is recommended over the `service:action` syntax with a single colon, which will be deprecated in the future.
* Added the ability to profile individual argument value resolvers via the
`Symfony\Component\HttpKernel\Controller\ArgumentResolver\TraceableValueResolver`

View File

@@ -21,12 +21,16 @@ namespace Symfony\Component\HttpKernel\CacheWarmer;
class CacheWarmerAggregate implements CacheWarmerInterface
{
private $warmers;
private $debug;
private $deprecationLogsFilepath;
private $optionalsEnabled = false;
private $onlyOptionalsEnabled = false;
public function __construct(iterable $warmers = array())
public function __construct(iterable $warmers = array(), bool $debug = false, string $deprecationLogsFilepath = null)
{
$this->warmers = $warmers;
$this->debug = $debug;
$this->deprecationLogsFilepath = $deprecationLogsFilepath;
}
public function enableOptionalWarmers()
@@ -46,15 +50,62 @@ class CacheWarmerAggregate implements CacheWarmerInterface
*/
public function warmUp($cacheDir)
{
foreach ($this->warmers as $warmer) {
if (!$this->optionalsEnabled && $warmer->isOptional()) {
continue;
}
if ($this->onlyOptionalsEnabled && !$warmer->isOptional()) {
continue;
}
if ($this->debug) {
$collectedLogs = array();
$previousHandler = \defined('PHPUNIT_COMPOSER_INSTALL');
$previousHandler = $previousHandler ?: set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) {
if (E_USER_DEPRECATED !== $type && E_DEPRECATED !== $type) {
return $previousHandler ? $previousHandler($type, $message, $file, $line) : false;
}
$warmer->warmUp($cacheDir);
if (isset($collectedLogs[$message])) {
++$collectedLogs[$message]['count'];
return;
}
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
// Clean the trace by removing first frames added by the error handler itself.
for ($i = 0; isset($backtrace[$i]); ++$i) {
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
$backtrace = \array_slice($backtrace, 1 + $i);
break;
}
}
$collectedLogs[$message] = array(
'type' => $type,
'message' => $message,
'file' => $file,
'line' => $line,
'trace' => $backtrace,
'count' => 1,
);
});
}
try {
foreach ($this->warmers as $warmer) {
if (!$this->optionalsEnabled && $warmer->isOptional()) {
continue;
}
if ($this->onlyOptionalsEnabled && !$warmer->isOptional()) {
continue;
}
$warmer->warmUp($cacheDir);
}
} finally {
if ($this->debug && true !== $previousHandler) {
restore_error_handler();
if (file_exists($this->deprecationLogsFilepath)) {
$previousLogs = unserialize(file_get_contents($this->deprecationLogsFilepath));
$collectedLogs = array_merge($previousLogs, $collectedLogs);
}
file_put_contents($this->deprecationLogsFilepath, serialize(array_values($collectedLogs)));
}
}
}

View File

@@ -81,8 +81,9 @@ class Client extends BaseClient
*/
protected function getScript($request)
{
$kernel = str_replace("'", "\\'", serialize($this->kernel));
$request = str_replace("'", "\\'", serialize($request));
$kernel = var_export(serialize($this->kernel), true);
$request = var_export(serialize($request), true);
$errorReporting = error_reporting();
$requires = '';
@@ -91,7 +92,7 @@ class Client extends BaseClient
$r = new \ReflectionClass($class);
$file = \dirname(\dirname($r->getFileName())).'/autoload.php';
if (file_exists($file)) {
$requires .= "require_once '".str_replace("'", "\\'", $file)."';\n";
$requires .= 'require_once '.var_export($file, true).";\n";
}
}
}
@@ -107,8 +108,8 @@ error_reporting($errorReporting);
$requires
\$kernel = unserialize('$kernel');
\$request = unserialize('$request');
\$kernel = unserialize($kernel);
\$request = unserialize($request);
EOF;
return $code.$this->getHandleScript();

View File

@@ -26,7 +26,7 @@ class FileLocator extends BaseFileLocator
/**
* @param KernelInterface $kernel A KernelInterface instance
* @param null|string $path The path the global resource directory
* @param string|null $path The path the global resource directory
* @param array $paths An array of paths where to look for resources
*/
public function __construct(KernelInterface $kernel, string $path = null, array $paths = array())

View File

@@ -48,6 +48,10 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface
$controller = ltrim($controller, '\\');
}
if (!$this->container->has($controller) && false !== $i = strrpos($controller, ':')) {
$controller = substr($controller, 0, $i).strtolower(substr($controller, $i));
}
return $this->container->has($controller) && $this->container->get($controller)->has($argument->getName());
}
@@ -64,6 +68,11 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface
$controller = ltrim($controller, '\\');
}
if (!$this->container->has($controller)) {
$i = strrpos($controller, ':');
$controller = substr($controller, 0, $i).strtolower(substr($controller, $i));
}
try {
yield $this->container->get($controller)->get($argument->getName());
} catch (RuntimeException $e) {

View File

@@ -38,7 +38,7 @@ final class TraceableValueResolver implements ArgumentValueResolverInterface
public function supports(Request $request, ArgumentMetadata $argument): bool
{
$method = \get_class($this->inner).'::'.__FUNCTION__;
$this->stopwatch->start($method);
$this->stopwatch->start($method, 'controller.argument_value_resolver');
$return = $this->inner->supports($request, $argument);
@@ -53,7 +53,7 @@ final class TraceableValueResolver implements ArgumentValueResolverInterface
public function resolve(Request $request, ArgumentMetadata $argument): iterable
{
$method = \get_class($this->inner).'::'.__FUNCTION__;
$this->stopwatch->start($method);
$this->stopwatch->start($method, 'controller.argument_value_resolver');
yield from $this->inner->resolve($request, $argument);

View File

@@ -36,7 +36,7 @@ class ContainerControllerResolver extends ControllerResolver
{
if (1 === substr_count($controller, ':')) {
$controller = str_replace(':', '::', $controller);
@trigger_error(sprintf('Referencing controllers with a single colon is deprecated since Symfony 4.1. Use %s instead.', $controller), E_USER_DEPRECATED);
// TODO deprecate this in 5.1
}
return parent::createController($controller);

View File

@@ -45,7 +45,7 @@ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface
*
* @param \ReflectionParameter $parameter
*
* @return null|string
* @return string|null
*/
private function getType(\ReflectionParameter $parameter, \ReflectionFunctionAbstract $function)
{

View File

@@ -30,12 +30,15 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
private $version;
private $hasVarDumper;
/**
* @param string $name The name of the application using the web profiler
* @param string $version The version of the application using the web profiler
*/
public function __construct(string $name = null, string $version = null)
{
if (1 <= \func_num_args()) {
@trigger_error(sprintf('The "$name" argument in method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if (2 <= \func_num_args()) {
@trigger_error(sprintf('The "$version" argument in method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
$this->name = $name;
$this->version = $version;
$this->hasVarDumper = class_exists(LinkStub::class);
@@ -60,7 +63,6 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
'token' => $response->headers->get('X-Debug-Token'),
'symfony_version' => Kernel::VERSION,
'symfony_state' => 'unknown',
'name' => isset($this->kernel) ? $this->kernel->getName() : 'n/a',
'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a',
'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a',
'php_version' => PHP_VERSION,
@@ -68,8 +70,8 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
'php_intl_locale' => class_exists('Locale', false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a',
'php_timezone' => date_default_timezone_get(),
'xdebug_enabled' => \extension_loaded('xdebug'),
'apcu_enabled' => \extension_loaded('apcu') && ini_get('apc.enabled'),
'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && ini_get('opcache.enable'),
'apcu_enabled' => \extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN),
'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN),
'bundles' => array(),
'sapi_name' => \PHP_SAPI,
);
@@ -106,13 +108,23 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
$this->data = $this->cloneVar($this->data);
}
/**
* @deprecated since Symfony 4.2
*/
public function getApplicationName()
{
@trigger_error(sprintf('The method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
return $this->data['app_name'];
}
/**
* @deprecated since Symfony 4.2
*/
public function getApplicationVersion()
{
@trigger_error(sprintf('The method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
return $this->data['app_version'];
}
@@ -227,10 +239,14 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte
* Gets the application name.
*
* @return string The application name
*
* @deprecated since Symfony 4.2
*/
public function getAppName()
{
return $this->data['name'];
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
return 'n/a';
}
/**

View File

@@ -13,13 +13,14 @@ namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Service\ResetInterface;
/**
* DataCollectorInterface.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface DataCollectorInterface
interface DataCollectorInterface extends ResetInterface
{
/**
* Collects data for the given Request and Response.
@@ -32,9 +33,4 @@ interface DataCollectorInterface
* @return string The collector name
*/
public function getName();
/**
* Resets this data collector to its initial state.
*/
public function reset();
}

View File

@@ -204,7 +204,13 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
--$i;
}
if (!\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true) && stripos($h[$i], 'html')) {
if (isset($_SERVER['VAR_DUMPER_FORMAT'])) {
$html = 'html' === $_SERVER['VAR_DUMPER_FORMAT'];
} else {
$html = !\in_array(\PHP_SAPI, array('cli', 'phpdbg'), true) && stripos($h[$i], 'html');
}
if ($html) {
$dumper = new HtmlDumper('php://output', $this->charset);
$dumper->setDisplayOptions(array('fileLinkFormat' => $this->fileLinkFormat));
} else {

View File

@@ -16,6 +16,7 @@ use Symfony\Component\EventDispatcher\Debug\TraceableEventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Contracts\Service\ResetInterface;
/**
* EventDataCollector.
@@ -47,7 +48,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter
{
$this->data = array();
if ($this->dispatcher instanceof TraceableEventDispatcherInterface) {
if ($this->dispatcher instanceof ResetInterface) {
$this->dispatcher->reset();
}
}

View File

@@ -134,7 +134,7 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
$log['timestamp'] = $bootTime;
$log['priority'] = 100;
$log['priorityName'] = 'DEBUG';
$log['channel'] = '-';
$log['channel'] = null;
$log['scream'] = false;
unset($log['type'], $log['file'], $log['line'], $log['trace'], $log['trace'], $log['count']);
$logs[] = $log;

View File

@@ -95,6 +95,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
'status_code' => $statusCode,
'request_query' => $request->query->all(),
'request_request' => $request->request->all(),
'request_files' => $request->files->all(),
'request_headers' => $request->headers->all(),
'request_server' => $request->server->all(),
'request_cookies' => $request->cookies->all(),
@@ -153,7 +154,8 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
'controller' => $this->parseController($request->attributes->get('_controller')),
'status_code' => $statusCode,
'status_text' => Response::$statusTexts[(int) $statusCode],
))
)),
0, '/', null, $request->isSecure(), true, false, 'lax'
));
}
@@ -195,6 +197,11 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
return new ParameterBag($this->data['request_query']->getValue());
}
public function getRequestFiles()
{
return new ParameterBag($this->data['request_files']->getValue());
}
public function getRequestHeaders()
{
return new ParameterBag($this->data['request_headers']->getValue());
@@ -402,12 +409,25 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
if ($controller instanceof \Closure) {
$r = new \ReflectionFunction($controller);
return array(
$controller = array(
'class' => $r->getName(),
'method' => null,
'file' => $r->getFileName(),
'line' => $r->getStartLine(),
);
if (false !== strpos($r->name, '{closure}')) {
return $controller;
}
$controller['method'] = $r->name;
if ($class = $r->getClosureScopeClass()) {
$controller['class'] = $class->name;
} else {
return $r->name;
}
return $controller;
}
if (\is_object($controller)) {

View File

@@ -96,7 +96,7 @@ class FileLinkFormatter implements \Serializable
}
return array(
$request->getSchemeAndHttpHost().$request->getBaseUrl().$this->urlFormat,
$request->getSchemeAndHttpHost().$request->getBasePath().$this->urlFormat,
$this->baseDir.\DIRECTORY_SEPARATOR, '',
);
}

View File

@@ -122,7 +122,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
$args = array();
foreach ($parameters as $p) {
/** @var \ReflectionParameter $p */
$type = $target = ProxyHelper::getTypeHint($r, $p, true);
$type = ltrim($target = ProxyHelper::getTypeHint($r, $p), '\\');
$invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
if (isset($arguments[$r->name][$p->name])) {
@@ -134,7 +134,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
} elseif ($p->allowsNull() && !$p->isOptional()) {
$invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
}
} elseif (isset($bindings[$bindingName = '$'.$p->name]) || isset($bindings[$bindingName = $type])) {
} elseif (isset($bindings[$bindingName = $type.' $'.$p->name]) || isset($bindings[$bindingName = '$'.$p->name]) || isset($bindings[$bindingName = $type])) {
$binding = $bindings[$bindingName];
list($bindingValue, $bindingId) = $binding->getValues();
@@ -150,7 +150,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
}
continue;
} elseif (!$type || !$autowire) {
} elseif (!$type || !$autowire || '\\' !== $target[0]) {
continue;
} elseif (!$p->allowsNull()) {
$invalidBehavior = ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE;
@@ -171,7 +171,8 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface
throw new InvalidArgumentException($message);
}
$args[$p->name] = $type ? new TypedReference($target, $type, $invalidBehavior) : new Reference($target, $invalidBehavior);
$target = ltrim($target, '\\');
$args[$p->name] = $type ? new TypedReference($target, $type, $invalidBehavior, $p->name) : new Reference($target, $invalidBehavior);
}
// register the maps as a per-method service-locators
if ($args) {

View File

@@ -11,6 +11,8 @@
namespace Symfony\Component\HttpKernel\DependencyInjection;
use Symfony\Contracts\Service\ResetInterface;
/**
* Resets provided services.
*
@@ -19,7 +21,7 @@ namespace Symfony\Component\HttpKernel\DependencyInjection;
*
* @internal
*/
class ServicesResetter
class ServicesResetter implements ResetInterface
{
private $resettableServices;
private $resetMethods;

View File

@@ -71,14 +71,17 @@ abstract class AbstractSessionListener implements EventSubscriberInterface
return;
}
$response = $event->getResponse();
$autoCacheControl = !$response->headers->has(self::NO_AUTO_CACHE_CONTROL_HEADER);
// Always remove the internal header if present
$response->headers->remove(self::NO_AUTO_CACHE_CONTROL_HEADER);
if (!$session = $this->container && $this->container->has('initialized_session') ? $this->container->get('initialized_session') : $event->getRequest()->getSession()) {
return;
}
$response = $event->getResponse();
if ($session instanceof Session ? $session->getUsageIndex() !== end($this->sessionUsageStack) : $session->isStarted()) {
if (!$response->headers->has(self::NO_AUTO_CACHE_CONTROL_HEADER)) {
if ($autoCacheControl) {
$response
->setPrivate()
->setMaxAge(0)
@@ -86,9 +89,6 @@ abstract class AbstractSessionListener implements EventSubscriberInterface
}
}
// Always remove the internal header if present
$response->headers->remove(self::NO_AUTO_CACHE_CONTROL_HEADER);
if ($session->isStarted()) {
/*
* Saves the session, in case it is still open, before sending the response/headers.

View File

@@ -30,6 +30,12 @@ use Symfony\Component\HttpKernel\KernelEvents;
abstract class AbstractTestSessionListener implements EventSubscriberInterface
{
private $sessionId;
private $sessionOptions;
public function __construct(array $sessionOptions = array())
{
$this->sessionOptions = $sessionOptions;
}
public function onKernelRequest(GetResponseEvent $event)
{
@@ -72,7 +78,12 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
}
if ($session instanceof Session ? !$session->isEmpty() || (null !== $this->sessionId && $session->getId() !== $this->sessionId) : $wasStarted) {
$params = session_get_cookie_params();
$params = session_get_cookie_params() + array('samesite' => null);
foreach ($this->sessionOptions as $k => $v) {
if (0 === strpos($k, 'cookie_')) {
$params[substr($k, 7)] = $v;
}
}
foreach ($event->getResponse()->headers->getCookies() as $cookie) {
if ($session->getName() === $cookie->getName() && $params['path'] === $cookie->getPath() && $params['domain'] == $cookie->getDomain()) {
@@ -80,7 +91,7 @@ abstract class AbstractTestSessionListener implements EventSubscriberInterface
}
}
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']));
$event->getResponse()->headers->setCookie(new Cookie($session->getName(), $session->getId(), 0 === $params['lifetime'] ? 0 : time() + $params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly'], false, $params['samesite'] ?: null));
$this->sessionId = $session->getId();
}
}

View File

@@ -13,9 +13,11 @@ namespace Symfony\Component\HttpKernel\EventListener;
use Psr\Log\LoggerInterface;
use Symfony\Component\Debug\Exception\FlattenException;
use Symfony\Component\Debug\ExceptionHandler;
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;
@@ -33,23 +35,39 @@ class ExceptionListener implements EventSubscriberInterface
protected $controller;
protected $logger;
protected $debug;
private $charset;
private $fileLinkFormat;
private $isTerminating = false;
public function __construct($controller, LoggerInterface $logger = null, $debug = false)
public function __construct($controller, LoggerInterface $logger = null, $debug = false, string $charset = null, $fileLinkFormat = null)
{
$this->controller = $controller;
$this->logger = $logger;
$this->debug = $debug;
$this->charset = $charset;
$this->fileLinkFormat = $fileLinkFormat;
}
public function logKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$e = FlattenException::create($event->getException());
$this->logException($exception, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', \get_class($exception), $exception->getMessage(), $exception->getFile(), $exception->getLine()));
$this->logException($event->getException(), sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), $e->getFile(), $e->getLine()));
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
if (null === $this->controller) {
if (!$event->isMasterRequest()) {
return;
}
if (!$this->isTerminating) {
$this->isTerminating = true;
return;
}
$this->isTerminating = false;
}
$exception = $event->getException();
$request = $this->duplicateRequest($exception, $event->getRequest());
$eventDispatcher = \func_num_args() > 2 ? func_get_arg(2) : null;
@@ -57,7 +75,9 @@ class ExceptionListener implements EventSubscriberInterface
try {
$response = $event->getKernel()->handle($request, HttpKernelInterface::SUB_REQUEST, false);
} catch (\Exception $e) {
$this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', \get_class($e), $e->getMessage(), $e->getFile(), $e->getLine()));
$f = FlattenException::create($e);
$this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), $e->getFile(), $e->getLine()));
$wrapper = $e;
@@ -85,6 +105,11 @@ class ExceptionListener implements EventSubscriberInterface
}
}
public function reset()
{
$this->isTerminating = false;
}
public static function getSubscribedEvents()
{
return array(
@@ -118,13 +143,17 @@ class ExceptionListener implements EventSubscriberInterface
* @param \Exception $exception The thrown exception
* @param Request $request The original request
*
* @return Request $request The cloned request
* @return Request The cloned request
*/
protected function duplicateRequest(\Exception $exception, Request $request)
{
$attributes = array(
'_controller' => $this->controller,
'exception' => FlattenException::create($exception),
'exception' => $exception = FlattenException::create($exception),
'_controller' => $this->controller ?: function () use ($exception) {
$handler = new ExceptionHandler($this->debug, $this->charset, $this->fileLinkFormat);
return new Response($handler->getHtml($exception), $exception->getStatusCode(), $exception->getHeaders());
},
'logger' => $this->logger instanceof DebugLoggerInterface ? $this->logger : null,
);
$request = $request->duplicate(null, null, $attributes);

View File

@@ -12,10 +12,15 @@
namespace Symfony\Component\HttpKernel\EventListener;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
/**
* Sets the session in the request.
*
* When the passed container contains a "session_storage" entry which
* holds a NativeSessionStorage instance, the "cookie_secure" option
* will be set to true whenever the current master request is secure.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final
@@ -33,6 +38,13 @@ class SessionListener extends AbstractSessionListener
return;
}
if ($this->container->has('session_storage')
&& ($storage = $this->container->get('session_storage')) instanceof NativeSessionStorage
&& $this->container->get('request_stack')->getMasterRequest()->isSecure()
) {
$storage->setOptions(array('cookie_secure' => true));
}
return $this->container->get('session');
}
}

View File

@@ -24,9 +24,10 @@ class TestSessionListener extends AbstractTestSessionListener
{
private $container;
public function __construct(ContainerInterface $container)
public function __construct(ContainerInterface $container, array $sessionOptions = array())
{
$this->container = $container;
parent::__construct($sessionOptions);
}
protected function getSession()

View File

@@ -17,7 +17,8 @@ use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Translation\TranslatorInterface;
use Symfony\Component\Translation\TranslatorInterface as LegacyTranslatorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Synchronizes the locale between the request and the translator.
@@ -29,8 +30,14 @@ class TranslatorListener implements EventSubscriberInterface
private $translator;
private $requestStack;
public function __construct(TranslatorInterface $translator, RequestStack $requestStack)
/**
* @param TranslatorInterface $translator
*/
public function __construct($translator, RequestStack $requestStack)
{
if (!$translator instanceof LegacyTranslatorInterface && !$translator instanceof TranslatorInterface) {
throw new \TypeError(sprintf('Argument 1 passed to %s() must be an instance of %s, %s given.', __METHOD__, TranslatorInterface::class, \is_object($translator) ? \get_class($translator) : \gettype($translator)));
}
$this->translator = $translator;
$this->requestStack = $requestStack;
}

View File

@@ -0,0 +1,78 @@
<?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\Exception;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
*/
class ControllerDoesNotReturnResponseException extends \LogicException
{
public function __construct(string $message, callable $controller, string $file, int $line)
{
parent::__construct($message);
if (!$controllerDefinition = $this->parseControllerDefinition($controller)) {
return;
}
$this->file = $controllerDefinition['file'];
$this->line = $controllerDefinition['line'];
$r = new \ReflectionProperty(\Exception::class, 'trace');
$r->setAccessible(true);
$r->setValue($this, array_merge(array(
array(
'line' => $line,
'file' => $file,
),
), $this->getTrace()));
}
private function parseControllerDefinition(callable $controller): ?array
{
if (\is_string($controller) && false !== strpos($controller, '::')) {
$controller = explode('::', $controller);
}
if (\is_array($controller)) {
try {
$r = new \ReflectionMethod($controller[0], $controller[1]);
return array(
'file' => $r->getFileName(),
'line' => $r->getEndLine(),
);
} catch (\ReflectionException $e) {
return null;
}
}
if ($controller instanceof \Closure) {
$r = new \ReflectionFunction($controller);
return array(
'file' => $r->getFileName(),
'line' => $r->getEndLine(),
);
}
if (\is_object($controller)) {
$r = new \ReflectionClass($controller);
return array(
'file' => $r->getFileName(),
'line' => $r->getEndLine(),
);
}
return null;
}
}

View File

@@ -125,6 +125,13 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
}
$setSession($subRequest, $request);
if ($request->get('_format')) {
$subRequest->attributes->set('_format', $request->get('_format'));
}
if ($request->getDefaultLocale() !== $request->getLocale()) {
$subRequest->setLocale($request->getLocale());
}
return $subRequest;
}

View File

@@ -93,7 +93,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
/**
* Gets the current store.
*
* @return StoreInterface $store A StoreInterface instance
* @return StoreInterface A StoreInterface instance
*/
public function getStore()
{

View File

@@ -28,6 +28,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
@@ -146,7 +147,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
$arguments = $event->getArguments();
// call controller
$response = \call_user_func_array($controller, $arguments);
$response = $controller(...$arguments);
// view
if (!$response instanceof Response) {
@@ -156,13 +157,14 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
if ($event->hasResponse()) {
$response = $event->getResponse();
} else {
$msg = sprintf('The controller must return a response (%s given).', $this->varToString($response));
$msg = sprintf('The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned %s.', $this->varToString($response));
// the user may have forgotten to return something
if (null === $response) {
$msg .= ' Did you forget to add a return statement somewhere in your controller?';
}
throw new \LogicException($msg);
throw new ControllerDoesNotReturnResponseException($msg, $controller, __FILE__, __LINE__ - 17);
}
}
@@ -251,20 +253,20 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
private function varToString($var): string
{
if (\is_object($var)) {
return sprintf('Object(%s)', \get_class($var));
return sprintf('an object of type %s', \get_class($var));
}
if (\is_array($var)) {
$a = array();
foreach ($var as $k => $v) {
$a[] = sprintf('%s => %s', $k, $this->varToString($v));
$a[] = sprintf('%s => ...', $k);
}
return sprintf('Array(%s)', implode(', ', $a));
return sprintf('an array ([%s])', mb_substr(implode(', ', $a), 0, 255));
}
if (\is_resource($var)) {
return sprintf('Resource(%s)', get_resource_type($var));
return sprintf('a resource (%s)', get_resource_type($var));
}
if (null === $var) {
@@ -272,11 +274,19 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
}
if (false === $var) {
return 'false';
return 'a boolean value (false)';
}
if (true === $var) {
return 'true';
return 'a boolean value (true)';
}
if (\is_string($var)) {
return sprintf('a string ("%s%s")', mb_substr($var, 0, 255), mb_strlen($var) > 255 ? '...' : '');
}
if (is_numeric($var)) {
return sprintf('a number (%s)', (string) $var);
}
return (string) $var;

View File

@@ -16,6 +16,7 @@ use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\Loader\DelegatingLoader;
use Symfony\Component\Config\Loader\LoaderResolver;
use Symfony\Component\Debug\DebugClassLoader;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
@@ -41,6 +42,9 @@ use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfiguration
*
* It manages an environment made of bundles.
*
* Environment names must always start with a letter and
* they must only contain letters and numbers.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface
@@ -51,10 +55,16 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
protected $bundles = array();
protected $container;
/**
* @deprecated since Symfony 4.2
*/
protected $rootDir;
protected $environment;
protected $debug;
protected $booted = false;
/**
* @deprecated since Symfony 4.2
*/
protected $name;
protected $startTime;
@@ -63,22 +73,22 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
private $requestStackSize = 0;
private $resetServices = false;
const VERSION = '4.1.4';
const VERSION_ID = 40104;
const VERSION = '4.2.0';
const VERSION_ID = 40200;
const MAJOR_VERSION = 4;
const MINOR_VERSION = 1;
const RELEASE_VERSION = 4;
const MINOR_VERSION = 2;
const RELEASE_VERSION = 0;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '01/2019';
const END_OF_LIFE = '07/2019';
const END_OF_MAINTENANCE = '07/2019';
const END_OF_LIFE = '01/2020';
public function __construct(string $environment, bool $debug)
{
$this->environment = $environment;
$this->debug = $debug;
$this->rootDir = $this->getRootDir();
$this->name = $this->getName();
$this->rootDir = $this->getRootDir(false);
$this->name = $this->getName(false);
}
public function __clone()
@@ -90,7 +100,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
}
/**
* Boots the current kernel.
* {@inheritdoc}
*/
public function boot()
{
@@ -215,7 +225,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
public function getBundle($name)
{
if (!isset($this->bundles[$name])) {
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, \get_class($this)));
$class = \get_class($this);
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).'@anonymous' : $class;
throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your %s.php file?', $name, $class));
}
return $this->bundles[$name];
@@ -244,19 +257,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
$isResource = 0 === strpos($path, 'Resources') && null !== $dir;
$overridePath = substr($path, 9);
$resourceBundle = null;
$bundle = $this->getBundle($bundleName);
$files = array();
if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) {
if (null !== $resourceBundle) {
throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.',
$file,
$resourceBundle,
$dir.'/'.$bundle->getName().$overridePath
));
}
$files[] = $file;
}
@@ -265,7 +269,6 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
return $file;
}
$files[] = $file;
$resourceBundle = $bundle->getName();
}
if (\count($files) > 0) {
@@ -277,9 +280,15 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
/**
* {@inheritdoc}
*
* @deprecated since Symfony 4.2
*/
public function getName()
public function getName(/* $triggerDeprecation = true */)
{
if (0 === \func_num_args() || func_get_arg(0)) {
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED);
}
if (null === $this->name) {
$this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir));
if (ctype_digit($this->name[0])) {
@@ -308,9 +317,15 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
/**
* {@inheritdoc}
*
* @deprecated since Symfony 4.2, use getProjectDir() instead
*/
public function getRootDir()
public function getRootDir(/* $triggerDeprecation = true */)
{
if (0 === \func_num_args() || func_get_arg(0)) {
@trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2, use getProjectDir() instead.', __METHOD__), E_USER_DEPRECATED);
}
if (null === $this->rootDir) {
$r = new \ReflectionObject($this);
$this->rootDir = \dirname($r->getFileName());
@@ -370,7 +385,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
public function getCacheDir()
{
return $this->rootDir.'/cache/'.$this->environment;
return $this->getProjectDir().'/var/cache/'.$this->environment;
}
/**
@@ -378,7 +393,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
public function getLogDir()
{
return $this->rootDir.'/logs';
return $this->getProjectDir().'/var/log';
}
/**
@@ -431,7 +446,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
*/
protected function getContainerClass()
{
return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
$class = \get_class($this);
$class = 'c' === $class[0] && 0 === strpos($class, "class@anonymous\0") ? get_parent_class($class).ContainerBuilder::hash($class) : $class;
return $this->name.str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container';
}
/**
@@ -493,7 +511,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
return;
}
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
$backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 5);
// Clean the trace by removing first frames added by the error handler itself.
for ($i = 0; isset($backtrace[$i]); ++$i) {
if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
@@ -501,13 +519,20 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
break;
}
}
// Remove frames added by DebugClassLoader.
for ($i = \count($backtrace) - 2; 0 < $i; --$i) {
if (DebugClassLoader::class === ($backtrace[$i]['class'] ?? null)) {
$backtrace = array($backtrace[$i + 1]);
break;
}
}
$collectedLogs[$message] = array(
'type' => $type,
'message' => $message,
'file' => $file,
'line' => $line,
'trace' => $backtrace,
'trace' => array($backtrace[0]),
'count' => 1,
);
});
@@ -582,10 +607,16 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
}
return array(
/*
* @deprecated since Symfony 4.2, use kernel.project_dir instead
*/
'kernel.root_dir' => realpath($this->rootDir) ?: $this->rootDir,
'kernel.project_dir' => realpath($this->getProjectDir()) ?: $this->getProjectDir(),
'kernel.environment' => $this->environment,
'kernel.debug' => $this->debug,
/*
* @deprecated since Symfony 4.2
*/
'kernel.name' => $this->name,
'kernel.cache_dir' => realpath($cacheDir = $this->warmupDir ?: $this->getCacheDir()) ?: $cacheDir,
'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),

View File

@@ -21,6 +21,8 @@ use Symfony\Component\HttpKernel\Bundle\BundleInterface;
* It manages an environment made of application kernel and bundles.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @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
{
@@ -100,6 +102,8 @@ interface KernelInterface extends HttpKernelInterface, \Serializable
* Gets the name of the kernel.
*
* @return string The kernel name
*
* @deprecated since Symfony 4.2
*/
public function getName();
@@ -121,13 +125,15 @@ interface KernelInterface extends HttpKernelInterface, \Serializable
* Gets the application root dir (path of the project's Kernel class).
*
* @return string The Kernel root dir
*
* @deprecated since Symfony 4.2
*/
public function getRootDir();
/**
* Gets the current container.
*
* @return ContainerInterface A ContainerInterface instance
* @return ContainerInterface|null A ContainerInterface instance or null when the Kernel is shutdown
*/
public function getContainer();

View File

@@ -89,7 +89,7 @@ class Profile
/**
* Returns the parent token.
*
* @return null|string The parent token
* @return string|null The parent token
*/
public function getParentToken()
{

View File

@@ -17,13 +17,14 @@ use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
use Symfony\Component\HttpKernel\DataCollector\LateDataCollectorInterface;
use Symfony\Contracts\Service\ResetInterface;
/**
* Profiler.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Profiler
class Profiler implements ResetInterface
{
private $storage;

View File

@@ -14,6 +14,14 @@ namespace Symfony\Component\HttpKernel\Profiler;
/**
* ProfilerStorageInterface.
*
* This interface exists for historical reasons. The only supported
* implementation is FileProfilerStorage.
*
* As the profiler must only be used on non-production servers, the file storage
* is more than enough and no other implementations will ever be supported.
*
* @internal since 4.2
*
* @author Fabien Potencier <fabien@symfony.com>
*/
interface ProfilerStorageInterface

View File

@@ -20,7 +20,7 @@ class ChainCacheClearerTest extends TestCase
public static function setUpBeforeClass()
{
self::$cacheDir = tempnam(sys_get_temp_dir(), 'sf2_cache_clearer_dir');
self::$cacheDir = tempnam(sys_get_temp_dir(), 'sf_cache_clearer_dir');
}
public static function tearDownAfterClass()

View File

@@ -20,7 +20,7 @@ class CacheWarmerAggregateTest extends TestCase
public static function setUpBeforeClass()
{
self::$cacheDir = tempnam(sys_get_temp_dir(), 'sf2_cache_warmer_dir');
self::$cacheDir = tempnam(sys_get_temp_dir(), 'sf_cache_warmer_dir');
}
public static function tearDownAfterClass()

View File

@@ -20,7 +20,7 @@ class CacheWarmerTest extends TestCase
public static function setUpBeforeClass()
{
self::$cacheFile = tempnam(sys_get_temp_dir(), 'sf2_cache_warmer_dir');
self::$cacheFile = tempnam(sys_get_temp_dir(), 'sf_cache_warmer_dir');
}
public static function tearDownAfterClass()

View File

@@ -61,13 +61,13 @@ class ClientTest extends TestCase
$m->setAccessible(true);
$response = new Response();
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true, false, null));
$domResponse = $m->invoke($client, $response);
$this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie'));
$response = new Response();
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie($cookie2 = new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true));
$response->headers->setCookie($cookie1 = new Cookie('foo', 'bar', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true, false, null));
$response->headers->setCookie($cookie2 = new Cookie('foo1', 'bar1', \DateTime::createFromFormat('j-M-Y H:i:s T', '15-Feb-2009 20:00:00 GMT')->format('U'), '/foo', 'http://example.com', true, true, false, null));
$domResponse = $m->invoke($client, $response);
$this->assertSame((string) $cookie1, $domResponse->getHeader('Set-Cookie'));
$this->assertSame(array((string) $cookie1, (string) $cookie2), $domResponse->getHeader('Set-Cookie', false));

View File

@@ -68,6 +68,24 @@ class ServiceValueResolverTest extends TestCase
$this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument));
}
public function testExistingControllerWithMethodNameStartUppercase()
{
$resolver = new ServiceValueResolver(new ServiceLocator(array(
'App\\Controller\\Mine::method' => function () {
return new ServiceLocator(array(
'dummy' => function () {
return new DummyService();
},
));
},
)));
$request = $this->requestWithAttributes(array('_controller' => 'App\\Controller\\Mine::Method'));
$argument = new ArgumentMetadata('dummy', DummyService::class, false, false, null);
$this->assertTrue($resolver->supports($request, $argument));
$this->assertYieldEquals(array(new DummyService()), $resolver->resolve($request, $argument));
}
public function testControllerNameIsAnArray()
{
$resolver = new ServiceValueResolver(new ServiceLocator(array(

View File

@@ -19,10 +19,6 @@ use Symfony\Component\HttpKernel\Controller\ContainerControllerResolver;
class ContainerControllerResolverTest extends ControllerResolverTest
{
/**
* @group legacy
* @expectedDeprecation Referencing controllers with a single colon is deprecated since Symfony 4.1. Use foo::action instead.
*/
public function testGetControllerServiceWithSingleColon()
{
$service = new ControllerTestService('foo');

View File

@@ -30,7 +30,6 @@ class ConfigDataCollectorTest extends TestCase
$this->assertSame('test', $c->getEnv());
$this->assertTrue($c->isDebug());
$this->assertSame('config', $c->getName());
$this->assertSame('testkernel', $c->getAppName());
$this->assertRegExp('~^'.preg_quote($c->getPhpVersion(), '~').'~', PHP_VERSION);
$this->assertRegExp('~'.preg_quote((string) $c->getPhpVersionExtra(), '~').'$~', PHP_VERSION);
$this->assertSame(PHP_INT_SIZE * 8, $c->getPhpArchitecture());
@@ -39,18 +38,29 @@ class ConfigDataCollectorTest extends TestCase
$this->assertSame(Kernel::VERSION, $c->getSymfonyVersion());
$this->assertNull($c->getToken());
$this->assertSame(\extension_loaded('xdebug'), $c->hasXDebug());
$this->assertSame(\extension_loaded('Zend OPcache') && ini_get('opcache.enable'), $c->hasZendOpcache());
$this->assertSame(\extension_loaded('apcu') && ini_get('apc.enabled'), $c->hasApcu());
$this->assertSame(\extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN), $c->hasZendOpcache());
$this->assertSame(\extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN), $c->hasApcu());
}
/**
* @group legacy
* @expectedDeprecation The "$name" argument in method "Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector::__construct()" is deprecated since Symfony 4.2.
* @expectedDeprecation The "$version" argument in method "Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector::__construct()" is deprecated since Symfony 4.2.
* @expectedDeprecation The method "Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector::getApplicationName()" is deprecated since Symfony 4.2.
* @expectedDeprecation The method "Symfony\Component\HttpKernel\DataCollector\ConfigDataCollector::getApplicationVersion()" is deprecated since Symfony 4.2.
*/
public function testLegacy()
{
$c = new ConfigDataCollector('name', null);
$c->collect(new Request(), new Response());
$this->assertSame('name', $c->getApplicationName());
$this->assertNull($c->getApplicationVersion());
}
}
class KernelForTest extends Kernel
{
public function getName()
{
return 'testkernel';
}
public function registerBundles()
{
}

View File

@@ -225,6 +225,8 @@ class RequestDataCollectorTest extends TestCase
$cookie = $this->getCookieByName($response, 'sf_redirect');
$this->assertNotEmpty($cookie->getValue());
$this->assertSame('lax', $cookie->getSameSite());
$this->assertFalse($cookie->isSecure());
}
public function testItCollectsTheRedirectionAndClearTheCookie()
@@ -274,9 +276,9 @@ class RequestDataCollectorTest extends TestCase
$response->setStatusCode(200);
$response->headers->set('Content-Type', 'application/json');
$response->headers->set('X-Foo-Bar', null);
$response->headers->setCookie(new Cookie('foo', 'bar', 1, '/foo', 'localhost', true, true));
$response->headers->setCookie(new Cookie('bar', 'foo', new \DateTime('@946684800')));
$response->headers->setCookie(new Cookie('bazz', 'foo', '2000-12-12'));
$response->headers->setCookie(new Cookie('foo', 'bar', 1, '/foo', 'localhost', true, true, false, null));
$response->headers->setCookie(new Cookie('bar', 'foo', new \DateTime('@946684800'), '/', null, false, true, false, null));
$response->headers->setCookie(new Cookie('bazz', 'foo', '2000-12-12', '/', null, false, true, false, null));
return $response;
}

View File

@@ -37,7 +37,6 @@ class FileLinkFormatterTest extends TestCase
public function testWhenFileLinkFormatAndRequest()
{
$file = __DIR__.\DIRECTORY_SEPARATOR.'file.php';
$baseDir = __DIR__;
$requestStack = new RequestStack();
$request = new Request();
$requestStack->push($request);
@@ -56,12 +55,12 @@ class FileLinkFormatterTest extends TestCase
$request->server->set('SERVER_NAME', 'www.example.org');
$request->server->set('SERVER_PORT', 80);
$request->server->set('SCRIPT_NAME', '/app.php');
$request->server->set('SCRIPT_FILENAME', '/web/app.php');
$request->server->set('REQUEST_URI', '/app.php/example');
$request->server->set('SCRIPT_NAME', '/index.php');
$request->server->set('SCRIPT_FILENAME', '/public/index.php');
$request->server->set('REQUEST_URI', '/index.php/example');
$sut = new FileLinkFormatter(null, $requestStack, __DIR__, '/_profiler/open?file=%f&line=%l#line%l');
$this->assertSame('http://www.example.org/app.php/_profiler/open?file=file.php&line=3#line3', $sut->format($file, 3));
$this->assertSame('http://www.example.org/_profiler/open?file=file.php&line=3#line3', $sut->format($file, 3));
}
}

View File

@@ -149,7 +149,7 @@ class RegisterControllerArgumentLocatorsPassTest extends TestCase
$this->assertSame(ServiceLocator::class, $locator->getClass());
$this->assertFalse($locator->isPublic());
$expected = array('bar' => new ServiceClosureArgument(new TypedReference(ControllerDummy::class, ControllerDummy::class, ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE)));
$expected = array('bar' => new ServiceClosureArgument(new TypedReference(ControllerDummy::class, ControllerDummy::class, ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE, 'bar')));
$this->assertEquals($expected, $locator->getArgument(0));
}
@@ -309,16 +309,23 @@ class RegisterControllerArgumentLocatorsPassTest extends TestCase
public function provideBindings()
{
return array(array(ControllerDummy::class), array('$bar'));
return array(
array(ControllerDummy::class.'$bar'),
array(ControllerDummy::class),
array('$bar'),
);
}
public function testBindScalarValueToControllerArgument()
/**
* @dataProvider provideBindScalarValueToControllerArgument
*/
public function testBindScalarValueToControllerArgument($bindingKey)
{
$container = new ContainerBuilder();
$resolver = $container->register('argument_resolver.service')->addArgument(array());
$container->register('foo', ArgumentWithoutTypeController::class)
->setBindings(array('$someArg' => '%foo%'))
->setBindings(array($bindingKey => '%foo%'))
->addTag('controller.service_arguments');
$container->setParameter('foo', 'foo_val');
@@ -341,6 +348,12 @@ class RegisterControllerArgumentLocatorsPassTest extends TestCase
$this->assertSame('foo_val', $container->get((string) $reference));
}
public function provideBindScalarValueToControllerArgument()
{
yield array('$someArg');
yield array('string $someArg');
}
public function testBindingsOnChildDefinitions()
{
$container = new ContainerBuilder();
@@ -420,7 +433,7 @@ class NonExistentClassOptionalController
class ArgumentWithoutTypeController
{
public function fooAction($someArg)
public function fooAction(string $someArg)
{
}
}

View File

@@ -155,6 +155,25 @@ class ExceptionListenerTest extends TestCase
$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');
}
public function testNullController()
{
$listener = new ExceptionListener(null);
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->getMock();
$kernel->expects($this->once())->method('handle')->will($this->returnCallback(function (Request $request) {
$controller = $request->attributes->get('_controller');
return $controller();
}));
$request = Request::create('/');
$event = new GetResponseForExceptionEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST, new \Exception('foo'));
$listener->onKernelException($event);
$this->assertNull($event->getResponse());
$listener->onKernelException($event);
$this->assertContains('Whoops, looks like something went wrong.', $event->getResponse()->getContent());
}
}
class TestLogger extends Logger implements DebugLoggerInterface

View File

@@ -106,17 +106,24 @@ class SessionListenerTest extends TestCase
$this->assertFalse($response->headers->has(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER));
}
public function testUninitilizedSession()
public function testUninitializedSession()
{
$event = $this->getMockBuilder(FilterResponseEvent::class)->disableOriginalConstructor()->getMock();
$event->expects($this->once())->method('isMasterRequest')->willReturn(true);
$kernel = $this->getMockBuilder(HttpKernelInterface::class)->disableOriginalConstructor()->getMock();
$response = new Response();
$response->setSharedMaxAge(60);
$response->headers->set(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER, 'true');
$container = new ServiceLocator(array(
'initialized_session' => function () {},
));
$listener = new SessionListener($container);
$listener->onKernelResponse($event);
$listener->onKernelResponse(new FilterResponseEvent($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'));
$this->assertSame('60', $response->headers->getCacheControlDirective('s-maxage'));
$this->assertFalse($response->headers->has(AbstractSessionListener::NO_AUTO_CACHE_CONTROL_HEADER));
}
public function testSurrogateMasterRequestIsPublic()

View File

@@ -12,7 +12,6 @@
namespace Symfony\Component\HttpKernel\Tests\EventListener;
use PHPUnit\Framework\TestCase;
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
@@ -144,15 +143,6 @@ class TestSessionListenerTest extends TestCase
$this->filterResponse(new Request());
}
public function testDoesNotImplementServiceSubscriberInterface()
{
$this->assertTrue(interface_exists(ServiceSubscriberInterface::class));
$this->assertTrue(class_exists(SessionListener::class));
$this->assertTrue(class_exists(TestSessionListener::class));
$this->assertFalse(is_subclass_of(SessionListener::class, ServiceSubscriberInterface::class), 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford');
$this->assertFalse(is_subclass_of(TestSessionListener::class, ServiceSubscriberInterface::class, 'Implementing ServiceSubscriberInterface would create a dep on the DI component, which eg Silex cannot afford'));
}
public function testDoesNotThrowIfRequestDoesNotHaveASession()
{
$kernel = $this->getMockBuilder('Symfony\Component\HttpKernel\HttpKernelInterface')->getMock();

View File

@@ -17,6 +17,7 @@ use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\EventListener\TranslatorListener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
class TranslatorListenerTest extends TestCase
{
@@ -26,7 +27,7 @@ class TranslatorListenerTest extends TestCase
protected function setUp()
{
$this->translator = $this->getMockBuilder('Symfony\Component\Translation\TranslatorInterface')->getMock();
$this->translator = $this->getMockBuilder(TranslatorInterface::class)->getMock();
$this->requestStack = $this->getMockBuilder('Symfony\Component\HttpFoundation\RequestStack')->getMock();
$this->listener = new TranslatorListener($this->translator, $this->requestStack);
}

View File

@@ -1,37 +0,0 @@
<?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\Fixtures\_123;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\HttpKernel\Kernel;
class Kernel123 extends Kernel
{
public function registerBundles()
{
return array();
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
}
public function getCacheDir()
{
return sys_get_temp_dir().'/'.Kernel::VERSION.'/kernel123/cache/'.$this->environment;
}
public function getLogDir()
{
return sys_get_temp_dir().'/'.Kernel::VERSION.'/kernel123/logs';
}
}

View File

@@ -34,4 +34,14 @@ class KernelForTest extends Kernel
{
return $this->booted;
}
public function getCacheDir()
{
return $this->getProjectDir().'/Tests/Fixtures/cache.'.$this->environment;
}
public function getLogDir()
{
return $this->getProjectDir().'/Tests/Fixtures/logs';
}
}

View File

@@ -26,6 +26,11 @@ class KernelWithoutBundles extends Kernel
{
}
public function getProjectDir()
{
return __DIR__;
}
protected function build(ContainerBuilder $container)
{
$container->setParameter('test_executed', true);

View File

@@ -88,7 +88,7 @@ class FragmentHandlerTest extends TestCase
;
if ($arguments) {
\call_user_func_array(array($e, 'with'), $arguments);
$e->with(...$arguments);
}
$handler = new FragmentHandler($this->requestStack);

View File

@@ -145,6 +145,26 @@ class InlineFragmentRendererTest extends TestCase
$this->assertEquals('Foo', ob_get_clean());
}
public function testLocaleAndFormatAreIsKeptInSubrequest()
{
$expectedSubRequest = Request::create('/');
$expectedSubRequest->attributes->set('_format', 'foo');
$expectedSubRequest->setLocale('fr');
if (Request::HEADER_X_FORWARDED_FOR & Request::getTrustedHeaderSet()) {
$expectedSubRequest->headers->set('x-forwarded-for', array('127.0.0.1'));
$expectedSubRequest->server->set('HTTP_X_FORWARDED_FOR', '127.0.0.1');
}
$expectedSubRequest->headers->set('forwarded', array('for="127.0.0.1";host="localhost";proto=http'));
$expectedSubRequest->server->set('HTTP_FORWARDED', 'for="127.0.0.1";host="localhost";proto=http');
$strategy = new InlineFragmentRenderer($this->getKernelExpectingRequest($expectedSubRequest));
$request = Request::create('/');
$request->attributes->set('_format', 'foo');
$request->setLocale('fr');
$strategy->render('/', $request);
}
public function testESIHeaderIsKeptInSubrequest()
{
$expectedSubRequest = Request::create('/');

View File

@@ -234,7 +234,7 @@ class EsiTest extends TestCase
if (\is_array($response)) {
$cache->expects($this->any())
->method('handle')
->will(\call_user_func_array(array($this, 'onConsecutiveCalls'), $response))
->will($this->onConsecutiveCalls(...$response))
;
} else {
$cache->expects($this->any())

View File

@@ -201,7 +201,7 @@ class SsiTest extends TestCase
if (\is_array($response)) {
$cache->expects($this->any())
->method('handle')
->will(\call_user_func_array(array($this, 'onConsecutiveCalls'), $response))
->will($this->onConsecutiveCalls(...$response))
;
} else {
$cache->expects($this->any())

View File

@@ -23,6 +23,7 @@ use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\ControllerDoesNotReturnResponseException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\HttpKernel;
use Symfony\Component\HttpKernel\HttpKernelInterface;
@@ -211,15 +212,23 @@ class HttpKernelTest extends TestCase
$this->assertResponseEquals(new Response('foo'), $kernel->handle(new Request()));
}
/**
* @expectedException \LogicException
*/
public function testHandleWhenTheControllerDoesNotReturnAResponse()
{
$dispatcher = new EventDispatcher();
$kernel = $this->getHttpKernel($dispatcher, function () { return 'foo'; });
$kernel->handle(new Request());
try {
$kernel->handle(new Request());
$this->fail('The kernel should throw an exception.');
} catch (ControllerDoesNotReturnResponseException $e) {
}
$first = $e->getTrace()[0];
// `file` index the array starting at 0, and __FILE__ starts at 1
$line = file($first['file'])[$first['line'] - 2];
$this->assertContains('// call controller', $line);
}
public function testHandleWhenTheControllerDoesNotReturnAResponseButAViewIsRegistered()
@@ -265,7 +274,7 @@ class HttpKernelTest extends TestCase
$oldArguments = $event->getArguments();
$newController = function ($id) use ($oldController, $oldArguments) {
$response = \call_user_func_array($oldController, $oldArguments);
$response = $oldController(...$oldArguments);
$response->headers->set('X-Id', $id);

View File

@@ -33,7 +33,7 @@ class KernelTest extends TestCase
public static function tearDownAfterClass()
{
$fs = new Filesystem();
$fs->remove(__DIR__.'/Fixtures/cache');
$fs->remove(__DIR__.'/Fixtures/var');
}
public function testConstructor()
@@ -67,15 +67,15 @@ class KernelTest extends TestCase
public function testInitializeContainerClearsOldContainers()
{
$fs = new Filesystem();
$legacyContainerDir = __DIR__.'/Fixtures/cache/custom/ContainerA123456';
$legacyContainerDir = __DIR__.'/Fixtures/var/cache/custom/ContainerA123456';
$fs->mkdir($legacyContainerDir);
touch($legacyContainerDir.'.legacy');
$kernel = new CustomProjectDirKernel();
$kernel->boot();
$containerDir = __DIR__.'/Fixtures/cache/custom/'.substr(\get_class($kernel->getContainer()), 0, 16);
$this->assertTrue(unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta'));
$containerDir = __DIR__.'/Fixtures/var/cache/custom/'.substr(\get_class($kernel->getContainer()), 0, 16);
$this->assertTrue(unlink(__DIR__.'/Fixtures/var/cache/custom/TestsSymfony_Component_HttpKernel_Tests_CustomProjectDirKernelCustomDebugContainer.php.meta'));
$this->assertFileExists($containerDir);
$this->assertFileNotExists($containerDir.'.legacy');
@@ -295,6 +295,9 @@ EOF;
$this->assertEquals($expected, $output);
}
/**
* @group legacy
*/
public function testGetRootDir()
{
$kernel = new KernelForTest('test', true);
@@ -302,6 +305,9 @@ EOF;
$this->assertEquals(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures', realpath($kernel->getRootDir()));
}
/**
* @group legacy
*/
public function testGetName()
{
$kernel = new KernelForTest('test', true);
@@ -309,6 +315,9 @@ EOF;
$this->assertEquals('Fixtures', $kernel->getName());
}
/**
* @group legacy
*/
public function testOverrideGetName()
{
$kernel = new KernelForOverrideName('test', true);
@@ -506,40 +515,32 @@ EOF;
$this->assertTrue($kernel->getContainer()->getParameter('test_executed'));
}
public function testKernelRootDirNameStartingWithANumber()
{
$dir = __DIR__.'/Fixtures/123';
require_once $dir.'/Kernel123.php';
$kernel = new \Symfony\Component\HttpKernel\Tests\Fixtures\_123\Kernel123('dev', true);
$this->assertEquals('_123', $kernel->getName());
}
public function testProjectDirExtension()
{
$kernel = new CustomProjectDirKernel();
$kernel->boot();
$this->assertSame('foo', $kernel->getProjectDir());
$this->assertSame('foo', $kernel->getContainer()->getParameter('kernel.project_dir'));
$this->assertSame(__DIR__.'/Fixtures', $kernel->getProjectDir());
$this->assertSame(__DIR__.\DIRECTORY_SEPARATOR.'Fixtures', $kernel->getContainer()->getParameter('kernel.project_dir'));
}
public function testKernelReset()
{
(new Filesystem())->remove(__DIR__.'/Fixtures/cache');
(new Filesystem())->remove(__DIR__.'/Fixtures/var/cache');
$kernel = new CustomProjectDirKernel();
$kernel->boot();
$containerClass = \get_class($kernel->getContainer());
$containerFile = (new \ReflectionClass($kernel->getContainer()))->getFileName();
unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
unlink(__DIR__.'/Fixtures/var/cache/custom/TestsSymfony_Component_HttpKernel_Tests_CustomProjectDirKernelCustomDebugContainer.php.meta');
$kernel = new CustomProjectDirKernel();
$kernel->boot();
$this->assertInstanceOf($containerClass, $kernel->getContainer());
$this->assertFileExists($containerFile);
unlink(__DIR__.'/Fixtures/cache/custom/FixturesCustomDebugProjectContainer.php.meta');
unlink(__DIR__.'/Fixtures/var/cache/custom/TestsSymfony_Component_HttpKernel_Tests_CustomProjectDirKernelCustomDebugContainer.php.meta');
$kernel = new CustomProjectDirKernel(function ($container) { $container->register('foo', 'stdClass')->setPublic(true); });
$kernel->boot();
@@ -707,11 +708,10 @@ class CustomProjectDirKernel extends Kernel
private $buildContainer;
private $httpKernel;
public function __construct(\Closure $buildContainer = null, HttpKernelInterface $httpKernel = null, $name = 'custom')
public function __construct(\Closure $buildContainer = null, HttpKernelInterface $httpKernel = null, $env = 'custom')
{
parent::__construct($name, true);
parent::__construct($env, true);
$this->baseDir = 'foo';
$this->buildContainer = $buildContainer;
$this->httpKernel = $httpKernel;
}
@@ -726,11 +726,6 @@ class CustomProjectDirKernel extends Kernel
}
public function getProjectDir()
{
return $this->baseDir;
}
public function getRootDir()
{
return __DIR__.'/Fixtures';
}

View File

@@ -22,7 +22,7 @@ class FileProfilerStorageTest extends TestCase
protected function setUp()
{
$this->tmpDir = sys_get_temp_dir().'/sf2_profiler_file_storage';
$this->tmpDir = sys_get_temp_dir().'/sf_profiler_file_storage';
if (is_dir($this->tmpDir)) {
self::cleanDir();
}

View File

@@ -84,7 +84,7 @@ class ProfilerTest extends TestCase
protected function setUp()
{
$this->tmp = tempnam(sys_get_temp_dir(), 'sf2_profiler');
$this->tmp = tempnam(sys_get_temp_dir(), 'sf_profiler');
if (file_exists($this->tmp)) {
@unlink($this->tmp);
}

View File

@@ -17,6 +17,7 @@
],
"require": {
"php": "^7.1.3",
"symfony/contracts": "^1.0",
"symfony/event-dispatcher": "~4.1",
"symfony/http-foundation": "^4.1.1",
"symfony/debug": "~3.4|~4.0",
@@ -28,7 +29,7 @@
"symfony/config": "~3.4|~4.0",
"symfony/console": "~3.4|~4.0",
"symfony/css-selector": "~3.4|~4.0",
"symfony/dependency-injection": "^4.1",
"symfony/dependency-injection": "^4.2",
"symfony/dom-crawler": "~3.4|~4.0",
"symfony/expression-language": "~3.4|~4.0",
"symfony/finder": "~3.4|~4.0",
@@ -36,7 +37,7 @@
"symfony/routing": "~3.4|~4.0",
"symfony/stopwatch": "~3.4|~4.0",
"symfony/templating": "~3.4|~4.0",
"symfony/translation": "~3.4|~4.0",
"symfony/translation": "~4.2",
"symfony/var-dumper": "^4.1.1",
"psr/cache": "~1.0"
},
@@ -45,7 +46,8 @@
},
"conflict": {
"symfony/config": "<3.4",
"symfony/dependency-injection": "<4.1",
"symfony/dependency-injection": "<4.2",
"symfony/translation": "<4.2",
"symfony/var-dumper": "<4.1.1",
"twig/twig": "<1.34|<2.4,>=2"
},
@@ -65,7 +67,7 @@
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "4.1-dev"
"dev-master": "4.2-dev"
}
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/5.2/phpunit.xsd"
backupGlobals="false"
colors="true"
bootstrap="vendor/autoload.php"