/protected/extensions/doctrine/components/DoctrineComponent.php
PHP | 327 lines | 213 code | 42 blank | 72 comment | 27 complexity | e55e43c183c42d69563c8cfef3e2e1fc MD5 | raw file
Possible License(s): BSD-2-Clause, LGPL-2.1, BSD-3-Clause
- <?php
- use Doctrine\DBAL\Connection;
- use Doctrine\DBAL\DriverManager;
- use Doctrine\ORM\Configuration;
- use Doctrine\ORM\EntityManager;
- use Doctrine\Common\Cache\AbstractCache;
- use Doctrine\Common\Cache\MemcacheCache;
- use Doctrine\Common\ClassLoader;
- use Doctrine\Common\Annotations\AnnotationReader;
- use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
- // Register vendor namespaces.
- Yii::setPathOfAlias('Doctrine', __DIR__.'/../vendors/Doctrine');
- Yii::setPathOfAlias('Symfony', __DIR__.'/../vendors/Symfony');
- // todo: use Yii's cache component instead of a custom one.
- class DoctrineComponent extends CApplicationComponent {
- /**
- * List of dbal configurations. Each configuration has the following options
- * @link http://www.doctrine-project.org/docs/dbal/2.0/en/reference/configuration.html
- * See the Doctrine Documentation for an explanation of connection parameters
- * @var array
- */
- public $dbal;
- /**
- * List of cache configurations. Each with the following options
- * <ul>
- * <li>driver - (string) the driver e.g. ApcCache, MemcacheCache</li>
- * <li>namespace - (string) the cache namespace</li>
- * <li>servers - (array) used for memcache</li>
- * </ul>
- * @var array
- */
- public $cache;
- /**
- * List of entity manager configurations. Each with the following options
- * <ul>
- * <li>connection - (string) the dbal config name</li>
- * <li>mappingDriver - (string) [AnnotationDriver, YamlDriver, XmlDriver]</li>
- * <li>mappingPaths - (array) An array of paths to find mapping information</li>
- * <li>mappingDriverOptions - (array) Additional mapping driver options
- * defined in and array and make reference to each of the drivers set
- * methods</li>
- * <li>metadataCache - (string) the cache configuration for metadata</li>
- * <li>queryCache - (string) the cache configuration for query conversions</li>
- * <li>resultCache - (string) the cache configuration for results</li>
- * <li>proxyDir - (string)the directory location for proxy classes</li>
- * <li>proxyNamespace - (string) the proxy namespace</li>
- * <li>entityNamespaces - (array) entity namespaces</li>
- * <li>autoGenerateProxyClasses - (bool) true false</li>
- * </ul>
- * @var array
- */
- public $entityManager;
- /**
- * Cached component instances
- * @var array
- */
- private $_cache;
- /**
- * Get an instance of a DBAL Connection
- * @param string $name the connection name
- * @return Doctrine\DBAL\Connection
- */
- public function getConnection($name = 'default') {
- if (isset($this->_cache['dbal'][$name]) && $this->_cache['dbal'][$name] instanceof Connection) {
- return $this->_cache['dbal'][$name];
- }
- $config = $this->dbal[$name];
- $conn = DriverManager::getConnection($config, $this->_getDBALConfiguration($config), $this->_getEventManager($config));
- $this->_cache['dbal'][$name] = $conn;
- return $conn;
- }
- /**
- * Returns a cache instance. Drivers can be specified by their fully qualified name
- * e.g. Doctrine\Common\Cache\ArrayCache or by their short name e.g. ArrayCache.
- * If driver class is a custom implementation, it must extend from Doctrine\Common\Cache\AbstractCache.
- * @param string $name the cache name
- * @return Doctrine\Common\Cache\AbstractCache
- * @throws CException
- */
- public function getCache($name = 'default') {
- if (isset($this->_cache['cache'][$name]) && $this->_cache['cache'][$name] instanceof AbstractCache) {
- return $this->_cache['cache'][$name];
- }
- if (!isset($this->cache[$name])) {
- throw new \CException('Unknown cache configuration "'.$name.'"');
- }
- $doctrineDrivers = array(
- 'ApcCache' => 'Doctrine\Common\Cache\ApcCache',
- 'ArrayCache' => 'Doctrine\Common\Cache\ArrayCache',
- 'MemcacheCache' => 'Doctrine\Common\Cache\MemcacheCache',
- 'XcacheCache' => 'Doctrine\Common\Cache\XcacheCache',
- );
- $config = $this->cache[$name];
- if (array_key_exists($config['driver'], $doctrineDrivers)) {
- $driver = new $doctrineDrivers[$config['driver']];
- } else {
- if (in_array($config['driver'], $doctrineDrivers)) {
- $driver = new $config['driver'];
- } else {
- if (isset($config['driver'])) {
- $driver = new $config['driver'];
- if (!$driver instanceof AbstractCache) {
- throw new \CException('Cache driver must inherit from AbstractCache');
- }
- }
- }
- }
- if (!isset($driver)) {
- throw new \CException('Unknown cache configuration "'.$name.'"');
- }
- if (isset($config['namespace'])) {
- $driver->setNamespace($config['namespace']);
- }
- if (method_exists($driver, 'initialize')) {
- $driver->initialize($config);
- }
- if ($driver instanceof MemcacheCache) {
- $defaultServer = array(
- 'host' => 'localhost',
- 'port' => 11211,
- 'persistent' => true,
- 'weight' => 1,
- 'timeout' => 1,
- 'retryInterval' => 15,
- 'status' => true,
- );
- $memcache = new \Memcache();
- if (isset($config['servers'])) {
- foreach ($config['servers'] as $server) {
- $server = array_replace_recursive($defaultServer, $server);
- $memcache->addServer($server['host'], $server['port'], $server['persistent'], $server['weight'], $server['timeout'],
- $server['retryInterval'], $server['status']);
- }
- } else {
- $memcache->addServer($defaultServer['host'], $defaultServer['port'], $defaultServer['persistent'], $defaultServer['weight'],
- $defaultServer['timeout'], $defaultServer['retryInterval'], $defaultServer['status']);
- }
- $driver->setMemcache($memcache);
- }
- $this->_cache['cache'][$name] = $driver;
- return $driver;
- }
- /**
- * Returns an entity manager
- *
- * @param string $name the entity manager configuration name
- *
- * @return Doctrine\ORM\EntityManager
- * @throws CException
- */
- public function getEntityManager($name = 'default') {
- if (isset($this->_cache['em'][$name])) {
- return $this->_cache['em'][$name];
- }
- if (!isset($this->entityManager[$name])) {
- throw new \CException('Unknown entity manager configuration "'.$name.'"');
- }
- $options = $this->entityManager[$name];
- $conn = $this->getConnection($options['connection']);
- $config = new Configuration();
- unset($options['connection']);
- $driver = $this->_getMappingDriver($options);
- $config->setMetadataDriverImpl($driver);
- // set metadata cache
- if (isset($options['metadataCache'])) {
- $config->setMetadataCacheImpl($this->getCache($options['metadataCache']));
- unset($options['metadataCache']);
- }
- // set query cache
- if (isset($options['queryCache'])) {
- $config->setQueryCacheImpl($this->getCache($options['queryCache']));
- unset($options['queryCache']);
- }
- // set result cache
- if (isset($options['resultCache'])) {
- $config->setResultCacheImpl($this->getCache($options['resultCache']));
- unset($options['resultCache']);
- }
- $options['proxyDir'] = \Yii::getPathOfAlias($options['proxyDir']);
- // loop through setters of remaining options
- foreach ($options as $key => $value) {
- $method = 'set' . ucfirst($key);
- if (method_exists($config, $method)) {
- $config->{$method}($value);
- }
- }
- $em = EntityManager::create($conn, $config);
- $this->_cache['em'][$name] = $em;
- return $em;
- }
- /**
- * Take the configuration and return a mapping driver
- * @param array &$config the driver options
- * @return Doctrine\ORM\Mapping\Driver\Driver
- */
- private function _getMappingDriver(array & $config) {
- $drivers = array(
- 'XmlDriver' => 'Doctrine\ORM\Mapping\Driver\XmlDriver',
- 'YamlDriver' => 'Doctrine\ORM\Mapping\Driver\YamlDriver',
- );
- if (is_array($config['mappingPaths'])) {
- foreach ($config['mappingPaths'] as $index => $path) {
- $config['mappingPaths'][$index] = \Yii::getPathOfAlias($path);
- }
- } else {
- $config['mappingPaths'] = \Yii::getPathOfAlias($config['mappingPaths']);
- }
- // set default annotation driver
- // todo: fix AnnotationDriver, currently it throws an exception.
- if (!array_key_exists($config['mappingDriver'], $drivers) || $config['mappingDriver'] === 'AnnotationDriver') {
- $reader = new AnnotationReader();
- $reader->setDefaultAnnotationNamespace('Doctrine\ORM\Mapping\\');
- $driver = new AnnotationDriver($reader, $config['mappingPaths']);
- unset($config['mappingDriver']);
- unset($config['mappingPaths']);
- return $driver;
- }
- $mappingClass = $drivers[$config['mappingDriver']];
- $driver = new $mappingClass($config['mappingPaths']);
- if (isset($config['mappingDriverOptions']) === true) {
- foreach ($config['mappingDriverOptions'] as $key => $value) {
- $method = 'set' . ucfirst($key);
- if (method_exists($driver, $method) === true) {
- $driver->{$method}($value);
- }
- }
- unset($config['mappingDriverOptions']);
- }
- unset($config['mappingDriver']);
- unset($config['mappingDriverPaths']);
- return $driver;
- }
- /**
- * Get an event manager configuration
- * @param array $config the configuration
- * @return Doctrine\Common\EventManager|null
- */
- private function _getEventManager(array $config = array()) {
- if (!isset($config['eventManagerClass'])) {
- return null;
- }
- if (!isset($this->_cache['eventManager'])) {
- $eventManagerClass = $config['eventManagerClass'];
- $this->_cache['eventManager'] = new $eventManagerClass();
- }
- if (isset($config['eventSubscribers'])) {
- foreach ($config['eventSubscribers'] as $subscriber) {
- $sub = new $subscriber();
- $this->_cache['eventManager']->addEventSubscriber($sub);
- }
- }
- return $this->_cache['eventManager'];
- }
- /**
- * Get a DBAL configuration
- * @param array $config the configuration
- * @return Doctrine\DBAL\Configuration|null
- */
- private function _getDBALConfiguration(array $config = array()) {
- if (!array_key_exists('configurationClass', $config)) {
- return null;
- }
- $configClass = $config['configurationClass'];
- $configuration = new $configClass();
- if (empty($config['sqlLoggerClass']) === false) {
- $sqlLoggerClass = $config['sqlLoggerClass'];
- $loggerClass = new $sqlLoggerClass();
- $configuration->setSQLLogger($loggerClass);
- }
- return $configuration;
- }
- }