Change timezone data structure send to the templates
The goal of this is to be able to adapt the timezone form in template without hacking the HTML already rendered. * there are two arrays available: * `continents` which contains only a list of available continents * `cities` which contains a list of available timezone cities, associated with their continent Note: there are two distinct array because RainTPL doesn't support nested loop very well.
This commit is contained in:
parent
c843794786
commit
ae3aa96898
4 changed files with 106 additions and 101 deletions
|
@ -1,5 +1,7 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use Shaarli\Config\ConfigManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is in charge of building the final page.
|
* This class is in charge of building the final page.
|
||||||
* (This is basically a wrapper around RainTPL which pre-fills some fields.)
|
* (This is basically a wrapper around RainTPL which pre-fills some fields.)
|
||||||
|
|
|
@ -1,23 +1,42 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Generates the timezone selection form and JavaScript.
|
* Generates a list of available timezone continents and cities.
|
||||||
*
|
*
|
||||||
* Note: 'UTC/UTC' is mapped to 'UTC' to form a valid option
|
* Two distinct array based on available timezones
|
||||||
|
* and the one selected in the settings:
|
||||||
|
* - (0) continents:
|
||||||
|
* + list of available continents
|
||||||
|
* + special key 'selected' containing the value of the selected timezone's continent
|
||||||
|
* - (1) cities:
|
||||||
|
* + list of available cities associated with their continent
|
||||||
|
* + special key 'selected' containing the value of the selected timezone's city (without the continent)
|
||||||
*
|
*
|
||||||
* Example: preselect Europe/Paris
|
* Example:
|
||||||
* list($htmlform, $js) = generateTimeZoneForm('Europe/Paris');
|
* [
|
||||||
|
* [
|
||||||
|
* 'America',
|
||||||
|
* 'Europe',
|
||||||
|
* 'selected' => 'Europe',
|
||||||
|
* ],
|
||||||
|
* [
|
||||||
|
* ['continent' => 'America', 'city' => 'Toronto'],
|
||||||
|
* ['continent' => 'Europe', 'city' => 'Paris'],
|
||||||
|
* 'selected' => 'Paris',
|
||||||
|
* ],
|
||||||
|
* ];
|
||||||
*
|
*
|
||||||
|
* Notes:
|
||||||
|
* - 'UTC/UTC' is mapped to 'UTC' to form a valid option
|
||||||
|
* - a few timezone cities includes the country/state, such as Argentina/Buenos_Aires
|
||||||
|
* - these arrays are designed to build timezone selects in template files with any HTML structure
|
||||||
|
*
|
||||||
|
* @param array $installedTimeZones List of installed timezones as string
|
||||||
* @param string $preselectedTimezone preselected timezone (optional)
|
* @param string $preselectedTimezone preselected timezone (optional)
|
||||||
*
|
*
|
||||||
* @return array containing the generated HTML form and Javascript code
|
* @return array[] continents and cities
|
||||||
**/
|
**/
|
||||||
function generateTimeZoneForm($preselectedTimezone='')
|
function generateTimeZoneData($installedTimeZones, $preselectedTimezone = '')
|
||||||
{
|
{
|
||||||
// Select the server timezone
|
|
||||||
if ($preselectedTimezone == '') {
|
|
||||||
$preselectedTimezone = date_default_timezone_get();
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($preselectedTimezone == 'UTC') {
|
if ($preselectedTimezone == 'UTC') {
|
||||||
$pcity = $pcontinent = 'UTC';
|
$pcity = $pcontinent = 'UTC';
|
||||||
} else {
|
} else {
|
||||||
|
@ -27,62 +46,30 @@ function generateTimeZoneForm($preselectedTimezone='')
|
||||||
$pcity = substr($preselectedTimezone, $spos+1);
|
$pcity = substr($preselectedTimezone, $spos+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The list is in the form 'Europe/Paris', 'America/Argentina/Buenos_Aires'
|
$continents = [];
|
||||||
// We split the list in continents/cities.
|
$cities = [];
|
||||||
$continents = array();
|
foreach ($installedTimeZones as $tz) {
|
||||||
$cities = array();
|
|
||||||
|
|
||||||
// TODO: use a template to generate the HTML/Javascript form
|
|
||||||
|
|
||||||
foreach (timezone_identifiers_list() as $tz) {
|
|
||||||
if ($tz == 'UTC') {
|
if ($tz == 'UTC') {
|
||||||
$tz = 'UTC/UTC';
|
$tz = 'UTC/UTC';
|
||||||
}
|
}
|
||||||
$spos = strpos($tz, '/');
|
$spos = strpos($tz, '/');
|
||||||
|
|
||||||
if ($spos !== false) {
|
// Ignore invalid timezones
|
||||||
|
if ($spos === false) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
$continent = substr($tz, 0, $spos);
|
$continent = substr($tz, 0, $spos);
|
||||||
$city = substr($tz, $spos+1);
|
$city = substr($tz, $spos+1);
|
||||||
$continents[$continent] = 1;
|
$cities[] = ['continent' => $continent, 'city' => $city];
|
||||||
|
$continents[$continent] = true;
|
||||||
if (!isset($cities[$continent])) {
|
|
||||||
$cities[$continent] = '';
|
|
||||||
}
|
|
||||||
$cities[$continent] .= '<option value="'.$city.'"';
|
|
||||||
if ($pcity == $city) {
|
|
||||||
$cities[$continent] .= ' selected="selected"';
|
|
||||||
}
|
|
||||||
$cities[$continent] .= '>'.$city.'</option>';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$continentsHtml = '';
|
|
||||||
$continents = array_keys($continents);
|
$continents = array_keys($continents);
|
||||||
|
$continents['selected'] = $pcontinent;
|
||||||
|
$cities['selected'] = $pcity;
|
||||||
|
|
||||||
foreach ($continents as $continent) {
|
return [$continents, $cities];
|
||||||
$continentsHtml .= '<option value="'.$continent.'"';
|
|
||||||
if ($pcontinent == $continent) {
|
|
||||||
$continentsHtml .= ' selected="selected"';
|
|
||||||
}
|
|
||||||
$continentsHtml .= '>'.$continent.'</option>';
|
|
||||||
}
|
|
||||||
|
|
||||||
// Timezone selection form
|
|
||||||
$timezoneForm = 'Continent:';
|
|
||||||
$timezoneForm .= '<select name="continent" id="continent" onChange="onChangecontinent();">';
|
|
||||||
$timezoneForm .= $continentsHtml.'</select>';
|
|
||||||
$timezoneForm .= ' City:';
|
|
||||||
$timezoneForm .= '<select name="city" id="city">'.$cities[$pcontinent].'</select><br />';
|
|
||||||
|
|
||||||
// Javascript handler - updates the city list when the user selects a continent
|
|
||||||
$timezoneJs = '<script>';
|
|
||||||
$timezoneJs .= 'function onChangecontinent() {';
|
|
||||||
$timezoneJs .= 'document.getElementById("city").innerHTML =';
|
|
||||||
$timezoneJs .= ' citiescontinent[document.getElementById("continent").value]; }';
|
|
||||||
$timezoneJs .= 'var citiescontinent = '.json_encode($cities).';';
|
|
||||||
$timezoneJs .= '</script>';
|
|
||||||
|
|
||||||
return array($timezoneForm, $timezoneJs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
21
index.php
21
index.php
|
@ -1166,9 +1166,12 @@ function renderPage($conf, $pluginManager, $LINKSDB)
|
||||||
$PAGE->assign('theme', $conf->get('resource.theme'));
|
$PAGE->assign('theme', $conf->get('resource.theme'));
|
||||||
$PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl')));
|
$PAGE->assign('theme_available', ThemeUtils::getThemes($conf->get('resource.raintpl_tpl')));
|
||||||
$PAGE->assign('redirector', $conf->get('redirector.url'));
|
$PAGE->assign('redirector', $conf->get('redirector.url'));
|
||||||
list($timezone_form, $timezone_js) = generateTimeZoneForm($conf->get('general.timezone'));
|
list($continents, $cities) = generateTimeZoneData(
|
||||||
$PAGE->assign('timezone_form', $timezone_form);
|
timezone_identifiers_list(),
|
||||||
$PAGE->assign('timezone_js',$timezone_js);
|
$conf->get('general.timezone')
|
||||||
|
);
|
||||||
|
$PAGE->assign('continents', $continents);
|
||||||
|
$PAGE->assign('cities', $cities);
|
||||||
$PAGE->assign('private_links_default', $conf->get('privacy.default_private_links', false));
|
$PAGE->assign('private_links_default', $conf->get('privacy.default_private_links', false));
|
||||||
$PAGE->assign('session_protection_disabled', $conf->get('security.session_protection_disabled', false));
|
$PAGE->assign('session_protection_disabled', $conf->get('security.session_protection_disabled', false));
|
||||||
$PAGE->assign('enable_rss_permalinks', $conf->get('feed.rss_permalinks', false));
|
$PAGE->assign('enable_rss_permalinks', $conf->get('feed.rss_permalinks', false));
|
||||||
|
@ -1970,16 +1973,10 @@ function install($conf)
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display config form:
|
|
||||||
list($timezone_form, $timezone_js) = generateTimeZoneForm();
|
|
||||||
$timezone_html = '';
|
|
||||||
if ($timezone_form != '') {
|
|
||||||
$timezone_html = '<tr><td><b>Timezone:</b></td><td>'.$timezone_form.'</td></tr>';
|
|
||||||
}
|
|
||||||
|
|
||||||
$PAGE = new PageBuilder($conf);
|
$PAGE = new PageBuilder($conf);
|
||||||
$PAGE->assign('timezone_html',$timezone_html);
|
list($continents, $cities) = generateTimeZoneData(timezone_identifiers_list(), date_default_timezone_get());
|
||||||
$PAGE->assign('timezone_js',$timezone_js);
|
$PAGE->assign('continents', $continents);
|
||||||
|
$PAGE->assign('cities', $cities);
|
||||||
$PAGE->renderPage('install');
|
$PAGE->renderPage('install');
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,25 +10,46 @@
|
||||||
*/
|
*/
|
||||||
class TimeZoneTest extends PHPUnit_Framework_TestCase
|
class TimeZoneTest extends PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var array of timezones
|
||||||
|
*/
|
||||||
|
protected $installedTimezones;
|
||||||
|
|
||||||
|
public function setUp()
|
||||||
|
{
|
||||||
|
$this->installedTimezones = [
|
||||||
|
'Antarctica/Syowa',
|
||||||
|
'Europe/London',
|
||||||
|
'Europe/Paris',
|
||||||
|
'UTC'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a timezone selection form
|
* Generate a timezone selection form
|
||||||
*/
|
*/
|
||||||
public function testGenerateTimeZoneForm()
|
public function testGenerateTimeZoneForm()
|
||||||
{
|
{
|
||||||
$generated = generateTimeZoneForm();
|
$expected = [
|
||||||
|
'continents' => [
|
||||||
|
'Antarctica',
|
||||||
|
'Europe',
|
||||||
|
'UTC',
|
||||||
|
'selected' => '',
|
||||||
|
],
|
||||||
|
'cities' => [
|
||||||
|
['continent' => 'Antarctica', 'city' => 'Syowa'],
|
||||||
|
['continent' => 'Europe', 'city' => 'London'],
|
||||||
|
['continent' => 'Europe', 'city' => 'Paris'],
|
||||||
|
['continent' => 'UTC', 'city' => 'UTC'],
|
||||||
|
'selected' => '',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
// HTML form
|
list($continents, $cities) = generateTimeZoneData($this->installedTimezones);
|
||||||
$this->assertStringStartsWith('Continent:<select', $generated[0]);
|
|
||||||
$this->assertContains('selected="selected"', $generated[0]);
|
|
||||||
$this->assertStringEndsWith('</select><br />', $generated[0]);
|
|
||||||
|
|
||||||
// Javascript handler
|
$this->assertEquals($expected['continents'], $continents);
|
||||||
$this->assertStringStartsWith('<script>', $generated[1]);
|
$this->assertEquals($expected['cities'], $cities);
|
||||||
$this->assertContains(
|
|
||||||
'<option value=\"Bermuda\">Bermuda<\/option>',
|
|
||||||
$generated[1]
|
|
||||||
);
|
|
||||||
$this->assertStringEndsWith('</script>', $generated[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,28 +57,26 @@ public function testGenerateTimeZoneForm()
|
||||||
*/
|
*/
|
||||||
public function testGenerateTimeZoneFormPreselected()
|
public function testGenerateTimeZoneFormPreselected()
|
||||||
{
|
{
|
||||||
$generated = generateTimeZoneForm('Antarctica/Syowa');
|
$expected = [
|
||||||
|
'continents' => [
|
||||||
|
'Antarctica',
|
||||||
|
'Europe',
|
||||||
|
'UTC',
|
||||||
|
'selected' => 'Antarctica',
|
||||||
|
],
|
||||||
|
'cities' => [
|
||||||
|
['continent' => 'Antarctica', 'city' => 'Syowa'],
|
||||||
|
['continent' => 'Europe', 'city' => 'London'],
|
||||||
|
['continent' => 'Europe', 'city' => 'Paris'],
|
||||||
|
['continent' => 'UTC', 'city' => 'UTC'],
|
||||||
|
'selected' => 'Syowa',
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
// HTML form
|
list($continents, $cities) = generateTimeZoneData($this->installedTimezones, 'Antarctica/Syowa');
|
||||||
$this->assertStringStartsWith('Continent:<select', $generated[0]);
|
|
||||||
$this->assertContains(
|
|
||||||
'value="Antarctica" selected="selected"',
|
|
||||||
$generated[0]
|
|
||||||
);
|
|
||||||
$this->assertContains(
|
|
||||||
'value="Syowa" selected="selected"',
|
|
||||||
$generated[0]
|
|
||||||
);
|
|
||||||
$this->assertStringEndsWith('</select><br />', $generated[0]);
|
|
||||||
|
|
||||||
|
$this->assertEquals($expected['continents'], $continents);
|
||||||
// Javascript handler
|
$this->assertEquals($expected['cities'], $cities);
|
||||||
$this->assertStringStartsWith('<script>', $generated[1]);
|
|
||||||
$this->assertContains(
|
|
||||||
'<option value=\"Bermuda\">Bermuda<\/option>',
|
|
||||||
$generated[1]
|
|
||||||
);
|
|
||||||
$this->assertStringEndsWith('</script>', $generated[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue