From 10b43b953b19f38bdb8fdcb695b52cb1673a54e6 Mon Sep 17 00:00:00 2001
From: Alex Pott <alex.a.pott@googlemail.com>
Date: Fri, 27 Sep 2013 12:06:58 +0200
Subject: [PATCH] Issue #1953528 by swentel, Hydra: Store 'per-bundle view mode
 settings' in CMI, get rid of field_bundle_settings() & its variable.

---
 core/includes/entity.inc                      |  42 ++++--
 .../Core/Entity/EntityFormController.php      |   8 +-
 .../Drupal/comment/CommentFormController.php  |   4 +-
 core/modules/entity/entity.install            |   2 +
 .../Drupal/entity/Entity/EntityDisplay.php    |   3 +-
 .../entity/Entity/EntityFormDisplay.php       |   3 +-
 .../lib/Drupal/entity/EntityDisplayBase.php   |   9 ++
 core/modules/field/field.install              |  33 +++--
 core/modules/field/field.module               | 126 ------------------
 .../field/lib/Drupal/field/FieldInfo.php      |  41 +-----
 .../field_ui/Access/FormModeAccessCheck.php   |  12 +-
 .../field_ui/Access/ViewModeAccessCheck.php   |  12 +-
 .../lib/Drupal/field_ui/DisplayOverview.php   |  13 +-
 .../Drupal/field_ui/DisplayOverviewBase.php   |  84 +++++++++---
 .../Drupal/field_ui/FormDisplayOverview.php   |  13 +-
 ...y.display.taxonomy_term.forums.default.yml |   1 +
 ...m_display.taxonomy_term.forums.default.yml |   1 +
 .../Tests/Entity/FieldSqlStorageTest.php      |   3 +-
 .../tests/upgrade/drupal-7.field.database.php |  10 +-
 .../user/Tests/UserRegistrationTest.php       |   2 +
 core/modules/user/user.install                |  13 +-
 .../entity.display.node.article.default.yml   |   1 +
 .../entity.display.node.article.teaser.yml    |   1 +
 ...tity.form_display.node.article.default.yml |   1 +
 24 files changed, 181 insertions(+), 257 deletions(-)

diff --git a/core/includes/entity.inc b/core/includes/entity.inc
index e8a0e956b1b0..390d9763b6db 100644
--- a/core/includes/entity.inc
+++ b/core/includes/entity.inc
@@ -717,6 +717,7 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
       'targetEntityType' => $entity_type,
       'bundle' => $bundle,
       'mode' => $view_mode,
+      'status' => TRUE,
     ));
   }
 
@@ -750,12 +751,20 @@ function entity_get_display($entity_type, $bundle, $view_mode) {
 function entity_get_render_display(EntityInterface $entity, $view_mode) {
   $entity_type = $entity->entityType();
   $bundle = $entity->bundle();
-
-  // Determine the display to use for rendering this entity. Depending on the
-  // configuration of the view mode for this bundle, this will be either the
-  // display associated to the view mode, or the 'default' display.
-  $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
-  $render_view_mode = !empty($view_mode_settings[$view_mode]['status']) ? $view_mode : 'default';
+  $render_view_mode = 'default';
+
+  // Look at the default display and display for the view mode, and fallback to
+  // the former if the latter does not exist is disabled.
+  if ($view_mode != 'default') {
+    $ids = array(
+      'default' => $entity_type . '.' . $bundle . '.default',
+      $view_mode => $entity_type . '.' . $bundle . '.' . $view_mode,
+    );
+    $entity_displays = entity_load_multiple('entity_display', $ids);
+    if (isset($entity_displays[$ids[$view_mode]]) && $entity_displays[$ids[$view_mode]]->status()) {
+      $render_view_mode = $view_mode;
+    }
+  }
 
   $display = entity_get_display($entity_type, $bundle, $render_view_mode);
   $display->originalMode = $view_mode;
@@ -812,6 +821,7 @@ function entity_get_form_display($entity_type, $bundle, $form_mode) {
       'targetEntityType' => $entity_type,
       'bundle' => $bundle,
       'mode' => $form_mode,
+      'status' => TRUE,
     ));
   }
 
