Verified Commit aa25d8ff authored by Alex Pott's avatar Alex Pott
Browse files

Issue #3439824 by quietone: Remove deprecated code from assertion,...

Issue #3439824 by quietone: Remove deprecated code from assertion, eventdispatcher and plugin components
parent 5637aff4
Loading
Loading
Loading
Loading
Loading
+0 −32
Original line number Diff line number Diff line
<?php

namespace Drupal\Component\Assertion;

trigger_error(__NAMESPACE__ . '\Handle is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, use assert_options(ASSERT_EXCEPTION, TRUE). See https://www.drupal.org/node/3105918', E_USER_DEPRECATED);

/**
 * Handler for runtime assertion failures.
 *
 * @ingroup php_assert
 *
 * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use
 *   assert_options(ASSERT_EXCEPTION, TRUE).
 *
 * @see https://www.drupal.org/node/3105918
 */
class Handle {

  /**
   * Ensures exceptions are thrown when an assertion fails.
   */
  public static function register() {
    // Since we're using exceptions, turn error warnings off.
    // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
    assert_options(ASSERT_WARNING, FALSE);

    // Turn exception throwing on.
    // phpcs:ignore Generic.PHP.DeprecatedFunctions.Deprecated
    assert_options(ASSERT_EXCEPTION, TRUE);
  }

}
+0 −19
Original line number Diff line number Diff line
@@ -18,25 +18,6 @@
 */
class Inspector {

  /**
   * Asserts argument can be traversed with foreach.
   *
   * @param mixed $traversable
   *   Variable to be examined.
   *
   * @return bool
   *   TRUE if $traversable can be traversed with foreach.
   *
   * @deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use
   *   is_iterable() instead.
   *
   * @see https://www.drupal.org/node/3422775
   */
  public static function assertTraversable($traversable) {
    @trigger_error(__METHOD__ . '() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use is_iterable() instead. See https://www.drupal.org/node/3422775', E_USER_DEPRECATED);
    return is_iterable($traversable);
  }

  /**
   * Asserts callback returns TRUE for each member of a traversable.
   *
+0 −298
Original line number Diff line number Diff line
<?php

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;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

/**
 * A performance optimized container aware event dispatcher.
 *
 * This version of the event dispatcher contains the following optimizations
 * in comparison to the Symfony event dispatcher component:
 *
 * <dl>
 *   <dt>Faster instantiation of the event dispatcher service</dt>
 *   <dd>
 *     Instead of calling <code>addSubscriberService</code> once for each
 *     subscriber, a pre-compiled array of listener definitions is passed
 *     directly to the constructor. This is faster by roughly an order of
 *     magnitude. The listeners are collected and prepared using a compiler
 *     pass.
 *   </dd>
 *   <dt>Lazy instantiation of listeners</dt>
 *   <dd>
 *     Services are only retrieved from the container just before invocation.
 *     Especially when dispatching the KernelEvents::REQUEST event, this leads
 *     to a more timely invocation of the first listener. Overall dispatch
 *     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 {

  /**
   * The service container.
   *
   * @var \Symfony\Component\DependencyInjection\ContainerInterface
   */
  protected $container;

  /**
   * Listener definitions.
   *
   * A nested array of listener definitions keyed by event name and priority.
   * A listener definition is an associative array with one of the following key
   * value pairs:
   * - callable: A callable listener
   * - service: An array of the form [service id, method]
   *
   * A service entry will be resolved to a callable only just before its
   * invocation.
   *
   * @var array
   */
  protected $listeners;

  /**
   * Whether listeners need to be sorted prior to dispatch, keyed by event name.
   *
   * @var TRUE[]
   */
  protected $unsorted;

