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
parent
7cab8103ce
commit
e1c95b2f99
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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'));
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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.');
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue