Symfony 在运行时重写条令实体管理器
我正在尝试在我的Symfony2项目中创建一个演示系统,允许为登录到我正在工作的系统中的每个“演示”用户创建一个临时sqlite演示数据库,这样每个用户都可以访问一组默认数据,并且可以修改数据,而不会干扰登录到系统中的其他演示用户 首先,我定义了一个演示连接和一个orm条目,其中包含对我想重定向到config.yml中temp db的所有bundle的引用,然后在登录时覆盖连接细节(更准确地说是db路径),以包含登录用户的会话id。所以从理论上讲,当他们登录时,他们将有权访问一组默认的演示数据,当他们注销时,不会保留任何更改,只有他们才能看到这些更改 $this->doctrine->resetManager('demo') 问题是,当我试图修改演示连接以指向新路径时,当我调用上述步骤时(正如我发现散布在互联网上的几篇文章中提到的),系统会因一个我不熟悉且不确定如何处理的错误而死亡。如果有人能帮助我了解出了什么问题,我应该能够解决,但目前我遇到了困难:( 错误输出: 这个过程是:Symfony 在运行时重写条令实体管理器,symfony,doctrine-orm,doctrine,symfony-2.3,Symfony,Doctrine Orm,Doctrine,Symfony 2.3,我正在尝试在我的Symfony2项目中创建一个演示系统,允许为登录到我正在工作的系统中的每个“演示”用户创建一个临时sqlite演示数据库,这样每个用户都可以访问一组默认数据,并且可以修改数据,而不会干扰登录到系统中的其他演示用户 首先,我定义了一个演示连接和一个orm条目,其中包含对我想重定向到config.yml中temp db的所有bundle的引用,然后在登录时覆盖连接细节(更准确地说是db路径),以包含登录用户的会话id。所以从理论上讲,当他们登录时,他们将有权访问一组默认的演示数据,
- 演示用户登录(内存中,未存储任何数据库)
- 登录侦听器覆盖“demo”实体管理器,将数据库位置更改为/tmp/portal\u demo\u[SESSION\u ID].DB,并用演示数据填充它
- 接下来的所有数据库调用都应该使用demo数据库
doctrine:
dbal:
default_connection: default
connections:
demo:
driver: pdo_sqlite
default:
driver: "%database_driver%"
host: "%database_host%"
port: "%database_port%"
dbname: "%database_name%"
user: "%database_user%"
password: "%database_password%"
charset: UTF8
# Following added to allow importing of existing mysql database. DZH
mapping_types:
enum: string
orm:
default_entity_manager: default
entity_managers:
default:
connection: default
mappings:
SPSettingsBundle: ~
SPUserBundle: ~
SPCompanyBundle: ~
SPVenueBundle: ~
SPAccessBundle: ~
SPHardwareBundle: ~
SPResellerBundle: ~
SPVouchersBundle: ~
SPTokenBundle: ~
SPAdminBundle: ~
SPSocialBundle: ~
demo:
connection: demo
mappings:
SPUserBundle: ~
SPCompanyBundle: ~
SPVenueBundle: ~
SPAccessBundle: ~
SPHardwareBundle: ~
SPResellerBundle: ~
SPVouchersBundle: ~
SPTokenBundle: ~
SPAdminBundle: ~
SPSocialBundle: ~
SPLegacyPortalBundle:
type: "annotation"
dir: "Entity"
SPLegacyPortalBundle:
type: "annotation"
dir: "Entity/Radius"
<?php
namespace SP\DemoBundle\Listener;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Doctrine\DBAL\Connection;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Console\Input\ArrayInput;
class DemoLoginListener {
private $defaultConnection;
private $doctrine;
private $kernel;
public function __construct(Connection $defaultConnection, Registry $doctrine, KernelInterface $kernel) {
$this->defaultConnection = $defaultConnection;
$this->doctrine = $doctrine;
$this->kernel = $kernel;
}
/**
* Create initial database schema
*/
public function createDbSchema() {
$application = new \Symfony\Bundle\FrameworkBundle\Console\Application($this->kernel);
$application->setAutoExit(false);
// Run initial schema install
$application->run(new ArrayInput(array(
'doctrine:schema:create',
'--em' => 'demo'
)));
}
/**
* Populate database with demo data
*/
public function populateDemoData() {
$query = <<<EOT
INSERT INTO `Company` (`account_manager_id`, `package_id`, `name`, `owner_first_name`, `owner_last_name`, `telephone`, `mobile`, `email`, `venues`, `created_by`, `date_created`) VALUES
(NULL, NULL, 'Demo Company', 'Demo', 'User', NULL, NULL, 'demo@company.com', 'N;', 1, '2013-05-16 15:06:16');
EOT;
$this->defaultConnection->query($query);
}
public function onSecurityInteractiveLogin(InteractiveLoginEvent $event) {
$token = $event->getAuthenticationToken();
$user = $token->getUser();
// Only create demo database with the 'demo' in_memory user logs in
if ('demo' == $user->getUsername()) {
$request = $event->getRequest();
$session = $request->getSession();
if ($session) {
$db_name = sprintf('/tmp/portal_demo_%s.db', $session->getId());
$this->defaultConnection->close();
$reflectionConn = new \ReflectionObject($this->defaultConnection);
$reflectionParams = $reflectionConn->getProperty('_params');
$reflectionParams->setAccessible('public');
$params = $reflectionParams->getValue($this->defaultConnection);
$params['driver'] = 'pdo_sqlite';
$params['dbname'] = $db_name;
$params['path'] = $db_name;
unset($params['host']);
unset($params['port']);
unset($params['password']);
unset($params['user']);
$reflectionParams->setValue($this->defaultConnection, $params);
$reflectionParams->setAccessible('private');
$this->doctrine->resetManager('demo');
// $this->defaultConnection->connect();
}
}
// Create the naked database
// $this->createDbSchema();
// Populate the database with demo data
// $this->populateDemoData();
}
}