Skip to content

Instantly share code, notes, and snippets.

@itsliamjones
Forked from xphere/Configuration.php
Created January 16, 2019 09:04
Show Gist options
  • Save itsliamjones/1ca680d16370e8379a083e32ec50b168 to your computer and use it in GitHub Desktop.
Save itsliamjones/1ca680d16370e8379a083e32ec50b168 to your computer and use it in GitHub Desktop.
Recursive symfony/configuration
<?php
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* Helper function to create recursive nodes
*/
function recursiveNode(string $name, callable $callback)
{
$builder = new TreeBuilder();
$root = $builder->root($name, 'variable');
$root->defaultValue([]);
$root
->beforeNormalization()
->ifTrue(function ($v) { return !is_array($v); })
->thenInvalid("The {$name} element must be an array.")
;
$root
->beforeNormalization()
->always(function (iterable $children) use ($builder, $callback) {
$config = [];
foreach ($children as $name => $child) {
$node = $builder->root($name);
$callback($node, $callback);
$config[$name] = $node->getNode(true)->finalize($child);
}
return $config;
})
;
return $root;
}
/**
* Usage of recursiveNode
* This allows for configuration like:
*
* routing_bundle:
* routes:
* - name: route_1
* url: url_1
* children:
* - name: route_2
* url: url_2
* - name: route_3
* url: url_3
* children:
* - name: route_4
* - url: url_4
* - name: route_5
* url: url_5
*/
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$tree = new TreeBuilder();
$root = $tree->root('my_routing_bundle');
$root
->children()
->append(
recursiveNode('routes', function ($node, $recursive) {
return $this->routes($node, $recursive);
})
)
->end()
;
return $tree;
}
private function routes(ArrayNodeDefinition $node, callable $recursive)
{
$node
->addDefaultsIfNotSet()
->children()
->scalarNode('description')->end()
->scalarNode('name')
->isRequired()
->cannotBeEmpty()
->end()
->scalarNode('url')
->defaultNull()
->end()
->append(recursiveNode('children', $recursive))
;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment