Update to Drupal 8.1.0. For more information, see https://www.drupal.org/drupal-8.1.0-release-notes

This commit is contained in:
Pantheon Automation 2016-04-20 09:56:34 -07:00 committed by Greg Anderson
parent b11a755ba8
commit c0a0d5a94c
6920 changed files with 64395 additions and 57312 deletions

View file

@ -11,7 +11,7 @@
namespace Symfony\Component\HttpKernel\Bundle;
use Symfony\Component\DependencyInjection\ContainerAware;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\Console\Application;
@ -24,8 +24,12 @@ use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
*
* @author Fabien Potencier <fabien@symfony.com>
*/
abstract class Bundle extends ContainerAware implements BundleInterface
abstract class Bundle implements BundleInterface
{
/**
* @var ContainerInterface
*/
protected $container;
protected $name;
protected $extension;
protected $path;
@ -58,6 +62,16 @@ abstract class Bundle extends ContainerAware implements BundleInterface
{
}
/**
* Sets the container.
*
* @param ContainerInterface|null $container A ContainerInterface instance or null
*/
public function setContainer(ContainerInterface $container = null)
{
$this->container = $container;
}
/**
* Returns the bundle's container extension.
*
@ -68,17 +82,17 @@ abstract class Bundle extends ContainerAware implements BundleInterface
public function getContainerExtension()
{
if (null === $this->extension) {
$class = $this->getContainerExtensionClass();
if (class_exists($class)) {
$extension = new $class();
$extension = $this->createContainerExtension();
if (null !== $extension) {
if (!$extension instanceof ExtensionInterface) {
throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', $class));
throw new \LogicException(sprintf('Extension %s must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', get_class($extension)));
}
// check naming convention
$basename = preg_replace('/Bundle$/', '', $this->getName());
$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.',
@ -166,6 +180,10 @@ abstract class Bundle extends ContainerAware implements BundleInterface
return;
}
if (!class_exists('Symfony\Component\Finder\Finder')) {
throw new \RuntimeException('You need the symfony/finder component to register bundle commands.');
}
$finder = new Finder();
$finder->files()->name('*Command.php')->in($dir);
@ -173,7 +191,7 @@ abstract class Bundle extends ContainerAware implements BundleInterface
foreach ($finder as $file) {
$ns = $prefix;
if ($relativePath = $file->getRelativePath()) {
$ns .= '\\'.strtr($relativePath, '/', '\\');
$ns .= '\\'.str_replace('/', '\\', $relativePath);
}
$class = $ns.'\\'.$file->getBasename('.php');
if ($this->container) {
@ -200,4 +218,16 @@ abstract class Bundle extends ContainerAware implements BundleInterface
return $this->getNamespace().'\\DependencyInjection\\'.$basename.'Extension';
}
/**
* Creates the bundle's container extension.
*
* @return ExtensionInterface|null
*/
protected function createContainerExtension()
{
if (class_exists($class = $this->getContainerExtensionClass())) {
return new $class();
}
}
}

View file

@ -1,6 +1,11 @@
CHANGELOG
=========
2.8.0
-----
* deprecated `Profiler::import` and `Profiler::export`
2.7.0
-----

View file

@ -105,7 +105,7 @@ class Client extends BaseClient
$code = <<<EOF
<?php
error_reporting($errorReporting & ~E_USER_DEPRECATED);
error_reporting($errorReporting);
require_once '$requirePath';

View file

