8000 Merge branch '5.0' · symfony/symfony@de4c45c · GitHub
[go: up one dir, main page]

Skip to content

Commit de4c45c

Browse files
committed
Merge branch '5.0'
* 5.0: Avoid stale-if-error if kernel.debug = true, because it hides errors [Console] Fix SymfonyQuestionHelper tests sometimes failing on AppVeyor [SecurityBundle] Fix collecting traceable listeners info using anonymous: lazy [Filesystem][FilesystemCommonTrait] Use a dedicated directory when there are no namespace [Workflow] Fix configuration node reference for "initial_marking" expand listener in place [DI] deferred exceptions in ResolveParameterPlaceHoldersPass Do not throw exception on valut generate key
2 parents 37a8863 + b4a63f9 commit de4c45c

File tree

13 files changed

+216
-56
lines changed

13 files changed

+216
-56
lines changed

UPGRADE-5.0.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -602,7 +602,7 @@ Workflow
602602
* `ClassInstanceSupportStrategy` has been removed, use `InstanceOfSupportStrategy` instead.
603603
* `WorkflowInterface::apply()` has a third argument: `array $context = []`.
604604
* `MarkingStoreInterface::setMarking()` has a third argument: `array $context = []`.
605-
* Removed support of `initial_place`. Use `initial_places` instead.
605+
* Removed support of `initial_place`. Use `initial_marking` instead.
606606
* `MultipleStateMarkingStore` has been removed. Use `MethodMarkingStore` instead.
607607
* `DefinitionBuilder::setInitialPlace()` has been removed, use `DefinitionBuilder::setInitialPlaces()` instead.
608608

src/Symfony/Bundle/FrameworkBundle/HttpCache/HttpCache.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,14 @@ public function __construct(KernelInterface $kernel, string $cacheDir = null)
3636
$this->kernel = $kernel;
3737
$this->cacheDir = $cacheDir;
3838

39-
parent::__construct($kernel, $this->createStore(), $this->createSurrogate(), array_merge(['debug' => $kernel->isDebug()], $this->getOptions()));
39+
$isDebug = $kernel->isDebug();
40+
$options = ['debug' => $isDebug];
41+
42+
if ($isDebug) {
43+
$options['stale_if_error'] = 0;
44+
}
45+
46+
parent::__construct($kernel, $this->createStore(), $this->createSurrogate(), array_merge($options, $this->getOptions()));
4047
}
4148

