Search code examples
phpsymfonydependency-injectionconfigurationmicrokernel

register custom config namespace for Symfony MicroKernel


I have an app with a MicroKernel and would like to use Symfony's TreeBuilder with a custom config because the app will be quite generic and I would like to have as much as possible configured externally. My problem is, I can't get my custom namespace registered for symfony:

There is no extension able to load the configuration for "research" 
(in /var/www/html/src/app/config/config.yml). Looked for 
namespace "research", found "framework", "twig", 
"sensio_framework_extra", "web_profiler"

I have this Configuration class:

<?php
namespace App\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode    = $treeBuilder->root('research');

        // @formatter:off
        $rootNode
            ->children()
                ->arrayNode('questions')
                    ->children()
                        ->integerNode('client_id')->end()
                        ->scalarNode('client_secret')->end()
                    ->end()
                ->end()// twitter
            ->end();
        // @formatter:on

        return $treeBuilder;
    }
}

and my AppExtension:

<?php
namespace App\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\ConfigurableExtension;

class AppExtension extends ConfigurableExtension
{
    // note that this method is called loadInternal and not load
    protected function loadInternal(array $mergedConfig, ContainerBuilder $container)
    {
        dump($mergedConfig);
    }

    public function getAlias()
    {
        return 'research';
    }
}

In my AppKernel class, I'm initializing the extension like this and as a result I also get an output from the dump($mergedConfig) call in my AppExtension from my original research.yml

<?php
namespace App;

use App\DependencyInjection\AppExtension;
use Doctrine\Common\Annotations\AnnotationRegistry;
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Routing\RouteCollectionBuilder;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Yaml;

$loader = require __DIR__ . '/../vendor/autoload.php';

// auto-load annotations
AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

/**
 * Class AppKernel
 */
class AppKernel extends Kernel
{
    use MicroKernelTrait;

    ...

    protected function configureContainer(ContainerBuilder $c, LoaderInterface $loader)
    {
        $researchConfig = Yaml::parse(file_get_contents(__DIR__ . '/config/research.yml'));
        $appExtension = new AppExtension();
        $appExtension->load(researchConfig, $c);

        $loader->load(__DIR__ . '/config/config.yml');
    }

    ...
}

nevertheless, when my config.yml looks like this, I get the error mentioned above:

framework:
    secret: S0ME_SUPER_SECRET
    profiler: { only_exceptions: false }


research:
    questions:
       client_id: 2342323423
       clent_secret: mysecret

so what do I need to do, to actually register my namespace research so I can properly overwrite it? Or does it have to an external vendor bundle?


Solution

  • You get the error because you dont register a bundle and so symfony doesnt know the bundle config namespace.

    I cant say how you could fix this with your approach but i would suggest to make a AppBundle instead of the App and register AppBundle in public function registerBundles().

    See f.E. in some boilerplates like https://github.com/ikoene/symfony-micro.

    Alternativly you could try to set up your project with the new symfony Flex.
    This already uses MicroKernel, is bundleless and also supports latest stable symfony version (sf3.3).
    https://symfony.com/doc/current/setup/flex.html#using-symfony-flex-in-new-applications

    So no need to build something off the track yourself.