8000 [DI] Allow autoconfiguring bindings · symfony/symfony@9032b03 · GitHub
[go: up one dir, main page]

Skip to content

Commit 9032b03

Browse files
[DI] Allow autoconfiguring bindings
1 parent 9efa555 commit 9032b03

File tree

6 files changed

+79
-4
lines changed

6 files changed

+79
-4
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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\DependencyInjection\Compiler;
13+
14+
use Symfony\Bridge\Monolog\Processor\ProcessorInterface;
15+
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
16+
use Symfony\Component\DependencyInjection\ContainerBuilder;
17+
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
18+
use Symfony\Component\DependencyInjection\Reference;
19+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
20+
21+
/**
22+
* Adds a rule to bind "security.actual_token_storage" to ProcessorInterface instances.
23+
*
24+
* @author Nicolas Grekas <p@tchwork.com>
25+
*/
26+
class RegisterForAutoconfigurationPass implements CompilerPassInterface
27+
{
28+
/**
29+
* {@inheritdoc}
30+
*/
31+
public function process(ContainerBuilder $container)
32+
{
33+
if ($container->has('security.actual_token_storage')) {
34+
$processorAutoconfiguration = $container->registerForAutoconfiguration(ProcessorInterface::class);
35+
$processorAutoconfiguration->setBindings($processorAutoconfiguration->getBindings() + array(
36+
TokenStorageInterface::class => new BoundArgument(new Reference('security.actual_token_storage'), false),
37+
));
38+
}
39+
}
40+
}

src/Symfony/Bundle/SecurityBundle/SecurityBundle.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
ED48 @@ -13,6 +13,7 @@
1313

1414
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\AddExpressionLanguageProvidersPass;
1515
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterCsrfTokenClearingLogoutHandlerPass;
16+
use Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler\RegisterForAutoconfigurationPass;
1617
use Symfony\Bundle\SecurityBundle\DependencyInjection\Security\Factory\JsonLoginFactory;
1718
use Symfony\Component\HttpKernel\Bundle\Bundle;
1819
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
@@ -62,5 +63,6 @@ public function build(ContainerBuilder $container)
6263
$container->addCompilerPass(new AddSecurityVotersPass());
6364
$container->addCompilerPass(new AddSessionDomainConstraintPass(), PassConfig::TYPE_BEFORE_REMOVING);
6465
$container->addCompilerPass(new RegisterCsrfTokenClearingLogoutHandlerPass());
66+
$container->addCompilerPass(new RegisterForAutoconfigurationPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 200);
6567
}
6668
}

src/Symfony/Bundle/SecurityBundle/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"ext-xml": "*",
2121
"symfony/config": "^4.2",
2222
"symfony/security": "~4.2",
23-
"symfony/dependency-injection": "^3.4.3|^4.0.3",
23+
"symfony/dependency-injection": "^4.2",
2424
"symfony/http-kernel": "^4.1"
2525
},
2626
"require-dev": {

src/Symfony/Component/DependencyInjection/Argument/BoundArgument.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,14 @@ final class BoundArgument implements ArgumentInterface
2222
private $identifier;
2323
private $used;
2424

25-
public function __construct($value)
25+
public function __construct($value, bool $trackUsage = true)
2626
{
2727
$this->value = $value;
28-
$this->identifier = ++self::$sequence;
28+
if ($trackUsage) {
29+
$this->identifier = ++self::$sequence;
30+
} else {
31+
$this->used = true;
32+
}
2933
}
3034

3135
/**

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
6262
$parent = $shared = null;
6363
$instanceofTags = array();
6464
$instanceofCalls = array();
65+
$instanceofBindings = array();
6566

6667
foreach ($conditionals as $interface => $instanceofDefs) {
6768
if ($interface !== $class && (!$container->getReflectionClass($class, false))) {
@@ -79,13 +80,15 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
7980
$parent = '.instanceof.'.$interface.'.'.$key.'.'.$id;
8081
$container->setDefinition($parent, $instanceofDef);
8182
$instanceofTags[] = $instanceofDef->getTags();
83+
$instanceofBindings = $instanceofDef->getBindings() + $instanceofBindings;
8284

8385
foreach ($instanceofDef->getMethodCalls() as $methodCall) {
8486
$instanceofCalls[] = $methodCall;
8587
}
8688

8789
$instanceofDef->setTags(array());
8890
$instanceofDef->setMethodCalls(array());
91+
$instanceofDef->setBindings(array());
8992

9093
if (isset($instanceofDef->getChanges()['shared'])) {
9194
$shared = $instanceofDef->isShared();
@@ -123,10 +126,11 @@ private function processDefinition(ContainerBuilder $container, $id, Definition
123126
}
124127

125128
$definition->setMethodCalls(array_merge($instanceofCalls, $definition->getMethodCalls()));
129+
$definition->setBindings($bindings + $instanceofBindings);
126130

127131
// reset fields with "merge" behavior
128132
$abstract
129-
->setBindings($bindings)
133+
->setBindings(array())
130134
->setArguments(array())
131135
->setMethodCalls(array())
132136
->setDecoratedService(null)

src/Symfony/Component/DependencyInjection/Tests/Compiler/ResolveInstanceofConditionalsPassTest.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,12 @@
1212
namespace Symfony\Component\DependencyInjection\Tests\Compiler;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
1516
use Symfony\Component\DependencyInjection\ChildDefinition;
1617
use Symfony\Component\DependencyInjection\Compiler\ResolveInstanceofConditionalsPass;
1718
use Symfony\Component\DependencyInjection\Compiler\ResolveChildDefinitionsPass;
1819
use Symfony\Component\DependencyInjection\ContainerBuilder;
20+
use Symfony\Component\DependencyInjection\Reference;
1921

2022
class ResolveInstanceofConditionalsPassTest extends TestCase
2123
{
@@ -268,4 +270,27 @@ public function testMergeReset()
268270
$this->assertEmpty($abstract->getTags());
269271
$this->assertTrue($abstract->isAbstract());
270272
}
273+
274+
public function testProcessForAutoconfiguredBindings()
275+
{
276+
$container = new ContainerBuilder();
277+
278+
$container->registerForAutoconfiguration(self::class)
279+
->setBindings(array(
280+
'$foo' => new BoundArgument(234, false),
281+
parent::class => new BoundArgument(new Reference('foo'), false),
282+
));
283+
284+
$container->register('foo', self::class)
285+
->setAutoconfigured(true)
286+
->setBindings(array('$foo' => new BoundArgument(123, false)));
287+
288+
(new ResolveInstanceofConditionalsPass())->process($container);
289+
290+
$expected = array(
291+
'$foo' => new BoundArgument(123, false),
292+
parent::class => new BoundArgument(new Reference('foo'), false),
293+
);
294+
$this->assertEquals($expected, $container->findDefinition('foo')->getBindings());
295+
}
271296
}

0 commit comments

Comments
 (0)
0