From 527282d27f9dca63e5f9a17e5ffe3fba7aaba072 Mon Sep 17 00:00:00 2001
From: "christian.wiedemann"
 <7688-Christian.wiedemann@users.noreply.drupalcode.org>
Date: Thu, 28 Nov 2024 15:44:16 +0000
Subject: [PATCH] Issue #3469808 by christian.wiedemann, pdureau: Use decorator
 instead overwriting the component plugin service

---
 .../src/Kernel/TwigValidatorTestBase.php      |  2 +-
 .../tests/src/Kernel/ValidatorTest.php        |  2 +-
 .../FieldFormatter/ComponentFormatterBase.php |  5 +-
 .../src/Plugin/Derivative/ComponentLayout.php |  6 +-
 .../tests/src/Kernel/SourcesDeriverTest.php   |  3 +-
 src/ComponentPluginManager.php                | 78 +++++++++++++++----
 src/Element/ComponentForm.php                 |  1 +
 .../src/Kernel/ComponentPluginManagerTest.php |  7 +-
 tests/src/Traits/RunSourcePluginTestTrait.php |  2 +-
 ui_patterns.services.yml                      | 26 +++----
 10 files changed, 92 insertions(+), 40 deletions(-)

diff --git a/modules/ui_patterns_devel/tests/src/Kernel/TwigValidatorTestBase.php b/modules/ui_patterns_devel/tests/src/Kernel/TwigValidatorTestBase.php
index 33dad2929..d0f83a320 100644
--- a/modules/ui_patterns_devel/tests/src/Kernel/TwigValidatorTestBase.php
+++ b/modules/ui_patterns_devel/tests/src/Kernel/TwigValidatorTestBase.php
@@ -4,8 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\ui_patterns_devel\Kernel;
 
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
-use Drupal\ui_patterns\ComponentPluginManager;
 use Drupal\ui_patterns_devel\TwigValidator\TwigValidator;
 
 /**
diff --git a/modules/ui_patterns_devel/tests/src/Kernel/ValidatorTest.php b/modules/ui_patterns_devel/tests/src/Kernel/ValidatorTest.php
index bb53f30a2..af9462d86 100644
--- a/modules/ui_patterns_devel/tests/src/Kernel/ValidatorTest.php
+++ b/modules/ui_patterns_devel/tests/src/Kernel/ValidatorTest.php
@@ -4,8 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\ui_patterns_devel\Kernel;
 
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\Tests\Core\Theme\Component\ComponentKernelTestBase;
-use Drupal\ui_patterns\ComponentPluginManager;
 use Drupal\ui_patterns_devel\DefinitionValidator;
 use Drupal\ui_patterns_devel\TwigValidator\TwigValidator;
 use Drupal\ui_patterns_devel\Validator;
diff --git a/modules/ui_patterns_field_formatters/src/Plugin/Field/FieldFormatter/ComponentFormatterBase.php b/modules/ui_patterns_field_formatters/src/Plugin/Field/FieldFormatter/ComponentFormatterBase.php
index abeb167e0..9783aa7d9 100644
--- a/modules/ui_patterns_field_formatters/src/Plugin/Field/FieldFormatter/ComponentFormatterBase.php
+++ b/modules/ui_patterns_field_formatters/src/Plugin/Field/FieldFormatter/ComponentFormatterBase.php
@@ -11,6 +11,7 @@ use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Context\EntityContext;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\ui_patterns\Form\ComponentSettingsFormBuilderTrait;
 use Drupal\ui_patterns\Plugin\Context\RequirementsContext;
 use Drupal\ui_patterns\SourcePluginBase;
@@ -26,9 +27,9 @@ abstract class ComponentFormatterBase extends FormatterBase {
   /**
    * The component plugin manager.
    *
-   * @var \Drupal\ui_patterns\ComponentPluginManager
+   * @var \Drupal\Core\Theme\ComponentPluginManager
    */