@@ -841,12 +851,20 @@ function entity_get_form_display($entity_type, $bundle, $form_mode) {
 function entity_get_render_form_display(EntityInterface $entity, $form_mode) {
   $entity_type = $entity->entityType();
   $bundle = $entity->bundle();
-
-  // Determine the form display to use for rendering this entity form. Depending
-  // on the configuration of the form mode for this bundle, this will be either
-  // the form display associated to the form mode, or the 'default' display.
-  $form_mode_settings = field_form_mode_settings($entity_type, $bundle);
-  $render_form_mode = !empty($form_mode_settings[$form_mode]['status']) ? $form_mode : 'default';
+  $render_form_mode = 'default';
+
+  // Look at the default form display and form display for the view mode, and
+  // fallback to the former if the latter does not exist is disabled.
+  if ($form_mode != 'default') {
+    $ids = array(
+      'default' => $entity_type . '.' . $bundle . '.default',
+      $form_mode => $entity_type . '.' . $bundle . '.' . $form_mode,
+    );
+    $entity_form_displays = entity_load_multiple('entity_form_display', $ids);
+    if (isset($entity_form_displays[$ids[$form_mode]]) && $entity_form_displays[$ids[$form_mode]]->status()) {
+      $render_form_mode = $form_mode;
+    }
+  }
 
   $form_display = entity_get_form_display($entity_type, $bundle, $render_form_mode);
   $form_display->originalMode = $form_mode;
diff --git a/core/lib/Drupal/Core/Entity/EntityFormController.php b/core/lib/Drupal/Core/Entity/EntityFormController.php
index 552813b14866..d59ace315a0f 100644
--- a/core/lib/Drupal/Core/Entity/EntityFormController.php
+++ b/core/lib/Drupal/Core/Entity/EntityFormController.php
@@ -186,12 +186,16 @@ public function processForm($element, $form_state, $form) {
       }
     }
 
-    // Hide extra fields.
+    // Hide or assign weights for extra fields.
     $extra_fields = field_info_extra_fields($this->entity->entityType(), $this->entity->bundle(), 'form');
     foreach ($extra_fields as $extra_field => $info) {
-      if (!$this->getFormDisplay($form_state)->getComponent($extra_field)) {
+      $component = $this->getFormDisplay($form_state)->getComponent($extra_field);
+      if (!$component) {
         $element[$extra_field]['#access'] = FALSE;
       }
+      else {
+        $element[$extra_field]['#weight'] = $component['weight'];
+      }
     }
 
     return $element;
diff --git a/core/modules/comment/lib/Drupal/comment/CommentFormController.php b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
index 8256889d0861..0b6f2b16fbd5 100644
--- a/core/modules/comment/lib/Drupal/comment/CommentFormController.php
+++ b/core/modules/comment/lib/Drupal/comment/CommentFormController.php
@@ -46,9 +46,7 @@ public function form(array $form, array &$form_state) {
       $form += $form_state['comment_preview'];
     }
 
-    $form['author'] = array(
-      '#weight' => 10,
-    );
+    $form['author'] = array();
     // Display author information in a details element for comment moderators.
     if ($is_admin) {
       $form['author'] += array(
diff --git a/core/modules/entity/entity.install b/core/modules/entity/entity.install
index 01d898eaa3b3..5ed9e6bc100b 100644
--- a/core/modules/entity/entity.install
+++ b/core/modules/entity/entity.install
@@ -37,6 +37,7 @@ function _update_8000_entity_get_display($entity_type, $bundle, $view_mode) {
     'bundle' => $bundle,
     'mode' => $view_mode,
     'content' => array(),
+    'status' => TRUE,
   );
   foreach ($properties as $key => $value) {
     $config->set($key, $value);
@@ -76,6 +77,7 @@ function _update_8000_entity_get_form_display($entity_type, $bundle, $form_mode)
     'bundle' => $bundle,
     'mode' => $form_mode,
     'content' => array(),
+    'status' => TRUE,
   );
   foreach ($properties as $key => $value) {
     $config->set($key, $value);
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
index 29bf629fb20d..8b5936663f47 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityDisplay.php
@@ -26,7 +26,8 @@
  *   config_prefix = "entity.display",
  *   entity_keys = {
  *     "id" = "id",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
+ *     "status" = "status"
  *   }
  * )
  */
diff --git a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
index 6b0151042fa2..1e04cfb8010c 100644
--- a/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
+++ b/core/modules/entity/lib/Drupal/entity/Entity/EntityFormDisplay.php
@@ -26,7 +26,8 @@
  *   config_prefix = "entity.form_display",
  *   entity_keys = {
  *     "id" = "id",
- *     "uuid" = "uuid"
+ *     "uuid" = "uuid",
+ *     "status" = "status"
  *   }
  * )
  */
diff --git a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
index eabce2509f34..eab0b66fb5fd 100644
--- a/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
+++ b/core/modules/entity/lib/Drupal/entity/EntityDisplayBase.php
@@ -50,6 +50,14 @@ abstract class EntityDisplayBase extends ConfigEntityBase implements EntityDispl
    */
   public $mode;
 
+  /**
+   * Whether this display is enabled or not. If the entity (form) display
+   * is disabled, we'll fall back to the 'default' display.
+   *
+   * @var boolean
+   */
+  public $status;
+
   /**
    * List of component display options, keyed by component name.
    *
@@ -143,6 +151,7 @@ public function getExportProperties() {
       'bundle',
       'mode',
       'content',
+      'status',
     );
     $properties = array();
     foreach ($names as $name) {
diff --git a/core/modules/field/field.install b/core/modules/field/field.install
index c4211ffe8ae9..0029a60660e9 100644
--- a/core/modules/field/field.install
+++ b/core/modules/field/field.install
@@ -240,16 +240,16 @@ function field_update_8002() {
       ->execute();
   }
 
-  // Migration of 'extra_fields' display settings. Avoid calling
-  // entity_get_info() by fetching the relevant variables directly in the
-  // variable table.
+  // Migration of the content of the old 'bundle_settings_*'' variables.
+  // Avoid calling entity_get_info() by fetching the relevant variables
+  // directly in the variable table.
   $variables = array_map('unserialize', db_query("SELECT name, value FROM {variable} WHERE name LIKE '%field_bundle_settings_%'")->fetchAllKeyed());
   foreach ($variables as $variable_name => $variable_value) {
     if (preg_match('/field_bundle_settings_(.*)__(.*)/', $variable_name, $matches)) {
-      $variable_needs_update = FALSE;
       $entity_type = $matches[1];
       $bundle = $matches[2];
 
+      // Migrate form settings for extra fields.
       if (isset($variable_value['extra_fields']['form'])) {
         foreach ($variable_value['extra_fields']['form'] as $field_name => $field_settings) {
           // Determine name and create initial entry in the $form_displays
@@ -260,12 +260,9 @@ function field_update_8002() {
           }
           $form_displays[$form_display_id]->set("content.$field_name", $field_settings);
         }
-
-        // Remove the old entry.
-        unset($variable_value['extra_fields']['form']);
-        $variable_needs_update = TRUE;
       }
 
+      // Migrate display settings for extra fields.
       if (isset($variable_value['extra_fields']['display'])) {
         foreach ($variable_value['extra_fields']['display'] as $field_name => $field_settings) {
           foreach ($field_settings as $view_mode => $display_options) {
@@ -286,15 +283,23 @@ function field_update_8002() {
             $displays[$display_id]->set("content.$field_name", $new_options);
           }
         }
-
-        // Remove the old entry.
-        unset($variable_value['extra_fields']['display']);
-        $variable_needs_update = TRUE;
       }
 
-      if ($variable_needs_update) {
-        variable_set($variable_name, $variable_value);
+      // Migrate view mode settings.
+      if (isset($variable_value['view_modes'])) {
+        foreach ($variable_value['view_modes'] as $view_mode => $view_mode_settings) {
+          // Determine name and create initial entry in the $displays array
+          // if it does not exist yet.
+          $display_id =  $entity_type . '.' . $bundle . '.' . $view_mode;
+          if (!isset($displays[$display_id])) {
+            $displays[$display_id] = _update_8000_entity_get_display($entity_type, $bundle, $view_mode);
+          }
+          $displays[$display_id]->set('status', $view_mode_settings['custom_settings']);
+        }
       }
+
+      // Remove the variable.
+      update_variable_del($variable_name);
     }
   }
 
diff --git a/core/modules/field/field.module b/core/modules/field/field.module
index 681fc6372a83..01c9181edaa0 100644
--- a/core/modules/field/field.module
+++ b/core/modules/field/field.module
@@ -295,11 +295,6 @@ function field_entity_bundle_rename($entity_type, $bundle_old, $bundle_new) {
 
   // Clear the field cache.
   field_cache_clear();
-
-  // Update bundle settings.
-  $settings = variable_get('field_bundle_settings_' . $entity_type . '__' . $bundle_old, array());
-  variable_set('field_bundle_settings_' . $entity_type . '__' . $bundle_new, $settings);
-  variable_del('field_bundle_settings_' . $entity_type . '__' . $bundle_old);
 }
 
 /**
@@ -323,9 +318,6 @@ function field_entity_bundle_delete($entity_type, $bundle) {
 
   // Clear the cache.
   field_cache_clear();
-
-  // Clear bundle display settings.
-  variable_del('field_bundle_settings_' . $entity_type . '__' . $bundle);
 }
 
 /**
@@ -408,124 +400,6 @@ function field_sync_field_status() {
   field_cache_clear();
 }
 
-/**
- * Gets or sets administratively defined bundle settings.
- *
- * @param string $entity_type
- *   The type of $entity; e.g., 'node' or 'user'.
- * @param string $bundle
- *   The bundle name.
- * @param array|null $settings
- *   (optional) The settings to store, an associative array with the following
- *   elements:
- *   - view_modes: An associative array keyed by view mode, with the following
- *     key/value pairs:
- *     - status: Boolean specifying whether the view mode uses a dedicated set
- *       of display options (TRUE), or the 'default' options (FALSE). Defaults
- *       to FALSE.
- *   - extra_fields: An associative array containing the form and display
- *     settings for extra fields (also known as pseudo-fields):
- *     - form: An associative array whose keys are the names of extra fields,
- *       and whose values are associative arrays with the following elements:
- *       - weight: The weight of the extra field, determining its position on an
- *         entity form.
- *     - display: An associative array whose keys are the names of extra fields,
- *       and whose values are associative arrays keyed by the name of view
- *       modes. This array must include an item for the 'default' view mode.
- *       Each view mode sub-array contains the following elements:
- *       - weight: The weight of the extra field, determining its position when
- *         an entity is viewed.
- *       - visible: TRUE if the extra field is visible, FALSE otherwise.
- *
- * @return array|null
- *   If no $settings are passed, the current settings are returned.
- */
-function field_bundle_settings($entity_type, $bundle, $settings = NULL) {
-  if (isset($settings)) {
-    variable_set('field_bundle_settings_' . $entity_type . '__' . $bundle, $settings);
-    field_info_cache_clear();
-  }
-  else {
-    $settings = variable_get('field_bundle_settings_' . $entity_type . '__' . $bundle, array());
-    $settings += array(
-      'view_modes' => array(),
-      'form_modes' => array(),
-    );
-
-    return $settings;
-  }
-}
-
-/**
- * Returns form mode settings in a given bundle.
- *
- * @param string $entity_type
- *   The type of entity; e.g. 'node' or 'user'.
- * @param string $bundle
- *   The bundle name to return form mode settings for.
- *
- * @return
- *   An array keyed by form mode, with the following key/value pairs:
- *   - status: Boolean specifying whether the form mode uses a dedicated set of
- *     display options (TRUE), or the 'default' options (FALSE). Defaults to
- *     FALSE.
- */
-function field_form_mode_settings($entity_type, $bundle) {
-  $cache = &drupal_static(__FUNCTION__, array());
-
-  if (!isset($cache[$entity_type][$bundle])) {
-    $bundle_settings = field_bundle_settings($entity_type, $bundle);
-    $settings = $bundle_settings['form_modes'];
-    // Include form modes for which nothing has been stored yet, but whose
-    // definition in hook_entity_info_alter() specify they should use custom
-    // settings by default.
-    $form_modes = entity_get_form_modes($entity_type);
-    foreach ($form_modes as $form_mode => $form_mode_info) {
-      if (!isset($settings[$form_mode]['status']) && $form_mode_info['status']) {
-        $settings[$form_mode]['status'] = TRUE;
-      }
-    }
-    $cache[$entity_type][$bundle] = $settings;
-  }
-
-  return $cache[$entity_type][$bundle];
-}
-
-/**
- * Returns view mode settings in a given bundle.
- *
- * @param $entity_type
- *   The type of entity; e.g. 'node' or 'user'.
- * @param $bundle
- *   The bundle name to return view mode settings for.
- *
- * @return
- *   An array keyed by view mode, with the following key/value pairs:
- *   - status: Boolean specifying whether the view mode uses a dedicated set of
- *     display options (TRUE), or the 'default' options (FALSE). Defaults to
- *     FALSE.
- */
-function field_view_mode_settings($entity_type, $bundle) {
-  $cache = &drupal_static(__FUNCTION__, array());
-
-  if (!isset($cache[$entity_type][$bundle])) {
-    $bundle_settings = field_bundle_settings($entity_type, $bundle);
-    $settings = $bundle_settings['view_modes'];
-    // Include view modes for which nothing has been stored yet, but whose
-    // definition in hook_entity_info_alter() specify they should use custom
-    // settings by default.
-    $view_modes = entity_get_view_modes($entity_type);
-    foreach ($view_modes as $view_mode => $view_mode_info) {
-      if (!isset($settings[$view_mode]['status']) && $view_mode_info['status']) {
-        $settings[$view_mode]['status'] = TRUE;
-      }
-    }
-    $cache[$entity_type][$bundle] = $settings;
-  }
-
-  return $cache[$entity_type][$bundle];
-}
-
 /**
  * Clears the field info and field data caches.
  */
diff --git a/core/modules/field/lib/Drupal/field/FieldInfo.php b/core/modules/field/lib/Drupal/field/FieldInfo.php
index 8d6bc3a4d745..e6411c380714 100644
--- a/core/modules/field/lib/Drupal/field/FieldInfo.php
+++ b/core/modules/field/lib/Drupal/field/FieldInfo.php
@@ -545,13 +545,10 @@ public function getBundleExtraFields($entity_type, $bundle) {
     // Cache miss: read from hook_field_extra_fields(). Note: given the current
     // shape of the hook, we have no other way than collecting extra fields on
     // all bundles.
-    $info = array();
     $extra = $this->moduleHandler->invokeAll('field_extra_fields');
     drupal_alter('field_extra_fields', $extra);
-    // Merge in saved settings.
-    if (isset($extra[$entity_type][$bundle])) {
-      $info = $this->prepareExtraFields($extra[$entity_type][$bundle], $entity_type, $bundle);
-    }
+    $info = isset($extra[$entity_type][$bundle]) ? $extra[$entity_type][$bundle] : array();
+    $info += array('form' => array(), 'display' => array());
 
     // Store in the 'static' and persistent caches.
     $this->bundleExtraFields[$entity_type][$bundle] = $info;
@@ -599,38 +596,4 @@ public function prepareInstance($instance, $field_type) {
     return $instance;
   }
 
-  /**
-   * Prepares 'extra fields' for the current run-time context.
-   *
-   * @param $extra_fields
-   *   The array of extra fields, as collected in hook_field_extra_fields().
-   * @param $entity_type
-   *   The entity type.
-   * @param $bundle
-   *   The bundle name.
-   *
-   * @return
-   *   The list of extra fields completed for the current runtime context.
-   */
-  public function prepareExtraFields($extra_fields, $entity_type, $bundle) {
-    $entity_type_info = entity_get_info($entity_type);
-    $bundle_settings = field_bundle_settings($entity_type, $bundle);
-    $extra_fields += array('form' => array(), 'display' => array());
-
-    $result = array();
-    // Extra fields in forms.
-    foreach ($extra_fields['form'] as $name => $field_data) {
-      $settings = isset($bundle_settings['extra_fields']['form'][$name]) ? $bundle_settings['extra_fields']['form'][$name] : array();
-      if (isset($settings['weight'])) {
-        $field_data['weight'] = $settings['weight'];
-      }
-      $result['form'][$name] = $field_data;
-    }
-
-    // Extra fields in displayed entities.
-    $result['display'] = $extra_fields['display'];
-
-    return $result;
-  }
-
 }
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
index 928b12f6fcb6..5a9a2bee7583 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/FormModeAccessCheck.php
@@ -31,8 +31,16 @@ public function access(Route $route, Request $request) {
       $bundle = $request->attributes->get('bundle');
       $form_mode = $request->attributes->get('mode');
 
-      $form_mode_settings = field_form_mode_settings($entity_type, $bundle);
-      $visibility = ($form_mode == 'default') || !empty($form_mode_settings[$form_mode]['status']);
+      if ($form_mode == 'default') {
+        $visibility = TRUE;
+      }
+      elseif ($entity_form_display = entity_load('entity_form_display', $entity_type . '.' . $bundle . '.' . $form_mode)) {
+        $visibility = $entity_form_display->status();
+      }
+      else {
+        $visibility = FALSE;
+      }
+
       if ($visibility) {
         $permission = $route->getRequirement('_field_ui_form_mode_access');
         return user_access($permission) ? static::ALLOW : static::DENY;
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
index a431da280a6f..f841d60734ff 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Access/ViewModeAccessCheck.php
@@ -31,8 +31,16 @@ public function access(Route $route, Request $request) {
       $bundle = $request->attributes->get('bundle');
       $view_mode = $request->attributes->get('mode');
 
-      $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
-      $visibility = ($view_mode == 'default') || !empty($view_mode_settings[$view_mode]['status']);
+      if ($view_mode == 'default') {
+        $visibility = TRUE;
+      }
+      elseif ($entity_display = entity_load('entity_display', $entity_type . '.' . $bundle . '.' . $view_mode)) {
+        $visibility = $entity_display->status();
+      }
+      else {
+        $visibility = FALSE;
+      }
+
       if ($visibility) {
         $permission = $route->getRequirement('_field_ui_view_mode_access');
         return user_access($permission) ? static::ALLOW : static::DENY;
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
index dfc6a1376fad..6547f5bc3aba 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverview.php
@@ -139,17 +139,8 @@ protected function getDisplayModes() {
   /**
    * {@inheritdoc}
    */
-  protected function getDisplayModeSettings() {
-    return field_view_mode_settings($this->entity_type, $this->bundle);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function saveDisplayModeSettings($display_mode_settings) {
-    $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
-    $bundle_settings['view_modes'] = NestedArray::mergeDeep($bundle_settings['view_modes'], $display_mode_settings);
-    field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
+  protected function getDisplayType() {
+    return 'entity_display';
   }
 
   /**
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
index 3f9adea2d719..edd687af28d3 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php
@@ -149,10 +149,10 @@ public function buildForm(array $form, array &$form_state, $entity_type = NULL,
         // checkboxes.
         $options = array();
         $default = array();
-        $display_mode_settings = $this->getDisplayModeSettings();
+        $display_statuses = $this->getDisplayStatuses();
         foreach ($display_modes as $mode_name => $mode_info) {
           $options[$mode_name] = $mode_info['label'];
-          if (!empty($display_mode_settings[$mode_name]['status'])) {
+          if (!empty($display_statuses[$mode_name])) {
             $default[] = $mode_name;
           }
         }
@@ -506,14 +506,14 @@ public function submitForm(array &$form, array &$form_state) {
     // Save the display.
     $display->save();
 
-    // Handle the 'view modes' checkboxes if present.
+    // Handle the 'display modes' checkboxes if present.
     if ($this->mode == 'default' && !empty($form_values['display_modes_custom'])) {
       $display_modes = $this->getDisplayModes();
-      $display_mode_settings = $this->getDisplayModeSettings();
+      $current_statuses = $this->getDisplayStatuses();
 
-      $display_mode_bundle_settings = array();
+      $statuses = array();
       foreach ($form_values['display_modes_custom'] as $mode => $value) {
-        if (!empty($value) && empty($display_mode_settings[$mode]['status'])) {
+        if (!empty($value) && empty($current_statuses[$mode])) {
           // If no display exists for the newly enabled view mode, initialize
           // it with those from the 'default' view mode, which were used so
           // far.
@@ -526,11 +526,10 @@ public function submitForm(array &$form, array &$form_state) {
           $path = $this->getOverviewPath($mode);
           drupal_set_message($this->t('The %display_mode mode now uses custom display settings. You might want to <a href="@url">configure them</a>.', array('%display_mode' => $display_mode_label, '@url' => url($path))));
         }
-        $display_mode_bundle_settings[$mode]['status'] = !empty($value);
+        $statuses[$mode] = !empty($value);
       }
 
-      // Save updated bundle settings.
-      $this->saveDisplayModeSettings($display_mode_bundle_settings);
+      $this->saveDisplayStatuses($statuses);
     }
 
     drupal_set_message($this->t('Your settings have been saved.'));
@@ -679,20 +678,12 @@ abstract protected function getDefaultPlugin($field_type);
   abstract protected function getDisplayModes();
 
   /**
-   * Returns form or view modes settings for the bundle used by this form.
+   * Returns the display entity type.
    *
-   * @return array
-   *   An array of form or view mode settings.
-   */
-  abstract protected function getDisplayModeSettings();
-
-  /**
-   * Saves the updated display mode settings.
-   *
-   * @param array $display_mode_settings
-   *   An array holding updated form or view mode settings.
+   * @return string
+   *   The name of the display entity type.
    */
-  abstract protected function saveDisplayModeSettings($display_mode_settings);
+  abstract protected function getDisplayType();
 
   /**
    * Returns the region to which a row in the display overview belongs.
@@ -724,6 +715,57 @@ protected function getExtraFieldVisibilityOptions() {
     );
   }
 
+  /**
+   * Returns entity (form) displays for the current entity display type.
+   *
+   * @return array
+   *   An array holding entity displays or entity form displays.
+   */
+  protected function getDisplays() {
+    $load_ids = array();
+    $display_entity_type = $this->getDisplayType();
+    $entity_info = $this->entityManager->getDefinition($display_entity_type);
+    $config_prefix = $entity_info['config_prefix'];
+    $ids = config_get_storage_names_with_prefix($config_prefix . '.' . $this->entity_type . '.' . $this->bundle);
+    foreach ($ids as $id) {
+      $config_id = str_replace($config_prefix . '.', '', $id);
+      list(,, $display_mode) = explode('.', $config_id);
+      if ($display_mode != 'default') {
+        $load_ids[] = $config_id;
+      }
+    }
+    return entity_load_multiple($display_entity_type, $load_ids);
+  }
+
+  /**
+   * Returns form or view modes statuses for the bundle used by this form.
+   *
+   * @return array
+   *   An array of form or view mode statuses.
+   */
+  protected function getDisplayStatuses() {
+    $display_statuses = array();
+    $displays = $this->getDisplays();
+    foreach ($displays as $display) {
+      $display_statuses[$display->get('mode')] = $display->status();
+    }
+    return $display_statuses;
+  }
+
+  /**
+   * Saves the updated display mode statuses.
+   *
+   * @param array $display_statuses
+   *   An array holding updated form or view mode statuses.
+   */
+  protected function saveDisplayStatuses($display_statuses) {
+    $displays = $this->getDisplays();
+    foreach ($displays as $display) {
+      $display->set('status', $display_statuses[$display->get('mode')]);
+      $display->save();
+    }
+  }
+
   /**
    * Returns an array containing the table headers.
    *
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
index 1186fc20e75e..bdbea8acccd9 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/FormDisplayOverview.php
@@ -99,17 +99,8 @@ protected function getDisplayModes() {
   /**
    * {@inheritdoc}
    */
-  protected function getDisplayModeSettings() {
-    return field_form_mode_settings($this->entity_type, $this->bundle);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function saveDisplayModeSettings($display_mode_settings) {
-    $bundle_settings = field_bundle_settings($this->entity_type, $this->bundle);
-    $bundle_settings['form_modes'] = NestedArray::mergeDeep($bundle_settings['form_modes'], $display_mode_settings);
-    field_bundle_settings($this->entity_type, $this->bundle, $bundle_settings);
+  protected function getDisplayType() {
+    return 'entity_form_display';
   }
 
   /**
diff --git a/core/modules/forum/config/entity.display.taxonomy_term.forums.default.yml b/core/modules/forum/config/entity.display.taxonomy_term.forums.default.yml
index ef18047ad6ef..c4d4f8b3636a 100644
--- a/core/modules/forum/config/entity.display.taxonomy_term.forums.default.yml
+++ b/core/modules/forum/config/entity.display.taxonomy_term.forums.default.yml
@@ -3,6 +3,7 @@ uuid: adaef6a9-8dc0-4f2e-9858-88daac440aa9
 targetEntityType: taxonomy_term
 bundle: forums
 mode: default
+status: 1
 content:
   description:
     weight: '0'
diff --git a/core/modules/forum/config/entity.form_display.taxonomy_term.forums.default.yml b/core/modules/forum/config/entity.form_display.taxonomy_term.forums.default.yml
index 203b69a4704f..f091e30974af 100644
--- a/core/modules/forum/config/entity.form_display.taxonomy_term.forums.default.yml
+++ b/core/modules/forum/config/entity.form_display.taxonomy_term.forums.default.yml
@@ -3,6 +3,7 @@ uuid: c8eab085-8fd3-4545-8600-e13b7d8bb9c4
 targetEntityType: taxonomy_term
 bundle: forums
 mode: default
+status: 1
 content:
   name:
     weight: '-5'
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
index 34818e040c1b..5efa6b89928f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/FieldSqlStorageTest.php
@@ -26,7 +26,7 @@ class FieldSqlStorageTest extends EntityUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('system', 'field', 'field_test', 'text', 'number', 'entity_test');
+  public static $modules = array('field', 'field_test', 'text', 'number', 'entity_test');
 
   /**
    * The name of the created field.
@@ -67,7 +67,6 @@ public static function getInfo() {
   function setUp() {
     parent::setUp();
     $this->installSchema('entity_test', array('entity_test_rev', 'entity_test_rev_revision'));
-    $this->installSchema('system', array('variable'));
     $entity_type = 'entity_test_rev';
 
     $this->field_name = strtolower($this->randomName());
diff --git a/core/modules/system/tests/upgrade/drupal-7.field.database.php b/core/modules/system/tests/upgrade/drupal-7.field.database.php
index cb960344656e..420dc0b23fb4 100644
--- a/core/modules/system/tests/upgrade/drupal-7.field.database.php
+++ b/core/modules/system/tests/upgrade/drupal-7.field.database.php
@@ -12,19 +12,19 @@
 $value = array(
   'view_modes' => array(
     'teaser' => array(
-      'status' => 1,
+      'custom_settings' => 1,
     ),
     'full' => array(
-      'status' => 0,
+      'custom_settings' => 0,
     ),
     'rss' => array(
-      'status' => 0,
+      'custom_settings' => 0,
     ),
     'search_index' => array(
-      'status' => 0,
+      'custom_settings' => 0,
     ),
     'search_result' => array(
-      'status' => 0,
+      'custom_settings' => 0,
     ),
   ),
   'extra_fields' => array(
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
index b5dc5c73fcd0..34b348b49eca 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserRegistrationTest.php
@@ -213,6 +213,8 @@ function testRegistrationWithUserFields() {
     entity_get_form_display('user', 'user', 'default')
       ->setComponent('test_user_field', array('type' => 'test_field_widget'))
       ->save();
+    entity_get_form_display('user', 'user', 'register')
+      ->save();
 
     // Check that the field does not appear on the registration form.
     $this->drupalGet('user/register');
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index eeb5e63845a9..aabbce9b37a6 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -360,11 +360,11 @@ function user_update_dependencies() {
  * The 'Member for' extra field has moved one level up in the array.
  */
 function user_update_8000() {
-  $settings = field_bundle_settings('user', 'user');
+  $settings = update_variable_get('field_bundle_settings_user__user', array());
   if (isset($settings['extra_fields']['display']['summary'])) {
     $settings['extra_fields']['display']['member_for'] = $settings['extra_fields']['display']['summary'];
     unset($settings['extra_fields']['display']['summary']);
-    field_bundle_settings('user', 'user', $settings);
+    update_variable_set('field_bundle_settings_user__user', $settings);
   }
 }
 
@@ -739,7 +739,7 @@ function user_update_8011() {
   }
 
   // Assign form settings for the 'default' form mode.
-  $form_display = _update_8000_entity_get_form_display('user', 'user', 'default');
+  $form_display = _update_8000_entity_get_form_display('user', 'user', 'default', TRUE);
   $form_display->set('content.user_picture', array(
       'type' => $widget,
       'settings' => array(
@@ -748,6 +748,7 @@ function user_update_8011() {
       ),
       'weight' => -1,
     ))
+    ->set('status', 1)
     ->save();
 
   // Assign display settings for the 'default' and 'compact' view modes.
@@ -761,6 +762,7 @@ function user_update_8011() {
       ),
       'weight' => 0,
     ))
+    ->set('status', 1)
     ->save();
 
   $display = _update_8000_entity_get_display('user', 'user', 'compact');
@@ -772,8 +774,9 @@ function user_update_8011() {
         'image_link' => 'content',
       ),
       'weight' => 0,
-    ));
-  $display->set('content.member_for', array(
+    ))
+    ->set('status', 1)
+    ->set('content.member_for', array(
       'visible' => FALSE,
     ));
   $display->save();
diff --git a/core/profiles/standard/config/entity.display.node.article.default.yml b/core/profiles/standard/config/entity.display.node.article.default.yml
index 330de2d84e2f..78c65cb37fde 100644
--- a/core/profiles/standard/config/entity.display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.display.node.article.default.yml
@@ -2,6 +2,7 @@ id: node.article.default
 targetEntityType: node
 bundle: article
 mode: default
+status: 1
 content:
   body:
     label: hidden
diff --git a/core/profiles/standard/config/entity.display.node.article.teaser.yml b/core/profiles/standard/config/entity.display.node.article.teaser.yml
index 44add7e5862c..4c6131758051 100644
--- a/core/profiles/standard/config/entity.display.node.article.teaser.yml
+++ b/core/profiles/standard/config/entity.display.node.article.teaser.yml
@@ -2,6 +2,7 @@ id: node.article.teaser
 targetEntityType: node
 bundle: article
 mode: teaser
+status: 1
 content:
   body:
     label: hidden
diff --git a/core/profiles/standard/config/entity.form_display.node.article.default.yml b/core/profiles/standard/config/entity.form_display.node.article.default.yml
index ce4efbc8628c..bee1ea24e4d2 100644
--- a/core/profiles/standard/config/entity.form_display.node.article.default.yml
+++ b/core/profiles/standard/config/entity.form_display.node.article.default.yml
@@ -2,6 +2,7 @@ id: node.article.default
 targetEntityType: node
 bundle: article
 mode: default
+status: 1
 content:
   body:
     type: text_textarea_with_summary
-- 
GitLab