From 6d1348a45636e1f337ab5e09528d13fc64d0c3d5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?G=C3=A1bor=20Hojtsy?= <gabor@hojtsy.hu>
Date: Wed, 19 Feb 2020 13:56:05 +0100
Subject: [PATCH] =?UTF-8?q?Issue=20#3015811=20by=20alexpott,=20longwave,?=
 =?UTF-8?q?=20Berdir,=20catch,=20G=C3=A1bor=20Hojtsy,=20borisson=5F,=20and?=
 =?UTF-8?q?ypost:=20Properly=20deprecate=20DRUPAL=5FUSER=5FTIMEZONE=5F*=20?=
 =?UTF-8?q?constants?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 core/modules/system/src/Form/RegionalForm.php | 39 ---------
 core/modules/system/system.module             | 74 -----------------
 core/modules/user/src/AccountForm.php         | 26 ++++++
 core/modules/user/user.module                 | 81 +++++++++++++++++++
 4 files changed, 107 insertions(+), 113 deletions(-)

diff --git a/core/modules/system/src/Form/RegionalForm.php b/core/modules/system/src/Form/RegionalForm.php
index ccd880ace075..848e92867389 100644
--- a/core/modules/system/src/Form/RegionalForm.php
+++ b/core/modules/system/src/Form/RegionalForm.php
@@ -104,42 +104,6 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       '#options' => $zones,
     ];
 
-    $configurable_timezones = $system_date->get('timezone.user.configurable');
-    $form['timezone']['configurable_timezones'] = [
-      '#type' => 'checkbox',
-      '#title' => t('Users may set their own time zone'),
-      '#default_value' => $configurable_timezones,
-    ];
-
-    $form['timezone']['configurable_timezones_wrapper'] = [
-      '#type' => 'container',
-      '#states' => [
-        // Hide the user configured timezone settings when users are forced to use
-        // the default setting.
-        'invisible' => [
-          'input[name="configurable_timezones"]' => ['checked' => FALSE],
-        ],
-      ],
-    ];
-    $form['timezone']['configurable_timezones_wrapper']['empty_timezone_message'] = [
-      '#type' => 'checkbox',
-      '#title' => t('Remind users at login if their time zone is not set'),
-      '#default_value' => $system_date->get('timezone.user.warn'),
-      '#description' => t('Only applied if users may set their own time zone.'),
-    ];
-
-    $form['timezone']['configurable_timezones_wrapper']['user_default_timezone'] = [
-      '#type' => 'radios',
-      '#title' => t('Time zone for new users'),
-      '#default_value' => $system_date->get('timezone.user.default'),
-      '#options' => [
-        DRUPAL_USER_TIMEZONE_DEFAULT => t('Default time zone'),
-        DRUPAL_USER_TIMEZONE_EMPTY   => t('Empty time zone'),
-        DRUPAL_USER_TIMEZONE_SELECT  => t('Users may set their own time zone at registration'),
-      ],
-      '#description' => t('Only applied if users may set their own time zone.'),
-    ];
-
     return parent::buildForm($form, $form_state);
   }
 
@@ -151,9 +115,6 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       ->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'))
-      ->set('timezone.user.configurable', $form_state->getValue('configurable_timezones'))
-      ->set('timezone.user.warn', $form_state->getValue('empty_timezone_message'))
-      ->set('timezone.user.default', $form_state->getValue('user_default_timezone'))
       ->save();
 
     parent::submitForm($form, $form_state);
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index d78a1e6021f0..bf64016c885c 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -25,7 +25,6 @@
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Routing\StackedRouteMatchInterface;
 use Drupal\Core\Url;
-use Drupal\user\UserInterface;
 use GuzzleHttp\Exception\RequestException;
 use Symfony\Component\HttpFoundation\RedirectResponse;
 
@@ -805,79 +804,6 @@ function system_form_alter(&$form, FormStateInterface $form_state) {
   }
 }
 
-/**
- * Implements hook_form_FORM_ID_alter() for \Drupal\user\AccountForm.
- */
-function system_form_user_form_alter(&$form, FormStateInterface $form_state) {
-  if (\Drupal::config('system.date')->get('timezone.user.configurable')) {
-    system_user_timezone($form, $form_state);
-  }
-}
-
-/**
- * Implements hook_form_FORM_ID_alter() for \Drupal\user\RegisterForm.
- */
-function system_form_user_register_form_alter(&$form, FormStateInterface $form_state) {
-  $config = \Drupal::config('system.date');
-  if ($config->get('timezone.user.configurable') && $config->get('timezone.user.default') == DRUPAL_USER_TIMEZONE_SELECT) {
-    system_user_timezone($form, $form_state);
-  }
-}
-
-/**
- * Implements hook_ENTITY_TYPE_presave() for user entities.
- */
-function system_user_presave(UserInterface $account) {
-  $config = \Drupal::config('system.date');
-  if ($config->get('timezone.user.configurable') && !$account->getTimeZone() && !$config->get('timezone.user.default')) {
-    $account->timezone = $config->get('timezone.default');
-  }
-}
-
-/**
- * Implements hook_user_login().
- */
-function system_user_login(UserInterface $account) {
-  $config = \Drupal::config('system.date');
-  // If the user has a NULL time zone, notify them to set a time zone.
-  if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) {
-    \Drupal::messenger()
-      ->addStatus(t('Configure your <a href=":user-edit">account time zone setting</a>.', [
-        ':user-edit' => $account->toUrl('edit-form', [
-          'query' => \Drupal::destination()->getAsArray(),
-          'fragment' => 'edit-timezone',
-        ])->toString(),
-      ]));
-  }
-}
-
-/**
- * Add the time zone field to the user edit and register forms.
- */
-function system_user_timezone(&$form, FormStateInterface $form_state) {
-  $user = \Drupal::currentUser();
-
-  $account = $form_state->getFormObject()->getEntity();
-  $form['timezone'] = [
-    '#type' => 'details',
-    '#title' => t('Locale settings'),
-    '#open' => TRUE,
-    '#weight' => 6,
-  ];
-  $form['timezone']['timezone'] = [
-    '#type' => 'select',
-    '#title' => t('Time zone'),
-    '#default_value' => $account->getTimezone() ? $account->getTimezone() : \Drupal::config('system.date')->get('timezone.default'),
-    '#options' => system_time_zones($account->id() != $user->id(), TRUE),
-    '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
-  ];
-  $user_input = $form_state->getUserInput();
-  if (!$account->getTimezone() && $account->id() == $user->id() && empty($user_input['timezone'])) {
-    $form['timezone']['#attached']['library'][] = 'core/drupal.timezone';
-    $form['timezone']['timezone']['#attributes'] = ['class' => ['timezone-detect']];
-  }
-}
-
 /**
  * Implements hook_preprocess_HOOK() for block templates.
  */
diff --git a/core/modules/user/src/AccountForm.php b/core/modules/user/src/AccountForm.php
index 9758d5ec64a0..8e32dad8b179 100644
--- a/core/modules/user/src/AccountForm.php
+++ b/core/modules/user/src/AccountForm.php
@@ -275,6 +275,32 @@ public function form(array $form, FormStateInterface $form_state) {
     // or remove this item.
     $form['#entity_builders']['sync_user_langcode'] = '::syncUserLangcode';
 
+    $system_date_config = \Drupal::config('system.date');
+    $form['timezone'] = [
+      '#type' => 'details',
+      '#title' => t('Locale settings'),
+      '#open' => TRUE,
+      '#weight' => 6,
+      '#access' => $system_date_config->get('timezone.user.configurable'),
+    ];
+    if ($self_register && $system_date_config->get('timezone.user.default') != UserInterface::TIMEZONE_SELECT) {
+      $form['timezone']['#access'] = FALSE;
+    }
+    $form['timezone']['timezone'] = [
+      '#type' => 'select',
+      '#title' => t('Time zone'),
+      '#default_value' => $account->getTimezone() ?: $system_date_config->get('timezone.default'),
+      '#options' => system_time_zones($account->id() != $user->id(), TRUE),
+      '#description' => t('Select the desired local time and time zone. Dates and times throughout this site will be displayed using this time zone.'),
+    ];
+
+    // If not set or selected yet, detect timezone for the current user only.
+    $user_input = $form_state->getUserInput();
+    if (!$account->getTimezone() && $account->id() == $user->id() && empty($user_input['timezone'])) {
+      $form['timezone']['#attached']['library'][] = 'core/drupal.timezone';
+      $form['timezone']['timezone']['#attributes'] = ['class' => ['timezone-detect']];
+    }
+
     return parent::form($form, $form_state, $account);
   }
 
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 908f716c2c61..d4021f70f6f9 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -12,6 +12,7 @@
 use Drupal\Core\Asset\AttachedAssetsInterface;
 use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
 use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Form\FormStateInterface;
 use Drupal\Core\Render\Element;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountInterface;
@@ -140,6 +141,19 @@ function user_entity_extra_field_info() {
   return $fields;
 }
 
+/**
+ * Implements hook_ENTITY_TYPE_presave() for user entities.
+ *
+ * @todo https://www.drupal.org/project/drupal/issues/3112704 Move to
+ *   \Drupal\user\Entity\User::preSave().
+ */
+function user_user_presave(UserInterface $account) {
+  $config = \Drupal::config('system.date');
+  if ($config->get('timezone.user.configurable') && !$account->getTimeZone() && !$config->get('timezone.user.default')) {
+    $account->timezone = $config->get('timezone.default');
+  }
+}
+
 /**
  * Fetches a user object by email address.
  *
@@ -456,6 +470,18 @@ function user_user_login(UserInterface $account) {
   // Reset static cache of default variables in template_preprocess() to reflect
   // the new user.
   drupal_static_reset('template_preprocess');
+
+  // If the user has a NULL time zone, notify them to set a time zone.
+  $config = \Drupal::config('system.date');
+  if (!$account->getTimezone() && $config->get('timezone.user.configurable') && $config->get('timezone.user.warn')) {
+    \Drupal::messenger()
+      ->addStatus(t('Configure your <a href=":user-edit">account time zone setting</a>.', [
+        ':user-edit' => $account->toUrl('edit-form', [
+          'query' => \Drupal::destination()->getAsArray(),
+          'fragment' => 'edit-timezone',
+        ])->toString(),
+      ]));
+  }
 }
 
 /**
@@ -1216,3 +1242,58 @@ function template_preprocess_user(&$variables) {
     $variables['content'][$key] = $variables['elements'][$key];
   }
 }
+
+/**
+ * Implements hook_form_FORM_ID_alter() for \Drupal\system\Form\RegionalForm.
+ */
+function user_form_system_regional_settings_alter(&$form, FormStateInterface $form_state) {
+  $config = \Drupal::config('system.date');
+
+  $form['timezone']['configurable_timezones'] = [
+    '#type' => 'checkbox',
+    '#title' => t('Users may set their own time zone'),
+    '#default_value' => $config->get('timezone.user.configurable'),
+  ];
+
+  $form['timezone']['configurable_timezones_wrapper'] = [
+    '#type' => 'container',
+    '#states' => [
+      // Hide the user configured timezone settings when users are forced to use
+      // the default setting.
+      'invisible' => [
+        'input[name="configurable_timezones"]' => ['checked' => FALSE],
+      ],
+    ],
+  ];
+  $form['timezone']['configurable_timezones_wrapper']['empty_timezone_message'] = [
+    '#type' => 'checkbox',
+    '#title' => t('Remind users at login if their time zone is not set'),
+    '#default_value' => $config->get('timezone.user.warn'),
+    '#description' => t('Only applied if users may set their own time zone.'),
+  ];
+
+  $form['timezone']['configurable_timezones_wrapper']['user_default_timezone'] = [
+    '#type' => 'radios',
+    '#title' => t('Time zone for new users'),
+    '#default_value' => $config->get('timezone.user.default'),
+    '#options' => [
+      UserInterface::TIMEZONE_DEFAULT => t('Default time zone'),
+      UserInterface::TIMEZONE_EMPTY   => t('Empty time zone'),
+      UserInterface::TIMEZONE_SELECT  => t('Users may set their own time zone at registration'),
+    ],
+    '#description' => t('Only applied if users may set their own time zone.'),
+  ];
+
+  $form['#submit'][] = 'user_form_system_regional_settings_submit';
+}
+
+/**
+ * Additional submit handler for \Drupal\system\Form\RegionalForm.
+ */
+function user_form_system_regional_settings_submit($form, FormStateInterface $form_state) {
+  \Drupal::configFactory()->getEditable('system.date')
+    ->set('timezone.user.configurable', $form_state->getValue('configurable_timezones'))
+    ->set('timezone.user.warn', $form_state->getValue('empty_timezone_message'))
+    ->set('timezone.user.default', $form_state->getValue('user_default_timezone'))
+    ->save();
+}
-- 
GitLab