I am working on a Symfony2 site that will host many sites, and each site will have its own database. I have implemented a service uses reflection to change connection parameters (username, password, dbname) on the ‘client’ entity manager. I’m not sure how to trigger this service before FOSUserBundle invokes its authentication services. I tried to create a Symfony2 Request event listener, but that doesn’t seem to work:
class RequestListener {
private $clientSiteContext;
function __construct($clientSiteContext) {
$this->clientSiteContext = $clientSiteContext;
}
public function onKernelRequest(GetResponseEvent $event) {
if ($event->getRequestType() == HttpKernel::MASTER_REQUEST) {
$this->clientSiteContext->resetClientEntityManager();
}
}
}
resetClientEntityManager() implementation
public function resetClientEntityManager() {
/** @var $doctrine \Doctrine\Bundle\DoctrineBundle\Registry */
$doctrine = $this->container->get('doctrine');
$dbConfig = $this->getConnectionParams();
$dbalServiceName = sprintf('doctrine.dbal.%s_connection', 'client');
$clientEmName = 'client';
$connection = $this->container->get($dbalServiceName);
$connection->close();
$refConn = new \ReflectionObject($connection);
$refParams = $refConn->getProperty('_params');
$refParams->setAccessible('public');
$params = $refParams->getValue($connection);
$params['dbname'] = $dbConfig['dbname'];
$params['user'] = $dbConfig['user'];
$params['host'] = $dbConfig['host'];
$params['password'] = $dbConfig['password'];
$params['driver'] = $dbConfig['driver'];
$params['charset'] = 'UTF8';
$refParams->setAccessible('private');
$refParams->setValue($connection, $params);
$doctrine->resetEntityManager($clientEmName);
}
Can someone advise how I can get this Listener to get call once for every page request, and for it to affect the Entity Manager that FOSUserBundle uses?
You’d have to have this before any of the Kernel events. Probably the best place for it would be to put it somewhere within your AppKernel (
app/AppKernel.php) itself.You could probably take it in to getBundles(), or add something like:
I haven’t tested that out, but it should do the trick. boot() is the function where the container is initialized, so you should be making the switch right after the container is initialized, before anything else has a chance to do anything.