Creating configurations in Symfony
php, symfony
Solution
I have solved my own issue but not without trouble. I'm not at all pleased with Symfony's configuration system.
Step one - Create your config file
Create a file named `config.yml` in `src/<bundle name>/Resources/config/`
yourbundle:
param_one: value_one
param_two: value_two
param_three: value_three
param_four: value_four
param_five:
subparam_one: subvalue_one
subparam_two: subvalue_two
subparam_three: subvalue_three
subparam_four: subvalue_four
Step two - Importing your configuration file
Go to `app/config/config.yml` and add:
#app/config/config.yml
imports:
- { resource: "@YourBundle/Resources/config/config.yml" }
Step three - Create a configuration class
Create a file named `Configuration.php` in `src/<bundle name>/DependencyInjection/`
namespace YourBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
/**
* {@inheritDoc}
*/
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('yourbundle');
$rootNode
->children()
->scalarNode('param_one')->defaultValue('value_one')->end()
->scalarNode('param_two')->defaultValue('value_two')->end()
->scalarNode('param_three')->defaultValue('value_three')->end()
->scalarNode('param_four')->defaultValue('value_four')->end()
->arrayNode('param_five')
->children()
->scalarNode('subparam_one')->defaultValue('subvalue_one')->end()
->scalarNode('subparam_two')->defaultValue('subvalue_two')->end()
->scalarNode('subparam_three')->defaultValue('subvalue_three')->end()
->scalarNode('subparam_four')->defaultValue('subvalue_four')->end()
->end()
->end()
;
return $treeBuilder;
}
}
Step four - Creating an extension
Last but not least, you'll have to create an extension. Create a file `<yourbundle>Extension.php` in `src/<your bundle>/DependencyInjection/`
namespace YourBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class YourbundleExtension extends Extension
{
/**
* @var ContainerBuilder
*/
protected $container;
/**
* {@inheritDoc}
*/
public function load(array $configs, ContainerBuilder $container)
{
$this->container = $container;
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
foreach ($config as $key => $value) {
$this->parseNode('yourbundle.'.$key, $value);
}
$container->setParameter('yourbundle', $config);
}
/**
* @param string $name
* @param mixed $value
*
* @throws \Exception
*/
protected function parseNode($name, $value)
{
if (is_string($value)) {
$this->set($name, $value);
return;
}
if (is_integer($value)) {
$this->set($name, $value);
return;
}
if (is_array($value)) {
foreach ($value as $newKey => $newValue) {
$this->parseNode($name.'.'.$newKey, $newValue);
}
return;
}
if (is_bool($value)) {
$this->set($name, $value);
return;
}
throw new \Exception(gettype($value).' not supported');
}
/**
* @param string $key
* @param mixed $value
*/
protected function set($key, $value)
{
$this->container->setParameter($key, $value);
}
}
All these steps are required just to be able to call a configuration parameter specific for your bundle.
If any of you know any way to do this easier, feel free to post an answer or comment.
Problem
For a few hours now I've been struggling to do the most simple thing you can imagine and it just won't work. I've read tons of stackoverflow questions, read the complete Symfony documentation on configuration files and with every article or other piece of information I read, it gets harder and harder to understand. Details I've created my own Bundle. Lets call it `HappyBundle`. I've put this Bundle in my company's folder. So naturally I've got `CompanyHappyBundle`. I want to make a configuration file specifically for this bundle as I want it to be reusable. As I test i created the following: ``` # src/Company/HappyBundle/Resources/config/config.yml company_happy: import: path: /tmp ``` Now, what I want is to be able to use this value in my Controller. I just don't know how. It throws me the following error: ``` [Symfony\Component\Config\Exception\FileLoaderLoadException] There is no extension able to load the configuration for "company_happy" (in /home/user/symfony/src/Company/HappyBundle/Resources/config/config.yml). Looked for namespace "company_happy", found "framework", "security", "twig", "monolog", "swiftmailer", "assetic", "doctrine", "sensio_framework_extra", "debug", "web_profiler", "sensio_distribution" in /home/user/symfony/src/Company/HappyBundle/Resources/config/config.yml (which is being imported from "/home/user/symfony/app/config/config.yml"). ``` Update In the config.yml I added the following: ``` #app/config/config.yml imports: - { resource: "@CompanyHappyBundle/Resources/config/config.yml" } ``` I've also made a Configuration class because I read somewhere this was required. I really do think this is alot of work to make just one config file. ``` namespace Company\HappyBundle\DependencyInjection; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; class Configuration implements ConfigurationInterface { /** * {@inheritDoc} */ public function getConfigTreeBuilder() { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('company_happy'); $rootNode ->children() ->arrayNode('import') ->children() ->scalarNode('attachments_path')->defaultValue('/tmp')->end() ->scalarNode('method')->defaultValue('ALL')->end() ->booleanNode('move_mail')->defaultValue(true)->end() ->booleanNode('mark_read')->defaultValue(true)->end() ->end() ->end() ; return $treeBuilder; } } ``` What I am actually looking for are the steps and requirements needed to get this working. The thing with symfony is that it has a million ways to do this. The documentation doesn't just give a workflow. Can someone please help me out?