Skip to content

Commit

Permalink
ContainerAwareEventManager: always returns initialized listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
mabar authored and f3l1x committed Dec 4, 2019
1 parent d37aa13 commit 89f4421
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 20 deletions.
2 changes: 2 additions & 0 deletions phpstan.neon
Expand Up @@ -3,3 +3,5 @@ parameters:
- "#^Parameter \\#1 \\$function of function call_user_func expects callable\\(\\): mixed, array\\(object, 'getSubscribedEvents'\\) given.#"
# No replacement available
- '#^Fetching class constant class of deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ImportCommand.+#'
# Method iterates through property and converts string values to objects, cannot happen
- '#^Method Nettrine\\DBAL\\Events\\ContainerAwareEventManager\:\:getInitializedListeners\(\) should return array\<object\> but returns array\<object\|string\>\.$#'
60 changes: 40 additions & 20 deletions src/Events/ContainerAwareEventManager.php
Expand Up @@ -13,10 +13,10 @@ class ContainerAwareEventManager extends DoctrineEventManager
/** @var Container */
protected $container;

/** @var mixed[boolean[]] */
/** @var bool[] */
protected $initialized = [];

/** @var mixed[EventSubscriber[]] */
/** @var string[][]|object[][] */
protected $listeners = [];

public function __construct(Container $container)
Expand All @@ -30,33 +30,53 @@ public function __construct(Container $container)
*/
public function dispatchEvent($eventName, ?EventArgs $eventArgs = null): void
{
if (isset($this->listeners[$eventName])) {
$eventArgs = $eventArgs ?? EventArgs::getEmptyInstance();
$eventArgs = $eventArgs ?? EventArgs::getEmptyInstance();

$initialized = isset($this->initialized[$eventName]);
foreach ($this->getInitializedListeners($eventName) as $hash => $listener) {
$listener->$eventName($eventArgs);
}
}

foreach ($this->listeners[$eventName] as $hash => $listener) {
if (!$initialized && !is_object($listener)) {
$this->listeners[$eventName][$hash] = $listener = $this->container->getService($listener);
}
/**
* @param string|null $event
* @return object[]|object[][]
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
*/
public function getListeners($event = null): array
{
if ($event !== null) {
return $this->getInitializedListeners($event);
}

$listener->$eventName($eventArgs);
}
$stack = [];

$this->initialized[$eventName] = true;
foreach ($this->listeners as $eventName => $listeners) {
$stack[$eventName] = $this->getInitializedListeners($eventName);
}

return $stack;
}

/**
* @param string|NULL $event
* @return object[]
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
*/
public function getListeners($event = null): array
private function getInitializedListeners(string $event): array
{
return $event
? $this->listeners[$event]
: $this->listeners;
$initialized = $this->initialized[$event] ?? false;

if ($initialized) {
return $this->listeners[$event] ?? [];
}

foreach ($this->listeners[$event] ?? [] as $hash => $listener) {
if (!is_object($listener)) {
$this->listeners[$event][$hash] = $this->container->getService($listener);
}
}

$this->initialized[$event] = true;

return $this->listeners[$event] ?? [];
}

/**
Expand All @@ -72,7 +92,7 @@ public function hasListeners($event): bool
* Adds an event listener that listens on the specified events.
*
* @param string|string[] $events The event(s) to listen on.
* @param string|int|object $listener The listener object.
* @param string|object $listener The listener object.
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
*/
public function addEventListener($events, $listener): void
Expand All @@ -96,7 +116,7 @@ public function addEventListener($events, $listener): void
/**
* Removes an event listener from the specified events.
*
* @param string|string[] $events
* @param string|string[] $events
* @param string|int|object $listener
* @phpcsSuppress SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint
*/
Expand Down

0 comments on commit 89f4421

Please sign in to comment.