From 390e3e008b1505fc1ed742ad7713ee75dedbad7f Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Mon, 11 Oct 2021 16:48:22 +1000
Subject: [PATCH] Issue #3240909 by andypost, alexpott, tim.plunkett: Plugin
 definitions with no class trigger deprecations on PHP 8.1

---
 .../Core/Plugin/DefaultPluginManager.php       |  1 +
 .../src/Unit/SectionStorageManagerTest.php     | 18 +++++++++---------
 .../Core/Layout/LayoutPluginManagerTest.php    |  2 ++
 .../Core/Plugin/DefaultPluginManagerTest.php   |  2 ++
 4 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
index c74fcbe958fb..6b7d86e06631 100644
--- a/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
+++ b/core/lib/Drupal/Core/Plugin/DefaultPluginManager.php
@@ -246,6 +246,7 @@ public function processDefinition(&$definition, $plugin_id) {
 
     // Keep class definitions standard with no leading slash.
     if ($definition instanceof PluginDefinitionInterface) {
+      assert(is_string($definition->getClass()), 'Plugin definitions must have a class');
       $definition->setClass(ltrim($definition->getClass(), '\\'));
     }
     elseif (is_array($definition) && isset($definition['class'])) {
diff --git a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
index ddbe4c7cd75b..0c13e5ddd14e 100644
--- a/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
+++ b/core/modules/layout_builder/tests/src/Unit/SectionStorageManagerTest.php
@@ -126,10 +126,10 @@ public function testLoadNull() {
    */
   public function testFindDefinitions() {
     $this->discovery->getDefinitions()->willReturn([
-      'plugin1' => new SectionStorageDefinition(),
-      'plugin2' => new SectionStorageDefinition(['weight' => -5]),
-      'plugin3' => new SectionStorageDefinition(['weight' => -5]),
-      'plugin4' => new SectionStorageDefinition(['weight' => 10]),
+      'plugin1' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
+      'plugin2' => (new SectionStorageDefinition(['weight' => -5]))->setClass(SectionStorageInterface::class),
+      'plugin3' => (new SectionStorageDefinition(['weight' => -5]))->setClass(SectionStorageInterface::class),
+      'plugin4' => (new SectionStorageDefinition(['weight' => 10]))->setClass(SectionStorageInterface::class),
     ]);
 
     $expected = [
@@ -156,9 +156,9 @@ public function testFindByContext($plugin_is_applicable) {
       'foo' => new Context(new ContextDefinition('foo')),
     ];
     $definitions = [
-      'no_access' => new SectionStorageDefinition(),
-      'missing_contexts' => new SectionStorageDefinition(),
-      'provider_access' => new SectionStorageDefinition(),
+      'no_access' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
+      'missing_contexts' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
+      'provider_access' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
     ];
     $this->discovery->getDefinitions()->willReturn($definitions);
 
@@ -211,8 +211,8 @@ public function testFindByContextCacheableSectionStorage() {
     ];
 
     $definitions = [
-      'first' => new SectionStorageDefinition(),
-      'second' => new SectionStorageDefinition(),
+      'first' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
+      'second' => (new SectionStorageDefinition())->setClass(SectionStorageInterface::class),
     ];
     $this->discovery->getDefinitions()->willReturn($definitions);
 
diff --git a/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php
index 9ca845a0491e..35b7b32b6e40 100644
--- a/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Layout/LayoutPluginManagerTest.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Layout\LayoutDefault;
 use Drupal\Core\Layout\LayoutDefinition;
+use Drupal\Core\Layout\LayoutInterface;
 use Drupal\Core\Layout\LayoutPluginManager;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Tests\UnitTestCase;
@@ -404,6 +405,7 @@ public function getDerivativeDefinitions($base_plugin_definition) {
         'id' => 'invalid_provider',
         'provider' => 'invalid_provider',
       ]);
+      $this->derivatives['invalid_provider']->setClass(LayoutInterface::class);
     }
     return $this->derivatives;
   }
diff --git a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
index c953685a19fe..6504157720b4 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/DefaultPluginManagerTest.php
@@ -511,6 +511,8 @@ class ObjectDefinition extends PluginDefinition {
    * @param array $definition
    */
   public function __construct(array $definition) {
+    // This class does not exist but plugin definitions must provide a class.
+    $this->class = 'PluginObject';
     foreach ($definition as $property => $value) {
       $this->{$property} = $value;
     }
-- 
GitLab