Skip to content

[EventDispatcher] Remove deprecation layer #31709

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
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: 8 additions & 0 deletions src/Symfony/Component/EventDispatcher/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
CHANGELOG
=========

5.0.0
-----

* The signature of the `EventDispatcherInterface::dispatch()` method has been changed to `dispatch($event, string $eventName = null): object`.
* The `Event` class has been removed in favor of `Symfony\Contracts\EventDispatcher\Event`.
* The `TraceableEventDispatcherInterface` has been removed.
* The `WrappedListener` class is now final.

4.3.0
-----

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,12 @@
use Psr\EventDispatcher\StoppableEventInterface;
use Psr\Log\LoggerInterface;
use Symfony\Component\BrowserKit\Request;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\LegacyEventDispatcherProxy;
use Symfony\Component\EventDispatcher\LegacyEventProxy;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Contracts\EventDispatcher\Event as ContractsEvent;
use Symfony\Contracts\EventDispatcher\Event;
use Symfony\Contracts\Service\ResetInterface;

/**
* Collects some data about event listeners.
Expand All @@ -30,7 +28,7 @@
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TraceableEventDispatcher implements TraceableEventDispatcherInterface
class TraceableEventDispatcher implements EventDispatcherInterface, ResetInterface
{
protected $logger;
protected $stopwatch;
Expand All @@ -44,7 +42,7 @@ class TraceableEventDispatcher implements TraceableEventDispatcherInterface

public function __construct(EventDispatcherInterface $dispatcher, Stopwatch $stopwatch, LoggerInterface $logger = null, RequestStack $requestStack = null)
{
$this->dispatcher = LegacyEventDispatcherProxy::decorate($dispatcher);
$this->dispatcher = $dispatcher;
$this->stopwatch = $stopwatch;
$this->logger = $logger;
$this->wrappedListeners = [];
Expand Down Expand Up @@ -130,32 +128,22 @@ public function hasListeners($eventName = null)

/**
* {@inheritdoc}
*
* @param string|null $eventName
*/
public function dispatch($event/*, string $eventName = null*/)
public function dispatch($event, string $eventName = null): object
{
if (!\is_object($event)) {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, %s given.', EventDispatcherInterface::class, \gettype($event)));
}

$eventName = $eventName ?? \get_class($event);

if (null === $this->callStack) {
$this->callStack = new \SplObjectStorage();
}

$currentRequestHash = $this->currentRequestHash = $this->requestStack && ($request = $this->requestStack->getCurrentRequest()) ? spl_object_hash($request) : '';
$eventName = 1 < \func_num_args() ? \func_get_arg(1) : null;

if (\is_object($event)) {
$eventName = $eventName ?? \get_class($event);
} else {
@trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), E_USER_DEPRECATED);
$swap = $event;
$event = $eventName ?? new Event();
$eventName = $swap;

if (!$event instanceof Event) {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an instance of %s, %s given.', EventDispatcherInterface::class, Event::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}
}

