[DoctrineBundle] refactored event listeners/subscribers to not rely on parameter name conventions
* Doctrine event subscribers now all use the same "doctrine.event_subscriber" tag. To specify a connection, use the "connection" attribute. * Doctrine event listeners now all use the same "doctrine.event_listener" tag. To specify a connection, use the "connection" attribute.
This commit is contained in:
parent
a607afb8d2
commit
01695bc654
30
UPDATE.md
30
UPDATE.md
@ -9,6 +9,36 @@ timeline closely anyway.
|
||||
beta1 to beta2
|
||||
--------------
|
||||
|
||||
* Doctrine event subscribers now use a unique "doctrine.event_subscriber" tag.
|
||||
Doctrine event listeners also use a unique "doctrine.event_listener" tag. To
|
||||
specify a connection, use the optional "connection" attribute.
|
||||
|
||||
Before:
|
||||
|
||||
listener:
|
||||
class: MyEventListener
|
||||
tags:
|
||||
- { name: doctrine.common.event_listener, event: name }
|
||||
- { name: doctrine.dbal.default_event_listener, event: name }
|
||||
subscriber:
|
||||
class: MyEventSubscriber
|
||||
tags:
|
||||
- { name: doctrine.common.event_subscriber }
|
||||
- { name: doctrine.dbal.default_event_subscriber }
|
||||
|
||||
After:
|
||||
|
||||
listener:
|
||||
class: MyEventListener
|
||||
tags:
|
||||
- { name: doctrine.event_listener, event: name } # register for all connections
|
||||
- { name: doctrine.event_listener, event: name, connection: default } # only for the default connection
|
||||
subscriber:
|
||||
class: MyEventSubscriber
|
||||
tags:
|
||||
- { name: doctrine.event_subscriber } # register for all connections
|
||||
- { name: doctrine.event_subscriber, connection: default } # only for the default connection
|
||||
|
||||
* The `doctrine.orm.entity_managers` is now hash of entity manager names/ids pairs:
|
||||
|
||||
Before: array('default', 'foo')
|
||||
|
@ -9,55 +9,85 @@ use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
|
||||
class RegisterEventListenersAndSubscribersPass implements CompilerPassInterface
|
||||
{
|
||||
protected $container;
|
||||
private $container;
|
||||
private $connections;
|
||||
private $eventManagers;
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if (!$definition instanceof DefinitionDecorator || 'doctrine.dbal.connection.event_manager' !== $definition->getParent()) {
|
||||
continue;
|
||||
$this->connections = $container->getParameter('doctrine.dbal.connections');
|
||||
|
||||
foreach ($container->findTaggedServiceIds('doctrine.event_subscriber') as $subscriberId => $instances) {
|
||||
$this->registerSubscriber($subscriberId, $instances);
|
||||
}
|
||||
|
||||
foreach ($container->findTaggedServiceIds('doctrine.event_listener') as $listenerId => $instances) {
|
||||
$this->registerListener($listenerId, $instances);
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerSubscriber($subscriberId, $instances)
|
||||
{
|
||||
$connections = array();
|
||||
foreach ($instances as $attributes) {
|
||||
if (isset($attributes['connection'])) {
|
||||
$connections[] = $attributes['connection'];
|
||||
} else {
|
||||
$connections = array_keys($this->connections);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($connections as $name) {
|
||||
$this->getEventManager($name)->addMethodCall('addEventSubscriber', array(new Reference($subscriberId)));
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerListener($listenerId, $instances)
|
||||
{
|
||||
$connections = array();
|
||||
foreach ($instances as $attributes) {
|
||||
if (!isset($attributes['event'])) {
|
||||
throw new \InvalidArgumentException(sprintf('Doctrine event listener "%s" must specify the "event" attribute.', $listenerId));
|
||||
}
|
||||
|
||||
$prefix = substr($id, 0, -strlen('_connection.event_manager'));
|
||||
$this->registerListeners($prefix, $definition);
|
||||
$this->registerSubscribers($prefix, $definition);
|
||||
}
|
||||
}
|
||||
if (isset($attributes['connection'])) {
|
||||
$cs = array($attributes['connection']);
|
||||
} else {
|
||||
$cs = array_keys($this->connections);
|
||||
}
|
||||
|
||||
protected function registerSubscribers($prefix, $definition)
|
||||
{
|
||||
$subscribers = array_merge(
|
||||
$this->container->findTaggedServiceIds('doctrine.common.event_subscriber'),
|
||||
$this->container->findTaggedServiceIds($prefix.'_event_subscriber')
|
||||
);
|
||||
|
||||
foreach ($subscribers as $id => $instances) {
|
||||
$definition->addMethodCall('addEventSubscriber', array(new Reference($id)));
|
||||
}
|
||||
}
|
||||
|
||||
protected function registerListeners($prefix, $definition)
|
||||
{
|
||||
$listeners = array_merge(
|
||||
$this->container->findTaggedServiceIds('doctrine.common.event_listener'),
|
||||
$this->container->findTaggedServiceIds($prefix.'_event_listener')
|
||||
);
|
||||
|
||||
foreach ($listeners as $listenerId => $instances) {
|
||||
$events = array();
|
||||
foreach ($instances as $attributes) {
|
||||
if (isset($attributes['event'])) {
|
||||
$events[] = $attributes['event'];
|
||||
foreach ($cs as $connection) {
|
||||
if (!is_array($connections[$connection])) {
|
||||
$connections[$connection] = array();
|
||||
}
|
||||
}
|
||||
|
||||
if (0 < count($events)) {
|
||||
$definition->addMethodCall('addEventListener', array(
|
||||
$events,
|
||||
new Reference($listenerId),
|
||||
));
|
||||
$connections[$connection][] = $attributes['event'];
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($connections as $name => $events) {
|
||||
$this->getEventManager($name)->addMethodCall('addEventListener', array(
|
||||
array_unique($events),
|
||||
new Reference($listenerId),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getEventManager($name)
|
||||
{
|
||||
if (null === $this->eventManagers) {
|
||||
$this->eventManagers = array();
|
||||
foreach ($this->connections as $n => $id) {
|
||||
$arguments = $this->container->getDefinition($id)->getArguments();
|
||||
$this->eventManagers[$n] = $this->container->getDefinition((string) $arguments[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($this->eventManagers[$name])) {
|
||||
throw new \InvalidArgumentException(sprintf('Doctrine connection "%s" does not exist but is referenced in the "%s" event listener.', $name, $listenerId));
|
||||
}
|
||||
|
||||
return $this->eventManagers[$name];
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ class DoctrineExtension extends AbstractDoctrineExtension
|
||||
$mysqlSessionInit = new Definition('%doctrine.dbal.events.mysql_session_init.class%');
|
||||
$mysqlSessionInit->setArguments(array($connection['charset']));
|
||||
$mysqlSessionInit->setPublic(false);
|
||||
$mysqlSessionInit->addTag(sprintf('doctrine.dbal.%s_event_subscriber', $name));
|
||||
$mysqlSessionInit->addTag('doctrine.event_subscriber', array('connection' => $name));
|
||||
|
||||
$container->setDefinition(
|
||||
sprintf('doctrine.dbal.%s_connection.events.mysqlsessioninit', $name),
|
||||
|
Reference in New Issue
Block a user