Skip to content

Commit dde60b2

Browse files
Merge branch '3.4' into 4.1
* 3.4: [Debug] ignore underscore vs backslash namespaces in DebugClassLoader [TwigBridge][Form] Prevent multiple rendering of form collection prototypes [FrameworkBundle] fix describing routes with no controllers [DI] move RegisterServiceSubscribersPass before DecoratorServicePass Update ValidationListener.php [Yaml] ensures that the mb_internal_encoding is reset to its initial value [WebLink] Fixed documentation link [Security] getTargetPath of TargetPathTrait must return string or null [Hackday][Serializer] Deserialization ignores argument type hint from phpdoc for array in constructor argument [Security] defer log message in guard authenticator merge conflicts Fix HeaderBag::get phpdoc
2 parents 61ad026 + 158a7b3 commit dde60b2

File tree

4 files changed

+52
-9
lines changed

4 files changed

+52
-9
lines changed

Compiler/PassConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,11 @@ public function __construct()
5252
new ValidateEnvPlaceholdersPass(),
5353
new ResolveChildDefinitionsPass(),
5454
new ServiceLocatorTagPass(),
55+
new RegisterServiceSubscribersPass(),
5556
new DecoratorServicePass(),
5657
new ResolveParameterPlaceHoldersPass(false),
5758
new ResolveFactoryClassPass(),
5859
new CheckDefinitionValidityPass(),
59-
new RegisterServiceSubscribersPass(),
6060
new ResolveNamedArgumentsPass(),
6161
new AutowireRequiredMethodsPass(),
6262
new ResolveBindingsPass(),

ServiceLocator.php

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,39 +94,40 @@ private function createServiceNotFoundMessage($id)
9494
$class = isset($class[2]['object']) ? \get_class($class[2]['object']) : null;
9595
$externalId = $this->externalId ?: $class;
9696

97-
$msg = sprintf('Service "%s" not found: ', $id);
97+
$msg = array();
98+
$msg[] = sprintf('Service "%s" not found:', $id);
9899

99100
if (!$this->container) {
100101
$class = null;
101102
} elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
102-
$msg .= 'even though it exists in the app\'s container, ';
103+
$msg[] = 'even though it exists in the app\'s container,';
103104
} else {
104105
try {
105106
$this->container->get($id);
106107
$class = null;
107108
} catch (ServiceNotFoundException $e) {
108109
if ($e->getAlternatives()) {
109-
$msg .= sprintf(' did you mean %s? Anyway, ', $this->formatAlternatives($e->getAlternatives(), 'or'));
110+
$msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
110111
} else {
111112
$class = null;
112113
}
113114
}
114115
}
115116
if ($externalId) {
116-
$msg .= sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
117+
$msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
117118
} else {
118-
$msg .= sprintf('the current service locator %s', $this->formatAlternatives());
119+
$msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
119120
}
120121

121122
if (!$class) {
122123
// no-op
123124
} elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
124-
$msg .= sprintf(' Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
125+
$msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
125126
} else {
126-
$msg .= 'Try using dependency injection instead.';
127+
$msg[] = 'Try using dependency injection instead.';
127128
}
128129

129-
return $msg;
130+
return implode(' ', $msg);
130131
}
131132

132133
private function formatAlternatives(array $alternatives = null, $separator = 'and')

Tests/Compiler/IntegrationTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Component\DependencyInjection\ContainerBuilder;
1818
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
1919
use Symfony\Component\DependencyInjection\Reference;
20+
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
2021

2122
/**
2223
* This class tests the integration of the different compiler passes.
@@ -120,6 +121,21 @@ public function testProcessInlinesWhenThereAreMultipleReferencesButFromTheSameDe
120121
$this->assertFalse($container->hasDefinition('c'), 'Service C was not inlined.');
121122
}
122123

124+
public function testCanDecorateServiceSubscriber()
125+
{
126+
$container = new ContainerBuilder();
127+
$container->register(ServiceSubscriberStub::class)
128+
->addTag('container.service_subscriber')
129+
->setPublic(true);
130+
131+
$container->register(DecoratedServiceSubscriber::class)
132+
->setDecoratedService(ServiceSubscriberStub::class);
133+
134+
$container->compile();
135+
136+
$this->assertInstanceOf(DecoratedServiceSubscriber::class, $container->get(ServiceSubscriberStub::class));
137+
}
138+
123139
/**
124140
* @dataProvider getYamlCompileTests
125141
*/
@@ -220,6 +236,18 @@ public function getYamlCompileTests()
220236
}
221237
}
222238

239+
class ServiceSubscriberStub implements ServiceSubscriberInterface
240+
{
241+
public static function getSubscribedServices()
242+
{
243+
return array();
244+
}
245+
}
246+
247+
class DecoratedServiceSubscriber
248+
{
249+
}
250+
223251
class IntegrationTestStub extends IntegrationTestStubParent
224252
{
225253
}

Tests/ServiceLocatorTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,20 @@ public function testThrowsInServiceSubscriber()
115115
$subscriber->getFoo();
116116
}
117117

118+
/**
119+
* @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
120+
* @expectedExceptionMessage Service "foo" not found: even though it exists in the app's container, the container inside "foo" is a smaller service locator that is empty... Try using dependency injection instead.
121+
*/
122+
public function testGetThrowsServiceNotFoundException()
123+
{
124+
$container = new Container();
125+
$container->set('foo', new \stdClass());
126+
127+
$locator = new ServiceLocator(array());
128+
$locator = $locator->withContext('foo', $container);
129+
$locator->get('foo');
130+
}
131+
118132
public function testInvoke()
119133
{
120134
$locator = new ServiceLocator(array(

0 commit comments

Comments
 (0)