diff --git a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
index dfa604f7a85a..574b496c727b 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Command/ConfigDumpReferenceCommand.php
@@ -37,6 +37,7 @@ protected function configure()
->setName('config:dump-reference')
->setDefinition(array(
new InputArgument('name', InputArgument::OPTIONAL, 'The Bundle name or the extension alias'),
+ new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'),
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (yaml or xml)', 'yaml'),
))
->setDescription('Dumps the default configuration for an extension')
@@ -54,6 +55,10 @@ protected function configure()
When the option is not provided, yaml is used.
php %command.full_name% FrameworkBundle --format=xml
+
+For dumping a specific option, add its path as second argument (only available for the yaml format):
+
+ php %command.full_name% framework profiler.matcher
EOF
)
@@ -71,7 +76,10 @@ protected function execute(InputInterface $input, OutputInterface $output)
if (null === $name = $input->getArgument('name')) {
$this->listBundles($io);
- $io->comment('Provide the name of a bundle as the first argument of this command to dump its default configuration. (e.g. config:dump-reference FrameworkBundle)');
+ $io->comment(array(
+ 'Provide the name of a bundle as the first argument of this command to dump its default configuration. (e.g. config:dump-reference FrameworkBundle)',
+ 'For dumping a specific option, add its path as the second argument of this command. (e.g. config:dump-reference FrameworkBundle profiler.matcher to dump the framework.profiler.matcher configuration)',
+ ));
return;
}
@@ -82,13 +90,26 @@ protected function execute(InputInterface $input, OutputInterface $output)
$this->validateConfiguration($extension, $configuration);
+ $format = $input->getOption('format');
+ $path = $input->getArgument('path');
+
+ if ($path !== null && 'yaml' !== $format) {
+ $io->error('The "path" option is only available for the "yaml" format.');
+
+ return 1;
+ }
+
if ($name === $extension->getAlias()) {
$message = sprintf('Default configuration for extension with alias: "%s"', $name);
} else {
$message = sprintf('Default configuration for "%s"', $name);
}
- switch ($input->getOption('format')) {
+ if ($path !== null) {
+ $message .= sprintf(' at path "%s"', $path);
+ }
+
+ switch ($format) {
case 'yaml':
$io->writeln(sprintf('# %s', $message));
$dumper = new YamlReferenceDumper();
@@ -102,6 +123,6 @@ protected function execute(InputInterface $input, OutputInterface $output)
throw new \InvalidArgumentException('Only the yaml and xml formats are supported.');
}
- $io->writeln($dumper->dump($configuration, $extension->getNamespace()));
+ $io->writeln(null === $path ? $dumper->dump($configuration, $extension->getNamespace()) : $dumper->dumpAtPath($configuration, $path));
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/Config/CustomConfig.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/Config/CustomConfig.php
index 8b4abb7a08d6..d3a9b2a1b88e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/Config/CustomConfig.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/Bundle/TestBundle/DependencyInjection/Config/CustomConfig.php
@@ -18,6 +18,13 @@ public function addConfiguration($rootNode)
$rootNode
->children()
->scalarNode('custom')->end()
+ ->arrayNode('array')
+ ->children()
+ ->scalarNode('child1')->end()
+ ->scalarNode('child2')->end()
+ ->end()
+ ->end()
+ ->end()
->end()
;
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDumpReferenceCommandTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDumpReferenceCommandTest.php
index b0ac90c31f5f..3817afed170c 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDumpReferenceCommandTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/Functional/ConfigDumpReferenceCommandTest.php
@@ -40,6 +40,39 @@ public function testDumpBundleName()
$this->assertContains(' custom:', $tester->getDisplay());
}
+ public function testDumpAtPath()
+ {
+ $tester = $this->createCommandTester();
+ $ret = $tester->execute(array(
+ 'name' => 'test',
+ 'path' => 'array',
+ ));
+
+ $this->assertSame(0, $ret, 'Returns 0 in case of success');
+ $this->assertSame(<<<'EOL'
+# Default configuration for extension with alias: "test" at path "array"
+array:
+ child1: ~
+ child2: ~
+
+
+EOL
+ , $tester->getDisplay(true));
+ }
+
+ public function testDumpAtPathXml()
+ {
+ $tester = $this->createCommandTester();
+ $ret = $tester->execute(array(
+ 'name' => 'test',
+ 'path' => 'array',
+ '--format' => 'xml',
+ ));
+
+ $this->assertSame(1, $ret);
+ $this->assertContains('[ERROR] The "path" option is only available for the "yaml" format.', $tester->getDisplay());
+ }
+
/**
* @return CommandTester
*/
diff --git a/src/Symfony/Bundle/FrameworkBundle/composer.json b/src/Symfony/Bundle/FrameworkBundle/composer.json
index 54ebc0f0335c..d7055b8f512a 100644
--- a/src/Symfony/Bundle/FrameworkBundle/composer.json
+++ b/src/Symfony/Bundle/FrameworkBundle/composer.json
@@ -20,7 +20,7 @@
"symfony/cache": "~3.3",
"symfony/class-loader": "~3.2",
"symfony/dependency-injection": "~3.3",
- "symfony/config": "~2.8|~3.0",
+ "symfony/config": "~3.3",
"symfony/event-dispatcher": "~2.8|~3.0",
"symfony/http-foundation": "~3.1",
"symfony/http-kernel": "~3.3",
diff --git a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
index a47424938091..16076354db51 100644
--- a/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
+++ b/src/Symfony/Component/Config/Definition/Dumper/YamlReferenceDumper.php
@@ -33,6 +33,32 @@ public function dump(ConfigurationInterface $configuration)
return $this->dumpNode($configuration->getConfigTreeBuilder()->buildTree());
}
+ public function dumpAtPath(ConfigurationInterface $configuration, $path)
+ {
+ $rootNode = $node = $configuration->getConfigTreeBuilder()->buildTree();
+
+ foreach (explode('.', $path) as $step) {
+ if (!$node instanceof ArrayNode) {
+ throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
+ }
+
+ /** @var NodeInterface[] $children */
+ $children = $node instanceof PrototypedArrayNode ? $this->getPrototypeChildren($node) : $node->getChildren();
+
+ foreach ($children as $child) {
+ if ($child->getName() === $step) {
+ $node = $child;
+
+ continue 2;
+ }
+ }
+
+ throw new \UnexpectedValueException(sprintf('Unable to find node at path "%s.%s"', $rootNode->getName(), $path));
+ }
+
+ return $this->dumpNode($node);
+ }
+
public function dumpNode(NodeInterface $node)
{
$this->reference = '';
diff --git a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
index ede5a19d0dc2..44e161bb3e15 100644
--- a/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
+++ b/src/Symfony/Component/Config/Tests/Definition/Dumper/YamlReferenceDumperTest.php
@@ -25,6 +25,61 @@ public function testDumper()
$this->assertEquals($this->getConfigurationAsString(), $dumper->dump($configuration));
}
+ public function provideDumpAtPath()
+ {
+ return array(
+ 'Regular node' => array('scalar_true', << array('array', << array('array.child2', << array('cms_pages.page', << array('cms_pages.page.locale', <<assertSame(trim($expected), trim($dumper->dumpAtPath($configuration, $path)));
+ }
+
private function getConfigurationAsString()
{
return <<<'EOL'