  /**
   * Constructs a container aware event dispatcher.
   *
   * @param \Symfony\Component\DependencyInjection\ContainerInterface $container
   *   The service container.
   * @param array $listeners
   *   A nested array of listener definitions keyed by event name and priority.
   *   The array is expected to be ordered by priority. A listener definition is
   *   an associative array with one of the following key value pairs:
   *   - callable: A callable listener
   *   - service: An array of the form [service id, method]
   *   A service entry will be resolved to a callable only just before its
   *   invocation.
   */
  public function __construct(ContainerInterface $container, array $listeners = []) {
    $this->container = $container;
    $this->listeners = $listeners;
    $this->unsorted = [];
  }

  /**
   * {@inheritdoc}
   */
  public function dispatch(object $event, ?string $eventName = NULL): object {
    $event_name = $eventName ?? get_class($event);

    if (isset($this->listeners[$event_name])) {
      // Sort listeners if necessary.
      if (isset($this->unsorted[$event_name])) {
        krsort($this->listeners[$event_name]);
        unset($this->unsorted[$event_name]);
      }

      $stoppable = $event instanceof StoppableEventInterface;

      // Invoke listeners and resolve callables if necessary.
      foreach ($this->listeners[$event_name] as &$definitions) {
        foreach ($definitions as &$definition) {
          if (!isset($definition['callable'])) {
            $definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
          }
          if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
            $definition['callable'][0] = $definition['callable'][0]();
          }

          call_user_func($definition['callable'], $event, $event_name, $this);
          if ($stoppable && $event->isPropagationStopped()) {
            return $event;
          }
        }
      }
    }

