diff --git a/include/ajax.config.php b/include/ajax.config.php index a4e11bf22ab1ea5bebbab361604edbf71e569065..c259b6028f2ab42b3d615e0e097c5f5b3db7bb1c 100644 --- a/include/ajax.config.php +++ b/include/ajax.config.php @@ -97,5 +97,35 @@ class ConfigAjaxAPI extends AjaxController { return $links; } + + /** + * Ajax: GET /config/date-format?format=<format> + * + * Formats the user's current date and time according to the given + * format in INTL codes. + * + * Get-Arguments: + * format - (string) format string used to format the current date and + * time (from the user's perspective) + * + * Returns: + * (string) Current sequence number, optionally formatted + * + * Throws: + * 403 - Not logged in + * 400 - ?format missing + */ + function dateFormat() { + global $thisstaff; + + if (!$thisstaff) + Http::response(403, 'Login required'); + elseif (!isset($_GET['format'])) + Http::response(400, '?format is required'); + + return Format::htmlchars(Format::__formatDate( + Misc::gmtime(), $_GET['format'], false, null, null, '', 'UTC' + )); + } } ?> diff --git a/include/class.format.php b/include/class.format.php index 30e5a0197572478a208d0a993d85d8df484c8b4d..d418bf762203715c8732dbb03701bf4552bb46f2 100644 --- a/include/class.format.php +++ b/include/class.format.php @@ -533,7 +533,12 @@ class Format { } function getStrftimeFormat($format) { - static $dateToStrftime = array( + static $codes, $ids; + + if (!isset($codes)) { + // This array is flipped because of duplicated formats on the + // intl side due to slight differences in the libraries + $codes = array( '%d' => 'dd', '%a' => 'EEE', '%e' => 'd', @@ -563,17 +568,24 @@ class Format { '%z' => 'ZZZ', '%Z' => 'z', - ); + ); - $flipped = array_flip($dateToStrftime); - krsort($flipped); - // Also establish a list of ids, so we can do a creative replacement - // without clobbering the common letters in the formats - $ids = array_keys($flipped); - $ids = array_flip($ids); - foreach ($flipped as $icu=>$date) { - $format = str_replace($date, chr($ids[$icu]), $format); + $flipped = array_flip($codes); + krsort($flipped); + + // Also establish a list of ids, so we can do a creative replacement + // without clobbering the common letters in the formats + $keys = array_keys($flipped); + $ids = array_combine($keys, array_map('chr', array_flip($keys))); + + // Now create an array from the id codes back to strftime codes + $codes = array_combine($ids, $flipped); } + // $ids => array(intl => #id) + // $codes => array(#id => strftime) + $format = str_replace(array_keys($ids), $ids, $format); + $format = str_replace($ids, $codes, $format); + return preg_replace_callback('`[\x00-\x1f]`', function($m) use ($ids) { return $ids[ord($m[0])]; diff --git a/include/staff/profile.inc.php b/include/staff/profile.inc.php index a8ba88a3ecce4a8a2aece8139c10ba1774c67104..c942f984160efc0e6e12acc0bc87a27f5ee00d9b 100644 --- a/include/staff/profile.inc.php +++ b/include/staff/profile.inc.php @@ -112,6 +112,7 @@ $info['id']=$staff->getId(); </td> </tr> <?php } ?> +<?php if (extension_loaded('intl')) { ?> <tr><td width="220"><?php echo __('Preferred Locale');?>:</td> <td> <select name="locale"> @@ -125,6 +126,7 @@ $info['id']=$staff->getId(); </select> </td> </tr> +<?php } ?> <tr> <td width="180"><?php echo __('Maximum Page size');?>:</td> <td> diff --git a/include/staff/settings-system.inc.php b/include/staff/settings-system.inc.php index e9a261a213de2326fa45359c5f204f9387956d35..8063c1d15fae50ae7ed94a8165082625581faf7a 100644 --- a/include/staff/settings-system.inc.php +++ b/include/staff/settings-system.inc.php @@ -127,6 +127,7 @@ $gmtime = Misc::gmtime(); </em> </th> </tr> +<?php if (extension_loaded('intl')) { ?> <tr><td width="220" class="required"><?php echo __('Default Locale');?>:</td> <td> <select name="default_locale"> @@ -143,6 +144,7 @@ $gmtime = Misc::gmtime(); </select> </td> </tr> +<?php } ?> <tr><td width="220" class="required"><?php echo __('Default Time Zone');?>:</td> <td> <?php @@ -178,26 +180,39 @@ $gmtime = Misc::gmtime(); <tr> <td width="220" class="indented required"><?php echo __('Time Format');?>:</td> <td> - <input type="text" name="time_format" value="<?php echo $config['time_format']; ?>"> + <input type="text" name="time_format" value="<?php echo $config['time_format']; ?>" class="date-format-preview"> <font class="error">* <?php echo $errors['time_format']; ?></font> - <em><?php echo Format::time(null, false); ?></em></td> + <em><?php echo Format::time(null, false); ?></em> + <span class="faded date-format-preview" data-for="time_format"> + <?php echo Format::time('now'); ?> + </span> + </td> </tr> <tr><td width="220" class="indented required"><?php echo __('Date Format');?>:</td> - <td><input type="text" name="date_format" value="<?php echo $config['date_format']; ?>"> + <td><input type="text" name="date_format" value="<?php echo $config['date_format']; ?>" class="date-format-preview"> <font class="error">* <?php echo $errors['date_format']; ?></font> <em><?php echo Format::date(null, false); ?></em> + <span class="faded date-format-preview" data-for="date_format"> + <?php echo Format::date('now'); ?> + </span> </td> </tr> <tr><td width="220" class="indented required"><?php echo __('Date and Time Format');?>:</td> - <td><input type="text" name="datetime_format" value="<?php echo $config['datetime_format']; ?>"> + <td><input type="text" name="datetime_format" value="<?php echo $config['datetime_format']; ?>" class="date-format-preview"> <font class="error">* <?php echo $errors['datetime_format']; ?></font> <em><?php echo Format::datetime(null, false); ?></em> + <span class="faded date-format-preview" data-for="datetime_format"> + <?php echo Format::datetime('now'); ?> + </span> </td> </tr> <tr><td width="220" class="indented required"><?php echo __('Day, Date and Time Format');?>:</td> - <td><input type="text" name="daydatetime_format" value="<?php echo $config['daydatetime_format']; ?>"> + <td><input type="text" name="daydatetime_format" value="<?php echo $config['daydatetime_format']; ?>" class="date-format-preview"> <font class="error">* <?php echo $errors['daydatetime_format']; ?></font> <em><?php echo Format::daydatetime(null, false); ?></em> + <span class="faded date-format-preview" data-for="daydatetime_format"> + <?php echo Format::daydatetime('now'); ?> + </span> </td> </tr> </tbody> @@ -278,5 +293,17 @@ $(function() { $('#secondary_langs').sortable({ cursor: 'move' }); + var prev = []; + $('input.date-format-preview').keyup(function() { + var name = $(this).attr('name'), + div = $('span.date-format-preview[data-for='+name+']'), + current = $(this).val(); + if (prev[name] && prev[name] == current) + return; + prev[name] = current; + div.text('...'); + $.get('ajax.php/config/date-format', {format:$(this).val()}) + .done(function(html) { div.html(html); }); + }); }); </script> diff --git a/scp/ajax.php b/scp/ajax.php index 54e2770736488081832ac325a9a345e94bb5081d..054ef105068f6b36eb92797b4cac48467f78c066 100644 --- a/scp/ajax.php +++ b/scp/ajax.php @@ -50,7 +50,8 @@ $dispatcher = patterns('', )), url('^/config/', patterns('ajax.config.php:ConfigAjaxAPI', url_get('^scp', 'scp'), - url_get('^links', 'templateLinks') + url_get('^links', 'templateLinks'), + url_get('^date-format', 'dateFormat') )), url('^/form/', patterns('ajax.forms.php:DynamicFormsAjaxAPI', url_get('^help-topic/(?P<id>\d+)$', 'getFormsForHelpTopic'),