Verified Commit 9dbd2a6b authored by Alex Pott's avatar Alex Pott
Browse files

Issue #2909185 by longwave, donquixote, andypost, andregp, pounard, jibran,...

Issue #2909185 by longwave, donquixote, andypost, andregp, pounard, jibran, martin107, kostyashupenko, catch, znerol: Replace ContainerAwareEventDispatcher with Symfony EventDispatcher
parent 1f1d1ab3
Loading
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -871,8 +871,7 @@ services:
    arguments: ['@request_stack']
  Drupal\Core\Routing\RouteMatchInterface: '@current_route_match'
  event_dispatcher:
    class: Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
    arguments: ['@service_container']
    class: Symfony\Component\EventDispatcher\EventDispatcher
  Psr\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
  Symfony\Contracts\EventDispatcher\EventDispatcherInterface: '@event_dispatcher'
  controller_resolver:
+7 −0
Original line number Diff line number Diff line
@@ -2,6 +2,8 @@

namespace Drupal\Component\EventDispatcher;

@trigger_error('The ' . __NAMESPACE__ . '\ContainerAwareEventDispatcher is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use Symfony\Component\EventDispatcher\EventDispatcher instead. See https://www.drupal.org/node/3376090', E_USER_DEPRECATED);

use Psr\EventDispatcher\StoppableEventInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -30,6 +32,11 @@
 *     runtime is not affected by this change though.
 *   </dd>
 * </dl>
 *
 * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
 *   \Symfony\Component\EventDispatcher\EventDispatcher instead.
 *
 * @see https://www.drupal.org/node/3376090
 */
class ContainerAwareEventDispatcher implements EventDispatcherInterface {

+2 −1
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
use Psr\Log\LoggerAwareInterface;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
@@ -83,7 +84,7 @@ public function register(ContainerBuilder $container) {
    $container->addCompilerPass(new TwigExtensionPass());

    // Add a compiler pass for registering event subscribers.
    $container->addCompilerPass(new RegisterEventSubscribersPass(), PassConfig::TYPE_AFTER_REMOVING);
    $container->addCompilerPass(new RegisterEventSubscribersPass(new RegisterListenersPass()), PassConfig::TYPE_AFTER_REMOVING);
    $container->addCompilerPass(new LoggerAwarePass(), PassConfig::TYPE_AFTER_REMOVING);

    $container->addCompilerPass(new RegisterAccessChecksPass());
+32 −41
Original line number Diff line number Diff line
@@ -4,59 +4,50 @@

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;

/**
 * Registers all event subscribers to the event dispatcher.
 * Wraps the Symfony event subscriber pass to use different tag names.
 */
class RegisterEventSubscribersPass implements CompilerPassInterface {

  /**
   * Constructs a RegisterEventSubscribersPass object.
   *
   * @param \Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass $pass
   *   The Symfony compiler pass that registers event subscribers.
   */
  public function __construct(
    protected RegisterListenersPass $pass
  ) {}

  /**
   * {@inheritdoc}
   */
  public function process(ContainerBuilder $container): void {
    if (!$container->hasDefinition('event_dispatcher')) {
      return;
    $this->renameTag($container, 'event_subscriber', 'kernel.event_subscriber');
    $this->pass->process($container);
    $this->renameTag($container, 'kernel.event_subscriber', 'event_subscriber');
  }

    $definition = $container->getDefinition('event_dispatcher');

    $event_subscriber_info = [];
    foreach ($container->findTaggedServiceIds('event_subscriber') as $id => $attributes) {

      // We must assume that the class value has been correctly filled, even if
      // the service is created by a factory.
      $class = $container->getDefinition($id)->getClass();

      $interface = EventSubscriberInterface::class;
      if (!is_subclass_of($class, $interface)) {
        throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
      }

      // Get all subscribed events.
      foreach ($class::getSubscribedEvents() as $event_name => $params) {
        if (is_string($params)) {
          $priority = 0;
          $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params]];
        }
        elseif (is_string($params[0])) {
          $priority = $params[1] ?? 0;
          $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $params[0]]];
        }
        else {
          foreach ($params as $listener) {
            $priority = $listener[1] ?? 0;
            $event_subscriber_info[$event_name][$priority][] = ['service' => [$id, $listener[0]]];
          }
        }
      }
  /**
   * Renames tags in the container.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
   *   The container.
   * @param string $source_tag
   *   The tag to be renamed.
   * @param string $target_tag
   *   The tag to rename with.
   */
  protected function renameTag(ContainerBuilder $container, string $source_tag, string $target_tag): void {
    foreach ($container->getDefinitions() as $definition) {
      if ($definition->hasTag($source_tag)) {
        $attributes = $definition->getTag($source_tag)[0];
        $definition->addTag($target_tag, $attributes);
        $definition->clearTag($source_tag);
      }

    foreach (array_keys($event_subscriber_info) as $event_name) {
      krsort($event_subscriber_info[$event_name]);
    }

    $definition->addArgument($event_subscriber_info);
  }

}
+3 −3
Original line number Diff line number Diff line
@@ -4,7 +4,6 @@

namespace Drupal\Tests\layout_builder\Unit;

use Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher;
use Drupal\Component\Plugin\Exception\PluginException;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Block\BlockManagerInterface;
@@ -24,6 +23,7 @@
use Drupal\layout_builder\SectionComponent;
use Drupal\Tests\UnitTestCase;
use Prophecy\Argument;
use Symfony\Component\EventDispatcher\EventDispatcher;

/**
 * @coversDefaultClass \Drupal\layout_builder\Section
@@ -62,7 +62,7 @@ class SectionRenderTest extends UnitTestCase {
  /**
   * The event dispatcher.
   *
   * @var \Drupal\Component\EventDispatcher\ContainerAwareEventDispatcher
   * @var \Symfony\Component\EventDispatcher\EventDispatcher
   */
  protected $eventDispatcher;

@@ -77,7 +77,7 @@ protected function setUp(): void {
    $this->contextHandler = $this->prophesize(ContextHandlerInterface::class);
    $this->contextRepository = $this->prophesize(ContextRepositoryInterface::class);
    // @todo Refactor this into some better tests in https://www.drupal.org/node/2942605.
    $this->eventDispatcher = (new \ReflectionClass(ContainerAwareEventDispatcher::class))->newInstanceWithoutConstructor();
    $this->eventDispatcher = (new \ReflectionClass(EventDispatcher::class))->newInstanceWithoutConstructor();

    $this->account = $this->prophesize(AccountInterface::class);
    $subscriber = new BlockComponentRenderArray($this->account->reveal());
Loading