feature #14563 [FrameworkBundle][EventDispatcher] Add priorities to the debug:event-dispatcher command (Seldaek)

This PR was merged into the 2.8 branch.

Discussion
----------

[FrameworkBundle][EventDispatcher] Add priorities to the debug:event-dispatcher command

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        | TODO

I find it helps to figure out which priority is needed to override another event listener without digging in the sources.

Commits
-------

952929c [FrameworkBundle][EventDispatcher] Add priorities to the debug:event-dispatcher command
This commit is contained in:
Fabien Potencier 2015-05-06 18:31:35 +02:00
commit da0194b235
17 changed files with 125 additions and 80 deletions

View File

@ -288,17 +288,27 @@ class JsonDescriptor extends Descriptor
{
$data = array();
$registeredListeners = $eventDispatcher->getListeners($event);
$registeredListeners = $eventDispatcher->getListeners($event, true);
if (null !== $event) {
foreach ($registeredListeners as $listener) {
$data[] = $this->getCallableData($listener);
krsort($registeredListeners);
foreach ($registeredListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$listener = $this->getCallableData($listener);
$listener['priority'] = $priority;
$data[] = $listener;
}
}
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
foreach ($eventListeners as $eventListener) {
$data[$eventListened][] = $this->getCallableData($eventListener);
krsort($eventListeners);
foreach ($eventListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$listener = $this->getCallableData($listener);
$listener['priority'] = $priority;
$data[$eventListened][] = $listener;
}
}
}
}

View File

@ -269,21 +269,30 @@ class MarkdownDescriptor extends Descriptor
$this->write(sprintf('# %s', $title)."\n");
$registeredListeners = $eventDispatcher->getListeners($event);
$registeredListeners = $eventDispatcher->getListeners($event, true);
if (null !== $event) {
foreach ($registeredListeners as $order => $listener) {
$this->write("\n".sprintf('## Listener %d', $order + 1)."\n");
$this->describeCallable($listener);
krsort($registeredListeners);
$order = 1;
foreach ($registeredListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$this->write("\n".sprintf('## Listener %d', $order++)."\n");
$this->describeCallable($listener);
$this->write(sprintf('- Priority: `%d`', $priority)."\n");
}
}
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
$this->write("\n".sprintf('## %s', $eventListened)."\n");
foreach ($eventListeners as $order => $eventListener) {
$this->write("\n".sprintf('### Listener %d', $order + 1)."\n");
$this->describeCallable($eventListener);
krsort($eventListeners);
$order = 1;
foreach ($eventListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$this->write("\n".sprintf('### Listener %d', $order++)."\n");
$this->describeCallable($listener);
$this->write(sprintf('- Priority: `%d`', $priority)."\n");
}
}
}
}

View File

@ -336,33 +336,16 @@ class TextDescriptor extends Descriptor
$this->writeText($this->formatSection('event_dispatcher', $label)."\n", $options);
$registeredListeners = $eventDispatcher->getListeners($event);
$registeredListeners = $eventDispatcher->getListeners($event, true);
if (null !== $event) {
$this->writeText("\n");
$table = new Table($this->getOutput());
$table->getStyle()->setCellHeaderFormat('%s');
$table->setHeaders(array('Order', 'Callable'));
foreach ($registeredListeners as $order => $listener) {
$table->addRow(array(sprintf('#%d', $order + 1), $this->formatCallable($listener)));
}
$table->render();
$this->renderEventListenerTable($registeredListeners);
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
$this->writeText(sprintf("\n<info>[Event]</info> %s\n", $eventListened), $options);
$table = new Table($this->getOutput());
$table->getStyle()->setCellHeaderFormat('%s');
$table->setHeaders(array('Order', 'Callable'));
foreach ($eventListeners as $order => $eventListener) {
$table->addRow(array(sprintf('#%d', $order + 1), $this->formatCallable($eventListener)));
}
$table->render();
$this->renderEventListenerTable($eventListeners);
}
}
}
@ -375,6 +358,26 @@ class TextDescriptor extends Descriptor
$this->writeText($this->formatCallable($callable), $options);
}
/**
* @param array $array
*/
private function renderEventListenerTable(array $eventListeners)
{
$table = new Table($this->getOutput());
$table->getStyle()->setCellHeaderFormat('%s');
$table->setHeaders(array('Order', 'Callable', 'Priority'));
krsort($eventListeners);
$order = 1;
foreach ($eventListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$table->addRow(array(sprintf('#%d', $order++), $this->formatCallable($listener), $priority));
}
}
$table->render();
}
/**
* @param array $array
*

View File

@ -446,13 +446,9 @@ class XmlDescriptor extends Descriptor
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($eventDispatcherXML = $dom->createElement('event-dispatcher'));
$registeredListeners = $eventDispatcher->getListeners($event);
$registeredListeners = $eventDispatcher->getListeners($event, true);
if (null !== $event) {
foreach ($registeredListeners as $listener) {
$callableXML = $this->getCallableDocument($listener);
$eventDispatcherXML->appendChild($eventDispatcherXML->ownerDocument->importNode($callableXML->childNodes->item(0), true));
}
$this->appendEventListenerDocument($eventDispatcherXML, $registeredListeners);
} else {
ksort($registeredListeners);
@ -460,17 +456,30 @@ class XmlDescriptor extends Descriptor
$eventDispatcherXML->appendChild($eventXML = $dom->createElement('event'));
$eventXML->setAttribute('name', $eventListened);
foreach ($eventListeners as $eventListener) {
$callableXML = $this->getCallableDocument($eventListener);
$eventXML->appendChild($eventXML->ownerDocument->importNode($callableXML->childNodes->item(0), true));
}
$this->appendEventListenerDocument($eventXML, $eventListeners);
}
}
return $dom;
}
/**
* @param DOMElement $element
* @param array $eventListeners
*/
private function appendEventListenerDocument(\DOMElement $element, array $eventListeners)
{
krsort($eventListeners);
foreach ($eventListeners as $priority => $listeners) {
foreach ($listeners as $listener) {
$callableXML = $this->getCallableDocument($listener);
$callableXML->childNodes->item(0)->setAttribute('priority', $priority);
$element->appendChild($element->ownerDocument->importNode($callableXML->childNodes->item(0), true));
}
}
}
/**
* @param callable $callable
*

View File

@ -157,8 +157,8 @@ class ObjectsProvider
{
$eventDispatcher = new EventDispatcher();
$eventDispatcher->addListener('event1', 'global_function');
$eventDispatcher->addListener('event1', function () { return 'Closure'; });
$eventDispatcher->addListener('event1', 'global_function', 255);
$eventDispatcher->addListener('event1', function () { return 'Closure'; }, -1);
$eventDispatcher->addListener('event2', new CallableClass());
return array('event_dispatcher_1' => $eventDispatcher);

View File

@ -1,9 +1,11 @@
[
{
"type": "function",
"name": "global_function"
"name": "global_function",
"priority": 255
},
{
"type": "closure"
"type": "closure",
"priority": -1
}
]

View File

@ -4,7 +4,9 @@
- Type: `function`
- Name: `global_function`
- Priority: `255`
## Listener 2
- Type: `closure`
- Priority: `-1`

View File

@ -1,8 +1,8 @@
<info>[event_dispatcher]</info> Registered listeners for event <info>event1</info>
+-------+-------------------+
| Order | Callable |
+-------+-------------------+
| #1 | global_function() |
| #2 | \Closure() |
+-------+-------------------+
+-------+-------------------+----------+
| Order | Callable | Priority |
+-------+-------------------+----------+
| #1 | global_function() | 255 |
| #2 | \Closure() | -1 |
+-------+-------------------+----------+

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<event-dispatcher>
<callable type="function" name="global_function"/>
<callable type="closure"/>
<callable type="function" name="global_function" priority="255"/>
<callable type="closure" priority="-1"/>
</event-dispatcher>

View File

@ -2,16 +2,19 @@
"event1": [
{
"type": "function",
"name": "global_function"
"name": "global_function",
"priority": 255
},
{
"type": "closure"
"type": "closure",
"priority": -1
}
],
"event2": [
{
"type": "object",
"name": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass"
"name": "Symfony\\Bundle\\FrameworkBundle\\Tests\\Console\\Descriptor\\CallableClass",
"priority": 0
}
]
}

View File

@ -6,10 +6,12 @@
- Type: `function`
- Name: `global_function`
- Priority: `255`
### Listener 2
- Type: `closure`
- Priority: `-1`
## event2
@ -17,3 +19,4 @@
- Type: `object`
- Name: `Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass`
- Priority: `0`

View File

@ -1,16 +1,16 @@
<info>[event_dispatcher]</info> Registered listeners by event
<info>[Event]</info> event1
+-------+-------------------+
| Order | Callable |
+-------+-------------------+
| #1 | global_function() |
| #2 | \Closure() |
+-------+-------------------+
+-------+-------------------+----------+
| Order | Callable | Priority |
+-------+-------------------+----------+
| #1 | global_function() | 255 |
| #2 | \Closure() | -1 |
+-------+-------------------+----------+
<info>[Event]</info> event2
+-------+-----------------------------------------------------------------------------------+
| Order | Callable |
+-------+-----------------------------------------------------------------------------------+
| #1 | Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass::__invoke() |
+-------+-----------------------------------------------------------------------------------+
+-------+-----------------------------------------------------------------------------------+----------+
| Order | Callable | Priority |
+-------+-----------------------------------------------------------------------------------+----------+
| #1 | Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass::__invoke() | 0 |
+-------+-----------------------------------------------------------------------------------+----------+

View File

@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<event-dispatcher>
<event name="event1">
<callable type="function" name="global_function"/>
<callable type="closure"/>
<callable type="function" name="global_function" priority="255"/>
<callable type="closure" priority="-1"/>
</event>
<event name="event2">
<callable type="object" name="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass"/>
<callable type="object" name="Symfony\Bundle\FrameworkBundle\Tests\Console\Descriptor\CallableClass" priority="0"/>
</event>
</event-dispatcher>

View File

@ -118,7 +118,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
/**
* @see EventDispatcherInterface::getListeners()
*/
public function getListeners($eventName = null)
public function getListeners($eventName = null, $withPriorities = false)
{
if (null === $eventName) {
foreach ($this->listenerIds as $serviceEventName => $args) {
@ -128,7 +128,7 @@ class ContainerAwareEventDispatcher extends EventDispatcher
$this->lazyLoad($eventName);
}
return parent::getListeners($eventName);
return parent::getListeners($eventName, $withPriorities);
}
/**

View File

@ -94,9 +94,9 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface
/**
* {@inheritdoc}
*/
public function getListeners($eventName = null)
public function getListeners($eventName = null, $withPriorities = false)
{
return $this->dispatcher->getListeners($eventName);
return $this->dispatcher->getListeners($eventName, $withPriorities);
}
/**

View File

@ -58,8 +58,12 @@ class EventDispatcher implements EventDispatcherInterface
/**
* @see EventDispatcherInterface::getListeners()
*/
public function getListeners($eventName = null)
public function getListeners($eventName = null, $withPriorities = false)
{
if (true === $withPriorities) {
return $eventName ? $this->listeners[$eventName] : array_filter($this->listeners);
}
if (null !== $eventName) {
if (!isset($this->sorted[$eventName])) {
$this->sortListeners($eventName);

View File

@ -78,9 +78,9 @@ class ImmutableEventDispatcher implements EventDispatcherInterface
/**
* {@inheritdoc}
*/
public function getListeners($eventName = null)
public function getListeners($eventName = null, $withPriorities = false)
{
return $this->dispatcher->getListeners($eventName);
return $this->dispatcher->getListeners($eventName, $withPriorities);
}
/**