@ -11,14 +11,14 @@
namespace Symfony\Component\HttpKernel\Config;
use Symfony\Component\Config\Resource\ResourceInterface;
use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
/**
* EnvParametersResource represents resources stored in prefixed environment variables.
*
* @author Chris Wilkinson <chriswilkinson84@gmail.com>
*/
class EnvParametersResource implements ResourceInterface, \Serializable
class EnvParametersResource implements SelfCheckingResourceInterface, \Serializable
{
/**
* @var string

View file

@ -105,7 +105,11 @@ class ControllerResolver implements ControllerResolverInterface
$arguments = array();
foreach ($parameters as $param) {
if (array_key_exists($param->name, $attributes)) {
$arguments[] = $attributes[$param->name];
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
} else {
$arguments[] = $attributes[$param->name];
}
} elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
$arguments[] = $request;
} elseif ($param->isDefaultValueAvailable()) {

View file

@ -0,0 +1,33 @@
<?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\DataCollector;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* AjaxDataCollector.
*
* @author Bart van den Burg <bart@burgov.nl>
*/
class AjaxDataCollector extends DataCollector
{
public function collect(Request $request, Response $response, \Exception $exception = null)
{
// all collecting is done client side
}
public function getName()
{
return 'ajax';
}
}

View file

@ -75,7 +75,7 @@ class ConfigDataCollector extends DataCollector
'wincache_enabled' => extension_loaded('wincache') && ini_get('wincache.ocenabled'),
'zend_opcache_enabled' => extension_loaded('Zend OPcache') && ini_get('opcache.enable'),
'bundles' => array(),
'sapi_name' => php_sapi_name(),
'sapi_name' => PHP_SAPI,
);
if (isset($this->kernel)) {

View file

@ -22,6 +22,24 @@ use Symfony\Component\HttpKernel\Log\DebugLoggerInterface;
*/
class LoggerDataCollector extends DataCollector implements LateDataCollectorInterface
{
private $errorNames = array(
E_DEPRECATED => 'E_DEPRECATED',
E_USER_DEPRECATED => 'E_USER_DEPRECATED',
E_NOTICE => 'E_NOTICE',
E_USER_NOTICE => 'E_USER_NOTICE',
E_STRICT => 'E_STRICT',
E_WARNING => 'E_WARNING',
E_USER_WARNING => 'E_USER_WARNING',
E_COMPILE_WARNING => 'E_COMPILE_WARNING',
E_CORE_WARNING => 'E_CORE_WARNING',
E_USER_ERROR => 'E_USER_ERROR',
E_RECOVERABLE_ERROR => 'E_RECOVERABLE_ERROR',
E_COMPILE_ERROR => 'E_COMPILE_ERROR',
E_PARSE => 'E_PARSE',
E_ERROR => 'E_ERROR',
E_CORE_ERROR => 'E_CORE_ERROR',
);
private $logger;
public function __construct($logger = null)
@ -106,6 +124,9 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
if (isset($context['type'], $context['file'], $context['line'], $context['level'])) {
$errorId = md5("{$context['type']}/{$context['line']}/{$context['file']}\x00{$log['message']}", true);
$silenced = !($context['type'] & $context['level']);
if (isset($this->errorNames[$context['type']])) {
$context = array_merge(array('name' => $this->errorNames[$context['type']]), $context);
}
if (isset($errorContextById[$errorId])) {
if (isset($errorContextById[$errorId]['errorCount'])) {

View file

@ -35,6 +35,10 @@ class ValueExporter
return sprintf('Object(%s)', get_class($value));
}
if ($value instanceof \__PHP_Incomplete_Class) {
return sprintf('__PHP_Incomplete_Class(%s)', $this->getClassNameFromIncomplete($value));
}
if (is_array($value)) {
if (empty($value)) {
return '[]';
@ -75,4 +79,11 @@ class ValueExporter
return (string) $value;
}
private function getClassNameFromIncomplete(\__PHP_Incomplete_Class $value)
{
$array = new \ArrayObject($value);
return $array['__PHP_Incomplete_Class_Name'];
}
}

View file

@ -52,9 +52,9 @@ class FragmentRendererPass implements CompilerPassInterface
throw new \InvalidArgumentException(sprintf('The service "%s" must not be abstract as fragment renderer are lazy-loaded.', $id));
}
$refClass = new \ReflectionClass($container->getParameterBag()->resolveValue($def->getClass()));
$class = $container->getParameterBag()->resolveValue($def->getClass());
$interface = 'Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface';
if (!$refClass->implementsInterface($interface)) {
if (!is_subclass_of($class, $interface)) {
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}

View file

@ -25,11 +25,30 @@ class LazyLoadingFragmentHandler extends FragmentHandler
private $container;
private $rendererIds = array();
public function __construct(ContainerInterface $container, $debug = false, RequestStack $requestStack = null)
/**
* Constructor.
*
* RequestStack will become required in 3.0.
*
* @param ContainerInterface $container A container
* @param RequestStack $requestStack The Request stack that controls the lifecycle of requests
* @param bool $debug Whether the debug mode is enabled or not
*/
public function __construct(ContainerInterface $container, $requestStack = null, $debug = false)
{
$this->container = $container;
parent::__construct(array(), $debug, $requestStack);
if ((null !== $requestStack && !$requestStack instanceof RequestStack) || $debug instanceof RequestStack) {
$tmp = $debug;
$debug = $requestStack;
$requestStack = func_num_args() < 3 ? null : $tmp;
@trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
} elseif (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
parent::__construct($requestStack, array(), $debug);
}
/**

View file

@ -12,55 +12,28 @@
namespace Symfony\Component\HttpKernel\Event;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* 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 PostResponseEvent extends Event
class PostResponseEvent extends KernelEvent
{
/**
* The kernel in which this event was thrown.
*
* @var HttpKernelInterface
*/
private $kernel;
private $request;
private $response;
public function __construct(HttpKernelInterface $kernel, Request $request, Response $response)
{
$this->kernel = $kernel;
$this->request = $request;
parent::__construct($kernel, $request, HttpKernelInterface::MASTER_REQUEST);
$this->response = $response;
}
/**
* Returns the kernel in which this event was thrown.
*
* @return HttpKernelInterface
*/
public function getKernel()
{
return $this->kernel;
}
/**
* Returns the request for which this event was thrown.
*
* @return Request
*/
public function getRequest()
{
return $this->request;
}
/**
* Returns the response for which this event was thrown.
*

View file

@ -67,7 +67,7 @@ class DebugHandlersListener implements EventSubscriberInterface
}
$this->firstCall = false;
if ($this->logger || null !== $this->throwAt) {
$handler = set_error_handler('var_dump', 0);
$handler = set_error_handler('var_dump');
$handler = is_array($handler) ? $handler[0] : null;
restore_error_handler();
if ($handler instanceof ErrorHandler) {
@ -93,7 +93,9 @@ class DebugHandlersListener implements EventSubscriberInterface
}
if (!$this->exceptionHandler) {
if ($event instanceof KernelEvent) {
$this->exceptionHandler = array($event->getKernel(), 'terminateWithException');
if (method_exists($event->getKernel(), 'terminateWithException')) {
$this->exceptionHandler = array($event->getKernel(), 'terminateWithException');
}
} elseif ($event instanceof ConsoleEvent && $app = $event->getCommand()->getApplication()) {
$output = $event->getOutput();
if ($output instanceof ConsoleOutputInterface) {

View file

@ -57,7 +57,14 @@ class FragmentListener implements EventSubscriberInterface
{
$request = $event->getRequest();
if ($request->attributes->has('_controller') || $this->fragmentPath !== rawurldecode($request->getPathInfo())) {
if ($this->fragmentPath !== rawurldecode($request->getPathInfo())) {
return;
}
if ($request->attributes->has('_controller')) {
// Is a sub-request: no need to parse _path but it should still be removed from query parameters as below.
$request->query->remove('_path');
return;
}

View file

@ -36,10 +36,36 @@ class LocaleListener implements EventSubscriberInterface
private $requestStack;
/**
* Constructor.
*
* RequestStack will become required in 3.0.
*
* @param RequestStack $requestStack A RequestStack instance
* @param string $defaultLocale The default locale
* @param RequestContextAwareInterface|null $router The router
*
* @throws \InvalidArgumentException
*/
public function __construct($defaultLocale = 'en', RequestContextAwareInterface $router = null, RequestStack $requestStack = null)
public function __construct($requestStack = null, $defaultLocale = 'en', $router = null)
{
if ((null !== $requestStack && !$requestStack instanceof RequestStack) || $defaultLocale instanceof RequestContextAwareInterface || $router instanceof RequestStack) {
$tmp = $router;
$router = func_num_args() < 2 ? null : $defaultLocale;
$defaultLocale = $requestStack;
$requestStack = func_num_args() < 3 ? null : $tmp;
@trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
} elseif (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
if (null !== $requestStack && !$requestStack instanceof RequestStack) {
throw new \InvalidArgumentException('RequestStack instance expected.');
}
if (null !== $router && !$router instanceof RequestContextAwareInterface) {
throw new \InvalidArgumentException('Router must implement RequestContextAwareInterface.');
}
$this->defaultLocale = $defaultLocale;
$this->requestStack = $requestStack;
$this->router = $router;

View file

@ -42,18 +42,30 @@ class ProfilerListener implements EventSubscriberInterface
* Constructor.
*
* @param Profiler $profiler A Profiler instance
* @param RequestStack $requestStack A RequestStack instance
* @param RequestMatcherInterface|null $matcher A RequestMatcher instance
* @param bool $onlyException true if the profiler only collects data when an exception occurs, false otherwise
* @param bool $onlyMasterRequests true if the profiler only collects data when the request is a master request, false otherwise
* @param RequestStack|null $requestStack A RequestStack instance
*/
public function __construct(Profiler $profiler, RequestMatcherInterface $matcher = null, $onlyException = false, $onlyMasterRequests = false, RequestStack $requestStack = null)
public function __construct(Profiler $profiler, $requestStack = null, $matcher = null, $onlyException = false, $onlyMasterRequests = false)
{
if (null === $requestStack) {
// Prevent the deprecation notice to be triggered all the time.
// The onKernelRequest() method fires some logic only when the
// RequestStack instance is not provided as a dependency.
@trigger_error('Since version 2.4, the '.__METHOD__.' method must accept a RequestStack instance to get the request instead of using the '.__CLASS__.'::onKernelRequest method that will be removed in 3.0.', E_USER_DEPRECATED);
if ($requestStack instanceof RequestMatcherInterface || (null !== $matcher && !$matcher instanceof RequestMatcherInterface) || $onlyMasterRequests instanceof RequestStack) {
$tmp = $onlyMasterRequests;
$onlyMasterRequests = $onlyException;
$onlyException = $matcher;
$matcher = $requestStack;
$requestStack = func_num_args() < 5 ? null : $tmp;
@trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::onKernelRequest method will be removed in 3.0.', E_USER_DEPRECATED);
} elseif (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::onKernelRequest method will be removed in 3.0.', E_USER_DEPRECATED);
}
if (null !== $requestStack && !$requestStack instanceof RequestStack) {
throw new \InvalidArgumentException('RequestStack instance expected.');
}
if (null !== $matcher && !$matcher instanceof RequestMatcherInterface) {
throw new \InvalidArgumentException('Matcher must implement RequestMatcherInterface.');
}
$this->profiler = $profiler;

View file

@ -51,14 +51,35 @@ class RouterListener implements EventSubscriberInterface
* RequestStack will become required in 3.0.
*
* @param UrlMatcherInterface|RequestMatcherInterface $matcher The Url or Request matcher
* @param RequestStack $requestStack A RequestStack instance
* @param RequestContext|null $context The RequestContext (can be null when $matcher implements RequestContextAwareInterface)
* @param LoggerInterface|null $logger The logger
* @param RequestStack|null $requestStack A RequestStack instance
*
* @throws \InvalidArgumentException
*/
public function __construct($matcher, RequestContext $context = null, LoggerInterface $logger = null, RequestStack $requestStack = null)
public function __construct($matcher, $requestStack = null, $context = null, $logger = null)
{
if ($requestStack instanceof RequestContext || $context instanceof LoggerInterface || $logger instanceof RequestStack) {
$tmp = $requestStack;
$requestStack = $logger;
$logger = $context;
$context = $tmp;
@trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as second argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
} elseif (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
if (null !== $requestStack && !$requestStack instanceof RequestStack) {
throw new \InvalidArgumentException('RequestStack instance expected.');
}
if (null !== $context && !$context instanceof RequestContext) {
throw new \InvalidArgumentException('RequestContext instance expected.');
}
if (null !== $logger && !$logger instanceof LoggerInterface) {
throw new \InvalidArgumentException('Logger must implement LoggerInterface.');
}
if (!$matcher instanceof UrlMatcherInterface && !$matcher instanceof RequestMatcherInterface) {
throw new \InvalidArgumentException('Matcher must either implement UrlMatcherInterface or RequestMatcherInterface.');
}
@ -67,10 +88,6 @@ class RouterListener implements EventSubscriberInterface
throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.');
}
if (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
$this->matcher = $matcher;
$this->context = $context ?: $matcher->getContext();
$this->requestStack = $requestStack;

View file

@ -44,12 +44,30 @@ class FragmentHandler
*
* RequestStack will become required in 3.0.
*
* @param RequestStack $requestStack The Request stack that controls the lifecycle of requests
* @param FragmentRendererInterface[] $renderers An array of FragmentRendererInterface instances
* @param bool $debug Whether the debug mode is enabled or not
* @param RequestStack|null $requestStack The Request stack that controls the lifecycle of requests
*/
public function __construct(array $renderers = array(), $debug = false, RequestStack $requestStack = null)
public function __construct($requestStack = null, $renderers = array(), $debug = false)
{
if (is_array($requestStack)) {
$tmp = $debug;
$debug = func_num_args() < 2 ? false : $renderers;
$renderers = $requestStack;
$requestStack = func_num_args() < 3 ? null : $tmp;
@trigger_error('The '.__METHOD__.' method now requires a RequestStack to be given as first argument as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
} elseif (!$requestStack instanceof RequestStack) {
@trigger_error('The '.__METHOD__.' method now requires a RequestStack instance as '.__CLASS__.'::setRequest method will not be supported anymore in 3.0.', E_USER_DEPRECATED);
}
if (null !== $requestStack && !$requestStack instanceof RequestStack) {
throw new \InvalidArgumentException('RequestStack instance expected.');
}
if (!is_array($renderers)) {
throw new \InvalidArgumentException('Renderers must be an array.');
}
$this->requestStack = $requestStack;
foreach ($renderers as $renderer) {
$this->addRenderer($renderer);

View file

@ -277,7 +277,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
// invalidate only when the response is successful
if ($response->isSuccessful() || $response->isRedirect()) {
try {
$this->store->invalidate($request, $catch);
$this->store->invalidate($request);
// As per the RFC, invalidate Location and Content-Location URLs if present
foreach (array('Location', 'Content-Location') as $header) {
@ -503,7 +503,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$this->processResponseBody($request, $response);
if ($this->isPrivateRequest($request) && !$response->headers->hasCacheControlDirective('public')) {
$response->setPrivate(true);
$response->setPrivate();
} elseif ($this->options['default_ttl'] > 0 && null === $response->getTtl() && !$response->headers->getCacheControlDirective('must-revalidate')) {
$response->setTtl($this->options['default_ttl']);
}
@ -566,7 +566,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$wait += 50000;
}
if ($wait < 2000000) {
if ($wait < 5000000) {
// replace the current entry with the fresh one
$new = $this->lookup($request);
$entry->headers = $new->headers;

View file

@ -32,6 +32,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
private $embeddedResponses = 0;
private $ttls = array();
private $maxAges = array();
private $isNotCacheableResponseEmbedded = false;
/**
* {@inheritdoc}
@ -41,8 +42,13 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
if ($response->isValidateable()) {
$this->cacheable = false;
} else {
$maxAge = $response->getMaxAge();
$this->ttls[] = $response->getTtl();
$this->maxAges[] = $response->getMaxAge();
$this->maxAges[] = $maxAge;
if (null === $maxAge) {
$this->isNotCacheableResponseEmbedded = true;
}
}
++$this->embeddedResponses;
@ -76,7 +82,9 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface
$this->ttls[] = $response->getTtl();
$this->maxAges[] = $response->getMaxAge();
if (null !== $maxAge = min($this->maxAges)) {
if ($this->isNotCacheableResponseEmbedded) {
$response->headers->removeCacheControlDirective('s-maxage');
} elseif (null !== $maxAge = min($this->maxAges)) {
$response->setSharedMaxAge($maxAge);
$response->headers->set('Age', $maxAge - min($this->ttls));
}

View file

@ -32,12 +32,14 @@ class Store implements StoreInterface
* Constructor.
*
* @param string $root The path to the cache directory
*
* @throws \RuntimeException
*/
public function __construct($root)
{
$this->root = $root;
if (!is_dir($this->root)) {
mkdir($this->root, 0777, true);
if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root));
}
$this->keyCache = new \SplObjectStorage();
$this->locks = array();
@ -74,7 +76,7 @@ class Store implements StoreInterface
public function lock(Request $request)
{
$path = $this->getPath($this->getCacheKey($request).'.lck');
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) {
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}
@ -106,7 +108,10 @@ class Store implements StoreInterface
public function isLocked(Request $request)
{
return is_file($this->getPath($this->getCacheKey($request).'.lck'));
$path = $this->getPath($this->getCacheKey($request).'.lck');
clearstatcache(true, $path);
return is_file($path);
}
/**
@ -242,10 +247,8 @@ class Store implements StoreInterface
}
}
if ($modified) {
if (false === $this->save($key, serialize($entries))) {
throw new \RuntimeException('Unable to store the metadata.');
}
if ($modified && false === $this->save($key, serialize($entries))) {
throw new \RuntimeException('Unable to store the metadata.');
}
}
@ -266,7 +269,7 @@ class Store implements StoreInterface
}
foreach (preg_split('/[\s,]+/', $vary) as $header) {
$key = strtr(strtolower($header), '_', '-');
$key = str_replace('_', '-', strtolower($header));
$v1 = isset($env1[$key]) ? $env1[$key] : null;
$v2 = isset($env2[$key]) ? $env2[$key] : null;
if ($v1 !== $v2) {
@ -338,7 +341,7 @@ class Store implements StoreInterface
private function save($key, $data)
{
$path = $this->getPath($key);
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true)) {
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}

View file

@ -21,6 +21,7 @@ use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
@ -58,15 +59,15 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
const VERSION = '2.7.6';
const VERSION_ID = 20706;
const VERSION = '2.8.4-DEV';
const VERSION_ID = 20804;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 7;
const RELEASE_VERSION = 6;
const EXTRA_VERSION = '';
const MINOR_VERSION = 8;
const RELEASE_VERSION = 4;
const EXTRA_VERSION = 'DEV';
const END_OF_MAINTENANCE = '05/2018';
const END_OF_LIFE = '05/2019';
const END_OF_MAINTENANCE = '11/2018';
const END_OF_LIFE = '11/2019';
/**
* Constructor.
@ -662,10 +663,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$dumper->setProxyDumper(new ProxyDumper(md5($cache->getPath())));
}
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath()));
if (!$this->debug) {
$content = static::stripComments($content);
}
$content = $dumper->dump(array('class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath(), 'debug' => $this->debug));
$cache->write($content, $container->getResources());
}
@ -685,6 +683,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
new YamlFileLoader($container, $locator),
new IniFileLoader($container, $locator),
new PhpFileLoader($container, $locator),
new DirectoryLoader($container, $locator),
new ClosureLoader($container),
));
@ -711,14 +710,15 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$output = '';
$tokens = token_get_all($source);
$ignoreSpace = false;
for (reset($tokens); false !== $token = current($tokens); next($tokens)) {
if (is_string($token)) {
for ($i = 0; isset($tokens[$i]); ++$i) {
$token = $tokens[$i];
if (!isset($token[1]) || 'b"' === $token) {
$rawChunk .= $token;
} elseif (T_START_HEREDOC === $token[0]) {
$output .= $rawChunk.$token[1];
do {
$token = next($tokens);
$output .= $token[1];
$token = $tokens[++$i];
$output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
} while ($token[0] !== T_END_HEREDOC);
$rawChunk = '';
} elseif (T_WHITESPACE === $token[0]) {
@ -744,6 +744,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$output .= $rawChunk;
if (PHP_VERSION_ID >= 70000) {
// 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;
}

View file

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

View file

@ -11,10 +11,15 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\BaseMemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* Base Memcache storage for profiling information in a Memcache.
*
* @author Andrej Hudec <pulzarraider@gmail.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
abstract class BaseMemcacheProfilerStorage implements ProfilerStorageInterface
{

View file

@ -41,8 +41,8 @@ class FileProfilerStorage implements ProfilerStorageInterface
}
$this->folder = substr($dsn, 5);
if (!is_dir($this->folder)) {
mkdir($this->folder, 0777, true);
if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) {
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder));
}
}
@ -128,6 +128,8 @@ class FileProfilerStorage implements ProfilerStorageInterface
/**
* {@inheritdoc}
*
* @throws \RuntimeException
*/
public function write(Profile $profile)
{
@ -137,8 +139,8 @@ class FileProfilerStorage implements ProfilerStorageInterface
if (!$profileIndexed) {
// Create directory
$dir = dirname($file);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir));
}
}

View file

@ -11,10 +11,15 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\MemcacheProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* Memcache Profiler Storage.
*
* @author Andrej Hudec <pulzarraider@gmail.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class MemcacheProfilerStorage extends BaseMemcacheProfilerStorage
{

View file

@ -11,10 +11,15 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\MemcachedProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* Memcached Profiler Storage.
*
* @author Andrej Hudec <pulzarraider@gmail.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class MemcachedProfilerStorage extends BaseMemcacheProfilerStorage
{

View file

@ -11,6 +11,12 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\MongoDbProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class MongoDbProfilerStorage implements ProfilerStorageInterface
{
protected $dsn;

View file

@ -11,10 +11,15 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\MysqlProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* A ProfilerStorage for Mysql.
*
* @author Jan Schumann <js@schumann-it.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class MysqlProfilerStorage extends PdoProfilerStorage
{

View file

@ -11,11 +11,16 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\PdoProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* Base PDO storage for profiling information in a PDO database.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jan Schumann <js@schumann-it.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
abstract class PdoProfilerStorage implements ProfilerStorageInterface
{
@ -188,9 +193,8 @@ abstract class PdoProfilerStorage implements ProfilerStorageInterface
$stmt->bindValue($arg, $val, is_int($val) ? \PDO::PARAM_INT : \PDO::PARAM_STR);
}
$stmt->execute();
$return = $stmt->fetchAll(\PDO::FETCH_ASSOC);
return $return;
return $stmt->fetchAll(\PDO::FETCH_ASSOC);
}
protected function close($db)

View file

@ -137,9 +137,13 @@ class Profiler
* @param Profile $profile A Profile instance
*
* @return string The exported data
*
* @deprecated since Symfony 2.8, to be removed in 3.0.
*/
public function export(Profile $profile)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
return base64_encode(serialize($profile));
}
@ -149,9 +153,13 @@ class Profiler
* @param string $data A data string as exported by the export() method
*
* @return Profile A Profile instance
*
* @deprecated since Symfony 2.8, to be removed in 3.0.
*/
public function import($data)
{
@trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
$profile = unserialize(base64_decode($data));
if ($this->storage->read($profile->getToken())) {

View file

@ -11,11 +11,16 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\RedisProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* RedisProfilerStorage stores profiling information in Redis.
*
* @author Andrej Hudec <pulzarraider@gmail.com>
* @author Stephane PY <py.stephane1@gmail.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class RedisProfilerStorage implements ProfilerStorageInterface
{

View file

@ -11,10 +11,15 @@
namespace Symfony\Component\HttpKernel\Profiler;
@trigger_error('The '.__NAMESPACE__.'\SqliteProfilerStorage class is deprecated since Symfony 2.8 and will be removed in 3.0. Use FileProfilerStorage instead.', E_USER_DEPRECATED);
/**
* SqliteProfilerStorage stores profiling information in a SQLite database.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @deprecated Deprecated since Symfony 2.8, to be removed in Symfony 3.0.
* Use {@link FileProfilerStorage} instead.
*/
class SqliteProfilerStorage extends PdoProfilerStorage
{
@ -77,7 +82,7 @@ class SqliteProfilerStorage extends PdoProfilerStorage
$return = array();
if ($db instanceof \SQLite3) {
$stmt = $this->prepareStatement($db, $query, true);
$stmt = $this->prepareStatement($db, $query);
foreach ($args as $arg => $val) {
$stmt->bindValue($arg, $val, is_int($val) ? \SQLITE3_INTEGER : \SQLITE3_TEXT);
}

View file

@ -1,99 +1,16 @@
HttpKernel Component
====================
HttpKernel provides the building blocks to create flexible and fast HTTP-based
frameworks.
``HttpKernelInterface`` is the core interface of the Symfony full-stack
framework:
```php
interface HttpKernelInterface
{
/**
* Handles a Request to convert it to a Response.
*
* @param Request $request A Request instance
*
* @return Response A Response instance
*/
function handle(Request $request, $type = self::MASTER_REQUEST, $catch = true);
}
```
It takes a ``Request`` as an input and should return a ``Response`` as an
output. Using this interface makes your code compatible with all frameworks
using the Symfony components. And this will give you many cool features for
free.
Creating a framework based on the Symfony components is really easy. Here is
a very simple, but fully-featured framework based on the Symfony components:
```php
$routes = new RouteCollection();
$routes->add('hello', new Route('/hello', array('_controller' =>
function (Request $request) {
return new Response(sprintf("Hello %s", $request->get('name')));
}
)));
$request = Request::createFromGlobals();
$context = new RequestContext();
$context->fromRequest($request);
$matcher = new UrlMatcher($routes, $context);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new RouterListener($matcher));
$resolver = new ControllerResolver();
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel->handle($request)->send();
```
This is all you need to create a flexible framework with the Symfony
components.
Want to add an HTTP reverse proxy and benefit from HTTP caching and Edge Side
Includes?
```php
$kernel = new HttpKernel($dispatcher, $resolver);
$kernel = new HttpCache($kernel, new Store(__DIR__.'/cache'));
```
Want to functional test this small framework?
```php
$client = new Client($kernel);
$crawler = $client->request('GET', '/hello/Fabien');
$this->assertEquals('Fabien', $crawler->filter('p > span')->text());
```
Want nice error pages instead of ugly PHP exceptions?
```php
$dispatcher->addSubscriber(new ExceptionListener(function (Request $request) {
$msg = 'Something went wrong! ('.$request->get('exception')->getMessage().')';
return new Response($msg, 500);
}));
```
And that's why the simple looking ``HttpKernelInterface`` is so powerful. It
gives you access to a lot of cool features, ready to be used out of the box,
with no efforts.
The HttpKernel component provides a structured process for converting a Request
into a Response by making use of the EventDispatcher component. It's flexible
enough to create a full-stack framework (Symfony), a micro-framework (Silex) or
an advanced CMS system (Drupal).
Resources
---------
You can run the unit tests with the following command:
$ cd path/to/Symfony/Component/HttpKernel/
$ composer install
$ phpunit
* [Documentation](https://symfony.com/doc/current/components/http_kernel/index.html)
* [Contributing](https://symfony.com/doc/current/contributing/index.html)
* [Report issues](https://github.com/symfony/symfony/issues) and
[send Pull Requests](https://github.com/symfony/symfony/pulls)
in the [main Symfony repository](https://github.com/symfony/symfony)

View file

@ -51,7 +51,7 @@ class UriSigner
$uri = $this->buildUrl($url, $params);
return $uri.(false === (strpos($uri, '?')) ? '?' : '&').'_hash='.$this->computeHash($uri);
return $uri.(false === strpos($uri, '?') ? '?' : '&').'_hash='.$this->computeHash($uri);
}
/**
@ -91,7 +91,7 @@ class UriSigner
private function buildUrl(array $url, array $params = array())
{
ksort($params);
ksort($params, SORT_STRING);
$url['query'] = http_build_query($params, '', '&');
$scheme = isset($url['scheme']) ? $url['scheme'].'://' : '';

View file

@ -17,27 +17,27 @@
],
"require": {
"php": ">=5.3.9",
"symfony/event-dispatcher": "~2.6,>=2.6.7",
"symfony/http-foundation": "~2.5,>=2.5.4",
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
"symfony/http-foundation": "~2.5,>=2.5.4|~3.0.0",
"symfony/debug": "~2.6,>=2.6.2",
"psr/log": "~1.0"
},
"require-dev": {
"symfony/browser-kit": "~2.3",
"symfony/class-loader": "~2.1",
"symfony/config": "~2.7",
"symfony/console": "~2.3",
"symfony/css-selector": "~2.0,>=2.0.5",
"symfony/dependency-injection": "~2.2",
"symfony/dom-crawler": "~2.0,>=2.0.5",
"symfony/expression-language": "~2.4",
"symfony/finder": "~2.0,>=2.0.5",
"symfony/process": "~2.0,>=2.0.5",
"symfony/routing": "~2.2",
"symfony/stopwatch": "~2.3",
"symfony/templating": "~2.2",
"symfony/translation": "~2.0,>=2.0.5",
"symfony/var-dumper": "~2.6"
"symfony/browser-kit": "~2.3|~3.0.0",
"symfony/class-loader": "~2.1|~3.0.0",
"symfony/config": "~2.8",
"symfony/console": "~2.3|~3.0.0",
"symfony/css-selector": "~2.0,>=2.0.5|~3.0.0",
"symfony/dependency-injection": "~2.8|~3.0.0",
"symfony/dom-crawler": "~2.0,>=2.0.5|~3.0.0",
"symfony/expression-language": "~2.4|~3.0.0",
"symfony/finder": "~2.0,>=2.0.5|~3.0.0",
"symfony/process": "~2.0,>=2.0.5|~3.0.0",
"symfony/routing": "~2.8|~3.0.0",
"symfony/stopwatch": "~2.3|~3.0.0",
"symfony/templating": "~2.2|~3.0.0",
"symfony/translation": "~2.0,>=2.0.5|~3.0.0",
"symfony/var-dumper": "~2.6|~3.0.0"
},
"conflict": {
"symfony/config": "<2.7"
@ -52,12 +52,15 @@
"symfony/var-dumper": ""
},
"autoload": {
"psr-4": { "Symfony\\Component\\HttpKernel\\": "" }
"psr-4": { "Symfony\\Component\\HttpKernel\\": "" },
"exclude-from-classmap": [
"/Tests/"
]
},
"minimum-stability": "dev",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev"
"dev-master": "2.8-dev"
}
}
}

View file

@ -25,4 +25,14 @@
</exclude>
</whitelist>
</filter>
<listeners>
<listener class="Symfony\Bridge\PhpUnit\SymfonyTestsListener">
<arguments>
<array>
<element key="time-sensitive"><string>Symfony\Component\HttpFoundation</string></element>
</array>
</arguments>
</listener>
</listeners>
</phpunit>