-  protected $componentPluginManager;
+  protected ComponentPluginManager $componentPluginManager;
 
   /**
    * The entity type manager.
diff --git a/modules/ui_patterns_layouts/src/Plugin/Derivative/ComponentLayout.php b/modules/ui_patterns_layouts/src/Plugin/Derivative/ComponentLayout.php
index e5123e127..41c47bcee 100644
--- a/modules/ui_patterns_layouts/src/Plugin/Derivative/ComponentLayout.php
+++ b/modules/ui_patterns_layouts/src/Plugin/Derivative/ComponentLayout.php
@@ -8,7 +8,7 @@ use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\Layout\LayoutDefinition;
 use Drupal\Core\Plugin\Context\ContextDefinition;
 use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
-use Drupal\ui_patterns\ComponentPluginManager;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\Filesystem\Filesystem as SymfonyFilesystem;
 use Symfony\Component\Filesystem\Path;
@@ -23,7 +23,7 @@ class ComponentLayout extends DeriverBase implements ContainerDeriverInterface {
   /**
    * Constructs new ComponentLayout Deriver.
    *
-   * @param \Drupal\ui_patterns\ComponentPluginManager $pluginManager
+   * @param \Drupal\Core\Theme\ComponentPluginManager $pluginManager
    *   The component plugin manager.
    * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
    *   The module handler.
@@ -48,7 +48,9 @@ class ComponentLayout extends DeriverBase implements ContainerDeriverInterface {
    * {@inheritdoc}
    */
   public function getDerivativeDefinitions($base_plugin_definition) {
+    /* @phpstan-ignore method.notFound */
     $components = $this->pluginManager->getSortedDefinitions();
+
     foreach ($components as $component) {
       $component_instance = $this->pluginManager->find($component['id']);
       /** @var \Drupal\Core\Layout\LayoutDefinition $base_plugin_definition */
diff --git a/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php b/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php
index 48b0cc852..148b13db4 100644
--- a/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php
+++ b/modules/ui_patterns_layouts/tests/src/Kernel/SourcesDeriverTest.php
@@ -34,7 +34,7 @@ class SourcesDeriverTest extends SourcePluginsTestBase {
   /**
    * The component plugin manager.
    *
-   * @var \Drupal\ui_patterns\ComponentPluginManager
+   * @var \Drupal\Core\Theme\ComponentPluginManager
    */
   protected $componentManager;
 
@@ -51,6 +51,7 @@ class SourcesDeriverTest extends SourcePluginsTestBase {
    * Tests creating fields of all types on a content type.
    */
   public function testDerivedPluginPerComponent() {
+    /* @phpstan-ignore method.notFound */
     $components = $this->componentManager->getSortedDefinitions();
     foreach ($components as $component) {
       $component_instance = $this->componentManager->find($component['id']);
diff --git a/src/ComponentPluginManager.php b/src/ComponentPluginManager.php
index dc83d9cc0..0fc0d6c25 100644
--- a/src/ComponentPluginManager.php
+++ b/src/ComponentPluginManager.php
@@ -8,7 +8,6 @@ use Drupal\Component\Plugin\CategorizingPluginManagerInterface;
 use Drupal\Component\Plugin\Definition\PluginDefinitionInterface;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\ConfigFactoryInterface;
-use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\File\FileSystemInterface;
@@ -17,6 +16,7 @@ use Drupal\Core\Theme\Component\ComponentValidator;
 use Drupal\Core\Theme\Component\SchemaCompatibilityChecker;
 use Drupal\Core\Theme\ComponentNegotiator;
 use Drupal\Core\Theme\ComponentPluginManager as SdcPluginManager;
+use Drupal\Core\Theme\ComponentPluginManager as CoreComponentPluginManager;
 use Drupal\Core\Theme\ThemeManagerInterface;
 use Drupal\ui_patterns\SchemaManager\ReferencesResolver;
 
@@ -26,12 +26,48 @@ use Drupal\ui_patterns\SchemaManager\ReferencesResolver;
 class ComponentPluginManager extends SdcPluginManager implements CategorizingPluginManagerInterface {
 
   /**
-   * Cache key prefix to use in the cache backend.
+   * The prop type plugin manager.
    */
-  const CACHE_KEY = 'ui_patterns';
+  protected PropTypePluginManager $propTypePluginManager;
 
   /**
-   * {@inheritdoc}
+   * The prop type adapter plugin manager.
+   */
+  protected PropTypeAdapterPluginManager $propTypeAdapterPluginManager;
+
+  /**
+   * The reference resolver.
+   */
+  protected CoreComponentPluginManager $componentPluginManager;
+
+  /**
+   * The reference resolver.
+   */
+  protected ReferencesResolver $referencesSolver;
+
+  /**
+   * Constructs ComponentPluginManager object.
+   *
+   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
+   *   The module handler.
+   * @param \Drupal\Core\Extension\ThemeHandlerInterface $themeHandler
+   *   The theme handler.
+   * @param \Drupal\Core\Cache\CacheBackendInterface $cacheBackend
+   *   Cache backend instance to use.
+   * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory
+   *   The configuration factory.
+   * @param \Drupal\Core\Theme\ThemeManagerInterface $themeManager
+   *   The theme manager.
+   * @param \Drupal\Core\Theme\ComponentNegotiator $componentNegotiator
+   *   The component negotiator.
+   * @param \Drupal\Core\File\FileSystemInterface $fileSystem
+   *   The file system service.
+   * @param \Drupal\Core\Theme\Component\SchemaCompatibilityChecker $compatibilityChecker
+   *   The compatibility checker.
+   * @param \Drupal\Core\Theme\Component\ComponentValidator $componentValidator
+   *   The component validator.
+   * @param string $appRoot
+   *   The application root.
    */
   public function __construct(
     ModuleHandlerInterface $module_handler,
@@ -44,10 +80,6 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu
     SchemaCompatibilityChecker $compatibilityChecker,
     ComponentValidator $componentValidator,
     string $appRoot,
-    protected PropTypePluginManager $propTypePluginManager,
-    protected PropTypeAdapterPluginManager $prop_type_adapterPluginManager,
-    protected ReferencesResolver $referencesSolver,
-    ModuleExtensionList $moduleExtensionList,
   ) {
     parent::__construct(
       $module_handler,
@@ -59,17 +91,37 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu
       $fileSystem,
       $compatibilityChecker,
       $componentValidator,
-      $appRoot
-    );
-    $this->moduleExtensionList = $moduleExtensionList;
+      $appRoot);
     $this->alterInfo('component_info');
-    $this->setCacheBackend($cacheBackend, self::CACHE_KEY);
+    $this->setCacheBackend($cacheBackend, 'component_plugins');
+  }
+
+  /**
+   * Sets the prop type plugin manager.
+   */
+  public function setPropTypePluginManager(PropTypePluginManager $propTypePluginManager): void {
+    $this->propTypePluginManager = $propTypePluginManager;
+  }
+
+  /**
+   * Sets the prop type adapter plugin manager.
+   */
+  public function setPropTypePluginAdapter(PropTypeAdapterPluginManager $propTypeAdapterPluginManager): void {
+    $this->propTypeAdapterPluginManager = $propTypeAdapterPluginManager;
+  }
+
+  /**
+   * Sets reference resolver.
+   */
+  public function setReferenceSolver(ReferencesResolver $referencesSolver): void {
+    $this->referencesSolver = $referencesSolver;
   }
 
   /**
    * {@inheritdoc}
    */
   protected function alterDefinition(array $definition): array {
+
     // Overriding SDC alterDefinition method.
     $definition = parent::alterDefinition($definition);
     // Adding custom logic.
@@ -163,7 +215,7 @@ class ComponentPluginManager extends SdcPluginManager implements CategorizingPlu
       // the compatibility checker, but close enough to address the same
       // sources as an existing prop type with only some small unidirectional
       // transformation of the data. So, we need an adapter plugin.
-      $prop_type_adapter = $this->prop_type_adapterPluginManager->guessFromSchema($prop);
+      $prop_type_adapter = $this->propTypeAdapterPluginManager->guessFromSchema($prop);
       if ($prop_type_adapter) {
         $prop_type_id = $prop_type_adapter->getPropTypeId();
         $prop_type = $this->propTypePluginManager->createInstance($prop_type_id);
diff --git a/src/Element/ComponentForm.php b/src/Element/ComponentForm.php
index ec3a35a78..223017ddf 100644
--- a/src/Element/ComponentForm.php
+++ b/src/Element/ComponentForm.php
@@ -207,6 +207,7 @@ class ComponentForm extends ComponentFormBase {
     ?string $wrapper_id,
     ?string $selected_component_id,
   ): array {
+    /* @phpstan-ignore method.notFound */
     $definitions = \Drupal::service("plugin.manager.sdc")->getGroupedDefinitions();
     $options = [];
     foreach ($definitions as $group_id => $group) {
diff --git a/tests/src/Kernel/ComponentPluginManagerTest.php b/tests/src/Kernel/ComponentPluginManagerTest.php
index 3a32c4aa5..e07e47c7e 100644
--- a/tests/src/Kernel/ComponentPluginManagerTest.php
+++ b/tests/src/Kernel/ComponentPluginManagerTest.php
@@ -4,8 +4,8 @@ declare(strict_types=1);
 
 namespace Drupal\Tests\ui_patterns\Kernel;
 
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\KernelTests\KernelTestBase;
-use Drupal\ui_patterns\ComponentPluginManager;
 
 /**
  * Test the ComponentPluginManager service.
@@ -31,7 +31,7 @@ final class ComponentPluginManagerTest extends KernelTestBase {
   /**
    * The component plugin manager from ui_patterns.
    *
-   * @var \Drupal\ui_patterns\ComponentPluginManager
+   * @var \Drupal\Core\Theme\ComponentPluginManager
    */
   protected ComponentPluginManager $manager;
 
@@ -55,6 +55,7 @@ final class ComponentPluginManagerTest extends KernelTestBase {
    * @covers ::getCategories
    */
   public function testGetCategories() : void {
+    /* @phpstan-ignore method.notFound */
     $categories = $this->manager->getCategories();
     $this->assertNotEmpty($categories);
   }
@@ -63,6 +64,7 @@ final class ComponentPluginManagerTest extends KernelTestBase {
    * @covers ::getSortedDefinitions
    */
   public function testGetSortedDefinitions(): void {
+    /* @phpstan-ignore method.notFound */
     $sortedDefinitions = $this->manager->getSortedDefinitions();
     $this->assertNotEmpty($sortedDefinitions);
   }
@@ -71,6 +73,7 @@ final class ComponentPluginManagerTest extends KernelTestBase {
    * @covers ::getGroupedDefinitions
    */
   public function testGetGroupedDefinitions(): void {
+    /* @phpstan-ignore method.notFound */
     $groupedDefinitions = $this->manager->getGroupedDefinitions();
     $this->assertNotEmpty($groupedDefinitions);
   }
diff --git a/tests/src/Traits/RunSourcePluginTestTrait.php b/tests/src/Traits/RunSourcePluginTestTrait.php
index 4384ed36e..d44153f7a 100644
--- a/tests/src/Traits/RunSourcePluginTestTrait.php
+++ b/tests/src/Traits/RunSourcePluginTestTrait.php
@@ -4,7 +4,7 @@ namespace Drupal\Tests\ui_patterns\Traits;
 
 use Drupal\Core\Plugin\Context\Context;
 use Drupal\Core\Plugin\Context\ContextDefinition;
-use Drupal\ui_patterns\ComponentPluginManager;
+use Drupal\Core\Theme\ComponentPluginManager;
 use Drupal\ui_patterns\SourcePluginBase;
 use Drupal\ui_patterns\SourcePluginManager;
 use function PHPUnit\Framework\assertNotNull;
diff --git a/ui_patterns.services.yml b/ui_patterns.services.yml
index 593f10246..e089a47a9 100644
--- a/ui_patterns.services.yml
+++ b/ui_patterns.services.yml
@@ -1,22 +1,14 @@
 services:
   # Plugins managers.
-  plugin.manager.sdc:
-    class: Drupal\ui_patterns\ComponentPluginManager
-    arguments:
-      - "@module_handler"
-      - "@theme_handler"
-      - "@cache.discovery"
-      - "@config.factory"
-      - "@theme.manager"
-      - '@Drupal\Core\Theme\ComponentNegotiator'
-      - "@file_system"
-      - '@Drupal\Core\Theme\Component\SchemaCompatibilityChecker'
-      - '@Drupal\Core\Theme\Component\ComponentValidator'
-      - "%app.root%"
-      - "@plugin.manager.ui_patterns_prop_type"
-      - "@plugin.manager.ui_patterns_prop_type_adapter"
-      - "@ui_patterns.schema_reference_solver"
-      - "@extension.list.module"
+
+  Drupal\ui_patterns\ComponentPluginManager:
+    decorates: plugin.manager.sdc
+    parent: plugin.manager.sdc
+    decoration_priority: 0
+    calls:
+      - [ setPropTypePluginManager, [ '@plugin.manager.ui_patterns_prop_type' ] ]
+      - [ setPropTypePluginAdapter, [ '@plugin.manager.ui_patterns_prop_type_adapter' ] ]
+      - [ setReferenceSolver, [ '@ui_patterns.schema_reference_solver' ] ]
   plugin.manager.ui_patterns_prop_type:
     class: Drupal\ui_patterns\PropTypePluginManager
     parent: default_plugin_manager
-- 
GitLab