Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/Doctrine/aliases.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@ class EventArgs {
}

abstract class EventManager {
public function addEventSubscriber(EventSubscriber $subscriber) {
public function addEventSubscriber(EventSubscriber $subscriber): void {
$this->addEventListener($subscriber->getSubscribedEvents(), $subscriber);
}

public function removeEventSubscriber(EventSubscriber $subscriber) {
public function removeEventSubscriber(EventSubscriber $subscriber): void {
$this->removeEventListener($subscriber->getSubscribedEvents(), $subscriber);
}

abstract public function addEventListener($events, $listener);
abstract public function addEventListener(string|array $events, object $listener): void;

abstract public function removeEventListener($events, $listener = NULL);
abstract public function removeEventListener(string|array $events, object $listener = NULL): void;
Comment on lines +24 to +26
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These abstract signatures no longer allow callable listeners and will force downstream implementations to reject closures/array callables. If callable listeners are part of the supported API, widen these to callable|object to keep the interface compatible with implementations.

Copilot uses AI. Check for mistakes.
}

interface EventSubscriber {
Expand Down
24 changes: 10 additions & 14 deletions src/Events/EventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function setExceptionHandler(IExceptionHandler $exceptionHandler)
* @param string $eventName The name of the event to dispatch. The name of the event is the name of the method that is invoked on listeners.
* @param \Doctrine\Common\EventArgs $eventArgs The event arguments to pass to the event handlers/listeners. If not supplied, the single empty EventArgs instance is used
*/
public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
public function dispatchEvent(string $eventName, ?DoctrineEventArgs $eventArgs = NULL): void
{
if ($this->panel) {
$this->panel->eventDispatch($eventName, $eventArgs);
Expand Down Expand Up @@ -118,7 +118,7 @@ public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
* @param string|null $eventName
* @return \Doctrine\Common\EventSubscriber[]|callable[]|\Doctrine\Common\EventSubscriber[][]|callable[][]
*/
public function getListeners($eventName = NULL)
public function getListeners(string $eventName = NULL): array
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using null as a default for a non-nullable string parameter is invalid in PHP 8.x. Update the signature to: public function getListeners(?string $eventName = null): array.

Suggested change
public function getListeners(string $eventName = NULL): array
public function getListeners(?string $eventName = NULL): array

Copilot uses AI. Check for mistakes.
{
if ($eventName !== NULL) {
if (!isset($this->sorted[$eventName])) {
Expand All @@ -143,7 +143,7 @@ public function getListeners($eventName = NULL)
* @param string|null $eventName
* @return bool TRUE if the specified event has any listeners, FALSE otherwise.
*/
public function hasListeners($eventName)
public function hasListeners(string $eventName): bool
{
return (bool) count($this->getListeners($eventName));
}
Expand All @@ -156,7 +156,7 @@ public function hasListeners($eventName)
* @param int $priority
* @throws \Kdyby\Events\InvalidListenerException
*/
public function addEventListener($events, $subscriber, $priority = 0)
public function addEventListener(string|array $events, object $subscriber, $priority = 0): void
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typing the subscriber as object prevents using callable listeners (e.g., closures or array callables) that may have been supported previously. If callable listeners are still intended to be supported, widen the type to callable|object and handle callables accordingly.

Suggested change
public function addEventListener(string|array $events, object $subscriber, $priority = 0): void
public function addEventListener(string|array $events, $subscriber, $priority = 0): void

Copilot uses AI. Check for mistakes.
{
foreach ((array) $events as $eventName) {
[, $event] = Event::parseName($eventName);
Expand Down Expand Up @@ -184,14 +184,8 @@ public function addEventListener($events, $subscriber, $priority = 0)
* @param \Doctrine\Common\EventSubscriber|\Closure|array|string $unsubscribe
* @param \Doctrine\Common\EventSubscriber|\Closure|array $subscriber
*/
public function removeEventListener($unsubscribe, $subscriber = NULL)
public function removeEventListener(string|array $unsubscribe, object $subscriber = NULL): void
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This narrows the API and removes previously supported inputs (e.g., EventSubscriber or Closure as the first argument), as indicated by the removed instanceof checks. To preserve backward compatibility, either reintroduce handling for EventSubscriber/Closure (delegating to removeEventSubscriber/extractCallable) or widen the signature to accept callable|object for the subscriber and detect EventSubscriber when passed as the first parameter.

Suggested change
public function removeEventListener(string|array $unsubscribe, object $subscriber = NULL): void
public function removeEventListener(string|array $unsubscribe, $subscriber = NULL): void

Copilot uses AI. Check for mistakes.
{
if ($unsubscribe instanceof EventSubscriber) {
[$unsubscribe, $subscriber] = $this->extractSubscriber($unsubscribe);
} elseif ($unsubscribe instanceof Closure) {
[$unsubscribe, $subscriber] = $this->extractCallable($unsubscribe);
}

foreach ((array) $unsubscribe as $eventName) {
$eventName = ltrim($eventName, '\\');
foreach ($this->listeners[$eventName] as $priority => $listeners) {
Expand Down Expand Up @@ -272,7 +266,7 @@ protected function extractCallable(callable $subscriber)
/**
* {@inheritdoc}
*/
public function addEventSubscriber(EventSubscriber $subscriber)
public function addEventSubscriber(EventSubscriber $subscriber): void
{
$hash = spl_object_hash($subscriber);
if (isset($this->subscribers[$hash])) {
Expand Down Expand Up @@ -303,9 +297,11 @@ public function addEventSubscriber(EventSubscriber $subscriber)
/**
* {@inheritdoc}
*/
public function removeEventSubscriber(EventSubscriber $subscriber)
public function removeEventSubscriber(EventSubscriber $subscriber): void
{
$this->removeEventListener($subscriber);
[$unsubscribe, $subscriber] = $this->extractSubscriber($subscriber);

$this->removeEventListener($unsubscribe, $subscriber);
}

/**
Expand Down
10 changes: 2 additions & 8 deletions src/Events/LazyEventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public function setPanel(Panel $panel)
/**
* {@inheritdoc}
*/
public function getListeners($eventName = NULL)
public function getListeners(string $eventName = NULL): array
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A non-nullable string parameter cannot have a null default in PHP 8.x. Update to a nullable type: public function getListeners(?string $eventName = null): array.

Suggested change
public function getListeners(string $eventName = NULL): array
public function getListeners(?string $eventName = NULL): array

Copilot uses AI. Check for mistakes.
{
if ($eventName === NULL) {
while (($type = key($this->listenerIds)) !== NULL) {
Expand All @@ -67,14 +67,8 @@ public function getListeners($eventName = NULL)
/**
* {@inheritdoc}
*/
public function removeEventListener($unsubscribe, $subscriber = NULL)
public function removeEventListener(string|array $unsubscribe, object $subscriber = NULL): void
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new signature drops support for passing EventSubscriber or Closure as the first parameter, which the previous implementation handled. Consider restoring that behavior (e.g., detect EventSubscriber/Closure and delegate) or widen accepted types to callable|object for compatibility.

Copilot uses AI. Check for mistakes.
{
if ($unsubscribe instanceof EventSubscriber) {
[$unsubscribe, $subscriber] = $this->extractSubscriber($unsubscribe);
} elseif ($unsubscribe instanceof Closure) {
[$unsubscribe, $subscriber] = $this->extractCallable($unsubscribe);
}

foreach ((array) $unsubscribe as $eventName) {
if (array_key_exists($eventName, $this->listenerIds)) {
$this->initializeListener($eventName);
Expand Down
28 changes: 6 additions & 22 deletions src/Events/NamespacedEventManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function __construct($namespace, EventManager $eventManager)
/**
* {@inheritDoc}
*/
public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
public function dispatchEvent(string $eventName, ?DoctrineEventArgs $eventArgs = NULL): void
{
[$ns, $event] = Event::parseName($eventName);

Expand All @@ -54,7 +54,7 @@ public function dispatchEvent($eventName, DoctrineEventArgs $eventArgs = NULL)
/**
* {@inheritDoc}
*/
public function getListeners($eventName = NULL)
public function getListeners(string $eventName = null): array
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In PHP 8.x, a non-nullable string parameter cannot have a null default. Change the signature to accept a nullable string: public function getListeners(?string $eventName = null): array.

Suggested change
public function getListeners(string $eventName = null): array
public function getListeners(?string $eventName = null): array

Copilot uses AI. Check for mistakes.
{
if ($eventName === NULL) {
$listeners = [];
Expand Down Expand Up @@ -83,7 +83,7 @@ public function getListeners($eventName = NULL)
/**
* {@inheritDoc}
*/
public function hasListeners($eventName)
public function hasListeners(string $eventName): bool
{
[$ns, $event] = Event::parseName($eventName);

Expand All @@ -97,7 +97,7 @@ public function hasListeners($eventName)
/**
* {@inheritDoc}
*/
public function addEventListener($events, $subscriber, $priority = 0)
public function addEventListener(string|array $events, object $subscriber, $priority = 0): void
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new object-only subscriber type excludes callable listeners. If callables are valid in this layer, change the parameter type to callable|object and adapt usage accordingly.

Suggested change
public function addEventListener(string|array $events, object $subscriber, $priority = 0): void
public function addEventListener(string|array $events, callable|object $subscriber, $priority = 0): void

Copilot uses AI. Check for mistakes.
{
foreach ((array) $events as $eventName) {
[$ns, $event] = Event::parseName($eventName);
Expand All @@ -108,30 +108,14 @@ public function addEventListener($events, $subscriber, $priority = 0)
/**
* {@inheritDoc}
*/
public function removeEventListener($unsubscribe, $subscriber = NULL)
public function removeEventListener(string|array $unsubscribe, object $subscriber = NULL): void
{
Comment on lines +111 to 112
Copy link

Copilot AI Oct 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This narrows the accepted types and removes the previous convenience of passing an EventSubscriber as the first argument (the conversion block was removed). To avoid breaking existing usage, either re-add the EventSubscriber handling or provide/route through a removeEventSubscriber method in this class.

Suggested change
public function removeEventListener(string|array $unsubscribe, object $subscriber = NULL): void
{
public function removeEventListener(string|array|EventSubscriber $unsubscribe, object $subscriber = NULL): void
{
// Backward compatibility: allow passing EventSubscriber as first argument
if ($unsubscribe instanceof EventSubscriber) {
$events = $unsubscribe->getSubscribedEvents();
$this->evm->removeEventListener($events, $unsubscribe);
return;
}

Copilot uses AI. Check for mistakes.
if ($unsubscribe instanceof EventSubscriber) {
$subscriber = $unsubscribe;
$unsubscribe = [];

foreach ($subscriber->getSubscribedEvents() as $eventName => $params) {
if ((is_array($params) && is_array($params[0])) || !is_numeric($eventName)) {
// [EventName => [[method, priority], ...], ...]
// [EventName => [method, priority], ...] && [EventName => method, .
$unsubscribe[] = $eventName;

} else { // [EventName, ...]
$unsubscribe[] = $params;
}
}
}

$unsubscribe = array_map(function ($eventName) {
[$ns, $event] = Event::parseName($eventName);
return $ns === NULL ? $this->namespace . $event : $eventName;
}, (array) $unsubscribe);

$this->evm->removeEventListener($unsubscribe, $subscriber);
$this->evm->removeEventListener($unsubscribe, $subscriber);
}

/**
Expand Down