Merge branch '2.7' into 2.8

* 2.7:
  [Debug] cleanup ExceptionHandlerTest
  bumped Symfony version to 2.7.4
  updated VERSION for 2.7.3
  updated CHANGELOG for 2.7.3
  fixed typo in translation keys
  Fix the return value on error for intl methods returning arrays
  Fix merge
  Fix missing _route parameter notice in RouterListener logging case

Conflicts:
	src/Symfony/Component/Debug/composer.json
	src/Symfony/Component/HttpKernel/Kernel.php
This commit is contained in:
Nicolas Grekas 2015-08-01 08:34:21 +02:00
commit 68fdb02485
13 changed files with 173 additions and 68 deletions

View File

@ -7,6 +7,27 @@ in 2.7 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v2.7.0...v2.7.1
* 2.7.3 (2015-07-31)
* bug #15413 Fix the return value on error for intl methods returning arrays (stof)
* bug #15392 Fix missing _route parameter notice in RouterListener logging case (Haehnchen)
* bug #15390 [php7] Fix for substr() always returning a string (nicolas-grekas)
* bug #15386 [php7] Fix for substr() always returning a string (nicolas-grekas)
* bug #15355 [Security] Do not save the target path in the session for a stateless firewall (lyrixx)
* bug #15306 [HttpKernel] [HttpCache] Fix deprecated error in HttpCache#getSurrogate (m14t)
* bug #15369 [TwigBridge] type-dependent path discovery (marcosdsanchez, xabbuh)
* bug #15361 [Yaml] throw a ParseException on invalid data type (xabbuh)
* bug #15345 [Twig+FrameworkBundle] Fix forward compat with Form 2.8 (nicolas-grekas)
* bug #15330 [Console] Fix console output with closed stdout (jakzal)
* bug #15339 [Serializer] Fix 2 bugs regarding private setters (dunglas)
* bug #15326 [Security] fix check for empty usernames (xabbuh)
* bug #15291 [HttpFoundation] Fix Response::closeOutputBuffers() for HHVM 3.3 (nicolas-grekas)
* bug #15249 [HttpFoundation] [PSR-7] Allow to use resources as content body and to return resources from string content (dunglas)
* bug #15282 [HttpFoundation] Behaviour change in PHP7 for substr (Nicofuma)
* bug #15277 [Form] Fix a BC break in the entity (jakzal)
* bug #15271 fix broken ChoiceQuestion (sstok)
* bug #15250 [PropertyAccess] BC Break since 2.6.5 (Nicolas Macherey)
* 2.7.2 (2015-07-13)
* bug #15248 Added 'default' color (jaytaph)

View File

@ -38,7 +38,7 @@ class ExceptionHandler
public function __construct($debug = true, $charset = null, $fileLinkFormat = null)
{
if (false !== strpos($charset, '%') xor false === strpos($fileLinkFormat, '%')) {
if (false !== strpos($charset, '%')) {
// Swap $charset and $fileLinkFormat for BC reasons
$pivot = $fileLinkFormat;
$fileLinkFormat = $charset;
@ -153,19 +153,22 @@ class ExceptionHandler
* it will fallback to plain PHP functions.
*
* @param \Exception $exception An \Exception instance
*
* @see sendPhpResponse()
* @see createResponse()
*/
private function failSafeHandle(\Exception $exception)
{
if (class_exists('Symfony\Component\HttpFoundation\Response', false)) {
if (class_exists('Symfony\Component\HttpFoundation\Response', false)
&& __CLASS__ !== get_class($this)
&& ($reflector = new \ReflectionMethod($this, 'createResponse'))
&& __CLASS__ !== $reflector->class
) {
$response = $this->createResponse($exception);
$response->sendHeaders();
$response->sendContent();
} else {
$this->sendPhpResponse($exception);
return;
}
$this->sendPhpResponse($exception);
}
/**

View File

@ -13,71 +13,97 @@ namespace Symfony\Component\Debug\Tests;
use Symfony\Component\Debug\ExceptionHandler;
use Symfony\Component\Debug\Exception\OutOfMemoryException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
require_once __DIR__.'/HeaderMock.php';
class ExceptionHandlerTest extends \PHPUnit_Framework_TestCase
{
protected function setUp()
{
testHeader();
}
protected function tearDown()
{
testHeader();
}
public function testDebug()
{
$handler = new ExceptionHandler(false);
$response = $handler->createResponse(new \RuntimeException('Foo'));
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response->getContent());
ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo'));
$response = ob_get_clean();
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
$this->assertNotContains('<h2 class="block_exception clear_fix">', $response);
$handler = new ExceptionHandler(true);
$response = $handler->createResponse(new \RuntimeException('Foo'));
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response->getContent());
$this->assertContains('<h2 class="block_exception clear_fix">', $response->getContent());
ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo'));
$response = ob_get_clean();
$this->assertContains('<h1>Whoops, looks like something went wrong.</h1>', $response);
$this->assertContains('<h2 class="block_exception clear_fix">', $response);
}
public function testStatusCode()
{
$handler = new ExceptionHandler(false);
$handler = new ExceptionHandler(false, 'iso8859-1');
$response = $handler->createResponse(new \RuntimeException('Foo'));
$this->assertEquals('500', $response->getStatusCode());
$this->assertContains('Whoops, looks like something went wrong.', $response->getContent());
ob_start();
$handler->sendPhpResponse(new NotFoundHttpException('Foo'));
$response = ob_get_clean();
$response = $handler->createResponse(new NotFoundHttpException('Foo'));
$this->assertEquals('404', $response->getStatusCode());
$this->assertContains('Sorry, the page you are looking for could not be found.', $response->getContent());
$this->assertContains('Sorry, the page you are looking for could not be found.', $response);
$expectedHeaders = array(
array('HTTP/1.0 404', true, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);
$this->assertSame($expectedHeaders, testHeader());
}
public function testHeaders()
{
$handler = new ExceptionHandler(false);
$handler = new ExceptionHandler(false, 'iso8859-1');
$response = $handler->createResponse(new MethodNotAllowedHttpException(array('POST')));
$this->assertEquals('405', $response->getStatusCode());
$this->assertEquals('POST', $response->headers->get('Allow'));
ob_start();
$handler->sendPhpResponse(new MethodNotAllowedHttpException(array('POST')));
$response = ob_get_clean();
$expectedHeaders = array(
array('HTTP/1.0 405', true, null),
array('Allow: POST', false, null),
array('Content-Type: text/html; charset=iso8859-1', true, null),
);
$this->assertSame($expectedHeaders, testHeader());
}
public function testNestedExceptions()
{
$handler = new ExceptionHandler(true);
$response = $handler->createResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
ob_start();
$handler->sendPhpResponse(new \RuntimeException('Foo', 0, new \RuntimeException('Bar')));
$response = ob_get_clean();
$this->assertStringMatchesFormat('%A<span class="exception_message">Foo</span>%A<span class="exception_message">Bar</span>%A', $response);
}
public function testHandle()
{
$exception = new \Exception('foo');
if (class_exists('Symfony\Component\HttpFoundation\Response')) {
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('createResponse'));
$handler
->expects($this->exactly(2))
->method('createResponse')
->will($this->returnValue(new Response()));
} else {
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
$handler
->expects($this->exactly(2))
->method('sendPhpResponse');
}
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
$handler
->expects($this->exactly(2))
->method('sendPhpResponse');
$handler->handle($exception);
@ -93,18 +119,10 @@ class ExceptionHandlerTest extends \PHPUnit_Framework_TestCase
{
$exception = new OutOfMemoryException('foo', 0, E_ERROR, __FILE__, __LINE__);
if (class_exists('Symfony\Component\HttpFoundation\Response')) {
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('createResponse'));
$handler
->expects($this->once())
->method('createResponse')
->will($this->returnValue(new Response()));
} else {
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
$handler
->expects($this->once())
->method('sendPhpResponse');
}
$handler = $this->getMock('Symfony\Component\Debug\ExceptionHandler', array('sendPhpResponse'));
$handler
->expects($this->once())
->method('sendPhpResponse');
$that = $this;
$handler->setHandler(function ($e) use ($that) {

View File

@ -0,0 +1,38 @@
<?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\Debug;
function headers_sent()
{
return false;
}
function header($str, $replace = true, $status = null)
{
Tests\testHeader($str, $replace, $status);
}
namespace Symfony\Component\Debug\Tests;
function testHeader()
{
static $headers = array();
if (!$h = func_get_args()) {
$h = $headers;
$headers = array();
return $h;
}
$headers[] = func_get_args();
}

View File

@ -25,12 +25,7 @@
"require-dev": {
"symfony/phpunit-bridge": "~2.7|~3.0.0",
"symfony/class-loader": "~2.2|~3.0.0",
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0",
"symfony/http-foundation": "~2.1|~3.0.0"
},
"suggest": {
"symfony/http-foundation": "",
"symfony/http-kernel": ""
"symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
},
"autoload": {
"psr-4": { "Symfony\\Component\\Debug\\": "" }

View File

@ -140,7 +140,7 @@ class RouterListener implements EventSubscriberInterface
}
if (null !== $this->logger) {
$this->logger->info(sprintf('Matched route "%s".', $parameters['_route']), array(
$this->logger->info(sprintf('Matched route "%s".', isset($parameters['_route']) ? $parameters['_route'] : 'n/a'), array(
'route_parameters' => $parameters,
'request_uri' => $request->getUri(),
));

View File

@ -128,4 +128,34 @@ class RouterListenerTest extends \PHPUnit_Framework_TestCase
$this->assertEquals('GET', $context->getMethod());
}
/**
* @dataProvider getLoggingParameterData
*/
public function testLoggingParameter($parameter, $log)
{
$requestMatcher = $this->getMock('Symfony\Component\Routing\Matcher\RequestMatcherInterface');
$requestMatcher->expects($this->once())
->method('matchRequest')
->will($this->returnValue($parameter));
$logger = $this->getMock('Psr\Log\LoggerInterface');
$logger->expects($this->once())
->method('info')
->with($this->equalTo($log));
$kernel = $this->getMock('Symfony\Component\HttpKernel\HttpKernelInterface');
$request = Request::create('http://localhost/');
$listener = new RouterListener($requestMatcher, new RequestContext(), $logger, $this->requestStack);
$listener->onKernelRequest(new GetResponseEvent($kernel, $request, HttpKernelInterface::MASTER_REQUEST));
}
public function getLoggingParameterData()
{
return array(
array(array('_route' => 'foo'), 'Matched route "foo".'),
array(array(), 'Matched route "n/a".'),
);
}
}

View File

@ -76,7 +76,7 @@ class CurrencyBundle extends CurrencyDataProvider implements CurrencyBundleInter
try {
return $this->getNames($displayLocale);
} catch (MissingResourceException $e) {
return;
return array();
}
}
@ -112,7 +112,7 @@ class CurrencyBundle extends CurrencyDataProvider implements CurrencyBundleInter
try {
return $this->localeProvider->getLocales();
} catch (MissingResourceException $e) {
return;
return array();
}
}
}

