Skip to content

Commit 75c98cb

Browse files
committed
Added a way to define the priority of service decoration
1 parent 2655072 commit 75c98cb

File tree

16 files changed

+94
-17
lines changed

16 files changed

+94
-17
lines changed

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ CHANGELOG
88
* deprecated the concept of scopes
99
* added `Definition::setShared()` and `Definition::isShared()`
1010
* added ResettableContainerInterface to be able to reset the container to release memory on shutdown
11+
* added a way to define the priority of service decoration
1112

1213
2.7.0
1314
-----

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,28 @@
1919
*
2020
* @author Christophe Coevoet <stof@notk.org>
2121
* @author Fabien Potencier <fabien@symfony.com>
22+
* @author Diego Saint Esteben <diego@saintesteben.me>
2223
*/
2324
class DecoratorServicePass implements CompilerPassInterface
2425
{
2526
public function process(ContainerBuilder $container)
2627
{
28+
$definitions = new \SplPriorityQueue();
29+
$order = PHP_INT_MAX;
30+
2731
foreach ($container->getDefinitions() as $id => $definition) {
2832
if (!$decorated = $definition->getDecoratedService()) {
2933
continue;
3034
}
35+
$definitions->insert(array($id, $definition), array($decorated[2], --$order));
36+
}
37+
38+
foreach ($definitions as $arr) {
39+
list($id, $definition) = $arr;
40+
list($inner, $renamedId) = $definition->getDecoratedService();
41+
3142
$definition->setDecoratedService(null);
3243

33-
list($inner, $renamedId) = $decorated;
3444
if (!$renamedId) {
3545
$renamedId = $id.'.inner';
3646
}

src/Symfony/Component/DependencyInjection/Definition.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -150,12 +150,13 @@ public function setFactoryMethod($factoryMethod)
150150
*
151151
* @param null|string $id The decorated service id, use null to remove decoration
152152
* @param null|string $renamedId The new decorated service id
153+
* @param int $priority The priority of decoration
153154
*
154155
* @return Definition The current instance
155156
*
156157
* @throws InvalidArgumentException In case the decorated service id and the new decorated service id are equals.
157158
*/
158-
public function setDecoratedService($id, $renamedId = null)
159+
public function setDecoratedService($id, $renamedId = null, $priority = 0)
159160
{
160161
if ($renamedId && $id == $renamedId) {
161162
throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
@@ -164,7 +165,7 @@ public function setDecoratedService($id, $renamedId = null)
164165
if (null === $id) {
165166
$this->decoratedService = null;
166167
} else {
167-
$this->decoratedService = array($id, $renamedId);
168+
$this->decoratedService = array($id, $renamedId, (int) $priority);
168169
}
169170

170171
return $this;
@@ -173,7 +174,7 @@ public function setDecoratedService($id, $renamedId = null)
173174
/**
174175
* Gets the service that decorates this service.
175176
*
176-
* @return null|array An array composed of the decorated service id and the new id for it, null if no service is decorated
177+
* @return null|array An array composed of the decorated service id, the new id for it and the priority of decoration, null if no service is decorated
177178
*/
178179
public function getDecoratedService()
179180
{

src/Symfony/Component/DependencyInjection/DefinitionDecorator.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,11 +173,11 @@ public function setLazy($boolean)
173173
/**
174174
* {@inheritdoc}
175175
*/
176-
public function setDecoratedService($id, $renamedId = null)
176+
public function setDecoratedService($id, $renamedId = null, $priority = 0)
177177
{
178178
$this->changes['decorated_service'] = true;
179179

180-
return parent::setDecoratedService($id, $renamedId);
180+
return parent::setDecoratedService($id, $renamedId, $priority);
181181
}
182182

183183
/**

src/Symfony/Component/DependencyInjection/Dumper/XmlDumper.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,14 @@ private function addService($definition, $id, \DOMElement $parent)
145145
$service->setAttribute('lazy', 'true');
146146
}
147147
if (null !== $decorated = $definition->getDecoratedService()) {
148-
list($decorated, $renamedId) = $decorated;
148+
list($decorated, $renamedId, $priority) = $decorated;
149149
$service->setAttribute('decorates', $decorated);
150150
if (null !== $renamedId) {
151151
$service->setAttribute('decoration-inner-name', $renamedId);
152152
}
153+
if (0 !== $priority) {
154+
$service->setAttribute('decoration-priority', $priority);
155+
}
153156
}
154157

155158
foreach ($definition->getTags() as $name => $tags) {

src/Symfony/Component/DependencyInjection/Dumper/YamlDumper.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,11 +137,14 @@ private function addService($id, $definition)
137137
}
138138

139139
if (null !== $decorated = $definition->getDecoratedService()) {
140-
list($decorated, $renamedId) = $decorated;
140+
list($decorated, $renamedId, $priority) = $decorated;
141141
$code .= sprintf(" decorates: %s\n", $decorated);
142142
if (null !== $renamedId) {
143143
$code .= sprintf(" decoration_inner_name: %s\n", $renamedId);
144144
}
145+
if (0 !== $priority) {
146+
$code .= sprintf(" decoration_priority: %s\n", $priority);
147+
}
145148
}
146149

147150
if ($callable = $definition->getFactory()) {

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ private function parseDefinition(\DOMElement $service, $file)
245245

246246
if ($value = $service->getAttribute('decorates')) {
247247
$renameId = $service->hasAttribute('decoration-inner-name') ? $service->getAttribute('decoration-inner-name') : null;
248-
$definition->setDecoratedService($value, $renameId);
248+
$priority = $service->hasAttribute('decoration-priority') ? $service->getAttribute('decoration-priority') : 0;
249+
$definition->setDecoratedService($value, $renameId, $priority);
249250
}
250251

251252
return $definition;

src/Symfony/Component/DependencyInjection/Loader/YamlFileLoader.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,8 @@ private function parseDefinition($id, $service, $file)
290290

291291
if (isset($service['decorates'])) {
292292
$renameId = isset($service['decoration_inner_name']) ? $service['decoration_inner_name'] : null;
293-
$definition->setDecoratedService($service['decorates'], $renameId);
293+
$priority = isset($service['decoration_priority']) ? $service['decoration_priority'] : 0;
294+
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
294295
}
295296

296297
$this->container->setDefinition($id, $definition);

src/Symfony/Component/DependencyInjection/Loader/schema/dic/services/services-1.0.xsd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@
101101
<xsd:attribute name="parent" type="xsd:string" />
102102
<xsd:attribute name="decorates" type="xsd:string" />
103103
<xsd:attribute name="decoration-inner-name" type="xsd:string" />
104+
<xsd:attribute name="decoration-priority" type="xsd:integer" />
104105
</xsd:complexType>
105106

106107
<xsd:complexType name="tag">

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,48 @@ public function testProcessWithAlias()
7373
$this->assertNull($fooExtendedDefinition->getDecoratedService());
7474
}
7575

76+
public function testProcessWithPriority()
77+
{
78+
$container = new ContainerBuilder();
79+
$fooDefinition = $container
80+
->register('foo')
81+
->setPublic(false)
82+
;
83+
$barDefinition = $container
84+
->register('bar')
85+
->setPublic(true)
86+
->setDecoratedService('foo')
87+
;
88+
$bazDefinition = $container
89+
->register('baz')
90+
->setPublic(true)
91+
->setDecoratedService('foo', null, 5)
92+
;
93+
$quxDefinition = $container
94+
->register('qux')
95+
->setPublic(true)
96+
->setDecoratedService('foo', null, 3)
97+
;
98+
99+
$this->process($container);
100+
101+
$this->assertEquals('bar', $container->getAlias('foo'));
102+
$this->assertFalse($container->getAlias('foo')->isPublic());
103+
104+
$this->assertSame($fooDefinition, $container->getDefinition('baz.inner'));
105+
$this->assertFalse($container->getDefinition('baz.inner')->isPublic());
106+
107+
$this->assertEquals('qux', $container->getAlias('bar.inner'));
108+
$this->assertFalse($container->getAlias('bar.inner')->isPublic());
109+
110+
$this->assertEquals('baz', $container->getAlias('qux.inner'));
111+
$this->assertFalse($container->getAlias('qux.inner')->isPublic());
112+
113+
$this->assertNull($barDefinition->getDecoratedService());
114+
$this->assertNull($bazDefinition->getDecoratedService());
115+
$this->assertNull($quxDefinition->getDecoratedService());
116+
}
117+
76118
protected function process(ContainerBuilder $container)
77119
{
78120
$repeatedPass = new DecoratorServicePass();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy