Skip to content

Commit 9ddf500

Browse files
committed
Merge branch '3.3' into 3.4
* 3.3: [HttpFoundation] Support 0 bit netmask in IPv6 () [DI] Impossible to set an environment variable and then an array as container parameter [LDAP] added missing dots at the end of some exception messages. Set `width: auto` on WebProfiler toolbar's reset. [Process] Dont rely on putenv(), it fails on ZTS PHP [HttpKernel] detect deprecations thrown by container initialization during tests [HttpKernel] Fix logging of post-terminate errors/exceptions [Debug] Fix catching fatal errors in case of nested error handlers [VarDumper] Fixed file links leave blank pages when ide is configured Fix hidden currency element with Bootstrap 3 theme
2 parents eff904e + 0a95168 commit 9ddf500

File tree

24 files changed

+289
-82
lines changed

24 files changed

+289
-82
lines changed

src/Symfony/Bridge/Twig/Resources/views/Form/bootstrap_base_layout.html.twig

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,21 @@
88
{%- endblock textarea_widget %}
99

1010
{% block money_widget -%}
11-
<div class="input-group{{ group_class|default('') }}">
12-
{%- set append = money_pattern starts with '{{' -%}
13-
{%- if not append -%}
14-
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
15-
{%- endif -%}
11+
{% set prepend = not (money_pattern starts with '{{') %}
12+
{% set append = not (money_pattern ends with '}}') %}
13+
{% if prepend or append %}
14+
<div class="input-group{{ group_class|default('') }}">
15+
{% if prepend %}
16+
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
17+
{% endif %}
18+
{{- block('form_widget_simple') -}}
19+
{% if append %}
20+
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
21+
{% endif %}
22+
</div>
23+
{% else %}
1624
{{- block('form_widget_simple') -}}
17-
{%- if append -%}
18-
<span class="input-group-addon">{{ money_pattern|replace({ '{{ widget }}':''}) }}</span>
19-
{%- endif -%}
20-
</div>
25+
{% endif %}
2126
{%- endblock money_widget %}
2227

2328
{% block percent_widget -%}

src/Symfony/Bundle/WebProfilerBundle/Resources/views/Profiler/toolbar.css.twig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
box-sizing: content-box;
4242
vertical-align: baseline;
4343
letter-spacing: normal;
44+
width: auto;
4445
}
4546

4647
.sf-toolbarreset {

src/Symfony/Component/BrowserKit/Client.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,7 @@ protected function doRequestInProcess($request)
346346
{
347347
$deprecationsFile = tempnam(sys_get_temp_dir(), 'deprec');
348348
putenv('SYMFONY_DEPRECATIONS_SERIALIZE='.$deprecationsFile);
349+
$_ENV['SYMFONY_DEPRECATIONS_SERIALIZE'] = $deprecationsFile;
349350
$process = new PhpProcess($this->getScript($request), null, null);
350351
$process->run();
351352

src/Symfony/Component/Debug/ErrorHandler.php

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,7 @@ public function handleException($exception, array $error = null)
530530
$exception = new FatalThrowableError($exception);
531531
}
532532
$type = $exception instanceof FatalErrorException ? $exception->getSeverity() : E_ERROR;
533+
$handlerException = null;
533534

534535
if (($this->loggedErrors & $type) || $exception instanceof FatalThrowableError) {
535536
if ($exception instanceof FatalErrorException) {
@@ -564,18 +565,20 @@ public function handleException($exception, array $error = null)
564565
}
565566
}
566567
}
567-
if (empty($this->exceptionHandler)) {
568-
throw $exception; // Give back $exception to the native handler
569-
}
570568
try {
571-
call_user_func($this->exceptionHandler, $exception);
569+
if (null !== $this->exceptionHandler) {
570+
return \call_user_func($this->exceptionHandler, $exception);
571+
}
572+
$handlerException = $handlerException ?: $exception;
572573
} catch (\Exception $handlerException) {
573574
} catch (\Throwable $handlerException) {
574575
}
575-
if (isset($handlerException)) {
576-
$this->exceptionHandler = null;
577-
$this->handleException($handlerException);
576+
$this->exceptionHandler = null;
577+
if ($exception === $handlerException) {
578+
self::$reservedMemory = null; // Disable the fatal error handler
579+
throw $exception; // Give back $exception to the native handler
578580
}
581+
$this->handleException($handlerException);
579582
}
580583

581584
/**
@@ -591,15 +594,30 @@ public static function handleFatalError(array $error = null)
591594
return;
592595
}
593596

594-
self::$reservedMemory = null;
597+
$handler = self::$reservedMemory = null;
598+
$handlers = array();
595599

596-
$handler = set_error_handler('var_dump');
597-
$handler = is_array($handler) ? $handler[0] : null;
598-
restore_error_handler();
600+
while (!is_array($handler) || !$handler[0] instanceof self) {
601+
$handler = set_exception_handler('var_dump');
602+
restore_exception_handler();
599603

600-
if (!$handler instanceof self) {
604+
if (!$handler) {
605+
break;
606+
}
607+
restore_exception_handler();
608+
array_unshift($handlers, $handler);
609+
}
610+
foreach ($handlers as $h) {
611+
set_exception_handler($h);
612+
}
613+
if (!$handler) {
601614
return;
602615
}
616+
if ($handler !== $h) {
617+
$handler[0]->setExceptionHandler($h);
618+
}
619+
$handler = $handler[0];
620+
$handlers = array();
603621

604622
if ($exit = null === $error) {
605623
$error = error_get_last();
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
--TEST--
2+
Test rethrowing in custom exception handler
3+
--FILE--
4+
<?php
5+
6+
namespace Symfony\Component\Debug;
7+
8+
$vendor = __DIR__;
9+
while (!file_exists($vendor.'/vendor')) {
10+
$vendor = dirname($vendor);
11+
}
12+
require $vendor.'/vendor/autoload.php';
13+
14+
if (true) {
15+
class TestLogger extends \Psr\Log\AbstractLogger
16+
{
17+
public function log($level, $message, array $context = array())
18+
{
19+
echo $message, "\n";
20+
}
21+
}
22+
}
23+
24+
set_exception_handler(function ($e) { echo 123; throw $e; });
25+
ErrorHandler::register()->setDefaultLogger(new TestLogger());
26+
ini_set('display_errors', 1);
27+
28+
throw new \Exception('foo');
29+
30+
?>
31+
--EXPECTF--
32+
Uncaught Exception: foo
33+
123
34+
Fatal error: Uncaught %s:25
35+
Stack trace:
36+
%a
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Test catching fatal errors when handlers are nested
3+
--FILE--
4+
<?php
5+
6+
namespace Symfony\Component\Debug;
7+
8+
$vendor = __DIR__;
9+
while (!file_exists($vendor.'/vendor')) {
10+
$vendor = dirname($vendor);
11+
}
12+
require $vendor.'/vendor/autoload.php';
13+
14+
Debug::enable();
15+
ini_set('display_errors', 0);
16+
17+
$eHandler = set_error_handler('var_dump');
18+
$xHandler = set_exception_handler('var_dump');
19+
20+
var_dump(array(
21+
$eHandler[0] === $xHandler[0] ? 'Error and exception handlers do match' : 'Error and exception handlers are different',
22+
));
23+
24+
$eHandler[0]->setExceptionHandler('print_r');
25+
26+
if (true) {
27+
class Broken implements \Serializable {};
28+
}
29+
30+
?>
31+
--EXPECTF--
32+
array(1) {
33+
[0]=>
34+
string(37) "Error and exception handlers do match"
35+
}
36+
object(Symfony\Component\Debug\Exception\FatalErrorException)#4 (8) {
37+
["message":protected]=>
38+
string(199) "Error: Class Symfony\Component\Debug\Broken contains 2 abstract methods and must therefore be declared abstract or implement the remaining methods (Serializable::serialize, Serializable::unserialize)"
39+
%a
40+
}

src/Symfony/Component/DependencyInjection/ContainerBuilder.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,11 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs
13621362
$format = '%%env(%s)%%';
13631363
}
13641364

1365+
$bag = $this->getParameterBag();
1366+
if (true === $format) {
1367+
$value = $bag->resolveValue($value);
1368+
}
1369+
13651370
if (is_array($value)) {
13661371
$result = array();
13671372
foreach ($value as $k => $v) {
@@ -1374,11 +1379,6 @@ public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs
13741379
if (!is_string($value)) {
13751380
return $value;
13761381
}
1377-
1378-
$bag = $this->getParameterBag();
1379-
if (true === $format) {
1380-
$value = $bag->resolveValue($value);
1381-
}
13821382
$envPlaceholders = $bag instanceof EnvPlaceholderParameterBag ? $bag->getEnvPlaceholders() : $this->envPlaceholders;
13831383

13841384
foreach ($envPlaceholders as $env => $placeholders) {

src/Symfony/Component/DependencyInjection/Tests/ContainerBuilderTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,28 @@ public function testResolveEnvValues()
616616
unset($_ENV['DUMMY_ENV_VAR'], $_SERVER['DUMMY_SERVER_VAR'], $_SERVER['HTTP_DUMMY_VAR']);
617617
}
618618

619+
public function testResolveEnvValuesWithArray()
620+
{
621+
$_ENV['ANOTHER_DUMMY_ENV_VAR'] = 'dummy';
622+
623+
$dummyArray = array('1' => 'one', '2' => 'two');
624+
625+
$container = new ContainerBuilder();
626+
$container->setParameter('dummy', '%env(ANOTHER_DUMMY_ENV_VAR)%');
627+
$container->setParameter('dummy2', $dummyArray);
628+
629+
$container->resolveEnvPlaceholders('%dummy%', true);
630+
$container->resolveEnvPlaceholders('%dummy2%', true);
631+
632+
$this->assertInternalType('array', $container->resolveEnvPlaceholders('%dummy2%', true));
633+
634+
foreach ($dummyArray as $key => $value) {
635+
$this->assertArrayHasKey($key, $container->resolveEnvPlaceholders('%dummy2%', true));
636+
}
637+
638+
unset($_ENV['ANOTHER_DUMMY_ENV_VAR']);
639+
}
640+
619641
public function testCompileWithResolveEnv()
620642
{
621643
putenv('DUMMY_ENV_VAR=du%%y');

src/Symfony/Component/Form/Tests/AbstractBootstrap3LayoutTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1914,6 +1914,25 @@ public function testMoney()
19141914
);
19151915
}
19161916

1917+
public function testMoneyWithoutCurrency()
1918+
{
1919+
$form = $this->factory->createNamed('name', 'money', 1234.56, array(
1920+
'currency' => false,
1921+
));
1922+
1923+
$this->assertWidgetMatchesXpath($form->createView(), array('id' => 'my&id', 'attr' => array('class' => 'my&class')),
1924+
'/input
1925+
[@id="my&id"]
1926+
[@type="text"]
1927+
[@name="name"]
1928+
[@class="my&class form-control"]
1929+
[@value="1234.56"]
1930+
[not(preceding-sibling::*)]
1931+
[not(following-sibling::*)]
1932+
'
1933+
);
1934+
}
1935+
19171936
public function testNumber()
19181937
{
19191938
$form = $this->factory->createNamed('name', 'Symfony\Component\Form\Extension\Core\Type\NumberType', 1234.56);

src/Symfony/Component/Form/Tests/Extension/Core/Type/MoneyTypeTest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public function testMoneyPatternWorksForYen()
4343
$view = $this->factory->create(static::TESTED_TYPE, null, array('currency' => 'JPY'))
4444
->createView();
4545

46-
$this->assertTrue((bool) strstr($view->vars['money_pattern'], '¥'));
46+
$this->assertSame('¥ {{ widget }}', $view->vars['money_pattern']);
4747
}
4848

4949
// https://github.com/symfony/symfony/issues/5458
@@ -62,4 +62,12 @@ public function testSubmitNull($expected = null, $norm = null, $view = null)
6262
{
6363
parent::testSubmitNull($expected, $norm, '');
6464
}
65+
66+
public function testMoneyPatternWithoutCurrency()
67+
{
68+
$view = $this->factory->create(static::TESTED_TYPE, null, array('currency' => false))
69+
->createView();
70+
71+
$this->assertSame('{{ widget }}', $view->vars['money_pattern']);
72+
}
6573
}

0 commit comments

Comments
 (0)