Commit d2aa0ac4 authored by catch's avatar catch
Browse files

feat: #2066993 Use magic methods to sync container property to...

feat: #2066993 Use magic methods to sync container property to \Drupal::getContainer in functional tests

By: @andypost
By: @Mile23
By: @joelpittet
By: @alexpott
By: @catch
By: @berdir
By: @quietone
By: @benjifisher
By: @voleger
By: @mstrelan
By: @acbramley
By: @godotislate
By: @mondrake
By: @tim.plunkett
By: @longwave
(cherry picked from commit e8887b0e)
parent e69616b2
Loading
Loading
Loading
Loading
Loading
+42 −3
Original line number Diff line number Diff line
@@ -2,10 +2,13 @@

namespace Drupal\Core\Test;

use Drupal\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Database\Database;

/**
 * Provides a trait for shared test setup functionality.
 *
 * @property \Drupal\Component\DependencyInjection\ContainerInterface $container
 */
trait TestSetupTrait {

@@ -26,11 +29,11 @@ trait TestSetupTrait {
  ];

  /**
   * The dependency injection container used in the test.
   * Stores the container in case it is set before available with \Drupal.
   *
   * @var \Symfony\Component\DependencyInjection\ContainerInterface
   * @see \Drupal::getContainer()
   */
  protected $container;
  private ?ContainerInterface $privateContainer = NULL;

  /**
   * The site directory of this test run.
@@ -194,4 +197,40 @@ protected function getConfigSchemaExclusions() {
    return array_unique(array_merge(...$exceptions));
  }

  /**
   * Implements the magic method for getting object properties.
   *
   * Ensures \Drupal::getContainer() is used when getting the container
   * property, if possible.
   */
  public function __get($name): mixed {
    if ($name === 'container') {
      return \Drupal::hasContainer() ? \Drupal::getContainer() : $this->privateContainer;
    }

    trigger_error('Undefined property ' . __CLASS__ . "::\${$name}", E_USER_WARNING);
    return NULL;
  }

  /**
   * Implements the magic method for setting object properties.
   *
   * Ensures \Drupal::getContainer() is used when getting the container
   * property, if possible.
   */
  public function __set($name, $value): void {
    if ($name === 'container') {
      $this->privateContainer = $value;
      return;
    }

    // This deprecation message is intended to match the one PHP 8.2+ emits for
    // dynamic properties. The magic setter and this deprecation message will
    // be removed once property hooks can be used.
    // @see https://www.drupal.org/project/drupal/issues/3558863
    // @phpcs:ignore Drupal.Semantics.FunctionTriggerError.TriggerErrorTextLayoutRelaxed
    trigger_error('Creation of dynamic property ' . __CLASS__ . "::\${$name} is deprecated", E_USER_DEPRECATED);
    $this->$name = $value;
  }

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

namespace Drupal\FunctionalTests\Installer;

use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Language\Language;
use Drupal\Core\Session\UserSession;
@@ -13,7 +14,6 @@
use Drupal\Tests\BrowserTestBase;
use Drupal\Tests\RequirementsPageTrait;
use GuzzleHttp\HandlerStack;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
@@ -123,7 +123,7 @@ public function installDrupal() {
    // @see install_begin_request()
    $request = Request::create($GLOBALS['base_url'] . '/core/install.php', 'GET', [], $_COOKIE, [], $_SERVER);
    $request->setSession(new Session(new MockArraySessionStorage()));
    $this->container = new ContainerBuilder();
    \Drupal::setContainer(new ContainerBuilder());
    $request_stack = new RequestStack();
    $request_stack->push($request);
    $this->container
@@ -150,7 +150,6 @@ public function installDrupal() {

    $this->container
      ->setParameter('app.root', DRUPAL_ROOT);
    \Drupal::setContainer($this->container);
  }

  /**