4249
/**

src/Symfony/Bundle/FrameworkBundle/Secrets/SodiumVault.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,9 @@ public function generateKeys(bool $override = false): bool
4747
$this->lastMessage = null;
4848

4949
if (null === $this->encryptionKey && '' !== $this->decryptionKey = (string) $this->decryptionKey) {
50-
throw new \LogicException('Cannot generate keys when a decryption key has been provided while instantiating the vault.');
50+
$this->lastMessage = 'Cannot generate keys when a decryption key has been provided while instantiating the vault.';
51+
52+
return false;
5153
}
5254

5355
try {

src/Symfony/Bundle/SecurityBundle/Debug/TraceableFirewallListener.php

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
namespace Symfony\Bundle\SecurityBundle\Debug;
1313

1414
use Symfony\Bundle\SecurityBundle\EventListener\FirewallListener;
15+
use Symfony\Bundle\SecurityBundle\Security\FirewallContext;
16+
use Symfony\Bundle\SecurityBundle\Security\LazyFirewallContext;
1517
use Symfony\Component\HttpKernel\Event\RequestEvent;
18+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
1619

1720
/**
1821
* Firewall collecting called listeners.
@@ -21,7 +24,7 @@
2124
*/
2225
final class TraceableFirewallListener extends FirewallListener
2326
{
24-
private $wrappedListeners;
27+
private $wrappedListeners = [];
2528

2629
public function getWrappedListeners()
2730
{
@@ -30,14 +33,47 @@ public function getWrappedListeners()
3033

3134
protected function callListeners(RequestEvent $event, iterable $listeners)
3235
{
36+
$wrappedListeners = [];
37+
$wrappedLazyListeners = [];
38+
3339
foreach ($listeners as $listener) {
34-
$wrappedListener = new WrappedListener($listener);
35-
$wrappedListener($event);
36-
$this->wrappedListeners[] = $wrappedListener->getInfo();
40+
if ($listener instanceof LazyFirewallContext) {
41+
\Closure::bind(function () use (&$wrappedLazyListeners, &$wrappedListeners) {
42+
$listeners = [];
43+
foreach ($this->listeners as $listener) {
44+
if ($listener instanceof AbstractListener) {
45+
$listener = new WrappedLazyListener($listener);
46+
$listeners[] = $listener;
47+
$wrappedLazyListeners[] = $listener;
48+
} else {
49+
$listeners[] = function (RequestEvent $event) use ($listener, &$wrappedListeners) {
50+
$wrappedListener = new WrappedListener($listener);
51+
$wrappedListener($event);
52+
$wrappedListeners[] = $wrappedListener->getInfo();
53+
};
54+
}
55+
}
56+
$this->listeners = $listeners;
57+
}, $listener, FirewallContext::class)();
58+
59+
$listener($event);
60+
} else {
61+
$wrappedListener = $listener instanceof AbstractListener ? new WrappedLazyListener($listener) : new WrappedListener($listener);
62+
$wrappedListener($event);
63+
$wrappedListeners[] = $wrappedListener->getInfo();
64+
}
3765

3866
if ($event->hasResponse()) {
3967
break;
4068
}
4169
}
70+
71+
if ($wrappedLazyListeners) {
72+
foreach ($wrappedLazyListeners as $lazyListener) {
73+
$this->wrappedListeners[] = $lazyListener->getInfo();
74+
}
75+
}
76+
77+
$this->wrappedListeners = array_merge($this->wrappedListeners, $wrappedListeners);
4278
}
4379
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Debug;
13+
14+
/**
15+
* @author Robin Chalas <robin.chalas@gmail.com>
16+
*
17+
* @internal
18+
*/
19+
trait TraceableListenerTrait
20+
{
21+
private $response;
22+
private $listener;
23+
private $time;
24+
private $stub;
25+
26+
/**
27+
* Proxies all method calls to the original listener.
28+
*/
29+
public function __call(string $method, array $arguments)
30+
{
31+
return $this->listener->{$method}(...$arguments);
32+
}
33+
34+
public function getWrappedListener()
35+
{
36+
return $this->listener;
37+
}
38+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Bundle\SecurityBundle\Debug;
13+
14+
use Symfony\Component\HttpFoundation\Request;
15+
use Symfony\Component\HttpKernel\Event\RequestEvent;
16+
use Symfony\Component\Security\Core\Exception\LazyResponseException;
17+
use Symfony\Component\Security\Http\Firewall\AbstractListener;
18+
use Symfony\Component\VarDumper\Caster\ClassStub;
19+
20+
/**
21+
* Wraps a lazy security listener.
22+
*
23+
* @author Robin Chalas <robin.chalas@gmail.com>
24+
*
25+
* @internal
26+
*/
27+
final class WrappedLazyListener extends AbstractListener
28+
{
29+
use TraceableListenerTrait;
30+
31+
public function __construct(AbstractListener $listener)
32+
{
33+
$this->listener = $listener;
34+
}
35+
36+
public function supports(Request $request): ?bool
37+
{
38+
return $this->listener->supports($request);
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
public function authenticate(RequestEvent $event)
45+
{
46+
$startTime = microtime(true);
47+
48+
try {
49+
$ret = $this->listener->authenticate($event);
50+
} catch (LazyResponseException $e) {
51+
$this->response = $e->getResponse();
52+
53+
throw $e;
54+
} finally {
55+
$this->time = microtime(true) - $startTime;
56+
}
57+
58+
$this->response = $event->getResponse();
59+
60+
return $ret;
61+
}
62+
63+
public function getInfo(): array
64+
{
65+
return [
66+
'response' => $this->response,
67+
'time' => $this->time,
68+
'stub' => $this->stub ?? $this->stub = ClassStub::wrapCallable($this->listener),
69+
];
70+
}
71+
}

src/Symfony/Bundle/SecurityBundle/Debug/WrappedListener.php

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,7 @@
2323
*/
2424
final class WrappedListener
2525
{
26-
private $response;
27-
private $listener;
28-
private $time;
29-
private $stub;
30-
private static $hasVarDumper;
26+
use TraceableListenerTrait;
3127

3228
public function __construct(callable $listener)
3329
{
@@ -42,46 +38,12 @@ public function __invoke(RequestEvent $event)
4238
$this->response = $event->getResponse();
4339
}
4440

45-
/**
46-
* Proxies all method calls to the original listener.
47-
*/
48-
public function __call(string $method, array $arguments)
49-
{
50-
return $this->listener->{$method}(...$arguments);
51-
}
52-
53-
public function getWrappedListener(): callable
54-
{
55-
return $this->listener;
56-
}
57-
5841
public function getInfo(): array
5942
{
60-
if (null !== $this->stub) {
61-
// no-op
62-
} elseif (self::$hasVarDumper ?? self::$hasVarDumper = class_exists(ClassStub::class)) {
63-
$this->stub = ClassStub::wrapCallable($this->listener);
64-
} elseif (\is_array($this->listener)) {
65-
$this->stub = (\is_object($this->listener[0]) ? \get_class($this->listener[0]) : $this->listener[0]).'::'.$this->listener[1];
66-
} elseif ($this->listener instanceof \Closure) {
67-
$r = new \ReflectionFunction($this->listener);
68-
if (false !== strpos($r->name, '{closure}')) {
69-
$this->stub = 'closure';
70-
} elseif ($class = $r->getClosureScopeClass()) {
71-
$this->stub = $class->name.'::'.$r->name;
72-
} else {
73-
$this->stub = $r->name;
74-
}
75-
} elseif (\is_string($this->listener)) {
76-
$this->stub = $this->listener;
77-
} else {
78-
$this->stub = \get_class($this->listener).'::__invoke';
79-
}
80-
8143
return [
8244
'response' => $this->response,
8345
'time' => $this->time,
84-
'stub' => $this->stub,
46+
'stub' => $this->stub ?? $this->stub = ClassStub::wrapCallable($this->listener),
8547
];
8648
}
8749
}

src/Symfony/Component/Cache/Traits/FilesystemCommonTrait.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ private function init(string $namespace, ?string $directory)
3535
throw new InvalidArgumentException(sprintf('Namespace contains "%s" but only characters in [-+_.A-Za-z0-9] are allowed.', $match[0]));
3636
}
3737
$directory .= \DIRECTORY_SEPARATOR.$namespace;
38+ } else {
39+
$directory .= \DIRECTORY_SEPARATOR.'@';
3840
}
3941
if (!file_exists($directory)) {
4042
@mkdir($directory, 0777, true);

src/Symfony/Component/Console/Tests/Helper/SymfonyQuestionHelperTest.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -145,13 +145,13 @@ public function testChoiceQuestionPadding()
145145
);
146146

147147
$this->assertOutputContains(<<<EOT
148-
qqq:
148+
qqq:
149149
[foo ] foo
150150
[żółw ] bar
151151
[łabądź] baz
152152
>
153153
EOT
154-
, $output);
154+
, $output, true);
155155
}
156156

