Skip to content

Commit 217686d

Browse files
committed
feature #19190 [DependencyInjection] Add support for short services configurators syntax (voronkovich)
This PR was squashed before being merged into the 3.2-dev branch (closes #19190). Discussion ---------- [DependencyInjection] Add support for short services configurators syntax | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | License | MIT This PR adds support for short services configurators syntax in YAML files: ```yaml services: app.some_service: class: ... # Common syntax configurator: [ '@app.configurator', 'configure' ] # Short syntax configurator: 'app.configurator:configure' Commits ------- da2757f [DependencyInjection] Add support for short services configurators syntax
2 parents a2602b2 + 348e3c9 commit 217686d

File tree

4 files changed

+68
-18
lines changed

4 files changed

+68
-18
lines changed

Definition.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,17 @@ public function getDeprecationMessage($id)
612612
/**
613613
* Sets a configurator to call after the service is fully initialized.
614614
*
615-
* @param callable $callable A PHP callable
615+
* @param string|array $configurator A PHP callable
616616
*
617617
* @return Definition The current instance
618618
*/
619-
public function setConfigurator($callable)
619+
public function setConfigurator($configurator)
620620
{
621-
$this->configurator = $callable;
621+
if (is_string($configurator) && strpos($configurator, '::') !== false) {
622+
$configurator = explode('::', $configurator, 2);
623+
}
624+
625+
$this->configurator = $configurator;
622626

623627
return $this;
624628
}

Loader/YamlFileLoader.php

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -223,16 +223,7 @@ private function parseDefinition($id, $service, $file)
223223
}
224224

225225
if (isset($service['factory'])) {
226-
if (is_string($service['factory'])) {
227-
if (strpos($service['factory'], ':') !== false && strpos($service['factory'], '::') === false) {
228-
$parts = explode(':', $service['factory']);
229-
$definition->setFactory(array($this->resolveServices('@'.$parts[0]), $parts[1]));
230-
} else {
231-
$definition->setFactory($service['factory']);
232-
}
233-
} else {
234-
$definition->setFactory(array($this->resolveServices($service['factory'][0]), $service['factory'][1]));
235-
}
226+
$definition->setFactory($this->parseCallable($service['factory'], 'factory', $id, $file));
236227
}
237228

238229
if (isset($service['file'])) {
@@ -248,11 +239,7 @@ private function parseDefinition($id, $service, $file)
248239
}
249240

250241
if (isset($service['configurator'])) {
251-
if (is_string($service['configurator'])) {
252-
$definition->setConfigurator($service['configurator']);
253-
} else {
254-
$definition->setConfigurator(array($this->resolveServices($service['configurator'][0]), $service['configurator'][1]));
255-
}
242+
$definition->setConfigurator($this->parseCallable($service['configurator'], 'configurator', $id, $file));
256243
}
257244

258245
if (isset($service['calls'])) {
@@ -339,6 +326,45 @@ private function parseDefinition($id, $service, $file)
339326
$this->container->setDefinition($id, $definition);
340327
}
341328

329+
/**
330+
* Parses a callable.
331+
*
332+
* @param string|array $callable A callable
333+
* @param string $parameter A parameter (e.g. 'factory' or 'configurator')
334+
* @param string $id A service identifier
335+
* @param string $file A parsed file
336+
*
337+
* @throws InvalidArgumentException When errors are occuried
338+
*
339+
* @return string|array A parsed callable
340+
*/
341+
private function parseCallable($callable, $parameter, $id, $file)
342+
{
343+
if (is_string($callable)) {
344+
if ('' !== $callable && '@' === $callable[0]) {
345+
throw new InvalidArgumentException(sprintf('The value of the "%s" option for the "%s" service must be the id of the service without the "@" prefix (replace "%s" with "%s").', $parameter, $id, $callable, substr($callable, 1)));
346+
}
347+
348+
if (false !== strpos($callable, ':') && false === strpos($callable, '::')) {
349+
$parts = explode(':', $callable);
350+
351+
return array($this->resolveServices('@'.$parts[0]), $parts[1]);
352+
}
353+
354+
return $callable;
355+
}
356+
357+
if (is_array($callable)) {
358+
if (isset($callable[0]) && isset($callable[1])) {
359+
return array($this->resolveServices($callable[0]), $callable[1]);
360+
}
361+
362+
throw new InvalidArgumentException(sprintf('Parameter "%s" must contain an array with two elements for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file));
363+
}
364+
365+
throw new InvalidArgumentException(sprintf('Parameter "%s" must be a string or an array for service "%s" in %s. Check your YAML syntax.', $parameter, $id, $file));
366+
}
367+
342368
/**
343369
* Loads a YAML file.
344370
*
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
services:
2+
3+
foo_bar:
4+
class: FooBarClass
5+
configurator: foo_bar_configurator:configure
6+
7+
foo_bar_with_static_call:
8+
class: FooBarClass
9+
configurator: FooBarConfigurator::configureFooBar

Tests/Loader/YamlFileLoaderTest.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,17 @@ public function testLoadFactoryShortSyntax()
165165
$this->assertEquals(array('FooBacFactory', 'createFooBar'), $services['factory_with_static_call']->getFactory(), '->load() parses the factory tag with Class::method');
166166
}
167167

168+
public function testLoadConfiguratorShortSyntax()
169+
{
170+
$container = new ContainerBuilder();
171+
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
172+
$loader->load('services_configurator_short_syntax.yml');
173+
$services = $container->getDefinitions();
174+
175+
$this->assertEquals(array(new Reference('foo_bar_configurator'), 'configure'), $services['foo_bar']->getConfigurator(), '->load() parses the configurator tag with service:method');
176+
$this->assertEquals(array('FooBarConfigurator', 'configureFooBar'), $services['foo_bar_with_static_call']->getConfigurator(), '->load() parses the configurator tag with Class::method');
177+
}
178+
168179
public function testExtensions()
169180
{
170181
$container = new ContainerBuilder();

0 commit comments

Comments
 (0)