Change record status: 
Project: 
Introduced in branch: 
8.x
Description: 

Note: As of beta 6, https://drupal.org/node/2407153 makes this partially outdated. Particularly, the getEditableConfigNames() method must now be implemented. See https://drupal.org/node/2407153 for more information.

Drupal 7 and below contained a function system_settings_form() which took over a form's submit function and automatically mapped its fields to variables using the variable system. With the change to the new configuration system, this function was no longer appropriate, therefore it has been removed. Forms using system_settings_form() will have to be converted to form classes extending \Drupal\Core\Form\ConfigFormBase which implement Drupal 8's FormInterface. This provides a consistent submit button and theme definition. As part of the conversion a form submit methods will have to be written for each form by hand. Read more about FormInterface here: http://drupal.org/node/1932058

Note: If your settings form used to relay on $form['array_filter'] = ['#type' => 'value', '#value' => TRUE]; use to add array_filter() manually in submit method.

Drupal 7

function system_site_maintenance_mode() {
  $form['maintenance_mode'] = array(
    '#type' => 'checkbox', 
    '#title' => t('Put site into maintenance mode'), 
    '#default_value' => variable_get('maintenance_mode', 0), 
    '#description' => t('When enabled, only users with the "Use the site in maintenance mode" <a href="@permissions-url">permission</a> are able to access your site to perform maintenance; all other visitors see the maintenance mode message configured below. Authorized users can log in directly via the <a href="@user-login">user login</a> page.', array('@permissions-url' => url('admin/people/permissions'), '@user-login' => url('user'))),
  );
  $form['maintenance_mode_message'] = array(
    '#type' => 'textarea', 
    '#title' => t('Maintenance mode message'), 
    '#default_value' => variable_get('maintenance_mode_message', t('@site is currently under maintenance. We should be back shortly. Thank you for your patience.', array('@site' => variable_get('site_name', 'Drupal')))), 
    '#description' => t('Message to show visitors when the site is in maintenance mode.'),
  );

  return system_settings_form($form);
}

Drupal 8

This example is outdated. Better read Working with Configuration Forms.


/**
 * @file
 * Contains \Drupal\system\Form\SiteMaintenanceModeForm.
 */

namespace Drupal\Core\Form;

use Drupal\Core\Form\ConfigFormBase;

/**
 * Defines a form to configure maintenance settings for this site.
 */
class SiteMaintenanceModeForm extends ConfigFormBase {

  /**
   * {@inheritdoc}
   */
  public function getFormID() {
    return 'system_site_maintenance_mode';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this->config('system.maintenance');
    $form['maintenance_mode'] = array(
      '#type' => 'checkbox',
      '#title' => t('Put site into maintenance mode'),
      '#default_value' => $this->state->get('system.maintenance_mode'),
      '#description' => t('Visitors will only see the maintenance mode message. Only users with the "Access site in maintenance mode" <a href="@permissions-url">permission</a> will be able to access the site. Authorized users can log in directly via the <a href="@user-login">user login</a> page.', array('@permissions-url' => $this->url('user.admin_permissions'), '@user-login' => $this->url('user.login'))),
    );
    $form['maintenance_mode_message'] = array(
      '#type' => 'textarea',
      '#title' => t('Message to display when in maintenance mode'),
      '#default_value' => $config->get('message'),
    );

    return parent::buildForm($form, $form_state);
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, array &$form_state) {
    $this->config('system.maintenance')
      ->set('enabled', $form_state['values']['maintenance_mode'])
      ->set('message', $form_state['values']['maintenance_mode_message'])
      ->save();

    parent::submitForm($form, $form_state);
  }

}

Note that the system_config_form() helper that was added during Drupal 8 development has been removed.

Impacts: 
Module developers
Updates Done (doc team, etc.)
Online documentation: 
Not done
Theming guide: 
Not done
Module developer documentation: 
Not done
Examples project: 
Not done
Coder Review: 
Not done
Coder Upgrade: 
Not done
Other: 
Other updates done

Comments

mjkovacevich’s picture

Great! More code to do the same thing???

rvarkonyi’s picture

Hello,

I've been experimenting with configuration management and ConfigFormBase. I understand that with the new system it's not relevant anymore to use system_settings_form(). But if we look back at Drupal 7 and before, system_settings_form() did a lot more than simply provide a submit button and a status message. I guess I don't need to explain what it actually did but we all agree that it made our life much easier than the current Drupal 8 workflow of manually retrieving our module's configuration object and saving individual values by hand. It's not that I'm lazy to do that but I feel that this approach can introduce unnecessary bugs and headache during the development of a module (typos, accidentally skipping config settings etc), while system_settings_form() simply took care of all that automatically.

I think that ConfigFormBase should do the same thing, otherwise it's a pretty useless class I think. Yes it adds a themed submit button and a status message on submit but I don't see much value in that compared to the amount of work needed to actually make use of configuration management in forms.

I've got some ideas to actually make this work automatically, so please let me know if I should come up with a patch.

Thanks,
Rob

sebas5384’s picture

hey! I'm going to make a patch for the missing part of automatically saving values into a configuration, and I think that a perfect place is in the ConfigFormBase class.

I'll post here my progress about that :)

alexdmccabe’s picture

Something like this? It could obviously use a lot of work, but I think this is pointing in the right direction at least...

diff --git a/core/lib/Drupal/Core/Form/ConfigFormBase.php b/core/lib/Drupal/Core/Form/ConfigFormBase.php
index f58bc11..ffefcae 100644
--- a/core/lib/Drupal/Core/Form/ConfigFormBase.php
+++ b/core/lib/Drupal/Core/Form/ConfigFormBase.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\Form\FormBase;
+use Drupal\Core\Render\Element;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
@@ -39,6 +40,8 @@ public static function create(ContainerInterface $container) {
    * {@inheritdoc}
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
+    $form['#config']['keys'] = Element::children($form);
+
     $form['actions']['#type'] = 'actions';
     $form['actions']['submit'] = array(
       '#type' => 'submit',
@@ -56,6 +59,12 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@inheritdoc}
    */
   public function submitForm(array &$form, FormStateInterface $form_state) {
+    foreach ($form['#config']['keys'] as $key) {
+      \Drupal::config($form['#config']['location'])
+        ->set($key, $form_state->getValue($key))
+        ->save();
+    }
+
     drupal_set_message($this->t('The configuration options have been saved.'));
   }
 
diff --git a/core/modules/system/src/Form/SiteMaintenanceModeForm.php b/core/modules/system/src/Form/SiteMaintenanceModeForm.php
index b87533e..0dcaa16 100644
--- a/core/modules/system/src/Form/SiteMaintenanceModeForm.php
+++ b/core/modules/system/src/Form/SiteMaintenanceModeForm.php
@@ -59,6 +59,9 @@ public function getFormId() {
    */
   public function buildForm(array $form, FormStateInterface $form_state) {
     $config = $this->config('system.maintenance');
+
+    $form['#config']['location'] = 'system.maintenance';
+
     $form['maintenance_mode'] = array(
       '#type' => 'checkbox',
       '#title' => t('Put site into maintenance mode'),
@@ -78,10 +81,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
    * {@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);
   }
jlbellido’s picture

No plans for supporting this feature at D8 : https://www.drupal.org/node/2370611

SKAUGHT’s picture

a cleaner (d8 released) example would be:
/core/modules/system/src/Form/LoggingForm.php