157157
public function testChoiceQuestionCustomPrompt()
@@ -168,9 +168,9 @@ public function testChoiceQuestionCustomPrompt()
168168
$this->assertOutputContains(<<<EOT
169169
qqq:
170170
[0] foo
171-
>ccc>
171+
>ccc>
172172
EOT
173-
, $output);
173+
, $output, true);
174174
}
175175

176176
protected function getInputStream($input)
@@ -200,10 +200,15 @@ protected function createInputInterfaceMock($interactive = true)
200200
return $mock;
201201
}
202202

203-
private function assertOutputContains($expected, StreamOutput $output)
203+
private function assertOutputContains($expected, StreamOutput $output, $normalize = false)
204204
{
205205
rewind($output->getStream());
206206
$stream = stream_get_contents($output->getStream());
207+
208+
if ($normalize) {
209+
$stream = str_replace(PHP_EOL, "\n", $stream);
210+
}
211+
207212
$this->assertStringContainsString($expected, $stream);
208213
}
209214
}

src/Symfony/Component/DependencyInjection/Compiler/PassConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function __construct()
5252
new ValidateEnvPlaceholdersPass(),
5353
new ResolveChildDefinitionsPass(),
5454
new RegisterServiceSubscribersPass(),
55-
new ResolveParameterPlaceHoldersPass(false),
55+
new ResolveParameterPlaceHoldersPass(false, false),
5656
new ResolveFactoryClassPass(),
5757
new ResolveNamedArgumentsPass(),
5858
new AutowireRequiredMethodsPass(),

src/Symfony/Component/DependencyInjection/Compiler/ResolveParameterPlaceHoldersPass.php

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,12 @@ class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass
2424
{
2525
private $bag;
2626
private $resolveArrays;
27+
private $throwOnResolveException;
2728

28-
public function __construct(bool $resolveArrays = true)
29+
public function __construct($resolveArrays = true, $throwOnResolveException = true)
2930
{
3031
$this->resolveArrays = $resolveArrays;
32+
$this->throwOnResolveException = $throwOnResolveException;
3133
}
3234

3335
/**
@@ -61,7 +63,16 @@ public function process(ContainerBuilder $container)
6163
protected function processValue($value, bool $isRoot = false)
6264
{
6365
if (\is_string($value)) {
64-
$v = $this->bag->resolveValue($value);
66+
try {
67+
$v = $this->bag->resolveValue($value);
68+
} catch (ParameterNotFoundException $e) {
69+
if ($this->throwOnResolveException) {
70+
throw $e;
71+
}
72+
73+
$v = null;
74+
$this->container->getDefinition($this->currentId)->addError($e->getMessage());
75+
}
6576

6677
return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value;
6778
}

0 commit comments

Comments
 (0)
0