Issue #3382510 by phenaproxima, Wim Leers, alexpott, longwave, claudiu.cristea, borisson_, lauriii, effulgentsia, bircher: Introduce a new #config_target Form API property to make it super simple to use validation constraints on simple config forms, and adopt it in several core config forms

merge-requests/5228/head
Alex Pott 2023-11-02 14:17:04 +00:00
parent 7cab8103ce
commit e1c95b2f99
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
17 changed files with 445 additions and 311 deletions

View File

@ -5,6 +5,7 @@ namespace Drupal\Core\Form;
use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -17,6 +18,18 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
abstract class ConfigFormBase extends FormBase {
use ConfigFormBaseTrait;
/**
* The $form_state key which stores a map of config keys to form elements.
*
* This map is generated and stored by ::storeConfigKeyToFormElementMap(),
* which is one of the form's #after_build callbacks.
*
* @see ::storeConfigKeyToFormElementMap()
*
* @var string
*/
protected const CONFIG_KEY_TO_FORM_ELEMENT_MAP = 'config_targets';
/**
* Constructs a \Drupal\system\ConfigFormBase object.
*
@ -60,14 +73,89 @@ abstract class ConfigFormBase extends FormBase {
// By default, render the form using system-config-form.html.twig.
$form['#theme'] = 'system_config_form';
// Load default values from config into any element with a #config_target
// property.
$form['#process'][] = '::loadDefaultValuesFromConfig';
$form['#after_build'][] = '::storeConfigKeyToFormElementMap';
return $form;
}
/**
* Process callback to recursively load default values from #config_target.
*
* @param array $element
* The form element.
*
* @return array
* The form element, with its default value populated.
*/
public function loadDefaultValuesFromConfig(array $element): array {
if (array_key_exists('#config_target', $element) && !array_key_exists('#default_value', $element)) {
$target = $element['#config_target'];
if (is_string($target)) {
$target = ConfigTarget::fromString($target);
}
$value = $this->config($target->configName)->get($target->propertyPath);
if ($target->fromConfig) {
$value = call_user_func($target->fromConfig, $value);
}
$element['#default_value'] = $value;
}
foreach (Element::children($element) as $key) {
$element[$key] = $this->loadDefaultValuesFromConfig($element[$key]);
}
return $element;
}
/**
* #after_build callback which stores a map of element names to config keys.
*
* This will store an array in the form state whose keys are strings in the
* form of `CONFIG_NAME:PROPERTY_PATH`, and whose values are instances of
* \Drupal\Core\Form\ConfigTarget.
*
* This callback is run in the form's #after_build stage, rather than
* #process, to guarantee that all of the form's elements have their final
* #name and #parents properties set.
*
* @param array $element
* The element being processed.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current form state.
*
* @return array
* The processed element.
*/
public function storeConfigKeyToFormElementMap(array $element, FormStateInterface $form_state): array {
if (array_key_exists('#config_target', $element)) {
$map = $form_state->get(static::CONFIG_KEY_TO_FORM_ELEMENT_MAP) ?? [];
$target = $element['#config_target'];
if (is_string($target)) {
$target = ConfigTarget::fromString($target);
}
$target->elementName = $element['#name'];
$target->elementParents = $element['#parents'];
$map[$target->configName . ':' . $target->propertyPath] = $target;
$form_state->set(static::CONFIG_KEY_TO_FORM_ELEMENT_MAP, $map);
}
foreach (Element::children($element) as $key) {
$element[$key] = $this->storeConfigKeyToFormElementMap($element[$key], $form_state);
}
return $element;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
assert($this->typedConfigManager instanceof TypedConfigManagerInterface);
$map = $form_state->get(static::CONFIG_KEY_TO_FORM_ELEMENT_MAP) ?? [];
foreach ($this->getEditableConfigNames() as $config_name) {
$config = $this->config($config_name);
try {
@ -90,9 +178,9 @@ abstract class ConfigFormBase extends FormBase {
// @see \Drupal\Core\Config\Schema\Sequence
// @see \Drupal\Core\Config\Schema\SequenceDataDefinition
$violations_per_form_element = [];
/** @var \Symfony\Component\Validator\ConstraintViolationInterface $violation */
foreach ($violations as $violation) {
$property_path = $violation->getPropertyPath();
$form_element_name = static::mapConfigKeyToFormElementName($config_name, $property_path);
// Default to index 0.
$index = 0;
// Detect if this is a sequence property path, and if so, determine the
@ -100,7 +188,11 @@ abstract class ConfigFormBase extends FormBase {
$matches = [];
if (preg_match("/.*\.(\d+)$/", $property_path, $matches) === 1) {
$index = intval($matches[1]);
// The property path as known in the config key-to-form element map
// will not have the sequence index in it.
$property_path = rtrim($property_path, '0123456789.');
}
$form_element_name = $map["$config_name:$property_path"]->elementName;
$violations_per_form_element[$form_element_name][$index] = $violation;
}
@ -191,45 +283,25 @@ abstract class ConfigFormBase extends FormBase {
*
* @see \Drupal\Core\Entity\EntityForm::copyFormValuesToEntity()
*/
protected static function copyFormValuesToConfig(Config $config, FormStateInterface $form_state): void {
// This allows ::submitForm() and ::validateForm() to know that this config
// form is not yet using constraint-based validation.
throw new \BadMethodCallException();
}
private static function copyFormValuesToConfig(Config $config, FormStateInterface $form_state): void {
$map = $form_state->get(static::CONFIG_KEY_TO_FORM_ELEMENT_MAP);
// If there's no map of config keys to form elements, this form does not
// yet support config validation.
// @see ::validateForm()
if ($map === NULL) {
throw new \BadMethodCallException();
}
/**
* Maps the given Config key to a form element name.
*
* @param string $config_name
* The name of the Config whose value triggered a validation error.
* @param string $key
* The Config key that triggered a validation error (which corresponds to a
* property path on the validation constraint violation).
*
* @return string
* The corresponding form element name.
*/
protected static function mapConfigKeyToFormElementName(string $config_name, string $key) : string {
return self::defaultMapConfigKeyToFormElementName($config_name, $key);
}
/**
* Default implementation for ::mapConfigKeyToFormElementName().
*
* Suitable when the configuration is mapped 1:1 to form elements: when the
* keys in the Config match the form element names exactly.
*
* @param string $config_name
* The name of the Config whose value triggered a validation error.
* @param string $key
* The Config key that triggered a validation error (which corresponds to a
* property path on the validation constraint violation).
*
* @return string
* The corresponding form element name.
*/
final protected static function defaultMapConfigKeyToFormElementName(string $config_name, string $key) : string {
return str_replace('.', '][', $key);
/** @var \Drupal\Core\Form\ConfigTarget $target */
foreach ($map as $target) {
if ($target->configName === $config->getName()) {
$value = $form_state->getValue($target->elementParents);
if ($target->toConfig) {
$value = call_user_func($target->toConfig, $value);
}
$config->set($target->propertyPath, $value);
}
}
}
}

View File

@ -0,0 +1,98 @@
<?php
declare(strict_types = 1);
namespace Drupal\Core\Form;
/**
* Represents the mapping of a config property to a form element.
*/
final class ConfigTarget {
/**
* The name of the form element which maps to this config property.
*
* @var string
*
* @see \Drupal\Core\Form\ConfigFormBase::storeConfigKeyToFormElementMap()
*
* @internal
* This property is for internal use only.
*/
public string $elementName;
/**
* The parents of the form element which maps to this config property.
*
* @var array
*
* @see \Drupal\Core\Form\ConfigFormBase::storeConfigKeyToFormElementMap()
*
* @internal
* This property is for internal use only.
*/
public array $elementParents;
/**
* Constructs a ConfigTarget object.
*
* @param string $configName
* The name of the config object being read from or written to, e.g.
* `system.site`.
* @param string $propertyPath
* The property path being read or written, e.g., `page.front`.
* @param string|null $fromConfig
* (optional) A callback which should transform the value loaded from
* config before it gets displayed by the form. If NULL, no transformation
* will be done. Defaults to NULL.
* @param string|null $toConfig
* (optional) A callback which should transform the value submitted by the
* form before it is set in the config object. If NULL, no transformation
* will be done. Defaults to NULL.
*/
public function __construct(
public readonly string $configName,
public readonly string $propertyPath,
public readonly ?string $fromConfig = NULL,
public readonly ?string $toConfig = NULL,
) {
// If they're passed at all, $fromConfig and $toConfig need to be string
// callables in order to guarantee that this object can be serialized as
// part of a larger form array. If these could be arrays, then they could be
// in the form of [$object, 'method'], which would break serialization if
// $object was not serializable. This is also why we don't type hint these
// parameters as ?callable, since that would allow closures (which can't
// be serialized).
if ($fromConfig) {
assert(is_callable($fromConfig));
}
if ($toConfig) {
assert(is_callable($toConfig));
}
}
/**
* Creates a ConfigTarget object.
*
* @param string $target
* The name of the config object, and property path, being read from or
* written to, in the form `CONFIG_NAME:PROPERTY_PATH`. For example,
* `system.site:page.front`.
* @param string|null $fromConfig
* (optional) A callback which should transform the value loaded from
* config before it gets displayed by the form. If NULL, no transformation
* will be done. Defaults to NULL.
* @param string|null $toConfig
* (optional) A callback which should transform the value submitted by the
* form before it is set in the config object. If NULL, no transformation
* will be done. Defaults to NULL.
*
* @return self
* A ConfigTarget instance.
*/
public static function fromString(string $target, ?string $fromConfig = NULL, ?string $toConfig = NULL): self {
[$configName, $propertyPath] = explode(':', $target, 2);
return new self($configName, $propertyPath, $fromConfig, $toConfig);
}
}

View File

@ -3,6 +3,7 @@
namespace Drupal\book\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\Form\FormStateInterface;
/**
@ -31,11 +32,10 @@ class BookSettingsForm extends ConfigFormBase {
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$types = node_type_get_names();
$config = $this->config('book.settings');
$form['book_allowed_types'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Content types allowed in book outlines'),
'#default_value' => $config->get('allowed_types'),
'#config_target' => new ConfigTarget('book.settings', 'allowed_types', toConfig: static::class . '::filterAndSortAllowedTypes'),
'#options' => $types,
'#description' => $this->t('Users with the %outline-perm permission can add all content types.', ['%outline-perm' => $this->t('Administer book outlines')]),
'#required' => TRUE,
@ -43,7 +43,7 @@ class BookSettingsForm extends ConfigFormBase {
$form['book_child_type'] = [
'#type' => 'radios',
'#title' => $this->t('Content type for the <em>Add child page</em> link'),
'#default_value' => $config->get('child_type'),
'#config_target' => 'book.settings:child_type',
'#options' => $types,
'#required' => TRUE,
];
@ -64,21 +64,21 @@ class BookSettingsForm extends ConfigFormBase {
}
/**
* {@inheritdoc}
* Transformation callback for the book_allowed_types config value.
*
* @param array $allowed_types
* The config value to transform.
*
* @return array
* The transformed value.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$allowed_types = array_filter($form_state->getValue('book_allowed_types'));
public static function filterAndSortAllowedTypes(array $allowed_types): array {
$allowed_types = array_filter($allowed_types);
// We need to save the allowed types in an array ordered by machine_name so
// that we can save them in the correct order if node type changes.
// @see book_node_type_update().
sort($allowed_types);
$this->config('book.settings')
// Remove unchecked types.
->set('allowed_types', $allowed_types)
->set('child_type', $form_state->getValue('book_child_type'))
->save();
parent::submitForm($form, $form_state);
return $allowed_types;
}
}

View File

@ -0,0 +1,56 @@
<?php
namespace Drupal\Tests\book\Kernel;
use Drupal\book\Form\BookSettingsForm;
use Drupal\Core\Form\FormState;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\node\Traits\ContentTypeCreationTrait;
/**
* @covers \Drupal\book\Form\BookSettingsForm
* @group book
*/
class BookSettingsFormTest extends KernelTestBase {
use ContentTypeCreationTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'book',
'field',
'node',
'system',
'text',
'user',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
$this->installConfig(['book', 'node']);
$this->createContentType(['type' => 'chapter']);
$this->createContentType(['type' => 'page']);
}
/**
* Tests that submitted values are processed and saved correctly.
*/
public function testConfigValuesSavedCorrectly(): void {
$form_state = new FormState();
$form_state->setValues([
'book_allowed_types' => ['page', 'chapter', ''],
'book_child_type' => 'page',
]);
$this->container->get('form_builder')->submitForm(BookSettingsForm::class, $form_state);
$config = $this->config('book.settings');
$this->assertSame(['chapter', 'page'], $config->get('allowed_types'));
$this->assertSame('page', $config->get('child_type'));
}
}

View File

@ -3,6 +3,7 @@
namespace Drupal\jsonapi\Form;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\Form\FormStateInterface;
/**
@ -30,31 +31,26 @@ class JsonApiSettingsForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$jsonapi_config = $this->config('jsonapi.settings');
$form['read_only'] = [
'#type' => 'radios',
'#title' => $this->t('Allowed operations'),
'#options' => [
'r' => $this->t('Accept only JSON:API read operations.'),
'rw' => $this->t('Accept all JSON:API create, read, update, and delete operations.'),
1 => $this->t('Accept only JSON:API read operations.'),
0 => $this->t('Accept all JSON:API create, read, update, and delete operations.'),
],
'#default_value' => $jsonapi_config->get('read_only') === TRUE ? 'r' : 'rw',
'#config_target' => new ConfigTarget(
'jsonapi.settings',
'read_only',
// Convert the value to an integer when displaying the config value in
// the form.
'intval',
// Convert the submitted value to a boolean before storing it in config.
'boolval',
),
'#description' => $this->t('Warning: Only enable all operations if the site requires it. <a href=":docs">Learn more about securing your site with JSON:API.</a>', [':docs' => 'https://www.drupal.org/docs/8/modules/jsonapi/security-considerations']),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('jsonapi.settings')
->set('read_only', $form_state->getValue('read_only') === 'r')
->save();
parent::submitForm($form, $form_state);
}
}

View File

@ -0,0 +1,44 @@
<?php
namespace Drupal\Tests\jsonapi\Functional;
use Drupal\Tests\BrowserTestBase;
/**
* @covers \Drupal\jsonapi\Form\JsonApiSettingsForm
* @group jsonapi
*/
class SettingsFormTest extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['jsonapi'];
/**
* {@inheritdoc}
*/
protected $defaultTheme = 'stark';
/**
* Tests the JSON:API settings form.
*/
public function testSettingsForm(): void {
$account = $this->drupalCreateUser(['administer site configuration']);
$this->drupalLogin($account);
$this->drupalGet('/admin/config/services/jsonapi');
$page = $this->getSession()->getPage();
$page->selectFieldOption('read_only', 0);
$page->pressButton('Save configuration');
$assert_session = $this->assertSession();
$assert_session->pageTextContains('The configuration options have been saved.');
$assert_session->fieldValueEquals('read_only', 0);
$page->selectFieldOption('read_only', 1);
$page->pressButton('Save configuration');
$assert_session->fieldValueEquals('read_only', '1');
$assert_session->pageTextContains('The configuration options have been saved.');
}
}

View File

@ -5,6 +5,7 @@ namespace Drupal\media\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\media\IFrameUrlHelper;
@ -103,7 +104,7 @@ class MediaSettingsForm extends ConfigFormBase {
'#title' => $this->t('iFrame domain'),
'#size' => 40,
'#maxlength' => 255,
'#default_value' => $domain,
'#config_target' => new ConfigTarget('media.settings', 'iframe_domain', toConfig: static::class . '::nullIfEmptyString'),
'#description' => $this->t('Enter a different domain from which to serve oEmbed content, including the <em>http://</em> or <em>https://</em> prefix. This domain needs to point back to this site, or existing oEmbed content may not display correctly, or at all.'),
];
@ -111,27 +112,23 @@ class MediaSettingsForm extends ConfigFormBase {
'#prefix' => '<hr>',
'#type' => 'checkbox',
'#title' => $this->t('Standalone media URL'),
'#default_value' => $this->config('media.settings')->get('standalone_url'),
'#config_target' => 'media.settings:standalone_url',
'#description' => $this->t("Allow users to access @media-entities at /media/{id}.", ['@media-entities' => $this->entityTypeManager->getDefinition('media')->getPluralLabel()]),
];
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
* Converts an empty string to NULL.
*
* @param string|null $value
* The value to transform.
*
* @return string|null
* The given string, or NULL if it was empty.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$iframe_domain = $form_state->getValue('iframe_domain');
// The empty string is not a valid URI, but NULL is allowed.
if ($iframe_domain === '') {
$iframe_domain = NULL;
}
$this->config('media.settings')
->set('iframe_domain', $iframe_domain)
->set('standalone_url', $form_state->getValue('standalone_url'))
->save();
parent::submitForm($form, $form_state);
public static function nullIfEmptyString(?string $value): ?string {
return $value ?: NULL;
}
}

View File

@ -95,7 +95,6 @@ class FileSystemForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('system.file');
$form['file_public_path'] = [
'#type' => 'item',
'#title' => $this->t('Public file system path'),
@ -138,7 +137,7 @@ class FileSystemForm extends ConfigFormBase {
$form['file_default_scheme'] = [
'#type' => 'radios',
'#title' => $this->t('Default download method'),
'#default_value' => $config->get('default_scheme'),
'#config_target' => 'system.file:default_scheme',
'#options' => $options,
'#description' => $this->t('This setting is used as the preferred download method. The use of public files is more efficient, but does not provide any access control.'),
];
@ -150,7 +149,7 @@ class FileSystemForm extends ConfigFormBase {
$form['temporary_maximum_age'] = [
'#type' => 'select',
'#title' => $this->t('Delete temporary files after'),
'#default_value' => $config->get('temporary_maximum_age'),
'#config_target' => 'system.file:temporary_maximum_age',
'#options' => $period,
'#description' => $this->t('Temporary files are not referenced, but are in the file system and therefore may show up in administrative lists. <strong>Warning:</strong> If enabled, temporary files will be permanently deleted and may not be recoverable.'),
];
@ -158,19 +157,4 @@ class FileSystemForm extends ConfigFormBase {
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$config = $this->config('system.file')
->set('temporary_maximum_age', $form_state->getValue('temporary_maximum_age'));
if ($form_state->hasValue('file_default_scheme')) {
$config->set('default_scheme', $form_state->getValue('file_default_scheme'));
}
$config->save();
parent::submitForm($form, $form_state);
}
}

View File

@ -70,12 +70,10 @@ class ImageToolkitForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$current_toolkit = $this->config('system.image')->get('toolkit');
$form['image_toolkit'] = [
'#type' => 'radios',
'#title' => $this->t('Select an image processing toolkit'),
'#default_value' => $current_toolkit,
'#config_target' => 'system.image:toolkit',
'#options' => [],
];
@ -117,10 +115,6 @@ class ImageToolkitForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('system.image')
->set('toolkit', $form_state->getValue('image_toolkit'))
->save();
// Call the form submit handler for each of the toolkits.
foreach ($this->availableToolkits as $toolkit) {
$toolkit->submitConfigurationForm($form, $form_state);

View File

@ -30,11 +30,10 @@ class LoggingForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('system.logging');
$form['error_level'] = [
'#type' => 'radios',
'#title' => $this->t('Error messages to display'),
'#default_value' => $config->get('error_level'),
'#config_target' => 'system.logging:error_level',
'#options' => [
ERROR_REPORTING_HIDE => $this->t('None'),
ERROR_REPORTING_DISPLAY_SOME => $this->t('Errors and warnings'),
@ -47,15 +46,4 @@ class LoggingForm extends ConfigFormBase {
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('system.logging')
->set('error_level', $form_state->getValue('error_level'))
->save();
parent::submitForm($form, $form_state);
}
}

View File

@ -106,8 +106,6 @@ class PerformanceForm extends ConfigFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$form['#attached']['library'][] = 'system/drupal.system';
$config = $this->config('system.performance');
$form['caching'] = [
'#type' => 'details',
'#title' => $this->t('Caching'),
@ -121,7 +119,7 @@ class PerformanceForm extends ConfigFormBase {
$form['caching']['page_cache_maximum_age'] = [
'#type' => 'select',
'#title' => $this->t('Browser and proxy cache maximum age'),
'#default_value' => $config->get('cache.page.max_age'),
'#config_target' => 'system.performance:cache.page.max_age',
'#options' => $period,
'#description' => $this->t('This is used as the value for max-age in Cache-Control headers.'),
];
@ -148,13 +146,13 @@ class PerformanceForm extends ConfigFormBase {
$form['bandwidth_optimization']['preprocess_css'] = [
'#type' => 'checkbox',
'#title' => $this->t('Aggregate CSS files'),
'#default_value' => $config->get('css.preprocess'),
'#config_target' => 'system.performance:css.preprocess',
'#disabled' => $disabled,
];
$form['bandwidth_optimization']['preprocess_js'] = [
'#type' => 'checkbox',
'#title' => $this->t('Aggregate JavaScript files'),
'#default_value' => $config->get('js.preprocess'),
'#config_target' => 'system.performance:js.preprocess',
'#disabled' => $disabled,
];
@ -168,12 +166,6 @@ class PerformanceForm extends ConfigFormBase {
$this->cssCollectionOptimizer->deleteAll();
$this->jsCollectionOptimizer->deleteAll();
$this->config('system.performance')
->set('cache.page.max_age', $form_state->getValue('page_cache_maximum_age'))
->set('css.preprocess', $form_state->getValue('preprocess_css'))
->set('js.preprocess', $form_state->getValue('preprocess_js'))
->save();
parent::submitForm($form, $form_state);
}

View File

@ -5,6 +5,7 @@ namespace Drupal\system\Form;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Datetime\TimeZoneFormHelper;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Locale\CountryManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
@ -69,7 +70,6 @@ class RegionalForm extends ConfigFormBase {
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$countries = $this->countryManager->getList();
$system_date = $this->config('system.date');
// Date settings:
$zones = TimeZoneFormHelper::getOptionsListByRegion();
@ -84,7 +84,7 @@ class RegionalForm extends ConfigFormBase {
'#type' => 'select',
'#title' => $this->t('Default country'),
'#empty_value' => '',
'#default_value' => $system_date->get('country.default'),
'#config_target' => 'system.date:country.default',
'#options' => $countries,
'#attributes' => ['class' => ['country-detect']],
];
@ -92,7 +92,7 @@ class RegionalForm extends ConfigFormBase {
$form['locale']['date_first_day'] = [
'#type' => 'select',
'#title' => $this->t('First day of week'),
'#default_value' => $system_date->get('first_day'),
'#config_target' => 'system.date:first_day',
'#options' => [0 => $this->t('Sunday'), 1 => $this->t('Monday'), 2 => $this->t('Tuesday'), 3 => $this->t('Wednesday'), 4 => $this->t('Thursday'), 5 => $this->t('Friday'), 6 => $this->t('Saturday')],
];
@ -105,7 +105,11 @@ class RegionalForm extends ConfigFormBase {
$form['timezone']['date_default_timezone'] = [
'#type' => 'select',
'#title' => $this->t('Default time zone'),
'#default_value' => $system_date->get('timezone.default') ?: date_default_timezone_get(),
'#config_target' => new ConfigTarget(
'system.date',
'timezone.default',
static::class . '::loadDefaultTimeZone',
),
'#options' => $zones,
];
@ -113,16 +117,16 @@ class RegionalForm extends ConfigFormBase {
}
/**
* {@inheritdoc}
* Prepares the saved timezone.default property to be displayed in the form.
*
* @param string $value
* The value saved in config.
*
* @return string
* The value of the form element.
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('system.date')
->set('country.default', $form_state->getValue('site_default_country'))
->set('first_day', $form_state->getValue('date_first_day'))
->set('timezone.default', $form_state->getValue('date_default_timezone'))
->save();
parent::submitForm($form, $form_state);
public static function loadDefaultTimeZone(string $value): string {
return $value ?: date_default_timezone_get();
}
}

View File

@ -33,7 +33,7 @@ class RssFeedsForm extends ConfigFormBase {
$form['feed_view_mode'] = [
'#type' => 'select',
'#title' => $this->t('Feed content'),
'#default_value' => $this->config('system.rss')->get('items.view_mode'),
'#config_target' => 'system.rss:items.view_mode',
'#options' => [
'title' => $this->t('Titles only'),
'teaser' => $this->t('Titles plus teaser'),
@ -45,15 +45,4 @@ class RssFeedsForm extends ConfigFormBase {
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('system.rss')
->set('items.view_mode', $form_state->getValue('feed_view_mode'))
->save();
parent::submitForm($form, $form_state);
}
}

View File

@ -80,7 +80,6 @@ class SiteMaintenanceModeForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('system.maintenance');
$permissions = $this->permissionHandler->getPermissions();
$permission_label = $permissions['access site in maintenance mode']['title'];
$form['maintenance_mode'] = [
@ -92,7 +91,7 @@ class SiteMaintenanceModeForm extends ConfigFormBase {
$form['maintenance_mode_message'] = [
'#type' => 'textarea',
'#title' => $this->t('Message to display when in maintenance mode'),
'#default_value' => $config->get('message'),
'#config_target' => 'system.maintenance:message',
];
return parent::buildForm($form, $form_state);
@ -102,10 +101,6 @@ class SiteMaintenanceModeForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('system.maintenance')
->set('message', $form_state->getValue('maintenance_mode_message'))
->save();
$this->state->set('system.maintenance_mode', $form_state->getValue('maintenance_mode'));
parent::submitForm($form, $form_state);
}

View File

@ -2,8 +2,8 @@
namespace Drupal\update;
use Drupal\Core\Config\Config;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\ConfigTarget;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Url;
use Drupal\Core\Form\FormStateInterface;
@ -33,12 +33,10 @@ class UpdateSettingsForm extends ConfigFormBase {
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$config = $this->config('update.settings');
$form['update_check_frequency'] = [
'#type' => 'radios',
'#title' => $this->t('Check for updates'),
'#default_value' => $config->get('check.interval_days'),
'#config_target' => 'update.settings:check.interval_days',
'#options' => [
'1' => $this->t('Daily'),
'7' => $this->t('Weekly'),
@ -49,22 +47,26 @@ class UpdateSettingsForm extends ConfigFormBase {
$form['update_check_disabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Check for updates of uninstalled modules and themes'),
'#default_value' => $config->get('check.disabled_extensions'),
'#config_target' => 'update.settings:check.disabled_extensions',
];
$notification_emails = $config->get('notification.emails');
$form['update_notify_emails'] = [
'#type' => 'textarea',
'#title' => $this->t('Email addresses to notify when updates are available'),
'#rows' => 4,
'#default_value' => implode("\n", $notification_emails),
'#config_target' => new ConfigTarget(
'update.settings',
'notification.emails',
static::class . '::arrayToMultiLineString',
static::class . '::multiLineStringToArray',
),
'#description' => $this->t('Whenever your site checks for available updates and finds new releases, it can notify a list of users via email. Put each address on a separate line. If blank, no emails will be sent.'),
];
$form['update_notification_threshold'] = [
'#type' => 'radios',
'#title' => $this->t('Email notification threshold'),
'#default_value' => $config->get('notification.threshold'),
'#config_target' => 'update.settings:notification.threshold',
'#options' => [
'all' => $this->t('All newer versions'),
'security' => $this->t('Only security updates'),
@ -82,46 +84,6 @@ class UpdateSettingsForm extends ConfigFormBase {
return parent::buildForm($form, $form_state);
}
/**
* {@inheritdoc}
*/
protected static function copyFormValuesToConfig(Config $config, FormStateInterface $form_state): void {
switch ($config->getName()) {
case 'update.settings':
$config
->set('check.disabled_extensions', $form_state->getValue('update_check_disabled'))
->set('check.interval_days', $form_state->getValue('update_check_frequency'))
->set('notification.emails', array_map('trim', explode("\n", trim($form_state->getValue('update_notify_emails', '')))))
->set('notification.threshold', $form_state->getValue('update_notification_threshold'));
break;
}
}
/**
* {@inheritdoc}
*/
protected static function mapConfigKeyToFormElementName(string $config_name, string $key): string {
switch ($config_name) {
case 'update.settings':
// A `type: sequence` of emails is mapped to a single textarea. Property
// paths are `notification.emails.0`, `notification.emails.1`, etc.
if (str_starts_with($key, 'notification.emails.')) {
return 'update_notify_emails';
}
return match ($key) {
'check.disabled_extensions' => 'update_check_disabled',
'check.interval_days' => 'update_check_frequency',
'notification.emails' => 'update_notify_emails',
'notification.threshold' => 'update_notification_threshold',
default => self::defaultMapConfigKeyToFormElementName($config_name, $key),
};
default:
throw new \InvalidArgumentException();
}
}
/**
* {@inheritdoc}
*/
@ -151,4 +113,30 @@ class UpdateSettingsForm extends ConfigFormBase {
parent::submitForm($form, $form_state);
}
/**
* Prepares the submitted value to be stored in the notify_emails property.
*
* @param string $value
* The submitted value.
*
* @return array
* The value to be stored in config.
*/
public static function multiLineStringToArray(string $value): array {
return array_map('trim', explode("\n", trim($value)));
}
/**
* Prepares the saved notify_emails property to be displayed in the form.
*
* @param array $value
* The value saved in config.
*
* @return string
* The value of the form element.
*/
public static function arrayToMultiLineString(array $value): string {
return implode("\n", $value);
}
}

View File

@ -86,7 +86,6 @@ class AccountSettingsForm extends ConfigFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$config = $this->config('user.settings');
$mail_config = $this->config('user.mail');
$site_config = $this->config('system.site');
$form['#attached']['library'][] = 'user/drupal.user.admin';
@ -100,7 +99,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['anonymous_settings']['anonymous'] = [
'#type' => 'textfield',
'#title' => $this->t('Name'),
'#default_value' => $config->get('anonymous'),
'#config_target' => 'user.settings:anonymous',
'#description' => $this->t('The name used to indicate anonymous users.'),
'#required' => TRUE,
];
@ -126,7 +125,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['registration_cancellation']['user_register'] = [
'#type' => 'radios',
'#title' => $this->t('Who can register accounts?'),
'#default_value' => $config->get('register'),
'#config_target' => 'user.settings:register',
'#options' => [
UserInterface::REGISTER_ADMINISTRATORS_ONLY => $this->t('Administrators only'),
UserInterface::REGISTER_VISITORS => $this->t('Visitors'),
@ -136,18 +135,18 @@ class AccountSettingsForm extends ConfigFormBase {
$form['registration_cancellation']['user_email_verification'] = [
'#type' => 'checkbox',
'#title' => $this->t('Require email verification when a visitor creates an account'),
'#default_value' => $config->get('verify_mail'),
'#config_target' => 'user.settings:verify_mail',
'#description' => $this->t('New users will be required to validate their email address prior to logging into the site, and will be assigned a system-generated password. With this setting disabled, users will be logged in immediately upon registering, and may select their own passwords during registration.'),
];
$form['registration_cancellation']['user_password_strength'] = [
'#type' => 'checkbox',
'#title' => $this->t('Enable password strength indicator'),
'#default_value' => $config->get('password_strength'),
'#config_target' => 'user.settings:password_strength',
];
$form['registration_cancellation']['user_cancel_method'] = [
'#type' => 'radios',
'#title' => $this->t('When cancelling a user account'),
'#default_value' => $config->get('cancel_method'),
'#config_target' => 'user.settings:cancel_method',
'#description' => $this->t('Users with the %select-cancel-method or %administer-users <a href=":permissions-url">permissions</a> can override this default method.', ['%select-cancel-method' => $this->t('Select method for cancelling account'), '%administer-users' => $this->t('Administer users'), ':permissions-url' => Url::fromRoute('user.admin_permissions')->toString()]),
];
$form['registration_cancellation']['user_cancel_method'] += user_cancel_methods();
@ -164,7 +163,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['mail_notification_address'] = [
'#type' => 'email',
'#title' => $this->t('Notification email address'),
'#default_value' => $site_config->get('mail_notification'),
'#config_target' => 'system.site:mail_notification',
'#description' => $this->t("The email address to be used as the 'from' address for all account notifications listed below. If <em>'Visitors, but administrator approval is required'</em> is selected above, a notification email will also be sent to this address for any new registrations. Leave empty to use the default system email address <em>(%site-email).</em>", ['%site-email' => $site_config->get('mail')]),
'#maxlength' => 180,
];
@ -187,14 +186,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_admin_created']['user_mail_register_admin_created_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('register_admin_created.subject'),
'#config_target' => 'user.mail:register_admin_created.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_admin_created']['user_mail_register_admin_created_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('register_admin_created.body'),
'#config_target' => 'user.mail:register_admin_created.body',
'#rows' => 15,
];
@ -208,14 +207,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_pending_approval']['user_mail_register_pending_approval_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('register_pending_approval.subject'),
'#config_target' => 'user.mail:register_pending_approval.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_pending_approval']['user_mail_register_pending_approval_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('register_pending_approval.body'),
'#config_target' => 'user.mail:register_pending_approval.body',
'#rows' => 8,
];
@ -229,14 +228,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_pending_approval_admin']['register_pending_approval_admin_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('register_pending_approval_admin.subject'),
'#config_target' => 'user.mail:register_pending_approval_admin.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_pending_approval_admin']['register_pending_approval_admin_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('register_pending_approval_admin.body'),
'#config_target' => 'user.mail:register_pending_approval_admin.body',
'#rows' => 8,
];
@ -250,14 +249,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_no_approval_required']['user_mail_register_no_approval_required_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('register_no_approval_required.subject'),
'#config_target' => 'user.mail:register_no_approval_required.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_no_approval_required']['user_mail_register_no_approval_required_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('register_no_approval_required.body'),
'#config_target' => 'user.mail:register_no_approval_required.body',
'#rows' => 15,
];
@ -271,14 +270,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_password_reset']['user_mail_password_reset_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('password_reset.subject'),
'#config_target' => 'user.mail:password_reset.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_password_reset']['user_mail_password_reset_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('password_reset.body'),
'#config_target' => 'user.mail:password_reset.body',
'#rows' => 12,
];
@ -291,7 +290,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_activated']['user_mail_status_activated_notify'] = [
'#type' => 'checkbox',
'#title' => $this->t('Notify user when account is activated'),
'#default_value' => $config->get('notify.status_activated'),
'#config_target' => 'user.settings:notify.status_activated',
];
$form['email_activated']['settings'] = [
'#type' => 'container',
@ -305,14 +304,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_activated']['settings']['user_mail_status_activated_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('status_activated.subject'),
'#config_target' => 'user.mail:status_activated.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_activated']['settings']['user_mail_status_activated_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('status_activated.body'),
'#config_target' => 'user.mail:status_activated.body',
'#rows' => 15,
];
@ -325,7 +324,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_blocked']['user_mail_status_blocked_notify'] = [
'#type' => 'checkbox',
'#title' => $this->t('Notify user when account is blocked'),
'#default_value' => $config->get('notify.status_blocked'),
'#config_target' => 'user.settings:notify.status_blocked',
];
$form['email_blocked']['settings'] = [
'#type' => 'container',
@ -339,14 +338,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_blocked']['settings']['user_mail_status_blocked_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('status_blocked.subject'),
'#config_target' => 'user.mail:status_blocked.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_blocked']['settings']['user_mail_status_blocked_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('status_blocked.body'),
'#config_target' => 'user.mail:status_blocked.body',
'#rows' => 3,
];
@ -359,14 +358,14 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_cancel_confirm']['user_mail_cancel_confirm_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('cancel_confirm.subject'),
'#config_target' => 'user.mail:cancel_confirm.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_cancel_confirm']['user_mail_cancel_confirm_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('cancel_confirm.body'),
'#config_target' => 'user.mail:cancel_confirm.body',
'#rows' => 3,
];
@ -379,7 +378,7 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_canceled']['user_mail_status_canceled_notify'] = [
'#type' => 'checkbox',
'#title' => $this->t('Notify user when account is canceled'),
'#default_value' => $config->get('notify.status_canceled'),
'#config_target' => 'user.settings:notify.status_canceled',
];
$form['email_canceled']['settings'] = [
'#type' => 'container',
@ -393,59 +392,18 @@ class AccountSettingsForm extends ConfigFormBase {
$form['email_canceled']['settings']['user_mail_status_canceled_subject'] = [
'#type' => 'textfield',
'#title' => $this->t('Subject'),
'#default_value' => $mail_config->get('status_canceled.subject'),
'#config_target' => 'user.mail:status_canceled.subject',
'#required' => TRUE,
'#maxlength' => 180,
];
$form['email_canceled']['settings']['user_mail_status_canceled_body'] = [
'#type' => 'textarea',
'#title' => $this->t('Body'),
'#default_value' => $mail_config->get('status_canceled.body'),
'#config_target' => 'user.mail:status_canceled.body',
'#rows' => 3,
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
parent::submitForm($form, $form_state);
$this->config('user.settings')
->set('anonymous', $form_state->getValue('anonymous'))
->set('register', $form_state->getValue('user_register'))
->set('password_strength', $form_state->getValue('user_password_strength'))
->set('verify_mail', $form_state->getValue('user_email_verification'))
->set('cancel_method', $form_state->getValue('user_cancel_method'))
->set('notify.status_activated', $form_state->getValue('user_mail_status_activated_notify'))
->set('notify.status_blocked', $form_state->getValue('user_mail_status_blocked_notify'))
->set('notify.status_canceled', $form_state->getValue('user_mail_status_canceled_notify'))
->save();
$this->config('user.mail')
->set('cancel_confirm.body', $form_state->getValue('user_mail_cancel_confirm_body'))
->set('cancel_confirm.subject', $form_state->getValue('user_mail_cancel_confirm_subject'))
->set('password_reset.body', $form_state->getValue('user_mail_password_reset_body'))
->set('password_reset.subject', $form_state->getValue('user_mail_password_reset_subject'))
->set('register_admin_created.body', $form_state->getValue('user_mail_register_admin_created_body'))
->set('register_admin_created.subject', $form_state->getValue('user_mail_register_admin_created_subject'))
->set('register_no_approval_required.body', $form_state->getValue('user_mail_register_no_approval_required_body'))
->set('register_no_approval_required.subject', $form_state->getValue('user_mail_register_no_approval_required_subject'))
->set('register_pending_approval.body', $form_state->getValue('user_mail_register_pending_approval_body'))
->set('register_pending_approval.subject', $form_state->getValue('user_mail_register_pending_approval_subject'))
->set('register_pending_approval_admin.body', $form_state->getValue('register_pending_approval_admin_body'))
->set('register_pending_approval_admin.subject', $form_state->getValue('register_pending_approval_admin_subject'))
->set('status_activated.body', $form_state->getValue('user_mail_status_activated_body'))
->set('status_activated.subject', $form_state->getValue('user_mail_status_activated_subject'))
->set('status_blocked.body', $form_state->getValue('user_mail_status_blocked_body'))
->set('status_blocked.subject', $form_state->getValue('user_mail_status_blocked_subject'))
->set('status_canceled.body', $form_state->getValue('user_mail_status_canceled_body'))
->set('status_canceled.subject', $form_state->getValue('user_mail_status_canceled_subject'))
->save();
$this->config('system.site')
->set('mail_notification', $form_state->getValue('mail_notification_address'))
->save();
}
}

View File

@ -70,7 +70,6 @@ class BasicSettingsForm extends ConfigFormBase {
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$config = $this->config('views.settings');
$options = [];
foreach ($this->themeHandler->listInfo() as $name => $theme) {
if ($theme->status) {
@ -85,27 +84,27 @@ class BasicSettingsForm extends ConfigFormBase {
$form['basic']['ui_show_default_display'] = [
'#type' => 'checkbox',
'#title' => $this->t('Always show the default display'),
'#default_value' => $config->get('ui.show.default_display'),
'#config_target' => 'views.settings:ui.show.default_display',
];
$form['basic']['ui_show_advanced_column'] = [
'#type' => 'checkbox',
'#title' => $this->t('Always show advanced display settings'),
'#default_value' => $config->get('ui.show.advanced_column'),
'#config_target' => 'views.settings:ui.show.advanced_column',
];
$form['basic']['ui_show_display_embed'] = [
'#type' => 'checkbox',
'#title' => $this->t('Allow embedded displays'),
'#description' => $this->t('Embedded displays can be used in code via views_embed_view().'),
'#default_value' => $config->get('ui.show.display_embed'),
'#config_target' => 'views.settings:ui.show.display_embed',
];
$form['basic']['ui_exposed_filter_any_label'] = [
'#type' => 'select',
'#title' => $this->t('Label for "Any" value on non-required single-select exposed filters'),
'#options' => ['old_any' => '<Any>', 'new_any' => $this->t('- Any -')],
'#default_value' => $config->get('ui.exposed_filter_any_label'),
'#config_target' => 'views.settings:ui.exposed_filter_any_label',
];
$form['live_preview'] = [
@ -117,13 +116,13 @@ class BasicSettingsForm extends ConfigFormBase {
$form['live_preview']['ui_always_live_preview'] = [
'#type' => 'checkbox',
'#title' => $this->t('Automatically update preview on changes'),
'#default_value' => $config->get('ui.always_live_preview'),
'#config_target' => 'views.settings:ui.always_live_preview',
];
$form['live_preview']['ui_show_preview_information'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show information and statistics about the view during live preview'),
'#default_value' => $config->get('ui.show.preview_information'),
'#config_target' => 'views.settings:ui.show.preview_information',
];
$form['live_preview']['options'] = [
@ -138,7 +137,7 @@ class BasicSettingsForm extends ConfigFormBase {
$form['live_preview']['options']['ui_show_sql_query_enabled'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show the SQL query'),
'#default_value' => $config->get('ui.show.sql_query.enabled'),
'#config_target' => 'views.settings:ui.show.sql_query.enabled',
];
$form['live_preview']['options']['ui_show_sql_query_where'] = [
@ -153,43 +152,23 @@ class BasicSettingsForm extends ConfigFormBase {
'above' => $this->t('Above the preview'),
'below' => $this->t('Below the preview'),
],
'#default_value' => $config->get('ui.show.sql_query.where'),
'#config_target' => 'views.settings:ui.show.sql_query.where',
];
$form['live_preview']['options']['ui_show_performance_statistics'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show performance statistics'),
'#default_value' => $config->get('ui.show.performance_statistics'),
'#config_target' => 'views.settings:ui.show.performance_statistics',
];
$form['live_preview']['options']['ui_show_additional_queries'] = [
'#type' => 'checkbox',
'#title' => $this->t('Show other queries run during render during live preview'),
'#description' => $this->t("Drupal has the potential to run many queries while a view is being rendered. Checking this box will display every query run during view render as part of the live preview."),
'#default_value' => $config->get('ui.show.additional_queries'),
'#config_target' => 'views.settings:ui.show.additional_queries',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$this->config('views.settings')
->set('ui.show.default_display', $form_state->getValue('ui_show_default_display'))
->set('ui.show.advanced_column', $form_state->getValue('ui_show_advanced_column'))
->set('ui.show.display_embed', $form_state->getValue('ui_show_display_embed'))
->set('ui.exposed_filter_any_label', $form_state->getValue('ui_exposed_filter_any_label'))
->set('ui.always_live_preview', $form_state->getValue('ui_always_live_preview'))
->set('ui.show.preview_information', $form_state->getValue('ui_show_preview_information'))
->set('ui.show.sql_query.where', $form_state->getValue('ui_show_sql_query_where'))
->set('ui.show.sql_query.enabled', $form_state->getValue('ui_show_sql_query_enabled'))
->set('ui.show.performance_statistics', $form_state->getValue('ui_show_performance_statistics'))
->set('ui.show.additional_queries', $form_state->getValue('ui_show_additional_queries'))
->save();
parent::submitForm($form, $form_state);
}
}