rdf_sync-1.x-dev/src/Form/SettingsForm.php

src/Form/SettingsForm.php
<?php

declare(strict_types=1);

namespace Drupal\rdf_sync\Form;

use Drupal\Component\Utility\Html;
use Drupal\Core\Ajax\AjaxFormHelperTrait;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\DependencyInjection\AutowireTrait;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\SubformState;
use Drupal\Core\Plugin\PluginFormInterface;
use Drupal\rdf_sync\RdfSyncConnectorPluginInterface;
use Drupal\rdf_sync\RdfSyncConnectorPluginManager;
use Symfony\Component\HttpFoundation\Response;

/**
 * The RDF Sync settings form.
 */
class SettingsForm extends ConfigFormBase {

  use AjaxFormHelperTrait;
  use AutowireTrait;

  public function __construct(
    ConfigFactoryInterface $config_factory,
    TypedConfigManagerInterface $typedConfigManager,
    protected RdfSyncConnectorPluginManager $connectorManager,
  ) {
    parent::__construct($config_factory, $typedConfigManager);
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $form = parent::buildForm($form, $form_state);

    $form['graph_uri'] = [
      '#type' => 'url',
      '#title' => $this->t('Graph URI'),
      '#required' => TRUE,
      '#config_target' => 'rdf_sync.settings:graph_uri',
    ];

    $form['connector'] = [
      '#type' => 'details',
      '#title' => $this->t('Connection'),
      '#open' => TRUE,
    ];
    $config = $this->config('rdf_sync.settings');

    $userInput = $form_state->getUserInput();
    $connectorPluginId = $this->isAjax() ? $userInput['id'] : $config->get('connector.id');

    $form['connector']['id'] = [
      '#type' => 'select',
      '#title' => $this->t('Connector'),
      '#options' => $this->connectorManager->getDefinitionsAsOptions(),
      '#default_value' => $connectorPluginId,
      '#required' => TRUE,
      '#config_target' => 'rdf_sync.settings:connector.id',
      '#ajax' => ['callback' => '::ajaxSubmit'],
    ];

    if ($this->isAjax()) {
      // @see https://www.drupal.org/node/2897377
      $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);
    }

    $form['connector']['config'] = [
      '#tree' => TRUE,
      '#config_target' => 'rdf_sync.settings:connector.config',
    ];

    $connectorPluginConfig = $this->isAjax() ? $userInput['config'] : $config->get('connector.config');
    $this->askPluginToAct('build', $connectorPluginId, $connectorPluginConfig, $form, $form_state);

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state): void {
    parent::validateForm($form, $form_state);
    $this->askPluginToAct('validate', $form_state->getValue('id'), $form_state->getValue('config'), $form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {
    $plugin = $this->askPluginToAct('submit', $form_state->getValue('id'), $form_state->getValue('config'), $form, $form_state);
    if ($plugin) {
      $form_state->setValue('config', $plugin->getConfiguration());
    }
    parent::submitForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  protected function successfulAjaxSubmit(array $form, FormStateInterface $form_state): Response {
    $selector = '[data-drupal-selector="' . $form['#attributes']['data-drupal-selector'] . '"]';
    return (new AjaxResponse())->addCommand(new ReplaceCommand($selector, $form));
  }

  /**
   * Applies plugin actions against the form.
   *
   * @param string $method
   *   The method: 'build', 'validate', 'submit'.
   * @param string $connectorPluginId
   *   The connector plugin ID.
   * @param array|null $connectorPluginConfig
   *   The connector plugin configuration.
   * @param array $form
   *   The form.
   * @param \Drupal\Core\Form\FormStateInterface $formState
   *   The form state.
   *
   * @return \Drupal\rdf_sync\RdfSyncConnectorPluginInterface|null
   *   The plugin instance.
   */
  protected function askPluginToAct(
    string $method,
    string $connectorPluginId,
    ?array $connectorPluginConfig,
    array &$form,
    FormStateInterface $formState,
  ): ?RdfSyncConnectorPluginInterface {
    \assert(in_array($method, ['build', 'validate', 'submit'], TRUE));
    $plugin = $this->connectorManager->createInstance($connectorPluginId, $connectorPluginConfig ?? []);

    // This plugin doesn't support forms.
    if (!$plugin instanceof PluginFormInterface) {
      $form['connector']['config']['#value'] = $plugin->getConfiguration();
      return $plugin;
    }

    $subFormState = SubformState::createForSubform($form['connector']['config'], $form, $formState);

    // Casting to array as a hack, to avoid `if ($method === 'buildConf...')`.
    $method .= 'ConfigurationForm';
    $result = (array) $plugin->$method($form['connector']['config'], $subFormState);
    $form['connector']['config'] += $result;

    return $plugin;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'rdf_sync_settings';
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames(): array {
    return ['rdf_sync.settings'];
  }

}

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

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