1

我正在尝试在我的 Symfony2 项目中创建一个演示系统,以允许为每个登录到我正在使用的系统的“演示”用户创建一个临时的 sqlite 演示数据库,以便每个用户都可以访问一组默认数据并且可以在不干扰其他登录系统的演示用户的情况下修改数据。

我通过定义一个演示连接和一个包含对我想重定向到 config.yml 中的临时数据库的所有捆绑包的引用的 orm 条目开始此操作,然后在登录时覆盖连接详细信息(更准确地说是数据库路径)以包含会话 ID因此,理论上,当他们登录时,他们将可以访问一组默认的演示数据,而当他们注销时,不会保留任何更改,并且只有他们可以看到更改。

$this->doctrine->resetManager('demo');

问题是,当我尝试修改演示连接以指向新路径时,当我调用上述步骤时(正如我在互联网上发现的一些帖子中所述),系统因错误而死机不熟悉也不知道怎么解决。如果有人可以帮助我了解出了什么问题,我应该能够解决它,但目前我已经碰壁了:(

错误输出:http: //i.imgur.com/cllbIyy.png

过程是:

  • 演示用户登录(in_memory,未存储数据库)
  • 登录侦听器覆盖“演示”实体管理器,将数据库位置更改为 /tmp/portal_demo_[SESSION_ID].db 并使用演示数据填充它
  • 然后所有以下数据库调用都应使用演示数据库

这是我的代码:

配置.yml

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();
    }

}
4

0 回答 0