5

Scenario:

I'm using a bundle (FOSFacebookBundle) that allows me to set parameters for exactly one facebook app in my configuration. Everything works perfectly fine, but now I need to set not only one app, but multiple.

My approach:

I've created a AcmeFacebookBundle, which allows multiple apps to be defined (configuration defined in Acme\FacebookBundle\DependencyInjection\Configuration) in an array like so:

acme_facebook:
    apps:
        some_competition:
            server_url: %acme.facebook.some_competition.server_url%
            file:   %kernel.root_dir%/../vendor/facebook/php-sdk/src/base_facebook.php
            alias:  facebook
            app_id: %acme.facebook.some_competition.app_id%
            secret: % acme .facebook.some_competition.secret%
            cookie: true
            permissions: [email, user_birthday, user_location]
        some_other_competition:
            server_url: %acme.facebook. some_other_competition.server_url%
            file:   %kernel.root_dir%/../vendor/facebook/php-sdk/src/base_facebook.php
            alias:  facebook
            app_id: %acme.facebook. some_other_competition.app_id%
            secret: % acme .facebook. some_other_competition.secret%
            cookie: true
            permissions: [email, user_birthday, user_location]

In Acme\FacebookBundle\DependencyInjection\AcmeFacebookExtension I am then looping through all apps. The idea is to compare the server_url parameter against the current URL and override the fos_facebook configuration with mine.

class AcmeFacebookExtension extends Extension
{
    ...
    /**
     * {@inheritDoc}
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        foreach ($config['apps'] as $app)
        {
            // check for matching path here?
            foreach (array('file', 'app_id', 'secret', 'cookie', 'domain', 'logging', 'culture', 'permissions') as $attribute)
            {
                $container->setParameter('fos_facebook.' . $attribute, $app[$attribute]);
            }
        }
    }

Problem:

But this is exactly where I'm stuck. Obviously, I have no access to the Request object or the DiC from within AcmeFacebookExtension to do this comparison. Am I going completely wrong in my approach? Do you have any better idea on how to tackle this problem?

Tivie
  • 18,864
  • 5
  • 58
  • 77
Burgi
  • 1,385
  • 9
  • 13
  • Different questin, same goal: [Symfony2 load conditional configuration](http://stackoverflow.com/questions/9603384/symfony2-load-conditional-configuration) – leek Mar 13 '12 at 14:02
  • Yeah, I'm not sure if setting config in your controller is the right approach though? Injecting config when the config parsing happens feels like the right way to do it... – Burgi Mar 13 '12 at 23:11

1 Answers1

4

What you want to create is a CompilerPass so that you can manipulate the Container after all other configuration has loaded. These should get you started:

leek
  • 11,803
  • 8
  • 45
  • 61
  • Top stuff, exactly what I needed. I'll take it from there. The only problem I can see is that FOSUserbundle still requires all the fos_user config to be set upon initial parsing, so right now I have to mock up some dummy config. Can you see any way around this? – Burgi Mar 13 '12 at 11:21
  • Have you tried loading your bundle first? This way you could set the required parameters before the other bundles need them. (I'm not entirely sure this will work - just a guess) – leek Mar 13 '12 at 12:34
  • Yes, I've played around with the order of bundles. The Extension->load() methods seem to get called first, and CompilerPass methods only once all extension configs are processed. Also, since I still can't access the entire container in CompilerPass, I also can't get the Request object and have to resort to $_SERVER to get the current URL :( – Burgi Mar 13 '12 at 13:01
  • 2
    Hmm... perhaps an `EventListener` (rather an a `CompilerPass`) is what you will have to implement. If all else fails, you can ignore trying to change the Symfony configuration parameters and modify the instance itself, e.g; `$container->get('fos_facebook.api')->setAppId('foo')` – leek Mar 13 '12 at 14:00