From b37b56a339f416c9bc4cec7bc02fefd891cd181b Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 18 Jun 2009 17:40:40 +0000 Subject: [PATCH] Optimize timezone dropdown creation. Props sambauers. fixes #10125 for trunk git-svn-id: http://svn.automattic.com/wordpress/trunk@11597 1a063a9b-81f0-0310-95a4-ce76da25c4cd --- wp-admin/options-general.php | 11 +- wp-includes/functions.php | 235 +++++++++++++++++++++-------------- 2 files changed, 149 insertions(+), 97 deletions(-) diff --git a/wp-admin/options-general.php b/wp-admin/options-general.php index cd4b8cdb3..3f2588856 100644 --- a/wp-admin/options-general.php +++ b/wp-admin/options-general.php @@ -157,7 +157,7 @@ if (empty($tzstring)) { // set the Etc zone if no timezone string exists
- +
time()) { - $found = true; + $found = true; break; } } @@ -179,10 +179,7 @@ if (empty($tzstring)) { // set the Etc zone if no timezone string exists $message = $tr['isdst'] ? __('Daylight savings time begins on: %s.') : __('Standard time begins on: %s.'); - $tz = new DateTimeZone($tzstring); - $d = new DateTime( "@{$tr['ts']}" ); - $d->setTimezone($tz); - printf( $message, date_i18n(get_option('date_format').' '.get_option('time_format'), $d->format('U') ) ); + printf( $message, date_i18n(get_option('date_format').' '.get_option('time_format'), $tr['ts'] ) ); } else { _e('This timezone does not observe daylight savings time.'); } diff --git a/wp-includes/functions.php b/wp-includes/functions.php index cfd12badb..03019a807 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -3149,36 +3149,74 @@ function update_site_option( $key, $value ) { * Overrides the gmt_offset option if we have a timezone_string available */ function wp_timezone_override_offset() { - if (!wp_timezone_supported()) return false; + if ( !wp_timezone_supported() ) { + return false; + } + if ( !$timezone_string = get_option( 'timezone_string' ) ) { + return false; + } - $tz = get_option('timezone_string'); - if (empty($tz)) return false; - - @date_default_timezone_set($tz); - - $dateTimeZoneSelected = timezone_open($tz); - $dateTimeServer = date_create(); - if ($dateTimeZoneSelected === false || $dateTimeServer === false) return false; - - $timeOffset = timezone_offset_get($dateTimeZoneSelected, $dateTimeServer); - $timeOffset = $timeOffset / 3600; - - return $timeOffset; + @date_default_timezone_set( $timezone_string ); + $timezone_object = timezone_open( $timezone_string ); + $datetime_object = date_create(); + if ( false === $timezone_object || false === $datetime_object ) { + return false; + } + return round( timezone_offset_get( $timezone_object, $datetime_object ) / 3600, 2 ); } /** * Check for PHP timezone support - * */ function wp_timezone_supported() { - if (function_exists('date_default_timezone_set') - && function_exists('timezone_identifiers_list') - && function_exists('timezone_open') - && function_exists('timezone_offset_get') - ) - return apply_filters('timezone_support',true); + $support = false; + if ( + function_exists( 'date_default_timezone_set' ) && + function_exists( 'timezone_identifiers_list' ) && + function_exists( 'timezone_open' ) && + function_exists( 'timezone_offset_get' ) + ) { + $support = true; + } + return apply_filters( 'timezone_support', $support ); +} - return apply_filters('timezone_support',false); +function _wp_timezone_choice_usort_callback( $a, $b ) { + // Don't use translated versions of Etc + if ( 'Etc' === $a['continent'] && 'Etc' === $b['continent'] ) { + // Make the order of these more like the old dropdown + if ( 'GMT+' === substr( $a['city'], 0, 4 ) && 'GMT+' === substr( $b['city'], 0, 4 ) ) { + return -1 * ( strnatcasecmp( $a['city'], $b['city'] ) ); + } + if ( 'UTC' === $a['city'] ) { + if ( 'GMT+' === substr( $b['city'], 0, 4 ) ) { + return 1; + } + return -1; + } + if ( 'UTC' === $b['city'] ) { + if ( 'GMT+' === substr( $a['city'], 0, 4 ) ) { + return -1; + } + return 1; + } + return strnatcasecmp( $a['city'], $b['city'] ); + } + if ( $a['t_continent'] == $b['t_continent'] ) { + if ( $a['t_city'] == $b['t_city'] ) { + return strnatcasecmp( $a['t_subcity'], $b['t_subcity'] ); + } + return strnatcasecmp( $a['t_city'], $b['t_city'] ); + } else { + // Force Etc to the bottom of the list + if ( 'Etc' === $a['continent'] ) { + return 1; + } + if ( 'Etc' === $b['continent'] ) { + return -1; + } + return strnatcasecmp( $a['t_continent'], $b['t_continent'] ); + } } /** @@ -3187,90 +3225,107 @@ function wp_timezone_supported() { * @param string $selectedzone - which zone should be the selected one * */ -function wp_timezone_choice($selectedzone) { +function wp_timezone_choice( $selected_zone ) { static $mo_loaded = false; - $continents = array('Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific', 'Etc'); + $continents = array( 'Africa', 'America', 'Antarctica', 'Arctic', 'Asia', 'Atlantic', 'Australia', 'Europe', 'Indian', 'Pacific', 'Etc' ); // Load translations for continents and cities - if ( ! $mo_loaded ) { + if ( !$mo_loaded ) { $locale = get_locale(); - $mofile = WP_LANG_DIR . "/continents-cities-$locale.mo"; - load_textdomain('continents-cities', $mofile); + $mofile = WP_LANG_DIR . '/continents-cities-' . $locale . '.mo'; + load_textdomain( 'continents-cities', $mofile ); $mo_loaded = true; } - $all = timezone_identifiers_list(); - - $i = 0; - foreach ( $all as $zone ) { - $zone = explode('/',$zone); - if ( ! in_array($zone[0], $continents) ) + $zonen = array(); + foreach ( timezone_identifiers_list() as $zone ) { + $zone = explode( '/', $zone ); + if ( !in_array( $zone[0], $continents ) ) { continue; - if ( $zone[0] == 'Etc' && in_array($zone[1], array('UCT', 'GMT', 'GMT0', 'GMT+0', 'GMT-0', 'Greenwich', 'Universal', 'Zulu')) ) + } + if ( 'Etc' === $zone[0] && in_array( $zone[1], array( 'UCT', 'GMT', 'GMT0', 'GMT+0', 'GMT-0', 'Greenwich', 'Universal', 'Zulu' ) ) ) { continue; - $zonen[$i]['continent'] = isset($zone[0]) ? $zone[0] : ''; - $zonen[$i]['city'] = isset($zone[1]) ? $zone[1] : ''; - $zonen[$i]['subcity'] = isset($zone[2]) ? $zone[2] : ''; - $i++; - } - - usort($zonen, create_function( - '$a, $b', ' - $t = create_function(\'$s\', \'return translate(str_replace("_", " ", $s), "continents-cities");\'); - $a_continent = $t($a["continent"]); - $b_continent = $t($b["continent"]); - $a_city = $t($a["city"]); - $b_city = $t($b["city"]); - $a_subcity = $t($a["subcity"]); - $b_subcity = $t($b["subcity"]); - if ( $a_continent == $b_continent && $a_city == $b_city ) - return strnatcasecmp($a_subcity, $b_subcity); - elseif ( $a_continent == $b_continent ) - return strnatcasecmp($a_city, $b_city); - else - return strnatcasecmp($a_continent, $b_continent); - ')); - - $structure = ''; - $pad = '   '; - - if ( empty($selectedzone) ) - $structure .= '\n"; - foreach ( $zonen as $zone ) { - extract($zone); - if ( empty($selectcontinent) && !empty($city) ) { - $selectcontinent = $continent; - $structure .= '' . "\n"; // continent - } elseif ( !empty($selectcontinent) && $selectcontinent != $continent ) { - $structure .= "\n"; - $selectcontinent = ''; - if ( !empty($city) ) { - $selectcontinent = $continent; - $structure .= '' . "\n"; // continent - } } - if ( !empty($city) ) { - $display = str_replace('_',' ',$city); - $display = translate($display, "continents-cities"); - if ( !empty($subcity) ) { - $display_subcity = str_replace('_', ' ', $subcity); - $display_subcity = translate($display_subcity, "continents-cities"); - $city = $city . '/'. $subcity; - $display = $display . '/' . $display_subcity; - } - if ( $continent == 'Etc' ) - $display = strtr($display, '+-', '-+'); - $structure .= "\t\n"; //Timezone + // This determines what gets set and translated - we don't translate Etc/* strings here, they are done later + $exists = array( + 0 => ( isset( $zone[0] ) && $zone[0] ) ? true : false, + 1 => ( isset( $zone[1] ) && $zone[1] ) ? true : false, + 2 => ( isset( $zone[2] ) && $zone[2] ) ? true : false + ); + $exists[3] = ( $exists[0] && 'Etc' !== $zone[0] ) ? true : false; + $exists[4] = ( $exists[1] && $exists[3] ) ? true : false; + $exists[5] = ( $exists[2] && $exists[3] ) ? true : false; + + $zonen[] = array( + 'continent' => ( $exists[0] ? $zone[0] : '' ), + 'city' => ( $exists[1] ? $zone[1] : '' ), + 'subcity' => ( $exists[2] ? $zone[2] : '' ), + 't_continent' => ( $exists[3] ? translate( str_replace( '_', ' ', $zone[0] ), 'continents-cities' ) : '' ), + 't_city' => ( $exists[4] ? translate( str_replace( '_', ' ', $zone[1] ), 'continents-cities' ) : '' ), + 't_subcity' => ( $exists[5] ? translate( str_replace( '_', ' ', $zone[2] ), 'continents-cities' ) : '' ) + ); + } + usort( $zonen, '_wp_timezone_choice_usort_callback' ); + + $structure = array(); + + if ( empty( $selected_zone ) ) { + $structure[] = ''; + } + + foreach ( $zonen as $key => $zone ) { + // Build value in an array to join later + $value = array( $zone['continent'] ); + + if ( empty( $zone['city'] ) ) { + // It's at the continent level (generally won't happen) + $display = $zone['t_continent']; } else { - $structure .= "\n"; //Timezone + // It's inside a continent group + + // Continent optgroup + if ( !isset( $zonen[$key - 1] ) || $zonen[$key - 1]['continent'] !== $zone['continent'] ) { + $label = ( 'Etc' === $zone['continent'] ) ? __( 'Manual offsets' ) : $zone['t_continent']; + $structure[] = ''; + } + + // Add the city to the value + $value[] = $zone['city']; + if ( 'Etc' === $zone['continent'] ) { + if ( 'UTC' === $zone['city'] ) { + $display = ''; + } else { + $display = str_replace( 'GMT', '', $zone['city'] ); + $display = strtr( $display, '+-', '-+' ) . ':00'; + } + $display = '   ' . sprintf( __( 'UTC %s' ), $display ); + } else { + $display = '   ' . $zone['t_city']; + if ( !empty( $zone['subcity'] ) ) { + // Add the subcity to the value + $value[] = $zone['subcity']; + $display .= ' - ' . $zone['t_subcity']; + } + } + } + + // Build the value + $value = join( '/', $value ); + $selected = ''; + if ( $value === $selected_zone ) { + $selected = 'selected="selected" '; + } + $structure[] = '"; + + // Close continent optgroup + if ( !empty( $zone['city'] ) && isset( $zonen[$key + 1] ) && $zonen[$key + 1]['continent'] !== $zone['continent'] ) { + $structure[] = ''; } } - if ( !empty($selectcontinent) ) - $structure .= "\n"; - return $structure; + return join( "\n", $structure ); }