View File

@ -80,7 +80,7 @@ class LanguageBundle extends LanguageDataProvider implements LanguageBundleInter
try {
return $this->getNames($displayLocale);
} catch (MissingResourceException $e) {
return;
return array();
}
}
@ -104,7 +104,7 @@ class LanguageBundle extends LanguageDataProvider implements LanguageBundleInter
try {
return $this->scriptProvider->getNames($displayLocale);
} catch (MissingResourceException $e) {
return;
return array();
}
}
@ -116,7 +116,7 @@ class LanguageBundle extends LanguageDataProvider implements LanguageBundleInter
try {
return $this->localeProvider->getLocales();
} catch (MissingResourceException $e) {
return;
return array();
}
}
}

View File

@ -31,7 +31,7 @@ class LocaleBundle extends LocaleDataProvider implements LocaleBundleInterface
try {
return parent::getLocales();
} catch (MissingResourceException $e) {
return;
return array();
}
}
@ -55,7 +55,7 @@ class LocaleBundle extends LocaleDataProvider implements LocaleBundleInterface
try {
return $this->getNames($displayLocale);
} catch (MissingResourceException $e) {
return;
return array();
}
}
}

View File

@ -64,7 +64,7 @@ class RegionBundle extends RegionDataProvider implements RegionBundleInterface
try {
return $this->getNames($displayLocale);
} catch (MissingResourceException $e) {
return;
return array();
}
}
@ -76,7 +76,7 @@ class RegionBundle extends RegionDataProvider implements RegionBundleInterface
try {
return $this->localeProvider->getLocales();
} catch (MissingResourceException $e) {
return;
return array();
}
}
}

View File

@ -175,7 +175,7 @@
<target>画像の高さが小さすぎます({{ height }}ピクセル)。{{ min_height }}ピクセル以上にしてください。</target>
</trans-unit>
<trans-unit id="47">
<source>This value should be the user current password.</source>
<source>This value should be the user's current password.</source>
<target>ユーザーの現在のパスワードでなければなりません。</target>
</trans-unit>
<trans-unit id="48">

View File

@ -175,7 +175,7 @@
<target>ความสูงของภาพไม่ได้ขนาด ({{ height }}px) อนุญาตให้สูงอย่างน้อยที่สุด {{ min_height }}px</target>
</trans-unit>
<trans-unit id="47">
<source>This value should be the user current password.</source>
<source>This value should be the user's current password.</source>
<target>ค่านี้ควรจะเป็นรหัสผ่านปัจจุบันของผู้ใช้</target>
</trans-unit>
<trans-unit id="48">