From aa2c1662178de52458145e19d01d499d91b17b9c Mon Sep 17 00:00:00 2001
From: Christian Wiedemann <christian.wiedemann@key-tec.de>
Date: Thu, 20 Mar 2025 16:47:18 +0100
Subject: [PATCH] Add Generic entity field

---
 .../CustomEntityFieldSourceDeriver.php        | 41 +++++++++++++++
 .../EntityFieldSourceDeriverBase.php          |  1 +
 .../UiPatterns/Source/EntityFieldFoo.php      | 50 +++++++++++++++++++
 3 files changed, 92 insertions(+)
 create mode 100644 src/Plugin/Derivative/CustomEntityFieldSourceDeriver.php
 create mode 100644 tests/modules/ui_patterns_test/src/Plugin/UiPatterns/Source/EntityFieldFoo.php

diff --git a/src/Plugin/Derivative/CustomEntityFieldSourceDeriver.php b/src/Plugin/Derivative/CustomEntityFieldSourceDeriver.php
new file mode 100644
index 00000000..018a9583
--- /dev/null
+++ b/src/Plugin/Derivative/CustomEntityFieldSourceDeriver.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\ui_patterns\Plugin\Derivative;
+
+use Drupal\Component\Plugin\PluginBase;
+use Drupal\Core\Plugin\Context\ContextDefinition;
+
+/**
+ * Provides Plugin for every field property of type ui_patterns_source.
+ */
+class CustomEntityFieldSourceDeriver extends EntityFieldSourceDeriverBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getDerivativeDefinitionsForEntityStorageField(string $entity_type_id, string $field_name, array $base_plugin_derivative): void {
+    $id = implode(PluginBase::DERIVATIVE_SEPARATOR, [
+      $entity_type_id,
+      $field_name,
+    ]);
+    $field_type = $this->entityFieldsMetadata[$entity_type_id]["field_storages"][$field_name]["metadata"]["type"];
+    $target_field_types = $base_plugin_derivative['metadata']['parent_plugin_definition']['metadata']['field_type'] ?? [];
+    if (in_array($field_type, $target_field_types)) {
+      $this->derivatives[$id] = array_merge(
+        $base_plugin_derivative,
+        [
+          "label" => $base_plugin_derivative['metadata']['parent_plugin_definition']['label'],
+          "id" => $id,
+          "tags" => array_merge($base_plugin_derivative["tags"], $target_field_types),
+        ]);
+      $field_storage_data = $this->entityFieldsMetadata[$entity_type_id]["field_storages"][$field_name];
+      $bundle_context_for_properties = (new ContextDefinition('string'))
+        ->setRequired()
+        ->setLabel("Bundle")
+        ->addConstraint('AllowedValues', array_merge($field_storage_data["bundles"] ?? [], [""]));
+      $this->derivatives[$id]["context_definitions"]["bundle"] = $bundle_context_for_properties;
+    }
+
+  }
+
+}
\ No newline at end of file
diff --git a/src/Plugin/Derivative/EntityFieldSourceDeriverBase.php b/src/Plugin/Derivative/EntityFieldSourceDeriverBase.php
index ea8aa143..700dbc10 100644
--- a/src/Plugin/Derivative/EntityFieldSourceDeriverBase.php
+++ b/src/Plugin/Derivative/EntityFieldSourceDeriverBase.php
@@ -440,6 +440,7 @@ abstract class EntityFieldSourceDeriverBase extends DeriverBase implements Conta
           "field" => $field_storage_data["metadata"],
           'field_name' => $field_name,
           "entity_type_id" => $entity_type_id,
+          "parent_plugin_definition" => $base_plugin_definition
         ],
         'context_requirements' => [],
         'config_dependencies' => array_merge($base_plugin_definition['config_dependencies'], $field_storage_data['config_dependencies']),
diff --git a/tests/modules/ui_patterns_test/src/Plugin/UiPatterns/Source/EntityFieldFoo.php b/tests/modules/ui_patterns_test/src/Plugin/UiPatterns/Source/EntityFieldFoo.php
new file mode 100644
index 00000000..83ed68b1
--- /dev/null
+++ b/tests/modules/ui_patterns_test/src/Plugin/UiPatterns/Source/EntityFieldFoo.php
@@ -0,0 +1,50 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Drupal\ui_patterns_test\Plugin\UiPatterns\Source;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\StringTranslation\TranslatableMarkup;
+use Drupal\ui_patterns\Attribute\Source;
+use Drupal\ui_patterns\SourcePluginBase;
+use Drupal\ui_patterns\Plugin\Derivative\CustomEntityFieldSourceDeriver;
+
+/**
+ * Plugin implementation of the source_provider.
+ */
+#[Source(
+  id: 'entity_foo',
+  label: new TranslatableMarkup('Foo Field(ui_patterns_test)'),
+  description: new TranslatableMarkup('Foo description.'),
+  prop_types: ['string'],
+  deriver: CustomEntityFieldSourceDeriver::class,
+  metadata:
+  [
+    'field_type' => ['string_long', 'string'],
+  ],
+)]
+final class EntityFieldFoo extends SourcePluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsForm(array $form, FormStateInterface $form_state): array {
+    $form["value"] = [
+      '#type' => 'textfield',
+      '#attributes' => [
+        'placeholder' => $this->t('Test: FOO'),
+      ],
+      '#default_value' => $this->getSetting('value'),
+    ];
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropValue(): mixed {
+    return 'foo ';
+  }
+
+}
-- 
GitLab