    return $event;
  }

  /**
   * {@inheritdoc}
   */
  public function getListeners($event_name = NULL): array {
    $result = [];

    if ($event_name === NULL) {
      // If event name was omitted, collect all listeners of all events.
      foreach (array_keys($this->listeners) as $event_name) {
        $listeners = $this->getListeners($event_name);
        if (!empty($listeners)) {
          $result[$event_name] = $listeners;
        }
      }
    }
    elseif (isset($this->listeners[$event_name])) {
      // Sort listeners if necessary.
      if (isset($this->unsorted[$event_name])) {
        krsort($this->listeners[$event_name]);
        unset($this->unsorted[$event_name]);
      }

      // Collect listeners and resolve callables if necessary.
      foreach ($this->listeners[$event_name] as &$definitions) {
        foreach ($definitions as &$definition) {
          if (!isset($definition['callable'])) {
            $definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
          }
          if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
            $definition['callable'][0] = $definition['callable'][0]();
          }

          $result[] = $definition['callable'];
        }
      }
    }

    return $result;
  }

  /**
   * {@inheritdoc}
   */
  public function getListenerPriority($event_name, $listener): ?int {
    if (!isset($this->listeners[$event_name])) {
      return NULL;
    }
    if (is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
      $listener[0] = $listener[0]();
    }
    // Resolve service definitions if the listener has not been found so far.
    foreach ($this->listeners[$event_name] as $priority => &$definitions) {
      foreach ($definitions as &$definition) {
        if (!isset($definition['callable'])) {
          // Once the callable is retrieved we keep it for subsequent method
          // invocations on this class.
          $definition['callable'] = [
            $this->container->get($definition['service'][0]),
            $definition['service'][1],
          ];
        }
        if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure) {
          $definition['callable'][0] = $definition['callable'][0]();
        }
        if ($definition['callable'] === $listener) {
          return $priority;
        }
      }
    }
    return NULL;
  }

  /**
   * {@inheritdoc}
   */
  public function hasListeners($event_name = NULL): bool {
    if ($event_name !== NULL) {
      return !empty($this->listeners[$event_name]);
    }

    foreach ($this->listeners as $event_listeners) {
      if ($event_listeners) {
        return TRUE;
      }
    }

    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function addListener($event_name, $listener, $priority = 0): void {
    $this->listeners[$event_name][$priority][] = ['callable' => $listener];
    $this->unsorted[$event_name] = TRUE;
  }

  /**
   * {@inheritdoc}
   */
  public function removeListener($event_name, $listener): void {
    if (!isset($this->listeners[$event_name])) {
      return;
    }

    foreach ($this->listeners[$event_name] as $priority => $definitions) {
      foreach ($definitions as $key => $definition) {
        if (!isset($definition['callable'])) {
          if (!$this->container->initialized($definition['service'][0])) {
            continue;
          }
          $definition['callable'] = [$this->container->get($definition['service'][0]), $definition['service'][1]];
        }

        if (is_array($definition['callable']) && isset($definition['callable'][0]) && $definition['callable'][0] instanceof \Closure && !$listener instanceof \Closure) {
          $definition['callable'][0] = $definition['callable'][0]();
        }

        if (is_array($definition['callable']) && isset($definition['callable'][0]) && !$definition['callable'][0] instanceof \Closure && is_array($listener) && isset($listener[0]) && $listener[0] instanceof \Closure) {
          $listener[0] = $listener[0]();
        }
        if ($definition['callable'] === $listener) {
          unset($definitions[$key]);
        }
      }
      if ($definitions) {
        $this->listeners[$event_name][$priority] = $definitions;
      }
      else {
        unset($this->listeners[$event_name][$priority]);
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function addSubscriber(EventSubscriberInterface $subscriber): void {
    foreach ($subscriber->getSubscribedEvents() as $event_name => $params) {
      if (is_string($params)) {
        $this->addListener($event_name, [$subscriber, $params]);
      }
      elseif (is_string($params[0])) {
        $this->addListener($event_name, [$subscriber, $params[0]], $params[1] ?? 0);
      }
      else {
        foreach ($params as $listener) {
          $this->addListener($event_name, [$subscriber, $listener[0]], $listener[1] ?? 0);
        }
      }
    }
  }

  /**
   * {@inheritdoc}
   */
  public function removeSubscriber(EventSubscriberInterface $subscriber): void {
    foreach ($subscriber->getSubscribedEvents() as $event_name => $params) {
      if (is_array($params) && is_array($params[0])) {
        foreach ($params as $listener) {
          $this->removeListener($event_name, [$subscriber, $listener[0]]);
        }
      }
      else {
        $this->removeListener($event_name, [$subscriber, is_string($params) ? $params : $params[0]]);
      }
    }
  }

}
+0 −30
Original line number Diff line number Diff line
<?php

namespace Drupal\Component\Plugin;

@trigger_error('The ' . __NAMESPACE__ . '\PluginHelper is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, use instanceof() to check for \Drupal\Component\Plugin\ConfigurableInterface. See https://www.drupal.org/node/3198285', E_USER_DEPRECATED);

/**
 * A helper class to determine if a plugin is configurable.
 *
 * @deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Instead, use
 *   instanceof() to check for \Drupal\Component\Plugin\ConfigurableInterface.
 *
 * @see https://www.drupal.org/node/3198285
 */
class PluginHelper {

  /**
   * Determines if a plugin is configurable.
   *
   * @param mixed $plugin
   *   The plugin to check.
   *
   * @return bool
   *   A boolean indicating whether the plugin is configurable.
   */
  public static function isConfigurable($plugin) {
    return $plugin instanceof ConfigurableInterface;
  }

}
+0 −15
Original line number Diff line number Diff line
@@ -16,21 +16,6 @@ class InspectorTest extends TestCase {

  use ExpectDeprecationTrait;

  /**
   * Tests asserting argument is an array or traversable object.
   *
   * @covers ::assertTraversable
   *
   * @group legacy
   */
  public function testAssertTraversable() {
    $this->expectDeprecation('Drupal\Component\Assertion\Inspector::assertTraversable() is deprecated in drupal:10.3.0 and is removed from drupal:11.0.0. Use is_iterable() instead. See https://www.drupal.org/node/3422775');
    $this->assertTrue(Inspector::assertTraversable([]));
    $this->assertTrue(Inspector::assertTraversable(new \ArrayObject()));
    $this->assertFalse(Inspector::assertTraversable(new \stdClass()));
    $this->assertFalse(Inspector::assertTraversable('foo'));
  }

  /**
   * Tests asserting all members are strings.
   *
Loading