Skip to content

Instantly share code, notes, and snippets.

@carlcraig
Last active May 23, 2017 15:00
Show Gist options
  • Save carlcraig/5584317 to your computer and use it in GitHub Desktop.
Save carlcraig/5584317 to your computer and use it in GitHub Desktop.
Symfony2 Extension Configuration function to remap config tree builder to parameters
<?php
/**
* Remaps Configurations to Parameters
*
* @param array $configs The array of configurations
* @param ContainerBuilder $container The container builder
* @param string $prefix A prefix to apply to all parameters
* @param array $ignore An array of parameter namespaces to ignore
* @param array $isArray An array of parameter namespaces which should be arrays
*/
protected function remapConfigsToParameters(
array $configs,
ContainerBuilder $container,
$prefix = '',
array $ignore = array(),
array $isArray = array()
) {
foreach ($configs as $key => $config) {
if (!is_integer($key) and !in_array($prefix, $isArray)) {
$parameterKey = $prefix . '.' . strtolower($key);
if (!in_array($parameterKey, $ignore)) {
if (is_array($config)) {
$this->remapConfigsToParameters(
$config,
$container,
$parameterKey,
$ignore,
$isArray
);
} else {
$container->setParameter($parameterKey, $config);
}
}
unset($configs[$key]);
}
}
if (!empty($configs) or in_array($prefix, $isArray)) {
$container->setParameter($prefix, $configs);
}
}
<?php
namespace Acme\DemoBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\Loader;
/**
* This is the class that loads and manages your bundle configuration
*/
class AcmeDemoExtension extends Extension
{
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$loader = new Loader\XmlFileLoader(
$container,
new FileLocator(__DIR__.'/../Resources/config')
);
$loader->load('services.xml');
$prefix = 'acme_demo';
$this->remapConfigsToParameters(
$config,
$container,
$prefix,
array(
// Array of ignored parameters, which will not be created and set
$prefix.'.members.enabled', // acme_demo.members.enabled
$prefix.'.group_one.form.name' // acme_demo.group_one.form.name
),
array(
/* Array of parameters which will be arrays, prevents further namespaces being
* created for each child element.
*/
$prefix.'.group_one.form.tags' // acme_demo.group_one.form.tags
)
);
}
/**
* remapConfigsToParameters
*
* @param array $configs
* @param ContainerBuilder $container
* @param string $prefix
* @param array $ignore
* @param array $isArray
* @return array
*/
protected function remapConfigsToParameters(
array $configs,
ContainerBuilder $container,
$prefix = '',
array $ignore = array(),
array $isArray = array()
)
{
foreach ($configs as $key => $config) {
if (!is_integer($key) and !in_array($prefix, $isArray)) {
$parameterKey = $prefix . '.' . strtolower($key);
if (!in_array($parameterKey, $ignore)) {
if (is_array($config)) {
$this->remapConfigsToParameters($config,
$container,
$parameterKey,
$ignore,
$isArray
);
} else {
$container->setParameter($parameterKey, $config);
}
}
unset($configs[$key]);
}
}
if (!empty($configs) or in_array($prefix, $isArray)) {
$container->setParameter($prefix, $configs);
}
}
}
<?php
namespace Acme\DemoBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
/**
* This is the class that validates and merges configuration from your app/config files
*/
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme_demo');
$rootNode
->children()
->arrayNode('members')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->scalarNode('total')->defaultValue(0)->end()
->booleanNode('enabled')->defaultFalse()->end()
->end()
->end()
->arrayNode('group_one')
->addDefaultsIfNotSet()
->canBeUnset()
->children()
->arrayNode('form')
->addDefaultsIfNotSet()
->children()
->scalarNode('type')->defaultValue('group_one_form_type_class')
->end()
->scalarNode('handler')->defaultValue('group_one_form_handler_class')
->end()
->scalarNode('name')->defaultValue('group_one_form_name')
->end()
->arrayNode('validation_groups')
->prototype('scalar')->end()
->defaultValue(array('ValidationA', 'ValidationB'))
->end()
->arrayNode('tags')
->prototype('scalar')->end()
->defaultValue(array(
'tag1' => 'tag1 value',
'tag2' => 'tag2 value'
))
->end()
->end()
->end()
->end()
->end()
->end();
return $treeBuilder;
}
}
<?php
/* Below is a list of parameters created, by running the Configuration
* through the remapConfigsToParameters function.
*/
acme_demo.members.total = 0;
acme_demo.group_one.form.type = 'group_one_form_type_class';
acme_demo.group_one.form.handler = 'group_one_form_handler_class';
acme_demo.group_one.form.validation_groups = array(
'ValidationA',
'ValidationB'
);
acme_demo.group_one.form.tags = array(
'tag1' => 'tag1 value',
'tag2' => 'tag2 value'
);
/* Note -> acme_demo.group_one.form.tags is an array, because this
* namespace was listed in the isArray setting
* If we would leave this out, then we would have seperate namespaces for each tag
*/
// Please note that two parameters were not set because they were in the ignored array.
// They would have been as follows
acme_demo.members.enabled = false;
acme_demo.group_one.form.name = 'group_one_form_name';
<?php
/**
* This version of the function returns a debug array, showing all namespaces
* that were created, and their values
*/
/**
* remapConfigsToParameters
*
* @param array $configs
* @param ContainerBuilder $container
* @param string $prefix
* @param array $ignore
* @param array $isArray
* @param array $debug
* @return array
*/
protected function remapConfigsToParameters(
array $configs,
ContainerBuilder $container,
$prefix = '',
array $ignore = array(),
array $isArray = array(),
array $debug = array()
)
{
foreach ($configs as $key => $config) {
if (!is_integer($key) and !in_array($prefix, $isArray)) {
$parameterKey = $prefix . '.' . strtolower($key);
if (!in_array($parameterKey, $ignore)) {
if (is_array($config)) {
$debug = array_merge($debug, $this->remapConfigsToParameters(
$config,
$container,
$parameterKey,
$ignore,
$isArray,
$debug
)
);
} else {
$debug[$parameterKey] = $config;
$container->setParameter($parameterKey, $config);
}
}
unset($configs[$key]);
}
}
if (!empty($configs) or in_array($prefix, $isArray)) {
$debug[$prefix] = $configs;
$container->setParameter($prefix, $configs);
}
return $debug;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment