Last active
September 15, 2022 13:17
-
-
Save imcbride/ad84cb06e6a76983ba1a6b69d940a17e to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/config/schema/jsonapi_reference.schema.yml b/config/schema/jsonapi_reference.schema.yml | |
index 98a8eca..5a18a2c 100644 | |
--- a/config/schema/jsonapi_reference.schema.yml | |
+++ b/config/schema/jsonapi_reference.schema.yml | |
@@ -2,13 +2,19 @@ field.storage_settings.typed_resource_object: | |
type: mapping | |
label: 'Typed resource object storage settings' | |
mapping: | |
+ jsonapi_reference_entity: | |
+ type: string | |
+ label: 'Reference entrypoint' | |
resource_object_type: | |
type: string | |
label: 'Resource Object Type' | |
-jsonapi_reference.settings: | |
- type: config_object | |
- label: 'JSON:API reference settings' | |
+jsonapi_reference.settings.*: | |
+ type: config_entity | |
+ label: 'JSON:API reference configuration' | |
mapping: | |
+ id: | |
+ type: string | |
+ label: 'ID' | |
endpoint: | |
type: string | |
label: 'Entrypoint containing JSON:API objects to which we refer' | |
diff --git a/jsonapi_reference.info.yml b/jsonapi_reference.info.yml | |
index 64ce2ea4e9..81c5596bb7 100644 | |
--- a/jsonapi_reference.info.yml | |
+++ b/jsonapi_reference.info.yml | |
@@ -3,7 +3,10 @@ type: module | |
description: 'Provides a field for referencing remote data elements via JSON:API' | |
core_version_requirement: ^8 || ^9 || ^10 | |
package: 'Field types' | |
-configure: jsonapi_reference.json_api_reference_config_form | |
+configure: entity.jsonapi_reference.collection | |
+ | |
+test_dependencies: | |
+ - drupal:jsonapi | |
# Information added by Drupal.org packaging script on 2022-09-13 | |
version: '8.x-1.0-alpha3' | |
diff --git a/jsonapi_reference.install b/jsonapi_reference.install | |
new file mode 100644 | |
index 0000000..6afc14a | |
--- /dev/null | |
+++ b/jsonapi_reference.install | |
@@ -0,0 +1,53 @@ | |
+<?php | |
+ | |
+/** | |
+ * @file | |
+ * jsonapi_reference.install | |
+ */ | |
+ | |
+use Drupal\jsonapi_reference\Entity\JsonApiReference; | |
+use Drupal\field\Entity\FieldStorageConfig; | |
+ | |
+/** | |
+ * Migrate the existing jsonapi_reference configuration to the new format. | |
+ */ | |
+function jsonapi_reference_update_8101() { | |
+ // Calling to flush all caches feels like hammering a nail with a tank. | |
+ // Perhaps this could be more specific to the cache we need to clear for the | |
+ // new entity to be picked up? | |
+ drupal_flush_all_caches(); | |
+ | |
+ /** @var \Drupal\Core\Config\CacheConfig $config_storage */ | |
+ $config_storage = \Drupal::service('config.storage'); | |
+ | |
+ $existing_config = $config_storage->read('jsonapi_reference.settings'); | |
+ | |
+ if ($existing_config['endpoint']) { | |
+ // Create the new config entity. | |
+ JsonApiReference::create([ | |
+ 'id' => 'original_reference', | |
+ 'entrypoint' => $existing_config['endpoint'], | |
+ 'username' => $existing_config['username'], | |
+ 'password' => $existing_config['password'], | |
+ ])->save(); | |
+ | |
+ // Remove the no-longer-used stored configuration. | |
+ $config_storage->delete('jsonapi_reference.settings'); | |
+ | |
+ if (!$field_storage_configs = \Drupal::service('entity_type.manager') | |
+ ->getStorage('field_storage_config') | |
+ ->loadByProperties(['type' => 'typed_resource_object']) | |
+ ) { | |
+ return; | |
+ } | |
+ | |
+ foreach ($field_storage_configs as $field_storage) { | |
+ $new_field_storage = $field_storage->toArray(); | |
+ $new_field_storage['settings']['jsonapi_reference_entity'] = 'original_reference'; | |
+ $new_field_storage = FieldStorageConfig::create($new_field_storage); | |
+ $new_field_storage->original = $new_field_storage; | |
+ $new_field_storage->enforceIsNew(FALSE); | |
+ $new_field_storage->save(); | |
+ } | |
+ } | |
+} | |
\ No newline at end of file | |
diff --git a/jsonapi_reference.links.action.yml b/jsonapi_reference.links.action.yml | |
new file mode 100644 | |
index 0000000..53dac50 | |
--- /dev/null | |
+++ b/jsonapi_reference.links.action.yml | |
@@ -0,0 +1,5 @@ | |
+jsonapi_reference.json_api_reference_add_form: | |
+ route_name: 'entity.jsonapi_reference.add_form' | |
+ title: 'Add JSON:API Reference' | |
+ appears_on: | |
+ - 'entity.jsonapi_reference.collection' | |
diff --git a/jsonapi_reference.links.menu.yml b/jsonapi_reference.links.menu.yml | |
index d623e3c..b0c69f5 100644 | |
--- a/jsonapi_reference.links.menu.yml | |
+++ b/jsonapi_reference.links.menu.yml | |
@@ -1,6 +1,6 @@ | |
-jsonapi_reference.json_api_reference_config_form: | |
+entity.jsonapi_reference.collection: | |
title: 'JSON:API Reference' | |
- route_name: jsonapi_reference.json_api_reference_config_form | |
- description: 'Configure access to the remote JSON:API system for referencing in Typed Resource Object fields.' | |
+ route_name: entity.jsonapi_reference.collection | |
+ description: 'Configure access to remote JSON:API systems for referencing in Typed Resource Object fields.' | |
parent: system.admin_config_services | |
weight: 99 | |
diff --git a/jsonapi_reference.routing.yml b/jsonapi_reference.routing.yml | |
index 29f30ce..4179b6d 100644 | |
--- a/jsonapi_reference.routing.yml | |
+++ b/jsonapi_reference.routing.yml | |
@@ -1,5 +1,5 @@ | |
jsonapi_reference.typed_resource_controller_autocomplete: | |
- path: '/jsonapi-reference/typed-resource-autocomplete/{resource_object_type}/{autocomplete_attribute}' | |
+ path: '/jsonapi-reference/typed-resource-autocomplete/{resource_object_type}/{jsonapi_reference}/{autocomplete_attribute}' | |
defaults: | |
_controller: '\Drupal\jsonapi_reference\Controller\TypedResourceController::autocomplete' | |
_format: json | |
@@ -7,7 +7,7 @@ jsonapi_reference.typed_resource_controller_autocomplete: | |
_permission: 'access jsonapi autocomplete' | |
jsonapi_reference.json_api_reference_config_form: | |
- path: '/admin/config/jsonapi_reference' | |
+ path: '/admin/config/services/jsonapi-reference' | |
defaults: | |
_form: '\Drupal\jsonapi_reference\Form\JsonApiReferenceConfigForm' | |
_title: 'JSON:API Reference' | |
@@ -15,3 +15,35 @@ jsonapi_reference.json_api_reference_config_form: | |
_permission: 'configure jsonapi reference' | |
options: | |
_admin_route: TRUE | |
+ | |
+entity.jsonapi_reference.collection: | |
+ path: '/admin/config/services/jsonapi-reference' | |
+ defaults: | |
+ _entity_list: 'jsonapi_reference' | |
+ _title: 'JSON:API Reference' | |
+ requirements: | |
+ _permission: 'configure jsonapi reference' | |
+ | |
+entity.jsonapi_reference.add_form: | |
+ path: '/admin/config/services/jsonapi-reference/add' | |
+ defaults: | |
+ _entity_form: 'jsonapi_reference.add' | |
+ _title: 'Add JSON:API Reference' | |
+ requirements: | |
+ _permission: 'configure jsonapi reference' | |
+ | |
+entity.jsonapi_reference.edit_form: | |
+ path: '/admin/config/services/jsonapi-reference/{jsonapi_reference}/edit' | |
+ defaults: | |
+ _entity_form: 'jsonapi_reference.edit' | |
+ _title: 'Edit JSON:API Reference' | |
+ requirements: | |
+ _permission: 'configure jsonapi reference' | |
+ | |
+entity.jsonapi_reference.delete_form: | |
+ path: '/admin/config/services/jsonapi-reference/{jsonapi_reference}/delete' | |
+ defaults: | |
+ _entity_form: 'jsonapi_reference.delete' | |
+ _title: 'Delete JSON:API Reference' | |
+ requirements: | |
+ _permission: 'configure jsonapi reference' | |
diff --git a/jsonapi_reference.services.yml b/jsonapi_reference.services.yml | |
index 955090f..67e6e4a 100644 | |
--- a/jsonapi_reference.services.yml | |
+++ b/jsonapi_reference.services.yml | |
@@ -4,4 +4,4 @@ services: | |
arguments: ['JSON:API Reference'] | |
jsonapi_reference.jsonapi_client: | |
class: Drupal\jsonapi_reference\JsonApiClient | |
- arguments: ['@http_client', '@jsonapi_reference.logger_channel', '@config.factory'] | |
+ arguments: ['@http_client', '@jsonapi_reference.logger_channel'] | |
diff --git a/src/Controller/JsonApiReferenceListBuilder.php b/src/Controller/JsonApiReferenceListBuilder.php | |
new file mode 100644 | |
index 0000000..1fe89f6 | |
--- /dev/null | |
+++ b/src/Controller/JsonApiReferenceListBuilder.php | |
@@ -0,0 +1,35 @@ | |
+<?php | |
+ | |
+namespace Drupal\jsonapi_reference\Controller; | |
+ | |
+use Drupal\Core\Config\Entity\ConfigEntityListBuilder; | |
+use Drupal\Core\Entity\EntityInterface; | |
+ | |
+/** | |
+ * List builder for the 'jsonapi_reference' entity. | |
+ */ | |
+class JsonApiReferenceListBuilder extends ConfigEntityListBuilder { | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function buildHeader() { | |
+ $header['label'] = $this->t('Entrypoint'); | |
+ $header['id'] = $this->t('Machine name'); | |
+ $header['reachable'] = $this->t('Reachable'); | |
+ | |
+ return $header + parent::buildHeader(); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function buildRow(EntityInterface $entity) { | |
+ $row['label'] = $entity->label(); | |
+ $row['id'] = $entity->id(); | |
+ $row['reachable'] = $entity->isReachable() ? $this->t('Yes') : $this->t('No'); | |
+ | |
+ return $row + parent::buildRow($entity); | |
+ } | |
+ | |
+} | |
diff --git a/src/Controller/TypedResourceController.php b/src/Controller/TypedResourceController.php | |
index 3f764dd..6f08e5a 100644 | |
--- a/src/Controller/TypedResourceController.php | |
+++ b/src/Controller/TypedResourceController.php | |
@@ -4,6 +4,7 @@ namespace Drupal\jsonapi_reference\Controller; | |
use Drupal\Core\Controller\ControllerBase; | |
use Drupal\jsonapi_reference\JsonApiClientInterface; | |
+use Drupal\jsonapi_reference\JsonApiReferenceInterface; | |
use Symfony\Component\DependencyInjection\ContainerInterface; | |
use Symfony\Component\HttpFoundation\JsonResponse; | |
use Symfony\Component\HttpFoundation\Request; | |
@@ -46,6 +47,8 @@ class TypedResourceController extends ControllerBase { | |
* Incoming HTTP request. | |
* @param string $resource_object_type | |
* JSON:API Object type for which we are searching, EG node--article. | |
+ * @param \Drupal\jsonapi_reference\JsonApiReferenceInterface $jsonapi_reference | |
+ * The jsonapi_reference config entity. | |
* @param string $autocomplete_attribute | |
* Attribute on the JSON:API objects against which we are searching. | |
* | |
@@ -55,9 +58,10 @@ class TypedResourceController extends ControllerBase { | |
* values of the autocomplete attribute, and the corresponding objects | |
* JSON:API ID. | |
*/ | |
- public function autocomplete(Request $request, $resource_object_type, $autocomplete_attribute) { | |
+ public function autocomplete(Request $request, $resource_object_type, JsonApiReferenceInterface $jsonapi_reference, $autocomplete_attribute) { | |
$response = []; | |
$query = $request->query->get('q'); | |
+ $this->client->setConfig($jsonapi_reference); | |
$search_results = $this->client->search($resource_object_type, $autocomplete_attribute, $query); | |
foreach ($search_results as $attribute => $id) { | |
$response[] = [ | |
diff --git a/src/Entity/JsonApiReference.php b/src/Entity/JsonApiReference.php | |
new file mode 100644 | |
index 0000000..6f796ed | |
--- /dev/null | |
+++ b/src/Entity/JsonApiReference.php | |
@@ -0,0 +1,100 @@ | |
+<?php | |
+ | |
+namespace Drupal\jsonapi_reference\Entity; | |
+ | |
+use Drupal\Core\Config\Entity\ConfigEntityBase; | |
+use Drupal\jsonapi_reference\JsonApiReferenceInterface; | |
+ | |
+/** | |
+ * Defines the JsonApiReference entity. | |
+ * | |
+ * @ConfigEntityType( | |
+ * id = "jsonapi_reference", | |
+ * label = @Translation("JSON:API Reference"), | |
+ * handlers = { | |
+ * "list_builder" = "Drupal\jsonapi_reference\Controller\JsonApiReferenceListBuilder", | |
+ * "form" = { | |
+ * "add" = "Drupal\jsonapi_reference\Form\JsonApiReferenceForm", | |
+ * "edit" = "Drupal\jsonapi_reference\Form\JsonApiReferenceForm", | |
+ * "delete" = "Drupal\jsonapi_reference\Form\JsonApiReferenceDeleteForm", | |
+ * } | |
+ * }, | |
+ * config_prefix = "settings", | |
+ * admin_permission = "configure jsonapi reference", | |
+ * entity_keys = { | |
+ * "id" = "id", | |
+ * "label" = "entrypoint", | |
+ * }, | |
+ * config_export = { | |
+ * "id", | |
+ * "entrypoint", | |
+ * "username", | |
+ * "password", | |
+ * }, | |
+ * links = { | |
+ * "edit-form" = "/admin/config/services/jsonapi-reference/{jsonapi_reference}", | |
+ * "delete-form" = "/admin/config/services/jsonapi-reference/{jsonapi_reference}/delete", | |
+ * } | |
+ * ) | |
+ */ | |
+class JsonApiReference extends ConfigEntityBase implements JsonApiReferenceInterface { | |
+ | |
+ /** | |
+ * A unique identifier for the jsonapi_reference config entity. | |
+ * | |
+ * @var string | |
+ */ | |
+ public $id; | |
+ | |
+ /** | |
+ * The entrypoint to access the JSON:API reference. | |
+ * | |
+ * @var string | |
+ */ | |
+ public $entrypoint; | |
+ | |
+ /** | |
+ * The username to authenticate with the entrypoint. | |
+ * | |
+ * @var string | |
+ */ | |
+ public $username; | |
+ | |
+ /** | |
+ * The password to authenticate with the entrypoint. | |
+ * | |
+ * @var string | |
+ */ | |
+ public $password; | |
+ | |
+ /** | |
+ * The 'jsonapi_reference.jsonapi_client' service. | |
+ * | |
+ * @var \Drupal\jsonapi_reference\JsonApiClientInterface | |
+ */ | |
+ protected $jsonapiClient; | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function __construct(array $values, $entity_type) { | |
+ parent::__construct($values, $entity_type); | |
+ | |
+ $this->jsonapiClient = \Drupal::service('jsonapi_reference.jsonapi_client'); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function isReachable() { | |
+ $result = $this->jsonapiClient->setConfig($this)->listResourceObjectTypes(); | |
+ | |
+ if (!empty($result)) { | |
+ return TRUE; | |
+ } | |
+ else { | |
+ return FALSE; | |
+ } | |
+ } | |
+ | |
+} | |
diff --git a/src/Form/JsonApiReferenceConfigForm.php b/src/Form/JsonApiReferenceConfigForm.php | |
deleted file mode 100644 | |
index ae0f3b6..0000000 | |
--- a/src/Form/JsonApiReferenceConfigForm.php | |
+++ /dev/null | |
@@ -1,76 +0,0 @@ | |
-<?php | |
- | |
-namespace Drupal\jsonapi_reference\Form; | |
- | |
-use Drupal\Core\Form\ConfigFormBase; | |
-use Drupal\Core\Form\FormStateInterface; | |
- | |
-/** | |
- * Class JsonApiReferenceConfigForm. | |
- */ | |
-class JsonApiReferenceConfigForm extends ConfigFormBase { | |
- | |
- /** | |
- * {@inheritdoc} | |
- */ | |
- protected function getEditableConfigNames() { | |
- return [ | |
- 'jsonapi_reference.settings', | |
- ]; | |
- } | |
- | |
- /** | |
- * {@inheritdoc} | |
- */ | |
- public function getFormId() { | |
- return 'json_api_reference_config_form'; | |
- } | |
- | |
- /** | |
- * {@inheritdoc} | |
- */ | |
- public function buildForm(array $form, FormStateInterface $form_state) { | |
- $config = $this->config('jsonapi_reference.settings'); | |
- $form['entrypoint'] = [ | |
- '#type' => 'textfield', | |
- '#title' => $this->t('Entrypoint'), | |
- '#description' => $this->t('The root JSON:API entrypoint, for example, https://example.com/jsonapi'), | |
- '#maxlength' => 2048, | |
- '#size' => 64, | |
- '#default_value' => $config->get('endpoint'), | |
- ]; | |
- $form['username'] = [ | |
- '#type' => 'textfield', | |
- '#title' => $this->t('Username'), | |
- '#description' => $this->t('Username for authenticating on the JSON:API entrypoint'), | |
- '#maxlength' => 128, | |
- '#size' => 64, | |
- '#default_value' => $config->get('username'), | |
- ]; | |
- $form['password'] = [ | |
- '#type' => 'password', | |
- '#title' => $this->t('Password'), | |
- '#description' => $this->t('Password for authenticating on the JSON:API entrypoint'), | |
- '#maxlength' => 128, | |
- '#size' => 64, | |
- '#default_value' => $config->get('password'), | |
- ]; | |
- return parent::buildForm($form, $form_state); | |
- } | |
- | |
- /** | |
- * {@inheritdoc} | |
- */ | |
- public function submitForm(array &$form, FormStateInterface $form_state) { | |
- parent::submitForm($form, $form_state); | |
- | |
- $config = $this->config('jsonapi_reference.settings'); | |
- $config->set('endpoint', $form_state->getValue('entrypoint')) | |
- ->set('username', $form_state->getValue('username')); | |
- if ($password = $form_state->getValue('password')) { | |
- $config->set('password', $password); | |
- } | |
- $config->save(); | |
- } | |
- | |
-} | |
diff --git a/src/Form/JsonApiReferenceDeleteForm.php b/src/Form/JsonApiReferenceDeleteForm.php | |
new file mode 100644 | |
index 0000000..939eb22 | |
--- /dev/null | |
+++ b/src/Form/JsonApiReferenceDeleteForm.php | |
@@ -0,0 +1,78 @@ | |
+<?php | |
+ | |
+namespace Drupal\jsonapi_reference\Form; | |
+ | |
+use Drupal\Core\Form\FormStateInterface; | |
+use Drupal\Core\Entity\EntityConfirmFormBase; | |
+use Drupal\Core\Url; | |
+ | |
+/** | |
+ * Form handler for the jsonapi_reference delete form. | |
+ * | |
+ * @see \Drupal\jsonapi_reference\Entity\JsonApiReference | |
+ * @see \Drupal\jsonapi_reference\Form\JsonApiReferenceDeleteForm | |
+ */ | |
+class JsonApiReferenceDeleteForm extends EntityConfirmFormBase { | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function getQuestion() { | |
+ return $this->t('Are you sure you want to delete %name?', ['%name' => $this->entity->label()]); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function getCancelUrl() { | |
+ return new Url('entity.jsonapi_reference.collection'); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function getConfirmText() { | |
+ return $this->t('Delete'); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function validateForm(array &$form, FormStateInterface $form_state) { | |
+ parent::validateForm($form, $form_state); | |
+ | |
+ // Check if there is any typed_resource_object fields using the entity | |
+ // the user is trying to delete. | |
+ $entity_field_manager = \Drupal::service('entity_field.manager'); | |
+ $field_map = $entity_field_manager->getFieldMapByFieldType('typed_resource_object'); | |
+ | |
+ foreach ($field_map as $entity_type => $field) { | |
+ | |
+ foreach ($field as $field_name => $info) { | |
+ if (isset($info['bundles'])) { | |
+ foreach ($info['bundles'] as $bundle) { | |
+ $field_definitions = $entity_field_manager->getFieldDefinitions($entity_type, $bundle); | |
+ | |
+ if (isset($field_definitions[$field_name]) && $field_definitions[$field_name]->getSettings()['jsonapi_reference_entity'] === $this->entity->id()) { | |
+ $form_state->setError($form['actions']['submit'], $this->t('JSON:API reference %label could not be deleted as it is being used in a field (%field)', [ | |
+ '%label' => $this->entity->label(), | |
+ '%field' => $field_name, | |
+ ])); | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function submitForm(array &$form, FormStateInterface $form_state) { | |
+ $this->entity->delete(); | |
+ $this->messenger()->addMEssage($this->t('JSON:API reference %label has been deleted.', ['%label' => $this->entity->label()])); | |
+ | |
+ $form_state->setRedirectUrl($this->getCancelUrl()); | |
+ } | |
+ | |
+} | |
diff --git a/src/Form/JsonApiReferenceForm.php b/src/Form/JsonApiReferenceForm.php | |
new file mode 100644 | |
index 0000000..29c5d2d | |
--- /dev/null | |
+++ b/src/Form/JsonApiReferenceForm.php | |
@@ -0,0 +1,129 @@ | |
+<?php | |
+ | |
+namespace Drupal\jsonapi_reference\Form; | |
+ | |
+use Drupal\Core\Entity\EntityForm; | |
+use Drupal\Core\Entity\EntityTypeManagerInterface; | |
+use Drupal\Core\Form\FormStateInterface; | |
+use Drupal\Core\Messenger\MessengerInterface; | |
+use Symfony\Component\DependencyInjection\ContainerInterface; | |
+ | |
+/** | |
+ * Form handler for the jsonapi_reference add and edit form. | |
+ * | |
+ * @see \Drupal\jsonapi_reference\Entity\JsonApiReference | |
+ * @see \Drupal\jsonapi_reference\Form\JsonApiReferenceDeleteForm | |
+ */ | |
+class JsonApiReferenceForm extends EntityForm { | |
+ | |
+ /** | |
+ * The entity type manager. | |
+ * | |
+ * @var \Drupal\Core\Entity\EntityTypeManager | |
+ */ | |
+ protected $entityTypeManager; | |
+ | |
+ /** | |
+ * Constructs a new JsonApiReferenceForm object. | |
+ * | |
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager | |
+ * The entity type manager service. | |
+ */ | |
+ public function __construct(EntityTypeManagerInterface $entityTypeManager) { | |
+ $this->entityTypeManager = $entityTypeManager; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public static function create(ContainerInterface $container) { | |
+ return new static( | |
+ $container->get('entity_type.manager') | |
+ ); | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function form(array $form, FormStateInterface $form_state) { | |
+ $form = parent::form($form, $form_state); | |
+ | |
+ $form['id'] = [ | |
+ '#type' => 'machine_name', | |
+ '#title' => 'JSON:API Reference ID', | |
+ '#description' => $this->t('A machine-readable unique identifier for the JSON:API reference'), | |
+ '#default_value' => $this->entity->id, | |
+ '#disabled' => !$this->entity->isNew(), | |
+ '#machine_name' => [ | |
+ 'exists' => [ | |
+ $this, 'exists', | |
+ ], | |
+ ], | |
+ ]; | |
+ $form['entrypoint'] = [ | |
+ '#type' => 'textfield', | |
+ '#title' => $this->t('Entrypoint'), | |
+ '#description' => $this->t('The root JSON:API entrypoint, for example: https://example.com/jsonapi'), | |
+ '#maxlength' => 2048, | |
+ '#size' => 64, | |
+ '#default_value' => $this->entity->entrypoint, | |
+ ]; | |
+ $form['username'] = [ | |
+ '#type' => 'textfield', | |
+ '#title' => $this->t('Username'), | |
+ '#description' => $this->t('Username for authenticating on the JSON:API entrypoint'), | |
+ '#maxlength' => 128, | |
+ '#size' => 64, | |
+ '#default_value' => $this->entity->username, | |
+ ]; | |
+ $form['password'] = [ | |
+ '#type' => 'password', | |
+ '#title' => $this->t('Password'), | |
+ '#description' => $this->t('Password for authenticating on the JSON:API entrypoint'), | |
+ '#maxlength' => 128, | |
+ '#size' => 64, | |
+ '#default_value' => $this->entity->password, | |
+ ]; | |
+ | |
+ return $form; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public function save(array $form, FormStateInterface $form_state) { | |
+ $this->entity->entrypoint = $form_state->getValue('entrypoint'); | |
+ $this->entity->username = $form_state->getValue('username'); | |
+ $this->entity->password = $form_state->getValue('password'); | |
+ | |
+ if ($this->entity->isNew()) { | |
+ $this->entity->id = $form_state->getValue('id'); | |
+ } | |
+ | |
+ $status = $this->entity->save(); | |
+ | |
+ if ($status) { | |
+ $this->messenger()->addMessage($this->t('Saved the %label reference', [ | |
+ '%label' => $this->entity->entrypoint, | |
+ ])); | |
+ } | |
+ else { | |
+ $this->messenger()->addMessage($this->t('The %label reference was not saved', [ | |
+ '%label' => $this->entity->entrypoint, | |
+ ]), MessengerInterface::TYPE_ERROR); | |
+ } | |
+ | |
+ $form_state->setRedirect('entity.jsonapi_reference.collection'); | |
+ } | |
+ | |
+ /** | |
+ * Helper function to check whether an Example configuration entity exists. | |
+ */ | |
+ public function exists($id) { | |
+ $entity = $this->entityTypeManager->getStorage('jsonapi_reference')->getQuery() | |
+ ->condition('id', $id) | |
+ ->execute(); | |
+ return (bool) $entity; | |
+ } | |
+ | |
+} | |
diff --git a/src/JsonApiClient.php b/src/JsonApiClient.php | |
index 7b8d6df..a43d891 100644 | |
--- a/src/JsonApiClient.php | |
+++ b/src/JsonApiClient.php | |
@@ -2,7 +2,6 @@ | |
namespace Drupal\jsonapi_reference; | |
-use Drupal\Core\Config\ConfigFactoryInterface; | |
use Drupal\Core\Logger\LoggerChannelInterface; | |
use GuzzleHttp\ClientInterface; | |
use GuzzleHttp\Exception\GuzzleException; | |
@@ -16,32 +15,18 @@ use GuzzleHttp\RequestOptions; | |
class JsonApiClient implements JsonApiClientInterface { | |
/** | |
- * Client for querying the JSON:API entrypoint. | |
+ * Client for querying the JSON:API endpoint. | |
* | |
* @var \GuzzleHttp\ClientInterface | |
*/ | |
protected $httpClient; | |
/** | |
- * Entrypoint to call to retrieve JSONAPI objects. | |
+ * An array of jsonapi_reference config entities. | |
* | |
- * @var string | |
+ * @var \Drupal\jsonapi_reference\JsonApiReferenceInterface | |
*/ | |
- protected $entrypoint; | |
- | |
- /** | |
- * Username to use when authenticating to the entrypoint. | |
- * | |
- * @var string | |
- */ | |
- protected $username; | |
- | |
- /** | |
- * Password to use when authenticating to the entrypoint. | |
- * | |
- * @var string | |
- */ | |
- protected $password; | |
+ protected $configEntity; | |
/** | |
* Logger channel. | |
@@ -54,17 +39,12 @@ class JsonApiClient implements JsonApiClientInterface { | |
* JsonApiClient constructor. | |
* | |
* @param \GuzzleHttp\ClientInterface $httpClient | |
- * Client for querying the JSON:API entrypoint. | |
+ * Client for querying JSON:API endpoints. | |
* @param \Drupal\Core\Logger\LoggerChannelInterface $loggerChannel | |
* Channel for logging. | |
- * @param \Drupal\Core\Config\ConfigFactoryInterface $configFactory | |
- * Config factory. | |
*/ | |
- public function __construct(ClientInterface $httpClient, LoggerChannelInterface $loggerChannel, ConfigFactoryInterface $configFactory) { | |
+ public function __construct(ClientInterface $httpClient, LoggerChannelInterface $loggerChannel) { | |
$this->httpClient = $httpClient; | |
- $this->entrypoint = $configFactory->get('jsonapi_reference.settings')->get('endpoint'); | |
- $this->username = $configFactory->get('jsonapi_reference.settings')->get('username'); | |
- $this->password = $configFactory->get('jsonapi_reference.settings')->get('password'); | |
$this->loggerChannel = $loggerChannel; | |
} | |
@@ -76,16 +56,24 @@ class JsonApiClient implements JsonApiClientInterface { | |
} | |
/** | |
- * Gets the resource object type information from the entrypoint. | |
+ * {@inheritdoc} | |
+ */ | |
+ public function setConfig(JsonApiReferenceInterface $config_entity) { | |
+ $this->configEntity = $config_entity; | |
+ return $this; | |
+ } | |
+ | |
+ /** | |
+ * Gets the resource object type information from the endpoint. | |
* | |
* @return object[] | |
* Array of objects, keyed by type name (EG node--article). | |
- * Each object contains a href element pointing to the JSON:API entrypoint | |
+ * Each object contains a href element pointing to the JSON:API endpoint | |
* for that specific type. | |
*/ | |
protected function getResourceObjectTypes() { | |
try { | |
- $response = $this->httpClient->request('get', $this->entrypoint, $this->getRequestOptions()); | |
+ $response = $this->httpClient->request('get', $this->configEntity->entrypoint, $this->getRequestOptions()); | |
} | |
catch (GuzzleException $e) { | |
$this->loggerChannel->error($e->getMessage()); | |
@@ -93,7 +81,7 @@ class JsonApiClient implements JsonApiClientInterface { | |
} | |
$response = json_decode($response->getBody()->getContents()); | |
if (!isset($response->links)) { | |
- $this->loggerChannel->error('JSON:API entrypoint @entrypoint returned no type information.', ['@entrypoint' => $this->entrypoint]); | |
+ $this->loggerChannel->error('JSON:API endpoint @endpoint returned no type information.', ['@endpoint' => $this->configEntity->entrypoint]); | |
return []; | |
} | |
return (array) $response->links; | |
@@ -105,9 +93,9 @@ class JsonApiClient implements JsonApiClientInterface { | |
public function search($resource_object_type, $search_attribute, $query) { | |
$path = $this->getPathForResourceObjectType($resource_object_type); | |
if (!$path) { | |
- $this->loggerChannel->error('No path for resource object type @type found at JSON:API entrypoint @entrypoint.', [ | |
+ $this->loggerChannel->error('No path for resource object type @type found at JSON:API endpoint @endpoint.', [ | |
'@type' => $resource_object_type, | |
- '@entrypoint' => $this->entrypoint, | |
+ '@endpoint' => $this->configEntity->entrypoint, | |
]); | |
return []; | |
} | |
@@ -136,8 +124,8 @@ class JsonApiClient implements JsonApiClientInterface { | |
foreach ($response->data as $result) { | |
$results[$result->attributes->$search_attribute] = $result->id; | |
} | |
- $this->loggerChannel->error('JSON:API entrypoint @entrypoint returned no data for path @path when searching for objects where the @search_attribute attribute matched "@query".', [ | |
- '@entrypoint' => $this->entrypoint, | |
+ $this->loggerChannel->error('JSON:API endpoint @endpoint returned no data for path @path when searching for objects where the @search_attribute attribute matched "@query".', [ | |
+ '@endpoint' => $this->configEntity->endpoint, | |
'@path' => $path, | |
'@search_attribute' => $search_attribute, | |
'@query' => $query, | |
@@ -182,10 +170,10 @@ class JsonApiClient implements JsonApiClientInterface { | |
'Accept' => 'application/json', | |
], | |
]; | |
- if ($this->username && $this->password) { | |
+ if ($this->configEntity->username && $this->configEntity->password) { | |
$options[RequestOptions::AUTH] = [ | |
- $this->username, | |
- $this->password, | |
+ $this->configEntity->username, | |
+ $this->configEntity->password, | |
]; | |
} | |
diff --git a/src/JsonApiClientInterface.php b/src/JsonApiClientInterface.php | |
index fb97fcd..8b5f375 100644 | |
--- a/src/JsonApiClientInterface.php | |
+++ b/src/JsonApiClientInterface.php | |
@@ -60,4 +60,12 @@ interface JsonApiClientInterface { | |
*/ | |
public function searchById($resource_object_type, $id); | |
+ /** | |
+ * Set the configuration objects to use for the client. | |
+ * | |
+ * @param \Drupal\jsonapi_reference\JsonApiReferenceInterface $config_entity | |
+ * The jsonapi_reference entity to use. | |
+ */ | |
+ public function setConfig(JsonApiReferenceInterface $config_entity); | |
+ | |
} | |
diff --git a/src/JsonApiReferenceInterface.php b/src/JsonApiReferenceInterface.php | |
new file mode 100644 | |
index 0000000..75b2cf6 | |
--- /dev/null | |
+++ b/src/JsonApiReferenceInterface.php | |
@@ -0,0 +1,20 @@ | |
+<?php | |
+ | |
+namespace Drupal\jsonapi_reference; | |
+ | |
+use Drupal\Core\Config\Entity\ConfigEntityInterface; | |
+ | |
+/** | |
+ * Provides an interface defining the JsonApiReference config entity. | |
+ */ | |
+interface JsonApiReferenceInterface extends ConfigEntityInterface { | |
+ | |
+ /** | |
+ * Checks if the JSON:API entrypoint is reachable and returns a boolean value. | |
+ * | |
+ * @return bool | |
+ * Is the JSON:API entrypoint reachable? | |
+ */ | |
+ public function isReachable(); | |
+ | |
+} | |
diff --git a/src/Plugin/Field/FieldType/TypedResourceObjectItem.php b/src/Plugin/Field/FieldType/TypedResourceObjectItem.php | |
index c9855a9..3fb3a5d 100644 | |
--- a/src/Plugin/Field/FieldType/TypedResourceObjectItem.php | |
+++ b/src/Plugin/Field/FieldType/TypedResourceObjectItem.php | |
@@ -29,6 +29,7 @@ class TypedResourceObjectItem extends FieldItemBase { | |
public static function defaultStorageSettings() { | |
return [ | |
'resource_object_type' => '', | |
+ 'jsonapi_reference_entity' => '', | |
] + parent::defaultStorageSettings(); | |
} | |
@@ -89,23 +90,89 @@ class TypedResourceObjectItem extends FieldItemBase { | |
public function storageSettingsForm(array &$form, FormStateInterface $form_state, $has_data) { | |
$elements = []; | |
- /* @var $client \Drupal\jsonapi_reference\JsonApiClientInterface */ | |
- $client = \Drupal::service('jsonapi_reference.jsonapi_client'); | |
- $types = $client->listResourceObjectTypes(); | |
+ // Load all of the jsonapi_reference config entities to populate the select | |
+ // list. | |
+ $jsonapi_references = \Drupal::service('entity_type.manager') | |
+ ->getStorage('jsonapi_reference') | |
+ ->loadMultiple(); | |
+ | |
+ // Format the array of jsonapi_reference entities in to a format that is | |
+ // usable by the form api. | |
+ $formatted_references = $this->formatJsonapiReferences($jsonapi_references); | |
+ | |
+ if ($form_state->getValue(['settings', 'jsonapi_reference_entity'])) { | |
+ $resource_object_type_options = $this->getResourceObjectTypes($form_state->getValue(['settings', 'jsonapi_reference_entity'])); | |
+ } | |
+ elseif ($this->getSetting('jsonapi_reference_entity')) { | |
+ $resource_object_type_options = $this->getResourceObjectTypes($this->getSetting('jsonapi_reference_entity')); | |
+ } | |
+ else { | |
+ $resource_object_type_options = $this->getResourceObjectTypes(key($formatted_references)); | |
+ } | |
+ | |
+ $elements['jsonapi_reference_entity'] = [ | |
+ '#type' => 'select', | |
+ '#title' => $this->t('Reference entrypoint'), | |
+ '#default_value' => $this->getSetting('jsonapi_reference_entity'), | |
+ '#required' => TRUE, | |
+ '#description' => $this->t('The source JSON:API to use for the content of the field.'), | |
+ '#disabled' => $has_data || count($formatted_references) === 1, | |
+ '#options' => $formatted_references, | |
+ '#ajax' => [ | |
+ 'callback' => [$this, 'populateObjectTypes'], | |
+ 'method' => 'replace', | |
+ 'wrapper' => 'object-type-container', | |
+ ], | |
+ ]; | |
$elements['resource_object_type'] = [ | |
'#type' => 'select', | |
'#title' => $this->t('Type'), | |
'#default_value' => $this->getSetting('resource_object_type'), | |
- '#required' => TRUE, | |
'#description' => $this->t('The type of resource object.'), | |
- '#disabled' => $has_data, | |
- '#options' => array_combine($types, $types), | |
+ '#disabled' => $has_data || count($resource_object_type_options) == 0, | |
+ '#options' => $resource_object_type_options, | |
+ '#required' => TRUE, | |
+ '#prefix' => '<div id="object-type-container">', | |
+ '#suffix' => '</div>', | |
]; | |
return $elements; | |
} | |
+ /** | |
+ * Callback for populating the resource_object_types field with object types. | |
+ * | |
+ * @param array $form | |
+ * The form array. | |
+ * @param \Drupal\Core\Form\FormStateInterface $form_state | |
+ * The form state. | |
+ */ | |
+ public function populateObjectTypes(array &$form, FormStateInterface $form_state) { | |
+ return $form['settings']['resource_object_type']; | |
+ } | |
+ | |
+ /** | |
+ * Returns the list of available object types from the specified resource. | |
+ * | |
+ * @param string $id | |
+ * The ID of the jsonapi_reference entity. | |
+ * | |
+ * @return array | |
+ * The resource's object types. | |
+ */ | |
+ public function getResourceObjectTypes(string $id) { | |
+ $jsonapi_reference = \Drupal::service('entity_type.manager') | |
+ ->getStorage('jsonapi_reference') | |
+ ->load($id); | |
+ | |
+ /** @var \Drupal\jsonapi_reference\JsonApiClientInterface $client */ | |
+ $client = \Drupal::service('jsonapi_reference.jsonapi_client'); | |
+ $client->setConfig($jsonapi_reference); | |
+ $object_types = $client->listResourceObjectTypes(); | |
+ return array_combine($object_types, $object_types); | |
+ } | |
+ | |
/** | |
* {@inheritdoc} | |
*/ | |
@@ -128,4 +195,22 @@ class TypedResourceObjectItem extends FieldItemBase { | |
return $this->get('value')->getValue(); | |
} | |
+ /** | |
+ * Format an array of jsonapi_reference config entities. | |
+ * | |
+ * @param array[\Drupal\jsonapi_reference\JsonapiReferenceInterface] $entities | |
+ * The array of JsonapiReference entities. | |
+ * | |
+ * @return array | |
+ * An array suitable for use within the #options of a select form element. | |
+ */ | |
+ protected function formatJsonapiReferences(array $entities) { | |
+ $references = []; | |
+ foreach ($entities as $entity) { | |
+ $references[$entity->id()] = $entity->label(); | |
+ } | |
+ | |
+ return $references; | |
+ } | |
+ | |
} | |
diff --git a/src/Plugin/Field/FieldWidget/TypedResourceObjectAutocompleteWidget.php b/src/Plugin/Field/FieldWidget/TypedResourceObjectAutocompleteWidget.php | |
index 3cb1d47..385aa7e 100644 | |
--- a/src/Plugin/Field/FieldWidget/TypedResourceObjectAutocompleteWidget.php | |
+++ b/src/Plugin/Field/FieldWidget/TypedResourceObjectAutocompleteWidget.php | |
@@ -4,7 +4,12 @@ namespace Drupal\jsonapi_reference\Plugin\Field\FieldWidget; | |
use Drupal\Core\Field\FieldItemListInterface; | |
use Drupal\Core\Field\WidgetBase; | |
+use Drupal\Core\Field\FieldDefinitionInterface; | |
use Drupal\Core\Form\FormStateInterface; | |
+use Drupal\Core\Entity\EntityTypeManagerInterface; | |
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | |
+use Drupal\jsonapi_reference\JsonApiClientInterface; | |
+use Symfony\Component\DependencyInjection\ContainerInterface; | |
/** | |
* Plugin implementation of the 'typed_resource_object_autocomplete' widget. | |
@@ -18,7 +23,61 @@ use Drupal\Core\Form\FormStateInterface; | |
* } | |
* ) | |
*/ | |
-class TypedResourceObjectAutocompleteWidget extends WidgetBase { | |
+class TypedResourceObjectAutocompleteWidget extends WidgetBase implements ContainerFactoryPluginInterface { | |
+ | |
+ /** | |
+ * The entity_type.manager service. | |
+ * | |
+ * @var \Drupal\Core\Entity\EntityTypeManagerInterface | |
+ */ | |
+ protected $entityTypeManager; | |
+ | |
+ /** | |
+ * The jsonapi_reference.jsonapi_client service. | |
+ * | |
+ * @var \Drupal\jsonapi_reference\JsonApiClientInterface | |
+ */ | |
+ protected $jsonapiClient; | |
+ | |
+ /** | |
+ * Constructs a new TypedResourceObjectAutocompleteWidget object. | |
+ * | |
+ * @param string $plugin_id | |
+ * The plugin ID. | |
+ * @param mixed $plugin_definition | |
+ * The plugin definition. | |
+ * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition | |
+ * The field definition. | |
+ * @param array $settings | |
+ * The widget settings. | |
+ * @param array $third_party_settings | |
+ * The third party widget settings. | |
+ * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager | |
+ * The entity_type.manager service. | |
+ * @param \Drupal\jsonapi_reference\JsonApiClientInterface $jsonapi_client | |
+ * The jsonapi_reference.jsonapi_client service. | |
+ */ | |
+ public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, array $third_party_settings, EntityTypeManagerInterface $entity_type_manager, JsonApiClientInterface $jsonapi_client) { | |
+ parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $third_party_settings); | |
+ | |
+ $this->entityTypeManager = $entity_type_manager; | |
+ $this->jsonapiClient = $jsonapi_client; | |
+ } | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { | |
+ return new static( | |
+ $plugin_id, | |
+ $plugin_definition, | |
+ $configuration['field_definition'], | |
+ $configuration['settings'], | |
+ $configuration['third_party_settings'], | |
+ $container->get('entity_type.manager'), | |
+ $container->get('jsonapi_reference.jsonapi_client') | |
+ ); | |
+ } | |
/** | |
* {@inheritdoc} | |
@@ -63,10 +122,12 @@ class TypedResourceObjectAutocompleteWidget extends WidgetBase { | |
'#autocomplete_route_name' => 'jsonapi_reference.typed_resource_controller_autocomplete', | |
'#autocomplete_route_parameters' => [ | |
'resource_object_type' => $field_settings['resource_object_type'], | |
+ 'jsonapi_reference' => $field_settings['jsonapi_reference_entity'], | |
'autocomplete_attribute' => $this->getSetting('autocomplete_attribute'), | |
], | |
- '#value_callback' => [get_class($this), 'valueCallback'], | |
+ '#value_callback' => [$this, 'valueCallback'], | |
'#resource_object_type' => $field_settings['resource_object_type'], | |
+ '#jsonapi_reference_entity' => $field_settings['jsonapi_reference_entity'], | |
'#autocomplete_attribute' => $this->getSetting('autocomplete_attribute'), | |
]; | |
@@ -87,7 +148,7 @@ class TypedResourceObjectAutocompleteWidget extends WidgetBase { | |
* @return mixed | |
* The value to assign to the element. | |
*/ | |
- public static function valueCallback(array $element, $input, FormStateInterface $form_state) { | |
+ public function valueCallback(array $element, $input, FormStateInterface $form_state) { | |
$value = ''; | |
// If we're rebuilding the form due to AJAX (eg adding another item to the | |
@@ -115,10 +176,15 @@ class TypedResourceObjectAutocompleteWidget extends WidgetBase { | |
// Otherwise we need to convert the other way - for the given id.. | |
if ($element['#default_value']) { | |
- // ..look it up via jsonapi and format with the title. | |
- /* @var $client \Drupal\jsonapi_reference\JsonApiClientInterface */ | |
- $client = \Drupal::service('jsonapi_reference.jsonapi_client'); | |
- $jsonapi_object = $client->searchById($element['#resource_object_type'], $element['#default_value']); | |
+ /** @var \Drupal\jsonapi_reference\JsonApiReferenceInterface $config */ | |
+ $config = $this->entityTypeManager | |
+ ->getStorage('jsonapi_reference') | |
+ ->load($element['#jsonapi_reference_entity']); | |
+ | |
+ /** @var \Drupal\jsonapi_reference\JsonApiClientInterface $client */ | |
+ $this->jsonapiClient->setConfig($config); | |
+ $jsonapi_object = $this->jsonapiClient->searchById($element['#resource_object_type'], $element['#default_value']); | |
+ | |
if ($jsonapi_object) { | |
$value = $jsonapi_object->data->attributes->{$element['#autocomplete_attribute']} . ' (' . $element['#default_value'] . ')'; | |
} | |
diff --git a/tests/src/Functional/JsonApiReferenceTest.php b/tests/src/Functional/JsonApiReferenceTest.php | |
index 5624686..752166b 100644 | |
--- a/tests/src/Functional/JsonApiReferenceTest.php | |
+++ b/tests/src/Functional/JsonApiReferenceTest.php | |
@@ -4,6 +4,9 @@ namespace Drupal\Tests\jsonapi_reference\Functional; | |
use Drupal\KernelTests\AssertConfigTrait; | |
use Drupal\Tests\BrowserTestBase; | |
+use Drupal\Core\StringTranslation\StringTranslationTrait; | |
+use Drupal\jsonapi_reference\Entity\JsonApiReference; | |
+use Drupal\Core\Url; | |
/** | |
* Class JsonApiReferenceTest. | |
@@ -11,7 +14,26 @@ use Drupal\Tests\BrowserTestBase; | |
* @group jsonapi_reference | |
*/ | |
class JsonApiReferenceTest extends BrowserTestBase { | |
- use AssertConfigTrait; | |
+ use AssertConfigTrait, StringTranslationTrait; | |
+ | |
+ /** | |
+ * A user with no significant control. | |
+ * | |
+ * @var \Drupal\user\UserInterface | |
+ */ | |
+ protected $personOfNoSignificance; | |
+ | |
+ /** | |
+ * A user with appropriate permissions to administer jsonapi_reference config. | |
+ * | |
+ * @var \Drupal\user\UserInterface | |
+ */ | |
+ protected $personOfSignificance; | |
+ | |
+ /** | |
+ * {@inheritdoc} | |
+ */ | |
+ static protected $modules = ['jsonapi_reference', 'jsonapi']; | |
/** | |
* {@inheritdoc} | |
@@ -21,7 +43,39 @@ class JsonApiReferenceTest extends BrowserTestBase { | |
/** | |
* {@inheritdoc} | |
*/ | |
- static protected $modules = ['jsonapi_reference']; | |
+ protected function setUp() { | |
+ parent::setUp(); | |
+ | |
+ // Create a user with no significant administrative capabilities and a user | |
+ // with permissions to configure the jsonapi_reference module. | |
+ $this->personOfNoSignificance = $this->createUser(); | |
+ $this->personOfSignificance = $this->createUser(['configure jsonapi reference']); | |
+ } | |
+ | |
+ /** | |
+ * Test the entity list is protected by permissions. | |
+ */ | |
+ public function testEntityListProtected() { | |
+ // Test anonymous users can't access the config. | |
+ $this->drupalGet('admin/config/services/jsonapi-reference'); | |
+ $this->assertSession()->statusCodeEquals(403); | |
+ | |
+ // Test a logged-in user with a no specific permissions can't access the | |
+ // configuration screen. | |
+ $this->drupalLogin($this->personOfNoSignificance); | |
+ $this->drupalGet('admin/config/services/jsonapi-reference'); | |
+ $this->assertSession()->statusCodeEquals(403); | |
+ | |
+ $this->drupalLogout(); | |
+ | |
+ // Test a logged-in user with the appropriate permissions can access the | |
+ // configuration screen. | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ $this->drupalGet('admin/config/services/jsonapi-reference'); | |
+ $this->assertSession()->statusCodeEquals(200); | |
+ | |
+ $this->drupalLogout(); | |
+ } | |
/** | |
* Test configuration form protected by permissions. | |
@@ -31,26 +85,142 @@ class JsonApiReferenceTest extends BrowserTestBase { | |
*/ | |
public function testConfigFormProtected() { | |
// Test anonymous users can't access the configuration screen. | |
- $this->drupalGet('admin/config/jsonapi_reference'); | |
+ $this->drupalGet('admin/config/services/jsonapi-reference/add'); | |
$this->assertSession()->statusCodeEquals(403); | |
- // Test a logged in user with no specific permissions can't access the | |
+ // Test a logged-in user with no specific permissions can't access the | |
// configuration screen. | |
- $person_of_no_significance = $this->createUser(); | |
- $this->drupalLogin($person_of_no_significance); | |
- $this->drupalGet('admin/config/jsonapi_reference'); | |
+ $this->drupalLogin($this->personOfNoSignificance); | |
+ $this->drupalGet('admin/config/services/jsonapi-reference/add'); | |
$this->assertSession()->statusCodeEquals(403); | |
$this->drupalLogout(); | |
- // Test a logged in user with the appropriate permission can access the | |
+ // Test a logged-in user with the appropriate permission can access the | |
// configuration screen. | |
- $person_of_appropriate_significance = $this->createUser(['configure jsonapi reference']); | |
- $this->drupalLogin($person_of_appropriate_significance); | |
- $this->drupalGet('admin/config/jsonapi_reference'); | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ $this->drupalGet('admin/config/services/jsonapi-reference/add'); | |
$this->assertSession()->statusCodeEquals(200); | |
$this->drupalLogout(); | |
} | |
+ /** | |
+ * Test submitting the 'add' configuration form. | |
+ */ | |
+ public function testAddFormSubmit() { | |
+ // Login as a user with the appropriate permission to submit the form. | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ $this->drupalPostForm('admin/config/services/jsonapi-reference/add', [ | |
+ 'id' => 'testing', | |
+ 'entrypoint' => 'http://localhost/jsonapi', | |
+ 'username' => '', | |
+ 'password' => '', | |
+ ], $this->t('Save')); | |
+ | |
+ $this->assertSession()->statusCodeEquals(200); | |
+ | |
+ // Verify the config entity exists. | |
+ /** @var \Drupal\jsonapi_reference\JsonApiReferenceInterface $entity */ | |
+ $entity = JsonApiReference::load('testing'); | |
+ | |
+ $this->assert($entity->label() == 'http://localhost/jsonapi'); | |
+ | |
+ $this->drupalLogout(); | |
+ } | |
+ | |
+ /** | |
+ * Test submitting the 'delete' form for the jsonapi_reference entity type. | |
+ */ | |
+ public function testDeleteFormSubmit() { | |
+ // Login as a user with the appropriate permission to submit the form. | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ | |
+ // Create a jsonapi_reference entity. | |
+ $state = JsonApiReference::create([ | |
+ 'id' => 'testing', | |
+ 'entrypoint' => 'http://localhost/jsonapi', | |
+ 'username' => '', | |
+ 'password' => '', | |
+ ])->save(); | |
+ $this->assert($state == SAVED_NEW); | |
+ | |
+ $this->drupalPostForm('admin/config/services/jsonapi-reference/testing/delete', [], $this->t('Delete')); | |
+ $this->assertSession()->statusCodeEquals(200); | |
+ | |
+ // Verify the entity no longer exists. | |
+ $this->assert(is_null(JsonApiReference::load('testing'))); | |
+ | |
+ $this->drupalLogout(); | |
+ } | |
+ | |
+ /** | |
+ * Test submitting the 'edit' form for the jsonapi_reference entity type. | |
+ */ | |
+ public function testEditFormSubmit() { | |
+ // Login as a user with the appropriate permission to submit the form. | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ | |
+ // Create a jsonapi_reference entity that will be edited. | |
+ $state = JsonApiReference::create([ | |
+ 'id' => 'edit_me', | |
+ 'entrypoint' => 'http://localhost/jsonapi', | |
+ 'username' => '', | |
+ 'password' => '', | |
+ ])->save(); | |
+ $this->assert($state == SAVED_NEW); | |
+ | |
+ $this->drupalPostForm('admin/config/services/jsonapi-reference/edit_me/edit', [ | |
+ 'entrypoint' => 'http://localhost/jsonapitest', | |
+ ], $this->t('Save')); | |
+ $this->assertSession()->statusCodeEquals(200); | |
+ | |
+ // Verify the entity has been changed. | |
+ /** @var \Drupal\jsonapi_reference\JsonApiReferenceInterface $entity */ | |
+ $entity = JsonApiReference::load('edit_me'); | |
+ | |
+ $this->assert($entity->entrypoint == 'http://localhost/jsonapitest'); | |
+ | |
+ $this->drupalLogout(); | |
+ } | |
+ | |
+ /** | |
+ * Test the reachable method on the jsonapi_reference entity. | |
+ */ | |
+ public function testReachable() { | |
+ // Login as a user with the appropriate permission to submit the form. | |
+ $this->drupalLogin($this->personOfSignificance); | |
+ | |
+ // Create a new jsonapi_reference entity that is expected to be reachable. | |
+ $state = JsonApiReference::create([ | |
+ 'id' => 'reachable', | |
+ 'entrypoint' => Url::fromUri('base:/jsonapi')->setAbsolute()->toString(TRUE)->getGeneratedUrl(), | |
+ 'username' => '', | |
+ 'password' => '', | |
+ ])->save(); | |
+ $this->assert($state == SAVED_NEW); | |
+ | |
+ /** @var \Drupal\jsonapi_reference\JsonApiReferenceInterfae $reachable */ | |
+ $reachable = JsonApiReference::load('reachable'); | |
+ | |
+ $this->assert($reachable->isReachable()); | |
+ | |
+ // Create a new jsonapi_reference entity that should not be reachable. | |
+ $state = JsonApiReference::create([ | |
+ 'id' => 'unreachable', | |
+ 'entrypoint' => Url::fromUri('base:/jsonapiunreachable')->setAbsolute()->toString(TRUE)->getGeneratedUrl(), | |
+ 'username' => '', | |
+ 'password' => '', | |
+ ])->save(); | |
+ $this->assert($state == SAVED_NEW); | |
+ | |
+ /** @var \Drupal\jsonapi_reference\JsonApiReferenceInterface $unreachable */ | |
+ $unreachable = JsonApiReference::load('unreachable'); | |
+ | |
+ $this->assert(!$unreachable->isReachable()); | |
+ | |
+ | |
+ $this->drupalLogout(); | |
+ } | |
+ | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment