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'];
}
}
