Change instantiation of ORMs to allow adding listeners.

This commit is contained in:
Benoît Burnichon
2015-07-17 16:10:00 +02:00
parent 7462534fd2
commit 43a68777d1
4 changed files with 108 additions and 55 deletions

View File

@@ -69,6 +69,7 @@ $cli = new CLI("
. ' Phraseanet Developer Tools ', $version->getName() . ' ' . $version->getNumber());
if ($cli['configuration.store']->isSetup()) {
$cli->loadPlugins();
$helpers = [
'db' => new ConnectionHelper($cli['orm.em']->getConnection()),
'em' => new EntityManagerHelper($cli['orm.em'])

View File

@@ -15,6 +15,8 @@ use Alchemy\Geonames\GeonamesServiceProvider;
use Alchemy\Phrasea\Application\Helper\AclAware;
use Alchemy\Phrasea\Application\Helper\ApplicationBoxAware;
use Alchemy\Phrasea\Application\Helper\AuthenticatorAware;
use Alchemy\Phrasea\Cache\Factory;
use Alchemy\Phrasea\Cache\Manager;
use Alchemy\Phrasea\Core\Event\Subscriber\BasketSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\BridgeSubscriber;
use Alchemy\Phrasea\Core\Event\Subscriber\ExportSubscriber;
@@ -78,6 +80,7 @@ use Alchemy\Phrasea\Twig\JSUniqueID;
use Alchemy\Phrasea\Twig\PhraseanetExtension;
use Alchemy\Phrasea\Utilities\CachedTranslator;
use Dflydev\Silex\Provider\DoctrineOrm\DoctrineOrmServiceProvider;
use Doctrine\ORM\Configuration;
use FFMpeg\FFMpegServiceProvider;
use Gedmo\DoctrineExtensions as GedmoExtension;
use MediaAlchemyst\MediaAlchemystServiceProvider;
@@ -175,11 +178,11 @@ class Application extends SilexApplication
$this->register(new CacheConnectionServiceProvider());
$this->register(new PhraseanetServiceProvider());
$this->register(new ConfigurationTesterServiceProvider());
$this->register(new ORMServiceProvider());
$this->register(new DoctrineServiceProvider(), $this['dbs.service.conf']);
$this->register(new DoctrineServiceProvider());
$this->setupDBAL();
$this->register(new DoctrineOrmServiceProvider(), $this['orm.service.conf']);
$this->register(new DoctrineOrmServiceProvider());
$this->setupOrms();
$this->register(new ORMServiceProvider());
$this->register(new BasketMiddlewareProvider());
$this->register(new TokenMiddlewareProvider());
$this->register(new AccountServiceProvider());
@@ -880,6 +883,30 @@ class Application extends SilexApplication
private function setupOrms()
{
$app = $this;
// Override "orm.cache.configurer" service provided for benefiting
// of "phraseanet.cache-service"
$app['orm.cache.configurer'] = $app->protect(function($name, Configuration $config, $options) use ($app) {
/** @var Manager $service */
$service = $app['phraseanet.cache-service'];
$config->setMetadataCacheImpl(
$service->factory('ORM_metadata', $app['orm.cache.driver'], $app['orm.cache.options'])
);
$config->setQueryCacheImpl(
$service->factory('ORM_query', $app['orm.cache.driver'], $app['orm.cache.options'])
);
$config->setResultCacheImpl(
$service->factory('ORM_result', $app['orm.cache.driver'], $app['orm.cache.options'])
);
$config->setHydrationCacheImpl(
$service->factory('ORM_hydration', $app['orm.cache.driver'], $app['orm.cache.options'])
);
});
$app['orm.proxies_dir'] = $app['root.path'].'/resources/proxies';
$app['orm.auto_generate_proxies'] = $app['debug'];
$app['orm.proxies_namespace'] = 'Alchemy\Phrasea\Model\Proxies';
$this['orm.ems'] = $this->share($this->extend('orm.ems', function ($ems, $app) {
GedmoExtension::registerAnnotations();

View File

@@ -37,43 +37,6 @@ class ORMServiceProvider implements ServiceProviderInterface
{
public function register(Application $app)
{
/**
* Provide configuration for DoctrineServiceProvider.
*/
$app['dbs.service.conf'] = $app->share(function() use ($app) {
return array(
'dbs.options' => $app['dbs.options']
);
});
/**
* Provide configuration for DoctrineORMServiceProvider.
*/
$app['orm.service.conf'] = $app->share(function() use ($app) {
return array(
// Override "orm.cache.configurer" service provided for benefiting
// of "phraseanet.cache-service"
"orm.cache.configurer" => $app->protect(function($name, ORMConfig $config, $options) use ($app) {
$config->setMetadataCacheImpl($app['phraseanet.cache-service']->factory(
'ORM_metadata', $app['orm.cache.driver'], $app['orm.cache.options']
));
$config->setQueryCacheImpl($app['phraseanet.cache-service']->factory(
'ORM_query', $app['orm.cache.driver'], $app['orm.cache.options']
));
$config->setResultCacheImpl($app['phraseanet.cache-service']->factory(
'ORM_result', $app['orm.cache.driver'], $app['orm.cache.options']
));
$config->setHydrationCacheImpl($app['phraseanet.cache-service']->factory(
'ORM_hydration', $app['orm.cache.driver'], $app['orm.cache.options']
));
}),
"orm.proxies_dir" => $app['root.path'].'/resources/proxies',
"orm.auto_generate_proxies" => $app['debug'],
"orm.proxies_namespace" => 'Alchemy\Phrasea\Model\Proxies',
"orm.em.options" => $app['orm.ems.options']
);
});
/**
* Provides DSN string using database information
*/
@@ -321,11 +284,21 @@ SQL;
return $key;
});
$app['dbal.evm.register.listeners'] = $app->protect(function($evm) use($app) {
$evm->addEventSubscriber(new TimestampableListener());
// Listeners should be attached with their events as info.
$app['dbal.evm.listeners'] = $app->share(function () {
return new \SplObjectStorage();
});
$app['dbal.config.register.loggers'] = $app->protect(function($config) use($app) {
$app['dbal.evm.register.listeners'] = $app->protect(function(EventManager $evm) use ($app) {
$evm->addEventSubscriber(new TimestampableListener());
/** @var \SplObjectStorage $listeners */
$listeners = $app['dbal.evm.listeners'];
foreach ($listeners as $listener) {
$evm->addEventListener($listeners[$listener], $listener);
}
});
$app['dbal.config.register.loggers'] = $app->protect(function(Configuration $config) use ($app) {
if ($app->getEnvironment() === PhraseaApplication::ENV_DEV) {
$config->setSQLLogger($app['orm.query.logger']);
}
@@ -523,21 +496,23 @@ SQL;
return $options;
});
/**
* Return orm configuration for a connection given its unique id
*/
$app['orm.options.mappings'] = $app->share(function (PhraseaApplication $app) {
return array(
array(
"type" => "annotation",
"alias" => "Phraseanet",
"use_simple_annotation_reader" => false,
"namespace" => 'Alchemy\Phrasea\Model\Entities',
"path" => $app['root.path'].'/lib/Alchemy/Phrasea/Model/Entities',
)
);
});
// Return orm configuration for a connection given its unique id
$app['orm.options'] = $app->protect(function($connection) use ($app) {
return array(
"connection" => $connection,
"mappings" => array(
array(
"type" => "annotation",
"alias" => "Phraseanet",
"use_simple_annotation_reader" => false,
"namespace" => 'Alchemy\Phrasea\Model\Entities',
"path" => $app['root.path'].'/lib/Alchemy/Phrasea/Model/Entities',
)
),
"mappings" => $app['orm.options.mappings'],
"types" => array(
'blob' => 'Alchemy\Phrasea\Model\Types\Blob',
'enum' => 'Alchemy\Phrasea\Model\Types\Enum',

View File

@@ -0,0 +1,50 @@
<?php
/*
* This file is part of Phraseanet
*
* (c) 2005-2015 Alchemy
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Alchemy\Phrasea\DoctrineExtension;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
class TablePrefix
{
private $namespace;
private $prefix;
/**
* @param string $namespace namespace of classes to prefix
* @param string $prefix
*/
public function __construct($namespace, $prefix)
{
$this->namespace = trim((string)$namespace, '\\') . '\\';
$this->prefix = (string)$prefix;
}
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
/** @var ClassMetadataInfo $classMetadata */
$classMetadata = $eventArgs->getClassMetadata();
if (substr($classMetadata->getName(), 0, strlen($this->namespace)) != $this->namespace) {
return;
}
if (!$classMetadata->isInheritanceTypeSingleTable() || $classMetadata->getName() === $classMetadata->rootEntityName) {
$classMetadata->setPrimaryTable(['name' => $this->prefix . $classMetadata->getTableName()]);
}
foreach ($classMetadata->getAssociationMappings() as $fieldName => $mapping) {
if ($mapping['type'] == ClassMetadataInfo::MANY_TO_MANY && $mapping['isOwningSide']) {
$mappedTableName = $mapping['joinTable']['name'];
$classMetadata->associationMappings[$fieldName]['joinTable']['name'] = $this->prefix . $mappedTableName;
}
}
}
}