View source
<?php
namespace Drupal\key\Form;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Config\Entity\ConfigEntityStorageInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\key\Entity\Key;
use Drupal\key\Plugin\KeyPluginFormInterface;
use Drupal\key\Plugin\KeyProviderSettableValueInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class KeyFormBase extends EntityForm {
protected $storage;
protected $originalKey = NULL;
public function __construct(ConfigEntityStorageInterface $storage) {
$this->storage = $storage;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager')
->getStorage('key'));
}
public function buildForm(array $form, FormStateInterface $form_state) {
if ($form_state
->isRebuilding()) {
if ($form_state
->getTriggeringElement()['#name'] == 'key_type') {
$this
->updateKeyType($form_state);
$this
->updateKeyInput($form_state);
}
if ($form_state
->getTriggeringElement()['#name'] == 'key_provider') {
$this
->updateKeyProvider($form_state);
$this
->updateKeyInput($form_state);
}
}
else {
$this
->updateKeyInput($form_state);
}
return parent::buildForm($form, $form_state);
}
public function form(array $form, FormStateInterface $form_state) {
$key = $this->entity;
$form['label'] = [
'#type' => 'textfield',
'#title' => $this
->t('Key name'),
'#maxlength' => 255,
'#default_value' => $key
->label(),
'#required' => TRUE,
];
$form['id'] = [
'#type' => 'machine_name',
'#default_value' => $key
->id(),
'#machine_name' => [
'exists' => [
$this->storage,
'load',
],
],
'#disabled' => !$key
->isNew(),
];
$form['description'] = [
'#type' => 'textfield',
'#title' => $this
->t('Description'),
'#default_value' => $key
->getDescription(),
'#description' => $this
->t('A short description of the key.'),
];
$form['settings'] = [
'#type' => 'container',
'#prefix' => '<div id="key-settings">',
'#suffix' => '</div>',
];
$form['settings']['type_section'] = [
'#type' => 'details',
'#title' => $this
->t('Type settings'),
'#open' => TRUE,
];
$form['settings']['type_section']['key_type'] = [
'#type' => 'select',
'#title' => $this
->t('Key type'),
'#options' => $key
->getPluginsAsOptions('key_type'),
'#required' => TRUE,
'#default_value' => $key
->getKeyType()
->getPluginId(),
'#ajax' => [
'callback' => [
$this,
'ajaxUpdateSettings',
],
'event' => 'change',
'wrapper' => 'key-settings',
],
];
$form['settings']['type_section']['key_type_description'] = [
'#markup' => $key
->getKeyType()
->getPluginDefinition()['description'],
];
$form['settings']['type_section']['key_type_settings'] = [
'#type' => 'container',
'#title' => $this
->t('Key type settings'),
'#title_display' => FALSE,
'#tree' => TRUE,
];
if ($key
->getKeyType() instanceof KeyPluginFormInterface) {
$plugin_form_state = $this
->createPluginFormState('key_type', $form_state);
$form['settings']['type_section']['key_type_settings'] += $key
->getKeyType()
->buildConfigurationForm([], $plugin_form_state);
$form_state
->setValue('key_type_settings', $plugin_form_state
->getValues());
}
$form['settings']['provider_section'] = [
'#type' => 'details',
'#title' => $this
->t('Provider settings'),
'#open' => TRUE,
];
$form['settings']['provider_section']['key_provider'] = [
'#type' => 'select',
'#title' => $this
->t('Key provider'),
'#options' => $key
->getPluginsAsOptions('key_provider'),
'#required' => TRUE,
'#default_value' => $key
->getKeyProvider()
->getPluginId(),
'#ajax' => [
'callback' => [
$this,
'ajaxUpdateSettings',
],
'event' => 'change',
'wrapper' => 'key-settings',
],
];
$form['settings']['provider_section']['key_provider_description'] = [
'#markup' => $key
->getKeyProvider()
->getPluginDefinition()['description'],
];
$form['settings']['provider_section']['key_provider_settings'] = [
'#type' => 'container',
'#title' => $this
->t('Key provider settings'),
'#title_display' => FALSE,
'#tree' => TRUE,
];
if ($key
->getKeyProvider() instanceof KeyPluginFormInterface) {
$plugin_form_state = $this
->createPluginFormState('key_provider', $form_state);
$form['settings']['provider_section']['key_provider_settings'] += $key
->getKeyProvider()
->buildConfigurationForm([], $plugin_form_state);
$form_state
->setValue('key_provider_settings', $plugin_form_state
->getValues());
}
$form['settings']['input_section'] = [
'#type' => 'details',
'#title' => $this
->t('Value'),
'#open' => TRUE,
];
$form['settings']['input_section']['key_input'] = [
'#type' => 'value',
'#value' => $key
->getKeyInput()
->getPluginId(),
];
$form['settings']['input_section']['key_input_settings'] = [
'#type' => 'container',
'#title' => $this
->t('Key value settings'),
'#title_display' => FALSE,
'#tree' => TRUE,
];
if ($key
->getKeyInput() instanceof KeyPluginFormInterface) {
$plugin_form_state = $this
->createPluginFormState('key_input', $form_state);
$form['settings']['input_section']['key_input_settings'] += $key
->getKeyInput()
->buildConfigurationForm([], $plugin_form_state);
$form_state
->setValue('key_input_settings', $plugin_form_state
->getValues());
}
return parent::form($form, $form_state);
}
public function validateForm(array &$form, FormStateInterface $form_state) {
parent::validateForm($form, $form_state);
if (!$form_state
->isSubmitted()) {
return;
}
foreach ($this->entity
->getPluginTypes() as $type) {
if (!$form_state
->getValue($type . '_settings')) {
$form_state
->setValue($type . '_settings', []);
}
}
$processed_values = [
'submitted' => NULL,
'processed_submitted' => NULL,
];
foreach ($this->entity
->getPlugins() as $type => $plugin) {
if ($plugin instanceof KeyPluginFormInterface) {
$plugin_form_state = $this
->createPluginFormState($type, $form_state);
if ($type == 'key_input') {
if ($this->entity
->getKeyProvider()
->getPluginDefinition()['key_value']['accepted']) {
$processed_values = $plugin
->processSubmittedKeyValue($plugin_form_state);
}
}
$plugin
->validateConfigurationForm($form, $plugin_form_state);
$form_state
->setValue($type . '_settings', $plugin_form_state
->getValues());
$this
->moveFormStateErrors($plugin_form_state, $form_state);
$this
->moveFormStateStorage($plugin_form_state, $form_state);
}
}
$key_value_data = $form_state
->get('key_value');
$key_value_data['submitted'] = $processed_values['submitted'];
$key_value_data['processed_submitted'] = $processed_values['processed_submitted'];
$form_state
->set('key_value', $key_value_data);
if (isset($processed_values['processed_submitted'])) {
$key_value = $processed_values['processed_submitted'];
}
else {
$temp_key = new Key($form_state
->getValues(), 'key');
$key_value = $temp_key
->getKeyValue(TRUE);
}
$plugin_form_state = $this
->createPluginFormState('key_type', $form_state);
$this->entity
->getKeyType()
->validateKeyValue($form, $plugin_form_state, $key_value);
$form_state
->setValue('key_type_settings', $plugin_form_state
->getValues());
$this
->moveFormStateErrors($plugin_form_state, $form_state);
$this
->moveFormStateStorage($plugin_form_state, $form_state);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$key_value_data = $form_state
->get('key_value');
foreach ($this->entity
->getPlugins() as $type => $plugin) {
if ($plugin instanceof KeyPluginFormInterface) {
$plugin_form_state = $this
->createPluginFormState($type, $form_state);
$plugin
->submitConfigurationForm($form, $plugin_form_state);
$form_state
->setValue($type . '_settings', $plugin_form_state
->getValues());
}
}
if ($this->entity
->getKeyProvider() instanceof KeyProviderSettableValueInterface) {
$set_key_value = FALSE;
if ($this->originalKey && $this->originalKey
->getKeyProvider()
->getPluginId() != $this->entity
->getKeyProvider()
->getPluginId()) {
$set_key_value = TRUE;
}
if ($key_value_data['submitted'] != $key_value_data['obscured']) {
$set_key_value = TRUE;
}
if (!empty($key_value_data['processed_original']) && empty($key_value_data['submitted'])) {
$set_key_value = TRUE;
}
if ($set_key_value) {
$this->entity
->setKeyValue($key_value_data['processed_submitted']);
}
}
parent::submitForm($form, $form_state);
}
public function save(array $form, FormStateInterface $form_state) {
$status = parent::save($form, $form_state);
$t_args = [
'%name' => $this->entity
->label(),
];
if ($status == SAVED_UPDATED) {
$this
->messenger()
->addStatus($this
->t('The key %name has been updated.', $t_args));
}
elseif ($status == SAVED_NEW) {
$this
->messenger()
->addStatus($this
->t('The key %name has been added.', $t_args));
}
$form_state
->setRedirectUrl($this->entity
->toUrl('collection'));
return $status;
}
public function ajaxUpdateSettings(array &$form, FormStateInterface $form_state) {
return $form['settings'];
}
protected function updateKeyType(FormStateInterface $form_state) {
$key = $this->entity;
$plugin = $key
->getKeyType();
$key
->setPlugin('key_type', $plugin
->getPluginId());
if ($this->originalKey && $this->originalKey
->getKeyType()
->getPluginId() == $plugin
->getPluginId()) {
$configuration = $this->originalKey
->getKeyType()
->getConfiguration();
}
else {
$configuration = $plugin
->defaultConfiguration();
}
$plugin
->setConfiguration($configuration);
$form_state
->setValue('key_type_settings', []);
$form_state
->getUserInput()['key_type_settings'] = [];
}
protected function updateKeyProvider(FormStateInterface $form_state) {
$key = $this->entity;
$plugin = $key
->getKeyProvider();
$key
->setPlugin('key_provider', $plugin
->getPluginId());
if ($this->originalKey && $this->originalKey
->getKeyProvider()
->getPluginId() == $plugin
->getPluginId()) {
$configuration = $this->originalKey
->getKeyProvider()
->getConfiguration();
}
else {
$configuration = $plugin
->defaultConfiguration();
}
$plugin
->setConfiguration($configuration);
$form_state
->setValue('key_provider_settings', []);
$form_state
->getUserInput()['key_provider_settings'] = [];
}
protected function updateKeyInput(FormStateInterface $form_state) {
$key = $this->entity;
$plugin = $key
->getKeyInput();
$key_value_data = $form_state
->get('key_value');
$key_input_id = 'none';
if ($key
->getKeyProvider()
->getPluginDefinition()['key_value']['accepted']) {
$key_input_id = $key
->getKeyType()
->getPluginDefinition()['key_value']['plugin'];
}
$key
->setPlugin('key_input', $key_input_id);
$configuration = $plugin
->defaultConfiguration();
$key_value_data['current'] = '';
$use_original_key_value = FALSE;
if ($this->originalKey) {
if (empty($key_value_data['obscured'])) {
$use_original_key_value = TRUE;
}
if ($this->originalKey
->getKeyProvider()
->getPluginId() == $key
->getKeyProvider()
->getPluginId()) {
if ($this->originalKey
->getKeyType()
->getPluginId() == $key
->getKeyType()
->getPluginId()) {
$use_original_key_value = TRUE;
}
}
}
if ($use_original_key_value) {
$configuration = $this->originalKey
->getKeyInput()
->getConfiguration();
$key_value_data['current'] = !empty($key_value_data['obscured']) ? $key_value_data['obscured'] : $key_value_data['processed_original'];
}
$plugin
->setConfiguration($configuration);
$form_state
->setValue('key_input_settings', []);
$form_state
->getUserInput()['key_input_settings'] = [];
$form_state
->set('key_value', $key_value_data);
}
public function getOriginalKey() {
return $this->originalKey;
}
protected function createPluginFormState($type, FormStateInterface $form_state) {
$plugin_form_state = clone $form_state;
$plugin_form_state
->setValues($form_state
->getValue($type . '_settings', []));
return $plugin_form_state;
}
protected function moveFormStateErrors(FormStateInterface $from, FormStateInterface $to) {
foreach ($from
->getErrors() as $name => $error) {
$to
->setErrorByName($name, $error);
}
}
protected function moveFormStateStorage(FormStateInterface $from, FormStateInterface $to) {
foreach ($from
->getStorage() as $index => $value) {
$to
->set($index, $value);
}
}
}