Change service parameter value dynamically for FOSUserBundle

偶尔善良 提交于 2019-12-12 15:21:55

问题


I asked about using multiple entity manager for FOSUserBundle before, and it turns out that FOSUserBundle has (partially) supported that. All I need to do is to specify the connection / manager I want to use in the model_manager_name parameter, as explained here

fos_user:
# ........
    model_manager_name: account1

Sample app/config/config.yml

With this FOSUserBundle will use account1 connection, and use user information in that connection's database.

doctrine:
dbal:
    default_connection:       default
    connections:
    account2:
        dbname:           account2
        user:             account2
        password:         password2
        driver:   pdo_mysql
        host:     localhost
        port:     ~
        charset:  UTF8
    account1:
        dbname:           account1
        user:             account1
        password:         password1
        driver:   pdo_mysql
        host:     localhost
        port:     ~
        charset:  UTF8
    default:
        dbname:           account
        user:             account
        password:         password
        driver:   pdo_mysql
        host:     localhost
        port:     ~
        charset:  UTF8

My app require that when a user goes to (for example) http://myapp.com/a/account1, the app will use account1 connection, and going to http://myapp.com/a/account2 will use account2's connection. For my application's logic, this is easily done from my controllers as I could use something like the following;

$em = $this->get('doctrine')->getManager('account2');
$repository = $this->get('doctrine')->getRepository($class, 'account2')

For the login part though, it's not that easy. FOSUserBundle runs as a service container, and I don't know where/how to dynamically change the model_manager_name's value. I do know though that in FOS\UserBundle\DependencyInjection\FOSUserExtension I can manually change its value the following way;

class FOSUserExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
    $processor = new Processor();
    $configuration = new Configuration();

    $config = $processor->processConfiguration($configuration, $configs);

    $config['model_manager_name'] = 'account2';
    // .................

Any thoughts?


回答1:


The configuration is stored inside the container, in the fos_user.model_manager_name to be exact.

You can write a compiler pass. This will be executed just before freezing the container, it is the last place where you can change the container and it is the place to change the container based on other services.

Your compiler pass will look like this:

// src/Acme/DemoBundle/DependencyInjection/Compiler/ChangeModelManagerPass.php
namespace Acme\DemoBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

class ChangeModelManagerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        $request = $container->get('request');
        $uri = $request->getUri();

        // check if the uri matches some pattern which will cause a change in the
        // `model_manager_name` setting
        if (...) {
            // ... do some stuff to get the correct model manager name

            // set the setting
            $container->setParameter('fos_user.model_manager_name', ...);
        }
    }
}

Read more about compiler passes in the docs or in this great blog post by Richard Miller.



来源:https://stackoverflow.com/questions/15241218/change-service-parameter-value-dynamically-for-fosuserbundle

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!