if (null !== $this->logger && ($event instanceof Event || $event instanceof ContractsEvent || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
if (null !== $this->logger && ($event instanceof Event || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
$this->logger->debug(sprintf('The "%s" event is already stopped. No listeners have been called.', $eventName));
}

Expand Down Expand Up @@ -291,35 +279,15 @@ public function __call($method, $arguments)

/**
* Called before dispatching the event.
*
* @param object $event
*/
protected function beforeDispatch(string $eventName, $event)
protected function beforeDispatch(string $eventName, object $event)
{
$this->preDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event));
}

/**
* Called after dispatching the event.
*
* @param object $event
*/
protected function afterDispatch(string $eventName, $event)
{
$this->postDispatch($eventName, $event instanceof Event ? $event : new LegacyEventProxy($event));
}

/**
* @deprecated since Symfony 4.3, will be removed in 5.0, use beforeDispatch instead
*/
protected function preDispatch($eventName, Event $event)
{
}

/**
* @deprecated since Symfony 4.3, will be removed in 5.0, use afterDispatch instead
*/
protected function postDispatch($eventName, Event $event)
protected function afterDispatch(string $eventName, object $event)
{
}

Expand Down

This file was deleted.

24 changes: 8 additions & 16 deletions src/Symfony/Component/EventDispatcher/Debug/WrappedListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,15 @@
namespace Symfony\Component\EventDispatcher\Debug;

use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\EventDispatcher\Event;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\EventDispatcher\LegacyEventProxy;
use Symfony\Component\Stopwatch\Stopwatch;
use Symfony\Component\VarDumper\Caster\ClassStub;
use Symfony\Contracts\EventDispatcher\Event as ContractsEvent;
use Symfony\Contracts\EventDispatcher\Event;

/**
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.3: the "Event" type-hint on __invoke() will be replaced by "object" in 5.0
*/
class WrappedListener
final class WrappedListener
{
private $listener;
private $optimizedListener;
Expand Down Expand Up @@ -81,22 +77,22 @@ public function getWrappedListener()
return $this->listener;
}

public function wasCalled()
public function wasCalled(): bool
{
return $this->called;
}

public function stoppedPropagation()
public function stoppedPropagation(): bool
{
return $this->stoppedPropagation;
}

public function getPretty()
public function getPretty(): string
{
return $this->pretty;
}

public function getInfo($eventName)
public function getInfo(string $eventName): array
{
if (null === $this->stub) {
$this->stub = self::$hasClassStub ? new ClassStub($this->pretty.'()', $this->listener) : $this->pretty.'()';
Expand All @@ -110,12 +106,8 @@ public function getInfo($eventName)
];
}

public function __invoke(Event $event, $eventName, EventDispatcherInterface $dispatcher)
public function __invoke(object $event, string $eventName, EventDispatcherInterface $dispatcher): void
{
if ($event instanceof LegacyEventProxy) {
$event = $event->getEvent();
}

$dispatcher = $this->dispatcher ?: $dispatcher;

$this->called = true;
Expand All @@ -129,7 +121,7 @@ public function __invoke(Event $event, $eventName, EventDispatcherInterface $dis
$e->stop();
}

if (($event instanceof Event || $event instanceof ContractsEvent || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
if (($event instanceof Event || $event instanceof StoppableEventInterface) && $event->isPropagationStopped()) {
$this->stoppedPropagation = true;
}
}
Expand Down
38 changes: 0 additions & 38 deletions src/Symfony/Component/EventDispatcher/Event.php

This file was deleted.

47 changes: 8 additions & 39 deletions src/Symfony/Component/EventDispatcher/EventDispatcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\EventDispatcher\Debug\WrappedListener;
use Symfony\Contracts\EventDispatcher\Event as ContractsEvent;
use Symfony\Contracts\EventDispatcher\Event;

/**
* The EventDispatcherInterface is the central point of Symfony's event listener system.
Expand Down Expand Up @@ -45,26 +45,15 @@ public function __construct()

/**
* {@inheritdoc}
*
* @param string|null $eventName
*/
public function dispatch($event/*, string $eventName = null*/)
public function dispatch($event, string $eventName = null): object
{
$eventName = 1 < \func_num_args() ? \func_get_arg(1) : null;

if (\is_object($event)) {
$eventName = $eventName ?? \get_class($event);
} else {
@trigger_error(sprintf('Calling the "%s::dispatch()" method with the event name as first argument is deprecated since Symfony 4.3, pass it second and provide the event object first instead.', EventDispatcherInterface::class), E_USER_DEPRECATED);
$swap = $event;
$event = $eventName ?? new Event();
$eventName = $swap;

if (!$event instanceof Event) {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an instance of %s, %s given.', EventDispatcherInterface::class, Event::class, \is_object($event) ? \get_class($event) : \gettype($event)));
}
if (!\is_object($event)) {
throw new \TypeError(sprintf('Argument 1 passed to "%s::dispatch()" must be an object, %s given.', EventDispatcherInterface::class, \gettype($event)));
}

$eventName = $eventName ?? \get_class($event);

if (null !== $this->optimized && null !== $eventName) {
$listeners = $this->optimized[$eventName] ?? (empty($this->listeners[$eventName]) ? [] : $this->optimizeListeners($eventName));
} else {
Expand Down Expand Up @@ -229,34 +218,14 @@ public function removeSubscriber(EventSubscriberInterface $subscriber)
* @param string $eventName The name of the event to dispatch
* @param object $event The event object to pass to the event handlers/listeners
*/
protected function callListeners(iterable $listeners, string $eventName, $event)
protected function callListeners(iterable $listeners, string $eventName, object $event)
{
if ($event instanceof Event) {
$this->doDispatch($listeners, $eventName, $event);

return;
}

$stoppable = $event instanceof ContractsEvent || $event instanceof StoppableEventInterface;
$stoppable = $event instanceof Event || $event instanceof StoppableEventInterface;

foreach ($listeners as $listener) {
if ($stoppable && $event->isPropagationStopped()) {
break;
}
// @deprecated: the ternary operator is part of a BC layer and should be removed in 5.0
$listener($listener instanceof WrappedListener ? new LegacyEventProxy($event) : $event, $eventName, $this);
}
}

/**
* @deprecated since Symfony 4.3, use callListeners() instead
*/
protected function doDispatch($listeners, $eventName, Event $event)
{
foreach ($listeners as $listener) {
if ($event->isPropagationStopped()) {
break;
}
$listener($event, $eventName, $this);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@
*/
interface EventDispatcherInterface extends ContractsEventDispatcherInterface
{
/**
* {@inheritdoc}
*/
public function dispatch($event, string $eventName = null): object;

/**
* Adds an event listener that listens on the specified events.
*
Expand Down
2 changes: 2 additions & 0 deletions src/Symfony/Component/EventDispatcher/GenericEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

namespace Symfony\Component\EventDispatcher;

use Symfony\Contracts\EventDispatcher\Event;

/**
* Event encapsulation class.
*
Expand Down
Loading