Update to Drupal 8.2.6. For more information, see https://www.drupal.org/project/drupal/releases/8.2.6

This commit is contained in:
Pantheon Automation 2017-02-02 16:28:38 -08:00 committed by Greg Anderson
parent db56c09587
commit f1e72395cb
588 changed files with 26857 additions and 2777 deletions

View file

@ -21,7 +21,7 @@ interface CacheClearerInterface
/**
* Clears any caches necessary.
*
* @param string $cacheDir The cache directory.
* @param string $cacheDir The cache directory
*/
public function clear($cacheDir);
}

View file

@ -26,7 +26,7 @@ class ChainCacheClearer implements CacheClearerInterface
/**
* Constructs a new instance of ChainCacheClearer.
*
* @param array $clearers The initial clearers.
* @param array $clearers The initial clearers
*/
public function __construct(array $clearers = array())
{

View file

@ -20,7 +20,7 @@ abstract class CacheWarmer implements CacheWarmerInterface
{
protected function writeCacheFile($file, $content)
{
$tmpFile = tempnam(dirname($file), basename($file));
$tmpFile = @tempnam(dirname($file), basename($file));
if (false !== @file_put_contents($tmpFile, $content) && @rename($tmpFile, $file)) {
@chmod($file, 0666 & ~umask());

View file

@ -27,6 +27,22 @@ class ControllerResolver implements ControllerResolverInterface
{
private $logger;
/**
* If the ...$arg functionality is available.
*
* Requires at least PHP 5.6.0 or HHVM 3.9.1
*
* @var bool
*/
private $supportsVariadic;
/**
* If scalar types exists.
*
* @var bool
*/
private $supportsScalarTypes;
/**
* Constructor.
*
@ -35,6 +51,9 @@ class ControllerResolver implements ControllerResolverInterface
public function __construct(LoggerInterface $logger = null)
{
$this->logger = $logger;
$this->supportsVariadic = method_exists('ReflectionParameter', 'isVariadic');
$this->supportsScalarTypes = method_exists('ReflectionParameter', 'getType');
}
/**
@ -99,13 +118,20 @@ class ControllerResolver implements ControllerResolverInterface
return $this->doGetArguments($request, $controller, $r->getParameters());
}
/**
* @param Request $request
* @param callable $controller
* @param \ReflectionParameter[] $parameters
*
* @return array The arguments to use when calling the action
*/
protected function doGetArguments(Request $request, $controller, array $parameters)
{
$attributes = $request->attributes->all();
$arguments = array();
foreach ($parameters as $param) {
if (array_key_exists($param->name, $attributes)) {
if (PHP_VERSION_ID >= 50600 && $param->isVariadic() && is_array($attributes[$param->name])) {
if ($this->supportsVariadic && $param->isVariadic() && is_array($attributes[$param->name])) {
$arguments = array_merge($arguments, array_values($attributes[$param->name]));
} else {
$arguments[] = $attributes[$param->name];
@ -114,6 +140,8 @@ class ControllerResolver implements ControllerResolverInterface
$arguments[] = $request;
} elseif ($param->isDefaultValueAvailable()) {
$arguments[] = $param->getDefaultValue();
} elseif ($this->supportsScalarTypes && $param->hasType() && $param->allowsNull()) {
$arguments[] = null;
} else {
if (is_array($controller)) {
$repr = sprintf('%s::%s()', get_class($controller[0]), $controller[1]);

View file

@ -97,21 +97,24 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
break;
} elseif (isset($trace[$i]['object']) && $trace[$i]['object'] instanceof \Twig_Template) {
$info = $trace[$i]['object'];
$name = $info->getTemplateName();
$src = method_exists($info, 'getSource') ? $info->getSource() : $info->getEnvironment()->getLoader()->getSource($name);
$info = $info->getDebugInfo();
if (null !== $src && isset($info[$trace[$i - 1]['line']])) {
$file = false;
$template = $trace[$i]['object'];
$name = $template->getTemplateName();
$src = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getCode() : (method_exists($template, 'getSource') ? $template->getSource() : false);
$info = $template->getDebugInfo();
if (isset($info[$trace[$i - 1]['line']])) {
$line = $info[$trace[$i - 1]['line']];
$src = explode("\n", $src);
$fileExcerpt = array();
$file = method_exists($template, 'getSourceContext') ? $template->getSourceContext()->getPath() : null;
for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) {
$fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.$this->htmlEncode($src[$i - 1]).'</code></li>';
if ($src) {
$src = explode("\n", $src);
$fileExcerpt = array();
for ($i = max($line - 3, 1), $max = min($line + 3, count($src)); $i <= $max; ++$i) {
$fileExcerpt[] = '<li'.($i === $line ? ' class="selected"' : '').'><code>'.$this->htmlEncode($src[$i - 1]).'</code></li>';
}
$fileExcerpt = '<ol start="'.max($line - 3, 1).'">'.implode("\n", $fileExcerpt).'</ol>';
}
$fileExcerpt = '<ol start="'.max($line - 3, 1).'">'.implode("\n", $fileExcerpt).'</ol>';
}
break;
}
@ -170,6 +173,8 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
return 'a:0:{}';
}
$this->data[] = $this->fileLinkFormat;
$this->data[] = $this->charset;
$ser = serialize($this->data);
$this->data = array();
$this->dataCount = 0;
@ -184,8 +189,10 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
public function unserialize($data)
{
parent::unserialize($data);
$charset = array_pop($this->data);
$fileLinkFormat = array_pop($this->data);
$this->dataCount = count($this->data);
self::__construct($this->stopwatch);
self::__construct($this->stopwatch, $fileLinkFormat, $charset);
}
public function getDumpsCount()
@ -211,8 +218,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
// getLimitedClone is @deprecated, to be removed in 3.0
$dumper->dump($dump['data']->getLimitedClone($maxDepthLimit, $maxItemsPerDepth));
}
rewind($data);
$dump['data'] = stream_get_contents($data);
$dump['data'] = stream_get_contents($data, -1, 0);
ftruncate($data, 0);
rewind($data);
$dumps[] = $dump;
@ -260,7 +266,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
if (PHP_VERSION_ID >= 50400 && $this->dumper instanceof CliDumper) {
$contextDumper = function ($name, $file, $line, $fileLinkFormat) {
if ($this instanceof HtmlDumper) {
if ('' !== $file) {
if ($file) {
$s = $this->style('meta', '%s');
$name = strip_tags($this->style('', $name));
$file = strip_tags($this->style('', $file));

View file

@ -68,18 +68,6 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
}
}
/**
* Gets the called events.
*
* @return array An array of called events
*
* @see TraceableEventDispatcherInterface
*/
public function countErrors()
{
return isset($this->data['error_count']) ? $this->data['error_count'] : 0;
}
/**
* Gets the logs.
*
@ -95,6 +83,11 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
return isset($this->data['priorities']) ? $this->data['priorities'] : array();
}
public function countErrors()
{
return isset($this->data['error_count']) ? $this->data['error_count'] : 0;
}
public function countDeprecations()
{
return isset($this->data['deprecation_count']) ? $this->data['deprecation_count'] : 0;
@ -175,6 +168,10 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte
}
if (is_object($context)) {
if ($context instanceof \Exception) {
return sprintf('Exception(%s): %s', get_class($context), $context->getMessage());
}
return sprintf('Object(%s)', get_class($context));
}

View file

@ -12,10 +12,8 @@
namespace Symfony\Component\HttpKernel\DataCollector;
use Symfony\Component\HttpFoundation\ParameterBag;
use Symfony\Component\HttpFoundation\HeaderBag;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@ -40,12 +38,8 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
public function collect(Request $request, Response $response, \Exception $exception = null)
{
$responseHeaders = $response->headers->all();
$cookies = array();
foreach ($response->headers->getCookies() as $cookie) {
$cookies[] = $this->getCookieHeader($cookie->getName(), $cookie->getValue(), $cookie->getExpiresTime(), $cookie->getPath(), $cookie->getDomain(), $cookie->isSecure(), $cookie->isHttpOnly());
}
if (count($cookies) > 0) {
$responseHeaders['Set-Cookie'] = $cookies;
$responseHeaders['set-cookie'][] = (string) $cookie;
}
// attributes are serialized and as they can be anything, they need to be converted to strings.
@ -121,6 +115,18 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
$this->data['request_request']['_password'] = '******';
}
foreach ($this->data as $key => $value) {
if (!is_array($value)) {
continue;
}
if ('request_headers' === $key || 'response_headers' === $key) {
$value = array_map(function ($v) { return isset($v[0]) && !isset($v[1]) ? $v[0] : $v; }, $value);
}
if ('request_server' !== $key && 'request_cookies' !== $key) {
$this->data[$key] = $value;
}
}
if (isset($this->controllers[$request])) {
$controller = $this->controllers[$request];
if (is_array($controller)) {
@ -183,7 +189,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
public function getRequestHeaders()
{
return new HeaderBag($this->data['request_headers']);
return new ParameterBag($this->data['request_headers']);
}
public function getRequestServer()
@ -203,7 +209,7 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
public function getResponseHeaders()
{
return new ResponseHeaderBag($this->data['response_headers']);
return new ParameterBag($this->data['response_headers']);
}
public function getSessionMetadata()
@ -302,41 +308,4 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter
{
return 'request';
}
private function getCookieHeader($name, $value, $expires, $path, $domain, $secure, $httponly)
{
$cookie = sprintf('%s=%s', $name, urlencode($value));
if (0 !== $expires) {
if (is_numeric($expires)) {
$expires = (int) $expires;
} elseif ($expires instanceof \DateTime) {
$expires = $expires->getTimestamp();
} else {
$tmp = strtotime($expires);
if (false === $tmp || -1 == $tmp) {
throw new \InvalidArgumentException(sprintf('The "expires" cookie parameter is not valid (%s).', $expires));
}
$expires = $tmp;
}
$cookie .= '; expires='.str_replace('+0000', '', \DateTime::createFromFormat('U', $expires, new \DateTimeZone('GMT'))->format('D, d-M-Y H:i:s T'));
}
if ($domain) {
$cookie .= '; domain='.$domain;
}
$cookie .= '; path='.$path;
if ($secure) {
$cookie .= '; secure';
}
if ($httponly) {
$cookie .= '; httponly';
}
return $cookie;
}
}

View file

@ -27,6 +27,10 @@ class ValueExporter
*/
public function exportValue($value, $depth = 1, $deep = false)
{
if ($value instanceof \__PHP_Incomplete_Class) {
return sprintf('__PHP_Incomplete_Class(%s)', $this->getClassNameFromIncomplete($value));
}
if (is_object($value)) {
if ($value instanceof \DateTime || $value instanceof \DateTimeInterface) {
return sprintf('Object(%s) - %s', get_class($value), $value->format(\DateTime::ISO8601));
@ -35,10 +39,6 @@ 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 '[]';

View file

@ -71,6 +71,11 @@ class ContainerAwareHttpKernel extends HttpKernel
$this->container->set('request', null, 'request');
$this->container->leaveScope('request');
throw $e;
} catch (\Throwable $e) {
$this->container->set('request', null, 'request');
$this->container->leaveScope('request');
throw $e;
}

View file

@ -54,7 +54,12 @@ class FragmentRendererPass implements CompilerPassInterface
$class = $container->getParameterBag()->resolveValue($def->getClass());
$interface = 'Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface';
if (!is_subclass_of($class, $interface)) {
if (!class_exists($class, false)) {
throw new \InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
}
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}

View file

@ -54,6 +54,7 @@ class LazyLoadingFragmentHandler extends FragmentHandler
/**
* Adds a service as a fragment renderer.
*
* @param string $name The service name
* @param string $renderer The render service id
*/
public function addRendererService($name, $renderer)

View file

@ -11,8 +11,8 @@
namespace Symfony\Component\HttpKernel\EventListener;
use Symfony\Component\Console\ConsoleEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\VarDumper\Cloner\ClonerInterface;
use Symfony\Component\VarDumper\Dumper\DataDumperInterface;
use Symfony\Component\VarDumper\VarDumper;
@ -28,8 +28,8 @@ class DumpListener implements EventSubscriberInterface
private $dumper;
/**
* @param ClonerInterface $cloner Cloner service.
* @param DataDumperInterface $dumper Dumper service.
* @param ClonerInterface $cloner Cloner service
* @param DataDumperInterface $dumper Dumper service
*/
public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper)
{
@ -50,6 +50,6 @@ class DumpListener implements EventSubscriberInterface
public static function getSubscribedEvents()
{
// Register early to have a working dump() as early as possible
return array(KernelEvents::REQUEST => array('configure', 1024));
return array(ConsoleEvents::COMMAND => array('configure', 1024));
}
}

View file

@ -49,7 +49,7 @@ 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()), false);
$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()));
$wrapper = $e;
@ -96,10 +96,10 @@ class ExceptionListener implements EventSubscriberInterface
/**
* Clones the request for the exception.
*
* @param \Exception $exception The thrown exception.
* @param Request $request The original request.
* @param \Exception $exception The thrown exception
* @param Request $request The original request
*
* @return Request $request The cloned request.
* @return Request $request The cloned request
*/
protected function duplicateRequest(\Exception $exception, Request $request)
{

View file

@ -81,7 +81,7 @@ class FragmentListener implements EventSubscriberInterface
protected function validateRequest(Request $request)
{
// is the Request safe?
if (!$request->isMethodSafe()) {
if (!$request->isMethodSafe(false)) {
throw new AccessDeniedHttpException();
}

View file

@ -0,0 +1,55 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\HttpKernel\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
/**
* Validates that the headers and other information indicating the
* client IP address of a request are consistent.
*
* @author Magnus Nordlander <magnus@fervo.se>
*/
class ValidateRequestListener implements EventSubscriberInterface
{
/**
* Performs the validation.
*
* @param GetResponseEvent $event
*/
public function onKernelRequest(GetResponseEvent $event)
{
if (!$event->isMasterRequest()) {
return;
}
$request = $event->getRequest();
if ($request::getTrustedProxies()) {
// This will throw an exception if the headers are inconsistent.
$request->getClientIps();
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents()
{
return array(
KernelEvents::REQUEST => array(
array('onKernelRequest', 256),
),
);
}
}

View file

@ -140,12 +140,16 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer
}
$loader = $this->templating->getLoader();
if ($loader instanceof \Twig_ExistsLoaderInterface) {
if ($loader instanceof \Twig_ExistsLoaderInterface || method_exists($loader, 'exists')) {
return $loader->exists($template);
}
try {
$loader->getSource($template);
if (method_exists($loader, 'getSourceContext')) {
$loader->getSourceContext($template);
} else {
$loader->getSource($template);
}
return true;
} catch (\Twig_Error_Loader $e) {

View file

@ -129,6 +129,8 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer
}
$server['REMOTE_ADDR'] = '127.0.0.1';
unset($server['HTTP_IF_MODIFIED_SINCE']);
unset($server['HTTP_IF_NONE_MATCH']);
$subRequest = Request::create($uri, 'get', array(), $cookies, array(), $server);
if ($request->headers->has('Surrogate-Capability')) {

View file

@ -37,7 +37,7 @@ class Esi implements SurrogateInterface
/**
* Constructor.
*
* @param array $contentTypes An array of content-type that should be parsed for ESI information.
* @param array $contentTypes An array of content-type that should be parsed for ESI information
* (default: text/html, text/xml, application/xhtml+xml, and application/xml)
*/
public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))

View file

@ -153,9 +153,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
/**
* Gets the Surrogate instance.
*
* @throws \LogicException
*
* @return SurrogateInterface A Surrogate instance
*
* @throws \LogicException
*/
public function getSurrogate()
{
@ -169,10 +169,10 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
/**
* Gets the Esi instance.
*
* @throws \LogicException
*
* @return Esi An Esi instance
*
* @throws \LogicException
*
* @deprecated since version 2.6, to be removed in 3.0. Use getSurrogate() instead
*/
public function getEsi()
@ -202,9 +202,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
}
$this->traces[$request->getMethod().' '.$path] = array();
if (!$request->isMethodSafe()) {
if (!$request->isMethodSafe(false)) {
$response = $this->invalidate($request, $catch);
} elseif ($request->headers->has('expect')) {
} elseif ($request->headers->has('expect') || !$request->isMethodCacheable()) {
$response = $this->pass($request, $catch);
} else {
$response = $this->lookup($request, $catch);
@ -374,7 +374,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$subRequest = clone $request;
// send no head requests because we want content
$subRequest->setMethod('GET');
if ('HEAD' === $request->getMethod()) {
$subRequest->setMethod('GET');
}
// add our cached last-modified validator
$subRequest->headers->set('if_modified_since', $entry->headers->get('Last-Modified'));
@ -435,7 +437,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
$subRequest = clone $request;
// send no head requests because we want content
$subRequest->setMethod('GET');
if ('HEAD' === $request->getMethod()) {
$subRequest->setMethod('GET');
}
// avoid that the backend sends no content
$subRequest->headers->remove('if_modified_since');
@ -600,6 +604,9 @@ class HttpCache implements HttpKernelInterface, TerminableInterface
*/
protected function store(Request $request, Response $response)
{
if (!$response->headers->has('Date')) {
$response->setDate(\DateTime::createFromFormat('U', time()));
}
try {
$this->store->write($request, $response);

View file

@ -31,7 +31,7 @@ class Ssi implements SurrogateInterface
/**
* Constructor.
*
* @param array $contentTypes An array of content-type that should be parsed for SSI information.
* @param array $contentTypes An array of content-type that should be parsed for SSI information
* (default: text/html, text/xml, application/xhtml+xml, and application/xml)
*/
public function __construct(array $contentTypes = array('text/html', 'text/xml', 'application/xhtml+xml', 'application/xml'))

View file

@ -38,7 +38,7 @@ class Store implements StoreInterface
public function __construct($root)
{
$this->root = $root;
if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) {
if (!file_exists($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();
@ -52,22 +52,15 @@ class Store implements StoreInterface
{
// unlock everything
foreach ($this->locks as $lock) {
if (file_exists($lock)) {
@unlink($lock);
}
flock($lock, LOCK_UN);
fclose($lock);
}
$error = error_get_last();
if (1 === $error['type'] && false === headers_sent()) {
// send a 503
header('HTTP/1.0 503 Service Unavailable');
header('Retry-After: 10');
echo '503 Service Unavailable';
}
$this->locks = array();
}
/**
* Locks the cache for a given Request.
* Tries to lock the cache for a given Request, without blocking.
*
* @param Request $request A Request instance
*
@ -75,21 +68,24 @@ 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) && !is_dir(dirname($path))) {
return false;
$key = $this->getCacheKey($request);
if (!isset($this->locks[$key])) {
$path = $this->getPath($key);
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return $path;
}
$h = fopen($path, 'cb');
if (!flock($h, LOCK_EX | LOCK_NB)) {
fclose($h);
return $path;
}
$this->locks[$key] = $h;
}
$lock = @fopen($path, 'x');
if (false !== $lock) {
fclose($lock);
$this->locks[] = $path;
return true;
}
return !file_exists($path) ?: $path;
return true;
}
/**
@ -101,17 +97,37 @@ class Store implements StoreInterface
*/
public function unlock(Request $request)
{
$file = $this->getPath($this->getCacheKey($request).'.lck');
$key = $this->getCacheKey($request);
return is_file($file) ? @unlink($file) : false;
if (isset($this->locks[$key])) {
flock($this->locks[$key], LOCK_UN);
fclose($this->locks[$key]);
unset($this->locks[$key]);
return true;
}
return false;
}
public function isLocked(Request $request)
{
$path = $this->getPath($this->getCacheKey($request).'.lck');
clearstatcache(true, $path);
$key = $this->getCacheKey($request);
return is_file($path);
if (isset($this->locks[$key])) {
return true; // shortcut if lock held by this process
}
if (!file_exists($path = $this->getPath($key))) {
return false;
}
$h = fopen($path, 'rb');
flock($h, LOCK_EX | LOCK_NB, $wouldBlock);
flock($h, LOCK_UN); // release the lock we just acquired
fclose($h);
return (bool) $wouldBlock;
}
/**
@ -144,7 +160,7 @@ class Store implements StoreInterface
}
list($req, $headers) = $match;
if (is_file($body = $this->getPath($headers['x-content-digest'][0]))) {
if (file_exists($body = $this->getPath($headers['x-content-digest'][0]))) {
return $this->restoreResponse($headers, $body);
}
@ -291,7 +307,7 @@ class Store implements StoreInterface
*/
private function getMetadata($key)
{
if (false === $entries = $this->load($key)) {
if (!$entries = $this->load($key)) {
return array();
}
@ -307,7 +323,15 @@ class Store implements StoreInterface
*/
public function purge($url)
{
if (is_file($path = $this->getPath($this->getCacheKey(Request::create($url))))) {
$key = $this->getCacheKey(Request::create($url));
if (isset($this->locks[$key])) {
flock($this->locks[$key], LOCK_UN);
fclose($this->locks[$key]);
unset($this->locks[$key]);
}
if (file_exists($path = $this->getPath($key))) {
unlink($path);
return true;
@ -327,7 +351,7 @@ class Store implements StoreInterface
{
$path = $this->getPath($key);
return is_file($path) ? file_get_contents($path) : false;
return file_exists($path) ? file_get_contents($path) : false;
}
/**
@ -341,23 +365,36 @@ class Store implements StoreInterface
private function save($key, $data)
{
$path = $this->getPath($key);
if (!is_dir(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}
$tmpFile = tempnam(dirname($path), basename($path));
if (false === $fp = @fopen($tmpFile, 'wb')) {
return false;
}
@fwrite($fp, $data);
@fclose($fp);
if (isset($this->locks[$key])) {
$fp = $this->locks[$key];
@ftruncate($fp, 0);
@fseek($fp, 0);
$len = @fwrite($fp, $data);
if (strlen($data) !== $len) {
@ftruncate($fp, 0);
if ($data != file_get_contents($tmpFile)) {
return false;
}
return false;
}
} else {
if (!file_exists(dirname($path)) && false === @mkdir(dirname($path), 0777, true) && !is_dir(dirname($path))) {
return false;
}
if (false === @rename($tmpFile, $path)) {
return false;
$tmpFile = tempnam(dirname($path), basename($path));
if (false === $fp = @fopen($tmpFile, 'wb')) {
return false;
}
@fwrite($fp, $data);
@fclose($fp);
if ($data != file_get_contents($tmpFile)) {
return false;
}
if (false === @rename($tmpFile, $path)) {
return false;
}
}
@chmod($path, 0666 & ~umask());

View file

@ -12,6 +12,7 @@
namespace Symfony\Component\HttpKernel;
use Symfony\Component\HttpKernel\Controller\ControllerResolverInterface;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
@ -21,6 +22,7 @@ use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForControllerResultEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\PostResponseEvent;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Response;
@ -61,6 +63,9 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface
try {
return $this->handleRaw($request, $type);
} catch (\Exception $e) {
if ($e instanceof ConflictingHeadersException) {
$e = new BadRequestHttpException('The request headers contain conflicting information regarding the origin of this request.', $e);
}
if (false === $catch) {
$this->finishRequest($request, $type);

View file

@ -59,12 +59,12 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected $startTime;
protected $loadClassCache;
const VERSION = '2.8.4-DEV';
const VERSION_ID = 20804;
const VERSION = '2.8.16';
const VERSION_ID = 20816;
const MAJOR_VERSION = 2;
const MINOR_VERSION = 8;
const RELEASE_VERSION = 4;
const EXTRA_VERSION = 'DEV';
const RELEASE_VERSION = 16;
const EXTRA_VERSION = '';
const END_OF_MAINTENANCE = '11/2018';
const END_OF_LIFE = '11/2019';
@ -466,8 +466,8 @@ abstract class Kernel implements KernelInterface, TerminableInterface
$hierarchy[] = $name;
}
foreach ($hierarchy as $bundle) {
$this->bundleMap[$bundle] = $bundleMap;
foreach ($hierarchy as $hierarchyBundle) {
$this->bundleMap[$hierarchyBundle] = $bundleMap;
array_pop($bundleMap);
}
}
@ -532,8 +532,15 @@ abstract class Kernel implements KernelInterface, TerminableInterface
protected function getKernelParameters()
{
$bundles = array();
$bundlesMetadata = array();
foreach ($this->bundles as $name => $bundle) {
$bundles[$name] = get_class($bundle);
$bundlesMetadata[$name] = array(
'parent' => $bundle->getParent(),
'path' => $bundle->getPath(),
'namespace' => $bundle->getNamespace(),
);
}
return array_merge(
@ -545,6 +552,7 @@ abstract class Kernel implements KernelInterface, TerminableInterface
'kernel.cache_dir' => realpath($this->getCacheDir()) ?: $this->getCacheDir(),
'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),
'kernel.bundles' => $bundles,
'kernel.bundles_metadata' => $bundlesMetadata,
'kernel.charset' => $this->getCharset(),
'kernel.container_class' => $this->getContainerClass(),
),

View file

@ -108,6 +108,10 @@ final class KernelEvents
*
* This event allows you to reset the global and environmental state of
* the application, when it was changed during the request.
* The event listener method receives a
* Symfony\Component\HttpKernel\Event\FinishRequestEvent instance.
*
* @Event
*
* @var string
*/

View file

@ -27,7 +27,7 @@ interface KernelInterface extends HttpKernelInterface, \Serializable
/**
* Returns an array of bundles to register.
*
* @return BundleInterface[] An array of bundle instances.
* @return BundleInterface[] An array of bundle instances
*/
public function registerBundles();

View file

@ -1,4 +1,4 @@
Copyright (c) 2004-2016 Fabien Potencier
Copyright (c) 2004-2017 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

@ -76,7 +76,7 @@ class Profile
/**
* Sets the parent token.
*
* @param Profile $parent The parent Profile
* @param Profile $parent
*/
public function setParent(Profile $parent)
{
@ -86,7 +86,7 @@ class Profile
/**
* Returns the parent profile.
*
* @return Profile The parent profile
* @return self
*/
public function getParent()
{
@ -191,7 +191,7 @@ class Profile
/**
* Finds children profilers.
*
* @return Profile[] An array of Profile
* @return self[]
*/
public function getChildren()
{
@ -201,7 +201,7 @@ class Profile
/**
* Sets children profiler.
*
* @param Profile[] $children An array of Profile
* @param Profile[] $children
*/
public function setChildren(array $children)
{
@ -214,7 +214,7 @@ class Profile
/**
* Adds the child token.
*
* @param Profile $child The child Profile
* @param Profile $child
*/
public function addChild(Profile $child)
{

View file

@ -11,6 +11,7 @@
namespace Symfony\Component\HttpKernel\Profiler;
use Symfony\Component\HttpFoundation\Exception\ConflictingHeadersException;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;
@ -77,7 +78,7 @@ class Profiler
*
* @param Response $response A Response instance
*
* @return Profile A Profile instance
* @return Profile|false A Profile instance
*/
public function loadProfileFromResponse(Response $response)
{
@ -152,7 +153,7 @@ class Profiler
*
* @param string $data A data string as exported by the export() method
*
* @return Profile A Profile instance
* @return Profile|false A Profile instance
*
* @deprecated since Symfony 2.8, to be removed in 3.0.
*/
@ -208,9 +209,13 @@ class Profiler
$profile = new Profile(substr(hash('sha256', uniqid(mt_rand(), true)), 0, 6));
$profile->setTime(time());
$profile->setUrl($request->getUri());
$profile->setIp($request->getClientIp());
$profile->setMethod($request->getMethod());
$profile->setStatusCode($response->getStatusCode());
try {
$profile->setIp($request->getClientIp());
} catch (ConflictingHeadersException $e) {
$profile->setIp('Unknown');
}
$response->headers->set('X-Debug-Token', $profile->getToken());

View file

@ -98,7 +98,7 @@ class UriSigner
$host = isset($url['host']) ? $url['host'] : '';
$port = isset($url['port']) ? ':'.$url['port'] : '';
$user = isset($url['user']) ? $url['user'] : '';
$pass = isset($url['pass']) ? ':'.$url['pass'] : '';
$pass = isset($url['pass']) ? ':'.$url['pass'] : '';
$pass = ($user || $pass) ? "$pass@" : '';
$path = isset($url['path']) ? $url['path'] : '';
$query = isset($url['query']) && $url['query'] ? '?'.$url['query'] : '';

View file

@ -18,7 +18,7 @@
"require": {
"php": ">=5.3.9",
"symfony/event-dispatcher": "~2.6,>=2.6.7|~3.0.0",
"symfony/http-foundation": "~2.5,>=2.5.4|~3.0.0",
"symfony/http-foundation": "~2.7.20|~2.8.13|~3.1.6",
"symfony/debug": "~2.6,>=2.6.2",
"psr/log": "~1.0"
},