From 46397848d136ebb60c03fb89e103846e329b9713 Mon Sep 17 00:00:00 2001
From: Elliot Ward <12770-Eli-T@users.noreply.drupalcode.org>
Date: Mon, 7 Oct 2024 09:18:37 +0000
Subject: [PATCH] Issue #3474619 by eli-t, arousseau: Use
 OptionsProviderInterface to allow options widgets usage.

---
 .../FieldType/TypedResourceObjectItem.php     | 75 ++++++++++++++++---
 1 file changed, 64 insertions(+), 11 deletions(-)

diff --git a/src/Plugin/Field/FieldType/TypedResourceObjectItem.php b/src/Plugin/Field/FieldType/TypedResourceObjectItem.php
index d7f63b1..92c1208 100644
--- a/src/Plugin/Field/FieldType/TypedResourceObjectItem.php
+++ b/src/Plugin/Field/FieldType/TypedResourceObjectItem.php
@@ -6,8 +6,11 @@ use Drupal\Core\Field\FieldDefinitionInterface;
 use Drupal\Core\Field\FieldItemBase;
 use Drupal\Core\Field\FieldStorageDefinitionInterface;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\TranslatableMarkup;
 use Drupal\Core\TypedData\DataDefinition;
+use Drupal\Core\TypedData\OptionsProviderInterface;
+use Drupal\jsonapi_reference\JsonApiClientInterface;
 
 /**
  * Plugin implementation of the 'typed_resource_object' field type.
@@ -21,7 +24,12 @@ use Drupal\Core\TypedData\DataDefinition;
  *   default_widget = "typed_resource_object_autocomplete"
  * )
  */
-class TypedResourceObjectItem extends FieldItemBase {
+class TypedResourceObjectItem extends FieldItemBase implements OptionsProviderInterface {
+
+  /**
+   * The JSON:API client service.
+   */
+  private JsonApiClientInterface $client;
 
   /**
    * {@inheritdoc}
@@ -65,13 +73,7 @@ class TypedResourceObjectItem extends FieldItemBase {
    * {@inheritdoc}
    */
   public function getConstraints(): array {
-    $constraints = parent::getConstraints();
-    $constraint_manager = \Drupal::typedDataManager()->getValidationConstraintManager();
-    // @todo do we know these will all be GUIDs? What about a non-Drupal
-    // jsonapi implementation?
-    $constraints[] = $constraint_manager->create('Uuid', []);
-
-    return $constraints;
+    return [\Drupal::typedDataManager()->getValidationConstraintManager()->create('Uuid', [])];
   }
 
   /**
@@ -89,9 +91,7 @@ class TypedResourceObjectItem extends FieldItemBase {
   public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data): array {
     $elements = [];
 
-    /** @var \Drupal\jsonapi_reference\JsonApiClientInterface $client */
-    $client = \Drupal::service('jsonapi_reference.jsonapi_client');
-    $types = $client->listResourceObjectTypes();
+    $types = $this->client()->listResourceObjectTypes();
 
     $elements['resource_object_type'] = [
       '#type' => 'select',
@@ -124,6 +124,20 @@ class TypedResourceObjectItem extends FieldItemBase {
     return $value === NULL || $value === '';
   }
 
+  /**
+   * Gets the JSON:API client service.
+   *
+   * @return \Drupal\jsonapi_reference\JsonApiClientInterface
+   *   The JSON:API client service.
+   */
+  protected function client(): JsonApiClientInterface {
+    if (!isset($this->client)) {
+      $this->client = \Drupal::service('jsonapi_reference.jsonapi_client');
+    }
+
+    return $this->client;
+  }
+
   /**
    * Automatically cast field to a string.
    *
@@ -138,4 +152,43 @@ class TypedResourceObjectItem extends FieldItemBase {
     return $this->get('value')->getValue();
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getPossibleValues(?AccountInterface $account = NULL): array {
+    return $this->getSettableValues($account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPossibleOptions(?AccountInterface $account = NULL): array {
+    return $this->getSettableOptions($account);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSettableValues(?AccountInterface $account = NULL): array {
+    return array_keys($this->getSettableOptions($account));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getSettableOptions(?AccountInterface $account = NULL): array {
+    $options = $this->client()->search(
+      $this->getSetting('resource_object_type'),
+      $this->getSetting('title_attribute'),
+      NULL
+    );
+
+    $return = [];
+    foreach ($options as $option) {
+      $return[$option[1]] = $option[0];
+    }
+
+    return $return;
+  }
+
 }
-- 
GitLab