Last active
December 13, 2015 20:38
-
-
Save seikai/4970937 to your computer and use it in GitHub Desktop.
DoctrineOrmServiceProvider
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
use Doctrine\ORM\Tools\Setup; | |
use Doctrine\ORM\EntityManager; | |
use Doctrine\DBAL\Types\Type; | |
use Doctrine\Common\Cache\ArrayCache; | |
use Doctrine\Common\Cache\MemcacheCache; | |
use Doctrine\Common\Cache\ApcCache; | |
use Doctrine\Common\Cache\RedisCache; | |
use Doctrine\Common\Cache\XcacheCache; | |
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriverChain; | |
use Doctrine\Common\Persistence\Mapping\Driver\MappingDriver; | |
use Doctrine\ORM\Mapping\Driver\AnnotationDriver; | |
use Doctrine\ORM\Mapping\Driver\YamlDriver; | |
use Doctrine\ORM\Mapping\Driver\XmlDriver; | |
use Doctrine\Common\Annotations\SimpleAnnotationReader; | |
use Doctrine\Common\Annotations\CachedReader; | |
use \Silex\Application; | |
use \Silex\ServiceProviderInterface; | |
class DoctrineOrmServiceProvider implements ServiceProviderInterface | |
{ | |
public function register(Application $app) | |
{ | |
if (!$app['db'] instanceof \Doctrine\DBAL\Connection) { | |
throw new \InvalidArgumentException('$app[\'db\'] must be an instance of \Doctrine\DBAL\Connection'); | |
} | |
$app['db.orm.em'] = $app->share(function() use($app) { | |
return EntityManagerUtils::getEntityManager($app['db'], $app['db.orm.options']); | |
}); | |
} | |
public function boot(Application $app) { } | |
} | |
class EntityManagerUtils { | |
const CACHE_TYPE_APC = 'apc'; | |
const CACHE_TYPE_XCACHE = 'xcache'; | |
const CACHE_TYPE_MEMCACHE = 'memcache'; | |
const CACHE_TYPE_REDIS = 'redis'; | |
const CACHE_TYPE_ARRAY = 'array'; | |
/** | |
* @param mixed $dbal | |
* @param $ormOptions | |
* @return \Doctrine\ORM\EntityManager | |
*/ | |
public static function getEntityManager($dbal, $ormOptions) | |
{ | |
$config = self::getOrmConfiguration($ormOptions); | |
$em = EntityManager::create($dbal, $config); | |
$platform = $em->getConnection()->getDatabasePlatform(); | |
if(array_key_exists('additional_mapping_type', $ormOptions)) { | |
foreach($ormOptions['additional_mapping_type'] as $type => $cast) { | |
$platform->registerDoctrineTypeMapping($type, $cast); | |
} | |
} | |
return $em; | |
} | |
/** | |
* TODO キャッシュの設定は専用に設定値を持たせる | |
* | |
* @param $type | |
* @return \Doctrine\Common\Cache\Cache | |
*/ | |
private static function getCache($type) | |
{ | |
$cache = null; | |
$type = strtolower($type); | |
if ($type === self::CACHE_TYPE_APC && extension_loaded('apc')) { | |
$cache = new \Doctrine\Common\Cache\ApcCache(); | |
} else if ($type === self::CACHE_TYPE_XCACHE && extension_loaded('xcache')) { | |
$cache = new \Doctrine\Common\Cache\XcacheCache(); | |
} else if ($type === self::CACHE_TYPE_MEMCACHE && extension_loaded('memcache')) { | |
$memcache = new \Memcache(); | |
$memcache->connect('127.0.0.1'); | |
$cache = new \Doctrine\Common\Cache\MemcacheCache(); | |
$cache->setMemcache($memcache); | |
} else if ($type === self::CACHE_TYPE_REDIS && extension_loaded('redis')) { | |
$redis = new \Redis(); | |
$redis->connect('127.0.0.1'); | |
$cache = new \Doctrine\Common\Cache\RedisCache(); | |
$cache->setRedis($redis); | |
} else { | |
$cache = new ArrayCache(); | |
} | |
return $cache; | |
} | |
/** | |
* @param $type | |
* @param $path | |
* @return \Doctrine\Common\Persistence\Mapping\Driver\MappingDriver | |
* @throws \InvalidArgumentException | |
*/ | |
private static function getDriver($type, array $path) | |
{ | |
switch ($type) { | |
case 'default': | |
case 'annotation': | |
$reader = new SimpleAnnotationReader(); | |
$reader->addNamespace('Doctrine\ORM\Mapping'); | |
$cachedReader = new CachedReader($reader, new ArrayCache()); | |
$driver = new AnnotationDriver($cachedReader, $path); | |
break; | |
case 'yml': | |
$driver = new YamlDriver($path); | |
break; | |
case 'xml': | |
$driver = new XmlDriver($path); | |
break; | |
default: | |
throw new \InvalidArgumentException(sprintf('"%s" is not a recognized driver', $type)); | |
break; | |
} | |
return $driver; | |
} | |
/** | |
* @param $ormOptions | |
* @return \Doctrine\ORM\Configuration | |
*/ | |
private static function getOrmConfiguration($ormOptions) | |
{ | |
$cache = self::getCache($ormOptions['cache']); | |
$config = new \Doctrine\ORM\Configuration(); | |
$config->setMetadataCacheImpl($cache); | |
$config->setQueryCacheImpl($cache); | |
$chain = new MappingDriverChain; | |
foreach ((array)$ormOptions['entities'] as $entity) { | |
$driver = self::getDriver($entity['type'], (array)$entity['path']); | |
$chain->addDriver($driver, $entity['namespace']); | |
} | |
$config->setMetadataDriverImpl($chain); | |
if(array_key_exists('custom_types', $ormOptions)) { | |
foreach($ormOptions['custom_types'] as $type => $class) { | |
Type::addType($type, $class); | |
} | |
} | |
//Numericオンリーではまずいのでこのあたりは後ほど検討 | |
if(array_key_exists('custom_functions', $ormOptions)) { | |
foreach($ormOptions['custom_functions'] as $funcName => $class) { | |
$config->addCustomNumericFunction($funcName, $class); | |
} | |
} | |
$config->setProxyDir($ormOptions['proxies_dir']); | |
$config->setProxyNamespace($ormOptions['proxies_namespace']); | |
$config->setAutoGenerateProxyClasses($ormOptions['auto_generate_proxies']); | |
return $config; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--- | |
all: | |
dbal: | |
wrapperClass: Doctrine\DBAL\Connections\MasterSlaveConnection | |
driver: pdo_mysql | |
orm: | |
proxies_dir: /path/to/project/tmp/doctrine/proxy | |
proxies_namespace: DoctrineProxies | |
cache: null | |
auto_generate_proxies: true | |
entities: | |
- type: yml | |
path: /path/to/project/config/doctrine/meta | |
namespace: Hoge\ORM\Entity | |
custom_types: | |
point: Hoge\Doctrine\Type\PointType | |
custom_functions: | |
GEOMFROMTEXT: Hoge\Doctrine\Type\GeomFromText | |
DISTANCE: Hoge\Doctrine\Type\Distance | |
YEAR: DoctrineExtensions\Query\Mysql\Year | |
MONTH: DoctrineExtensions\Query\Mysql\Month | |
DAY: DoctrineExtensions\Query\Mysql\Day | |
additional_mapping_type: | |
point: point | |
geometry: point | |
enum: string | |
prod: | |
dbal: | |
master: | |
user: username | |
password: password | |
dbname: dbname | |
host: 127.0.0.1 | |
slaves: | |
- user: username | |
password: password | |
host: 127.0.0.1 | |
dbname: test | |
- user: username | |
password: password | |
host: 127.0.0.1 | |
dbname: dbname |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
$app = new Application(); | |
$app->register(new \Silex\Provider\DoctrineServiceProvider(), array( | |
'db.options' => Config::get('dbal') | |
)); | |
$app->register(new \DoctrineOrmServiceProvider(), array( | |
'db.orm.options' => Config::get('orm') | |
)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment