diff --git a/core/modules/system/src/Form/RegionalForm.php b/core/modules/system/src/Form/RegionalForm.php index ccd880ace075c627d6cf0bb93de279ed589e55ac..848e92867389a5ebd3721d1249627023fb9520b4 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 d78a1e6021f0035799664c1f19a769b65a3f3891..bf64016c885c032f081c49b27e56c92fa6bf3241 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 9758d5ec64a0e97bfa222590dc860e241d44b00b..8e32dad8b1790483a7026790f01b815f7007312c 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 908f716c2c61df053d897b676c529e7f203d8a88..d4021f70f6f9a34ce9033d7e9fc5e26697512bd2 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(); +}