Unverified Commit 9868bf9c authored by larowlan's avatar larowlan

Issue #2847651 by murrow, rachel_norfolk, john@johncook.me.uk, mpdonadio,...

Issue #2847651 by murrow, rachel_norfolk, john@johncook.me.uk, mpdonadio, BarisW, droplet, tstoeckler, andrewmacpherson, prabhu9484, ok_lyndsey, benjifisher, yoroy, lauriii, martin107: Improve timezones selector with optgroups
parent 537dbb1a
......@@ -132,7 +132,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
$elements['timezone'] = [
'#type' => 'select',
'#title' => $this->t('Time zone'),
'#options' => ['' => $this->t('- Default site/user time zone -')] + system_time_zones(FALSE),
'#options' => ['' => $this->t('- Default site/user time zone -')] + system_time_zones(FALSE, TRUE),
'#default_value' => $this->getSetting('timezone'),
];
......
......@@ -204,7 +204,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
'#title' => $this->t('Default time zone'),
// Use system timezone if set, but avoid throwing a warning in PHP >=5.4
'#default_value' => @date_default_timezone_get(),
'#options' => system_time_zones(),
'#options' => system_time_zones(NULL, TRUE),
'#description' => $this->t('By default, dates in this site will be displayed in the chosen time zone.'),
'#weight' => 5,
'#attributes' => ['class' => ['timezone-detect']],
......
......@@ -98,7 +98,7 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
'#type' => 'select',
'#title' => $this->t('Time zone override'),
'#description' => $this->t('The time zone selected here will always be used'),
'#options' => system_time_zones(TRUE),
'#options' => system_time_zones(TRUE, TRUE),
'#default_value' => $this->getSetting('timezone_override'),
];
......
......@@ -65,7 +65,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
$system_date = $this->config('system.date');
// Date settings:
$zones = system_time_zones();
$zones = system_time_zones(NULL, TRUE);
$form['locale'] = [
'#type' => 'details',
......
......@@ -845,7 +845,7 @@ function system_user_timezone(&$form, FormStateInterface $form_state) {
'#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()),
'#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();
......@@ -1355,10 +1355,15 @@ function system_mail($key, &$message, $params) {
/**
* Generate an array of time zones and their local time&date.
*
* @param $blank
* @param mixed $blank
* If evaluates true, prepend an empty time zone option to the array.
* @param bool $grouped
* (optional) Whether the timezones should be grouped by region.
*
* @return array
* An array or nested array containing time zones, keyed by the system name.
*/
function system_time_zones($blank = NULL) {
function system_time_zones($blank = NULL, $grouped = FALSE) {
$zonelist = timezone_identifiers_list();
$zones = $blank ? ['' => t('- None selected -')] : [];
foreach ($zonelist as $zone) {
......@@ -1371,6 +1376,27 @@ function system_time_zones($blank = NULL) {
}
// Sort the translated time zones alphabetically.
asort($zones);
if ($grouped) {
$grouped_zones = [];
foreach ($zones as $key => $value) {
$split = explode('/', $value);
$city = array_pop($split);
$region = array_shift($split);
if (!empty($region)) {
$grouped_zones[$region][$key] = empty($split) ? $city : $city . ' (' . join('/', $split) . ')';
}
else {
$grouped_zones[$key] = $value;
}
}
foreach ($grouped_zones as $key => $value) {
if (is_array($grouped_zones[$key])) {
asort($grouped_zones[$key]);
}
}
$zones = $grouped_zones;
}
return $zones;
}
......
<?php
namespace Drupal\Tests\system\Kernel\Timezone;
use Drupal\KernelTests\KernelTestBase;
/**
* Test coverage for time zone handling.
*
* @group system
*/
class TimezoneTest extends KernelTestBase {
public static $modules = ['system'];
/**
* Tests system_time_zones().
*/
public function testSystemTimeZones() {
// Test the default parameters for system_time_zones().
$result = system_time_zones();
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('Africa/Dar_es_Salaam', $result);
$this->assertEquals('Africa/Dar es Salaam', $result['Africa/Dar_es_Salaam']);
// Tests time zone grouping.
$result = system_time_zones(NULL, TRUE);
// Check a two-level time zone.
$this->assertInternalType('array', $result);
$this->assertArrayHasKey('Africa', $result);
$this->assertArrayHasKey('Africa/Dar_es_Salaam', $result['Africa']);
$this->assertEquals('Dar es Salaam', $result['Africa']['Africa/Dar_es_Salaam']);
// Check a three level time zone.
$this->assertArrayHasKey('America', $result);
$this->assertArrayHasKey('America/Indiana/Indianapolis', $result['America']);
$this->assertEquals('Indianapolis (Indiana)', $result['America']['America/Indiana/Indianapolis']);
// Make sure grouping hasn't erroneously created an entry with just the
// first and second levels.
$this->assertArrayNotHasKey('America/Indiana', $result['America']);
// Make sure grouping hasn't duplicated an entry with just the first and
// third levels.
$this->assertArrayNotHasKey('America/Indianapolis', $result['America']);
// Make sure that a grouped item isn't duplicated at the top level of the
// results array.
$this->assertArrayNotHasKey('America/Indiana/Indianapolis', $result);
// Test that the ungrouped and grouped results have the same number of
// items.
$ungrouped_count = count(system_time_zones());
$grouped_result = system_time_zones(NULL, TRUE);
$grouped_count = 0;
array_walk_recursive($grouped_result, function ($grouped_count) use
(&$grouped_count) {
$grouped_count++;
});
$this->assertEquals($ungrouped_count, $grouped_count);
}
}
......@@ -119,7 +119,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
'#type' => 'select',
'#title' => $this->t('Timezone'),
'#description' => $this->t('Timezone to be used for date output.'),
'#options' => ['' => $this->t('- Default site/user timezone -')] + system_time_zones(FALSE),
'#options' => ['' => $this->t('- Default site/user timezone -')] + system_time_zones(FALSE, TRUE),
'#default_value' => $this->options['timezone'],
];
foreach (array_merge(['custom'], array_keys($date_formats)) as $timezone_date_formats) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment