问题
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