external_entity-1.0.x-dev/src/Form/ExternalEntityConnectionForm.php

src/Form/ExternalEntityConnectionForm.php
<?php

declare(strict_types=1);

namespace Drupal\external_entity\Form;

use Drupal\Component\Utility\DeprecationHelper;
use Drupal\Core\Utility\Error;
use Drupal\Core\Render\Element;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\external_entity\AjaxFormTrait;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\Component\Plugin\PluginManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\external_entity\Contracts\ExternalEntityConnectionAwareInterface;
use Drupal\external_entity\Contracts\ExternalEntityConnectionTypeManagerInterface;
use Drupal\external_entity\Contracts\ExternalEntityAuthenticationTypeManagerInterface;

/**
 * Define the external entity connection default form.
 */
class ExternalEntityConnectionForm extends EntityForm {

  use AjaxFormTrait;

  /**
   * The external entity connection type manager.
   *
   * @var \Drupal\external_entity\Contracts\ExternalEntityConnectionTypeManagerInterface
   */
  protected $connectionTypeManager;

  /**
   * @var \Drupal\external_entity\Contracts\ExternalEntityAuthenticationTypeManagerInterface
   */
  protected $authenticationTypeManager;

  /**
   * External entity connection form constructor.
   *
   * @param \Drupal\external_entity\Contracts\ExternalEntityConnectionTypeManagerInterface $connection_type_manager
   *   The external entity connection type manager service.
   * @param \Drupal\external_entity\Contracts\ExternalEntityAuthenticationTypeManagerInterface $authentication_type_manager
   *   The external entity connection type manager service.
   */
  public function __construct(
    ExternalEntityConnectionTypeManagerInterface $connection_type_manager,
    ExternalEntityAuthenticationTypeManagerInterface $authentication_type_manager,
  ) {
    $this->connectionTypeManager = $connection_type_manager;
    $this->authenticationTypeManager = $authentication_type_manager;
  }

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container): self {
    return new static(
      $container->get('plugin.manager.external_entity.connection_type'),
      $container->get('plugin.manager.external_entity.authentication_type')
    );
  }

  /**
   * {@inheritDoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    /** @var \Drupal\external_entity\Entity\ExternalEntityConnection $entity */
    $entity = $this->entity;

    $form['#parents'] = [];
    $form['#prefix'] = '<div id="external-entity-connection">';
    $form['#suffix'] = '</div>';

    $form['label'] = [
      '#type' => 'textfield',
      '#title' => $this->t('Name'),
      '#maxlength' => 255,
      '#default_value' => $entity->label(),
      '#description' => $this->t('Input the connection name.'),
      '#required' => TRUE,
    ];
    $form['id'] = [
      '#type' => 'machine_name',
      '#machine_name' => [
        'exists' => [$entity, 'exists'],
      ],
      '#disabled' => !$entity->isNew(),
      '#default_value' => $entity->id(),
    ];

    $this->buildPluginConfigurationForm(
      $form,
      $form_state,
    );

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritDoc}
   */
  public function validateForm(
    array &$form,
    FormStateInterface $form_state,
  ): void {
    $this->validatePluginConfigurationForm(
      $form,
      $form_state
    );
    parent::validateForm($form, $form_state);
  }

  /**
   * {@inheritDoc}
   */
  public function submitForm(
    array &$form,
    FormStateInterface $form_state,
  ): void {
    $this->submitPluginConfigurationForm(
      $form,
      $form_state
    );
    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritDoc}
   */
  public function save(array $form, FormStateInterface $form_state) {
    /** @var \Drupal\external_entity\Entity\ExternalEntityConnection $entity */
    $entity = $this->entity;
    $entity->save();

    $form_state->setRedirectUrl(
      $entity->toUrl('collection')
    );
  }

  /**
   * @param array $form
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *
   * @return array
   */
  public function externalEntityConnectionAjax(
    array $form,
    FormStateInterface $form_state,
  ): array {
    return $form;
  }

  /**
   * Define the ajax element base.
   *
   * @return array
   */
  protected function ajaxElementBase(): array {
    return [
      'event' => 'change',
      'method' => 'replaceWith',
      'wrapper' => 'external-entity-connection',
      'callback' => [$this, 'externalEntityConnectionAjax'],
    ];
  }

  /**
   * Define the plugin dependency form information.
   *
   * @return array[]
   *   An array keyed by the element plugin id, which provides:
   *     - title: Set the element title.
   *     - description: Set the element description.
   *     - settings: An array of plugin settings.
   *         - title: Set the setting title/.
   *         - key: Set the element key which captures the settings.
   *     - plugin_manager: A plugin manager to use to create the plugin.
   */
  protected function pluginDependencyFormInfo(): array {
    /** @var \Drupal\external_entity\Entity\ExternalEntityConnection $entity */
    $entity = $this->entity;

    return [
      'authentication_type' => [
        'title' => $this->t('Authentication Type'),
        'description' => $this->t('Select the external entity authentication type.'),
        'default_value' => $entity->authenticationTypeId(),
        'settings' => [
          'key' => 'authentication_settings',
          'title' => $this->t('Authentication Settings'),
          'configuration' => $entity->authenticationSettings(),
        ],
        'plugin_manager' => $this->authenticationTypeManager,
      ],
      'connection_type' => [
        'title' => $this->t('Connection Type'),
        'description' => $this->t('Select the external entity connection type.'),
        'default_value' => $entity->connectionTypeId(),
        'required' => TRUE,
        'settings' => [
          'key' => 'connection_settings',
          'title' => $this->t('Connection Settings'),
          'configuration' => $entity->connectionSettings(),
        ],
        'plugin_manager' => $this->connectionTypeManager,
      ],
    ];
  }

  /**
   * Build the plugin configuration form.
   *
   * @param array $form
   *   An array of form elements.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state instance.
   * @param string|array $key
   *   The plugin configuration form element keys.
   *
   * @return void
   */
  protected function buildPluginConfigurationForm(
    array &$form,
    FormStateInterface $form_state,
    $key = NULL,
  ): void {
    if (!is_array($key)) {
      $key = isset($key) ? [$key] : [];
    }
    $form_info = $this->pluginDependencyFormInfo();

    $form_keys = !empty($key)
      ? array_intersect_key($form_info, array_flip($key))
      : $form_info;

    foreach ($form_keys as $input => $plugin_info) {
      if (
        !isset($plugin_info['plugin_manager'])
        || !$plugin_info['plugin_manager'] instanceof PluginManagerInterface
      ) {
        continue;
      }

      $plugin_id = $this->getFormStateValue(
        $input,
        $form_state,
        $plugin_info['default_value'] ?? NULL
      );
      $plugin_manager = $plugin_info['plugin_manager'];
      $plugin_options = $plugin_manager->getDefinitionOptions();
      $plugin_settings = $plugin_info['settings'] ?? [];

      $form[$input] = [
        '#type' => 'select',
        '#title' => $plugin_info['title'] ?? NULL,
        '#description' => $plugin_info['description'] ?? NULL,
        '#options' => $plugin_options,
        '#empty_option' => $this->t('- None -'),
        '#default_value' => $plugin_id,
        '#required' => $plugin_info['required'] ?? FALSE,
        '#ajax' => $this->ajaxElementBase(),
      ];

      if (isset($plugin_id, $plugin_options[$plugin_id], $plugin_settings['key'])) {
        $setting_key = $plugin_settings['key'];
        $configuration = $plugin_settings['configuration'] ?? [];

        $form[$setting_key] = [
          '#type' => 'fieldset',
          '#title' => $plugin_info['settings']['title'] ?? NULL,
          '#tree' => TRUE,
        ];

        try {
          $instance = $plugin_manager->createInstance(
            $plugin_id,
            $configuration
          );

          if ($instance instanceof ExternalEntityConnectionAwareInterface) {
            $instance->setConnection($this->entity);
          }

          if ($instance instanceof PluginFormInterface) {
            $subform = ['#parents' => [$setting_key]];

            $form[$setting_key] += $instance->buildConfigurationForm(
              $subform,
              SubformState::createForSubform($subform, $form, $form_state)
            );

            if (count(Element::children($form[$setting_key])) === 0) {
              unset($form[$setting_key]);
            }
          }
        }
        catch (\Exception $exception) {
          DeprecationHelper::backwardsCompatibleCall(
            \Drupal::VERSION,
            '10.1.0',
            static fn() => Error::logException(\Drupal::logger('external_entity'), $exception),
            static fn() => watchdog_exception('external_entity', $exception)
          );
        }
      }
    }
  }

  /**
   * Validate the plugin configuration form.
   *
   * @param array $form
   *   An array form elements.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state instance.
   *
   * @return void
   */
  protected function validatePluginConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ): void {
    foreach ($this->pluginDependencyFormInfo() as $input => $info) {
      if (
        !isset($info['plugin_manager'], $info['settings']['key'])
        || !$info['plugin_manager'] instanceof PluginManagerInterface
      ) {
        continue;
      }
      $manager = $info['plugin_manager'];
      $setting_key = $info['settings']['key'];

      if (
        ($connection_type = $form_state->getValue($input))
        && $manager->hasDefinition($connection_type)
      ) {
        try {
          $instance = $manager->createInstance(
            $connection_type,
            $form_state->getValue($setting_key, [])
          );

          if ($instance instanceof ExternalEntityConnectionAwareInterface) {
            $instance->setConnection($this->entity);
          }

          if ($instance instanceof PluginFormInterface) {
            $subform = $form[$setting_key] ?? [];
            $instance->validateConfigurationForm(
              $subform,
              SubformState::createForSubform($subform, $form, $form_state)
            );
          }
        }
        catch (\Exception $exception) {
          DeprecationHelper::backwardsCompatibleCall(
            \Drupal::VERSION,
            '10.1.0',
            static fn() => Error::logException(\Drupal::logger('external_entity'), $exception),
            static fn() => watchdog_exception('external_entity', $exception)
          );
        }
      }
    }
  }

  /**
   * Submit the plugin configuration form.
   *
   * @param array $form
   *   An array of form elements.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state instance.
   *
   * @return void
   */
  protected function submitPluginConfigurationForm(
    array $form,
    FormStateInterface $form_state,
  ): void {
    foreach ($this->pluginDependencyFormInfo() as $input => $info) {
      if (
        !isset($info['plugin_manager'], $info['settings']['key'])
        || !$info['plugin_manager'] instanceof PluginManagerInterface
      ) {
        continue;
      }
      $manager = $info['plugin_manager'];
      $setting_key = $info['settings']['key'];

      if (
        ($plugin_id = $form_state->getValue($input))
        && $manager->hasDefinition($plugin_id)
      ) {
        try {
          $instance = $manager->createInstance(
            $plugin_id,
            $form_state->getValue($setting_key, [])
          );

          if ($instance instanceof ExternalEntityConnectionAwareInterface) {
            $instance->setConnection($this->entity);
          }

          if ($instance instanceof PluginFormInterface) {
            $subform = $form[$setting_key];

            $instance->submitConfigurationForm(
              $subform,
              SubformState::createForSubform($subform, $form, $form_state)
            );

            $form_state->setValueForElement(
              $subform, $instance->getConfiguration()
            );
          }
        }
        catch (\Exception $exception) {
          DeprecationHelper::backwardsCompatibleCall(
            \Drupal::VERSION,
            '10.1.0',
            static fn() => Error::logException(\Drupal::logger('external_entity'), $exception),
            static fn() => watchdog_exception('external_entity', $exception)
          );
        }
      }
    }
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc