[DI] Add "_defaults" key to Yaml services configuration
This commit is contained in:
parent
306a060cc6
commit
7b4a18b044
@ -148,9 +148,56 @@ class YamlFileLoader extends FileLoader
|
||||
if (!is_array($content['services'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "services" key should contain an array in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
if (isset($content['services']['_defaults'])) {
|
||||
if (!is_array($defaults = $content['services']['_defaults'])) {
|
||||
throw new InvalidArgumentException(sprintf('Service defaults must be an array, "%s" given in "%s".', gettype($defaults), $file));
|
||||
}
|
||||
if (isset($defaults['alias']) || isset($defaults['class']) || isset($defaults['factory'])) {
|
||||
@trigger_error('Giving a service the "_defaults" name is deprecated since Symfony 3.3 and will be forbidden in 4.0. Rename your service.', E_USER_DEPRECATED);
|
||||
$defaults = array();
|
||||
} else {
|
||||
$defaultKeys = array('public', 'tags', 'autowire');
|
||||
unset($content['services']['_defaults']);
|
||||
|
||||
foreach ($defaults as $key => $default) {
|
||||
if (!in_array($key, $defaultKeys)) {
|
||||
throw new InvalidArgumentException(sprintf('The configuration key "%s" cannot be used to define a default value in "%s". Allowed keys are "%s".', $key, $file, implode('", "', $defaultKeys)));
|
||||
}
|
||||
}
|
||||
if (isset($defaults['tags'])) {
|
||||
if (!is_array($tags = $defaults['tags'])) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter "tags" in "_defaults" must be an array in %s. Check your YAML syntax.', $file));
|
||||
}
|
||||
|
||||
foreach ($tags as $tag) {
|
||||
if (!is_array($tag)) {
|
||||
$tag = array('name' => $tag);
|
||||
}
|
||||
|
||||
if (!isset($tag['name'])) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" entry in "_defaults" is missing a "name" key in %s.', $file));
|
||||
}
|
||||
$name = $tag['name'];
|
||||
unset($tag['name']);
|
||||
|
||||
if (!is_string($name) || '' === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The tag name in "_defaults" must be a non-empty string in %s.', $file));
|
||||
}
|
||||
|
||||
foreach ($tag as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type in %s. Check your YAML syntax.', $name, $attribute, $file));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$defaults = array();
|
||||
}
|
||||
|
||||
foreach ($content['services'] as $id => $service) {
|
||||
$this->parseDefinition($id, $service, $file);
|
||||
$this->parseDefinition($id, $service, $file, $defaults);
|
||||
}
|
||||
}
|
||||
|
||||
@ -160,10 +207,11 @@ class YamlFileLoader extends FileLoader
|
||||
* @param string $id
|
||||
* @param array $service
|
||||
* @param string $file
|
||||
* @param array $defaults
|
||||
*
|
||||
* @throws InvalidArgumentException When tags are invalid
|
||||
*/
|
||||
private function parseDefinition($id, $service, $file)
|
||||
private function parseDefinition($id, $service, $file, array $defaults)
|
||||
{
|
||||
if (is_string($service) && 0 === strpos($service, '@')) {
|
||||
$this->container->setAlias($id, substr($service, 1));
|
||||
@ -178,7 +226,7 @@ class YamlFileLoader extends FileLoader
|
||||
static::checkDefinition($id, $service, $file);
|
||||
|
||||
if (isset($service['alias'])) {
|
||||
$public = !array_key_exists('public', $service) || (bool) $service['public'];
|
||||
$public = array_key_exists('public', $service) ? (bool) $service['public'] : !empty($defaults['public']);
|
||||
$this->container->setAlias($id, new Alias($service['alias'], $public));
|
||||
|
||||
foreach ($service as $key => $value) {
|
||||
@ -192,6 +240,7 @@ class YamlFileLoader extends FileLoader
|
||||
|
||||
if (isset($service['parent'])) {
|
||||
$definition = new ChildDefinition($service['parent']);
|
||||
$defaults = array();
|
||||
} else {
|
||||
$definition = new Definition();
|
||||
}
|
||||
@ -212,8 +261,9 @@ class YamlFileLoader extends FileLoader
|
||||
$definition->setLazy($service['lazy']);
|
||||
}
|
||||
|
||||
if (isset($service['public'])) {
|
||||
$definition->setPublic($service['public']);
|
||||
$public = isset($service['public']) ? $service['public'] : (isset($defaults['public']) ? $defaults['public'] : null);
|
||||
if (null !== $public) {
|
||||
$definition->setPublic($public);
|
||||
}
|
||||
|
||||
if (isset($service['abstract'])) {
|
||||
@ -262,12 +312,13 @@ class YamlFileLoader extends FileLoader
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($service['tags'])) {
|
||||
if (!is_array($service['tags'])) {
|
||||
$tags = isset($service['tags']) ? $service['tags'] : (isset($defaults['tags']) ? $defaults['tags'] : null);
|
||||
if (null !== $tags) {
|
||||
if (!is_array($tags)) {
|
||||
throw new InvalidArgumentException(sprintf('Parameter "tags" must be an array for service "%s" in %s. Check your YAML syntax.', $id, $file));
|
||||
}
|
||||
|
||||
foreach ($service['tags'] as $tag) {
|
||||
foreach ($tags as $tag) {
|
||||
if (!is_array($tag)) {
|
||||
$tag = array('name' => $tag);
|
||||
}
|
||||
@ -275,14 +326,13 @@ class YamlFileLoader extends FileLoader
|
||||
if (!isset($tag['name'])) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" entry is missing a "name" key for service "%s" in %s.', $id, $file));
|
||||
}
|
||||
|
||||
if (!is_string($tag['name']) || '' === $tag['name']) {
|
||||
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file));
|
||||
}
|
||||
|
||||
$name = $tag['name'];
|
||||
unset($tag['name']);
|
||||
|
||||
if (!is_string($name) || '' === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The tag name for service "%s" in %s must be a non-empty string.', $id, $file));
|
||||
}
|
||||
|
||||
foreach ($tag as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('A "tags" attribute must be of a scalar-type for service "%s", tag "%s", attribute "%s" in %s. Check your YAML syntax.', $id, $name, $attribute, $file));
|
||||
@ -303,11 +353,12 @@ class YamlFileLoader extends FileLoader
|
||||
$definition->setDecoratedService($service['decorates'], $renameId, $priority);
|
||||
}
|
||||
|
||||
if (isset($service['autowire'])) {
|
||||
if (is_array($service['autowire'])) {
|
||||
$definition->setAutowiredMethods($service['autowire']);
|
||||
$autowire = isset($service['autowire']) ? $service['autowire'] : (isset($defaults['autowire']) ? $defaults['autowire'] : null);
|
||||
if (null !== $autowire) {
|
||||
if (is_array($autowire)) {
|
||||
$definition->setAutowiredMethods($autowire);
|
||||
} else {
|
||||
$definition->setAutowired($service['autowire']);
|
||||
$definition->setAutowired($autowire);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,30 @@
|
||||
services:
|
||||
_defaults:
|
||||
public: false
|
||||
autowire: true
|
||||
tags:
|
||||
- name: foo
|
||||
|
||||
with_defaults:
|
||||
class: Foo
|
||||
|
||||
with_null:
|
||||
class: Foo
|
||||
public: ~
|
||||
autowire: ~
|
||||
tags: ~
|
||||
|
||||
no_defaults:
|
||||
class: Foo
|
||||
public: true
|
||||
autowire: false
|
||||
tags: []
|
||||
|
||||
no_defaults_child:
|
||||
parent: no_defaults
|
||||
autowire: ~
|
||||
tags:
|
||||
- name: bar
|
||||
|
||||
with_defaults_child:
|
||||
parent: with_defaults
|
@ -352,6 +352,31 @@ class YamlFileLoaderTest extends \PHPUnit_Framework_TestCase
|
||||
$this->assertEquals(CaseSensitiveClass::class, $container->getDefinition(CaseSensitiveClass::class)->getClass());
|
||||
}
|
||||
|
||||
public function testDefaults()
|
||||
{
|
||||
$container = new ContainerBuilder();
|
||||
$loader = new YamlFileLoader($container, new FileLocator(self::$fixturesPath.'/yaml'));
|
||||
$loader->load('services28.yml');
|
||||
|
||||
$this->assertFalse($container->getDefinition('with_defaults')->isPublic());
|
||||
$this->assertFalse($container->getDefinition('with_null')->isPublic());
|
||||
$this->assertTrue($container->getDefinition('no_defaults')->isPublic());
|
||||
$this->assertTrue($container->getDefinition('no_defaults_child')->isPublic());
|
||||
$this->assertArrayNotHasKey('public', $container->getDefinition('no_defaults_child')->getChanges());
|
||||
|
||||
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_defaults')->getTags());
|
||||
$this->assertSame(array('foo' => array(array())), $container->getDefinition('with_null')->getTags());
|
||||
$this->assertSame(array(), $container->getDefinition('no_defaults')->getTags());
|
||||
$this->assertSame(array('bar' => array(array())), $container->getDefinition('no_defaults_child')->getTags());
|
||||
$this->assertSame(array(), $container->getDefinition('with_defaults_child')->getTags());
|
||||
|
||||
$this->assertTrue($container->getDefinition('with_defaults')->isAutowired());
|
||||
$this->assertTrue($container->getDefinition('with_null')->isAutowired());
|
||||
$this->assertFalse($container->getDefinition('no_defaults')->isAutowired());
|
||||
$this->assertFalse($container->getDefinition('no_defaults_child')->isAutowired());
|
||||
$this->assertArrayNotHasKey('autowire', $container->getDefinition('no_defaults_child')->getChanges());
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\DependencyInjection\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage The value of the "decorates" option for the "bar" service must be the id of the service without the "@" prefix (replace "@foo" with "foo").
|
||||
|
Reference in New Issue
Block a user