@@ -0,0 +1,617 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Timezones manipulation object.
|
||||
*
|
||||
* @author Time.ly Network, Inc.
|
||||
* @since 2.0
|
||||
* @package Ai1EC
|
||||
* @subpackage Ai1EC.Date
|
||||
*/
|
||||
class Ai1ec_Date_Timezone extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Cache_Interface In-memory storage for timezone objects.
|
||||
*/
|
||||
protected $_cache = null;
|
||||
|
||||
/**
|
||||
* @var array Map of timezone names and their Olson TZ counterparts.
|
||||
*/
|
||||
protected $_zones = array(
|
||||
'+00:00' => 'UTC',
|
||||
'Z' => 'UTC',
|
||||
'AUS Central Standard Time' => 'Australia/Darwin',
|
||||
'AUS Eastern Standard Time' => 'Australia/Sydney',
|
||||
'Acre' => 'America/Rio_Branco',
|
||||
'Afghanistan' => 'Asia/Kabul',
|
||||
'Afghanistan Standard Time' => 'Asia/Kabul',
|
||||
'Africa_Central' => 'Africa/Maputo',
|
||||
'Africa_Eastern' => 'Africa/Nairobi',
|
||||
'Africa_FarWestern' => 'Africa/El_Aaiun',
|
||||
'Africa_Southern' => 'Africa/Johannesburg',
|
||||
'Africa_Western' => 'Africa/Lagos',
|
||||
'Aktyubinsk' => 'Asia/Aqtobe',
|
||||
'Alaska' => 'America/Juneau',
|
||||
'Alaska_Hawaii' => 'America/Anchorage',
|
||||
'Alaskan Standard Time' => 'America/Anchorage',
|
||||
'Almaty' => 'Asia/Almaty',
|
||||
'Amazon' => 'America/Manaus',
|
||||
'America_Central' => 'America/Chicago',
|
||||
'America_Eastern' => 'America/New_York',
|
||||
'America_Mountain' => 'America/Denver',
|
||||
'America_Pacific' => 'America/Los_Angeles',
|
||||
'Anadyr' => 'Asia/Anadyr',
|
||||
'Aqtau' => 'Asia/Aqtau',
|
||||
'Aqtobe' => 'Asia/Aqtobe',
|
||||
'Arab Standard Time' => 'Asia/Riyadh',
|
||||
'Arabian' => 'Asia/Riyadh',
|
||||
'Arabian Standard Time' => 'Asia/Dubai',
|
||||
'Arabic Standard Time' => 'Asia/Baghdad',
|
||||
'Argentina' => 'America/Buenos_Aires',
|
||||
'Argentina Standard Time' => 'America/Buenos_Aires',
|
||||
'Argentina_Western' => 'America/Mendoza',
|
||||
'Armenia' => 'Asia/Yerevan',
|
||||
'Armenian Standard Time' => 'Asia/Yerevan',
|
||||
'Ashkhabad' => 'Asia/Ashgabat',
|
||||
'Atlantic' => 'America/Halifax',
|
||||
'Atlantic Standard Time' => 'America/Halifax',
|
||||
'Australia_Central' => 'Australia/Adelaide',
|
||||
'Australia_CentralWestern' => 'Australia/Eucla',
|
||||
'Australia_Eastern' => 'Australia/Sydney',
|
||||
'Australia_Western' => 'Australia/Perth',
|
||||
'Azerbaijan' => 'Asia/Baku',
|
||||
'Azerbaijan Standard Time' => 'Asia/Baku',
|
||||
'Azores' => 'Atlantic/Azores',
|
||||
'Azores Standard Time' => 'Atlantic/Azores',
|
||||
'Baku' => 'Asia/Baku',
|
||||
'Bangladesh' => 'Asia/Dhaka',
|
||||
'Bering' => 'America/Adak',
|
||||
'Bhutan' => 'Asia/Thimphu',
|
||||
'Bolivia' => 'America/La_Paz',
|
||||
'Borneo' => 'Asia/Kuching',
|
||||
'Brasilia' => 'America/Sao_Paulo',
|
||||
'British' => 'Europe/London',
|
||||
'Brunei' => 'Asia/Brunei',
|
||||
'Canada Central Standard Time' => 'America/Regina',
|
||||
'Cape Verde Standard Time' => 'Atlantic/Cape_Verde',
|
||||
'Cape_Verde' => 'Atlantic/Cape_Verde',
|
||||
'Caucasus Standard Time' => 'Asia/Yerevan',
|
||||
'Cen. Australia Standard Time' => 'Australia/Adelaide',
|
||||
'Central America Standard Time' => 'America/Guatemala',
|
||||
'Central Asia Standard Time' => 'Asia/Dhaka',
|
||||
'Central Brazilian Standard Time' => 'America/Manaus',
|
||||
'Central Europe Standard Time' => 'Europe/Budapest',
|
||||
'Central European Standard Time' => 'Europe/Warsaw',
|
||||
'Central Pacific Standard Time' => 'Pacific/Guadalcanal',
|
||||
'Central Standard Time' => 'America/Chicago',
|
||||
'Central Standard Time (Mexico)' => 'America/Mexico_City',
|
||||
'Chamorro' => 'Pacific/Saipan',
|
||||
'Changbai' => 'Asia/Harbin',
|
||||
'Chatham' => 'Pacific/Chatham',
|
||||
'Chile' => 'America/Santiago',
|
||||
'China' => 'Asia/Shanghai',
|
||||
'China Standard Time' => 'Asia/Shanghai',
|
||||
'Choibalsan' => 'Asia/Choibalsan',
|
||||
'Christmas' => 'Indian/Christmas',
|
||||
'Cocos' => 'Indian/Cocos',
|
||||
'Colombia' => 'America/Bogota',
|
||||
'Cook' => 'Pacific/Rarotonga',
|
||||
'Cuba' => 'America/Havana',
|
||||
'Dacca' => 'Asia/Dhaka',
|
||||
'Dateline Standard Time' => 'Etc/GMT+12',
|
||||
'Davis' => 'Antarctica/Davis',
|
||||
'Dominican' => 'America/Santo_Domingo',
|
||||
'DumontDUrville' => 'Antarctica/DumontDUrville',
|
||||
'Dushanbe' => 'Asia/Dushanbe',
|
||||
'Dutch_Guiana' => 'America/Paramaribo',
|
||||
'E. Africa Standard Time' => 'Africa/Nairobi',
|
||||
'E. Australia Standard Time' => 'Australia/Brisbane',
|
||||
'E. Europe Standard Time' => 'Europe/Minsk',
|
||||
'E. South America Standard Time' => 'America/Sao_Paulo',
|
||||
'East_Timor' => 'Asia/Dili',
|
||||
'Easter' => 'Pacific/Easter',
|
||||
'Eastern Standard Time' => 'America/New_York',
|
||||
'Ecuador' => 'America/Guayaquil',
|
||||
'Egypt Standard Time' => 'Africa/Cairo',
|
||||
'Ekaterinburg Standard Time' => 'Asia/Yekaterinburg',
|
||||
'Europe_Central' => 'Europe/Paris',
|
||||
'Europe_Eastern' => 'Europe/Bucharest',
|
||||
'Europe_Western' => 'Atlantic/Canary',
|
||||
'FLE Standard Time' => 'Europe/Kiev',
|
||||
'Falkland' => 'Atlantic/Stanley',
|
||||
'Fiji' => 'Pacific/Fiji',
|
||||
'Fiji Standard Time' => 'Pacific/Fiji',
|
||||
'French_Guiana' => 'America/Cayenne',
|
||||
'French_Southern' => 'Indian/Kerguelen',
|
||||
'Frunze' => 'Asia/Bishkek',
|
||||
'GMT' => 'UTC', // seems better than 'Atlantic/Reykjavik'
|
||||
'GMT Standard Time' => 'Europe/London',
|
||||
'GTB Standard Time' => 'Europe/Istanbul',
|
||||
'Galapagos' => 'Pacific/Galapagos',
|
||||
'Gambier' => 'Pacific/Gambier',
|
||||
'Georgia' => 'Asia/Tbilisi',
|
||||
'Georgian Standard Time' => 'Etc/GMT-3',
|
||||
'Gilbert_Islands' => 'Pacific/Tarawa',
|
||||
'Goose_Bay' => 'America/Goose_Bay',
|
||||
'Greenland Standard Time' => 'America/Godthab',
|
||||
'Greenland_Central' => 'America/Scoresbysund',
|
||||
'Greenland_Eastern' => 'America/Scoresbysund',
|
||||
'Greenland_Western' => 'America/Godthab',
|
||||
'Greenwich Standard Time' => 'Atlantic/Reykjavik',
|
||||
'Guam' => 'Pacific/Guam',
|
||||
'Gulf' => 'Asia/Dubai',
|
||||
'Guyana' => 'America/Guyana',
|
||||
'Hawaii_Aleutian' => 'Pacific/Honolulu',
|
||||
'Hawaiian Standard Time' => 'Pacific/Honolulu',
|
||||
'Hong_Kong' => 'Asia/Hong_Kong',
|
||||
'Hovd' => 'Asia/Hovd',
|
||||
'India' => 'Asia/Calcutta',
|
||||
'India Standard Time' => 'Asia/Calcutta',
|
||||
'Indian_Ocean' => 'Indian/Chagos',
|
||||
'Indochina' => 'Asia/Saigon',
|
||||
'Indonesia_Central' => 'Asia/Makassar',
|
||||
'Indonesia_Eastern' => 'Asia/Jayapura',
|
||||
'Indonesia_Western' => 'Asia/Jakarta',
|
||||
'Iran' => 'Asia/Tehran',
|
||||
'Iran Standard Time' => 'Asia/Tehran',
|
||||
'Irish' => 'Europe/Dublin',
|
||||
'Irkutsk' => 'Asia/Irkutsk',
|
||||
'Israel' => 'Asia/Jerusalem',
|
||||
'Israel Standard Time' => 'Asia/Jerusalem',
|
||||
'Japan' => 'Asia/Tokyo',
|
||||
'Jordan Standard Time' => 'Asia/Amman',
|
||||
'Kamchatka' => 'Asia/Kamchatka',
|
||||
'Karachi' => 'Asia/Karachi',
|
||||
'Kashgar' => 'Asia/Kashgar',
|
||||
'Kazakhstan_Eastern' => 'Asia/Almaty',
|
||||
'Kazakhstan_Western' => 'Asia/Aqtobe',
|
||||
'Kizilorda' => 'Asia/Qyzylorda',
|
||||
'Korea' => 'Asia/Seoul',
|
||||
'Korea Standard Time' => 'Asia/Seoul',
|
||||
'Kosrae' => 'Pacific/Kosrae',
|
||||
'Krasnoyarsk' => 'Asia/Krasnoyarsk',
|
||||
'Kuybyshev' => 'Europe/Samara',
|
||||
'Kwajalein' => 'Pacific/Kwajalein',
|
||||
'Kyrgystan' => 'Asia/Bishkek',
|
||||
'Lanka' => 'Asia/Colombo',
|
||||
'Liberia' => 'Africa/Monrovia',
|
||||
'Line_Islands' => 'Pacific/Kiritimati',
|
||||
'Long_Shu' => 'Asia/Chongqing',
|
||||
'Lord_Howe' => 'Australia/Lord_Howe',
|
||||
'Macau' => 'Asia/Macau',
|
||||
'Magadan' => 'Asia/Magadan',
|
||||
'Malaya' => 'Asia/Kuala_Lumpur',
|
||||
'Malaysia' => 'Asia/Kuching',
|
||||
'Maldives' => 'Indian/Maldives',
|
||||
'Marquesas' => 'Pacific/Marquesas',
|
||||
'Marshall_Islands' => 'Pacific/Majuro',
|
||||
'Mauritius' => 'Indian/Mauritius',
|
||||
'Mauritius Standard Time' => 'Indian/Mauritius',
|
||||
'Mawson' => 'Antarctica/Mawson',
|
||||
'Mexico Standard Time' => 'America/Mexico_City',
|
||||
'Mexico Standard Time 2' => 'America/Chihuahua',
|
||||
'Mid-Atlantic Standard Time' => 'Atlantic/South_Georgia',
|
||||
'Middle East Standard Time' => 'Asia/Beirut',
|
||||
'Mongolia' => 'Asia/Ulaanbaatar',
|
||||
'Montevideo Standard Time' => 'America/Montevideo',
|
||||
'Morocco Standard Time' => 'Africa/Casablanca',
|
||||
'Moscow' => 'Europe/Moscow',
|
||||
'Mountain Standard Time' => 'America/Denver',
|
||||
'Mountain Standard Time (Mexico)' => 'America/Chihuahua',
|
||||
'Myanmar' => 'Asia/Rangoon',
|
||||
'Myanmar Standard Time' => 'Asia/Rangoon',
|
||||
'N. Central Asia Standard Time' => 'Asia/Novosibirsk',
|
||||
'Namibia Standard Time' => 'Africa/Windhoek',
|
||||
'Nauru' => 'Pacific/Nauru',
|
||||
'Nepal' => 'Asia/Katmandu',
|
||||
'Nepal Standard Time' => 'Asia/Katmandu',
|
||||
'New Zealand Standard Time' => 'Pacific/Auckland',
|
||||
'New_Caledonia' => 'Pacific/Noumea',
|
||||
'New_Zealand' => 'Pacific/Auckland',
|
||||
'Newfoundland' => 'America/St_Johns',
|
||||
'Newfoundland Standard Time' => 'America/St_Johns',
|
||||
'Niue' => 'Pacific/Niue',
|
||||
'Norfolk' => 'Pacific/Norfolk',
|
||||
'Noronha' => 'America/Noronha',
|
||||
'North Asia East Standard Time' => 'Asia/Irkutsk',
|
||||
'North Asia Standard Time' => 'Asia/Krasnoyarsk',
|
||||
'North_Mariana' => 'Pacific/Saipan',
|
||||
'Novosibirsk' => 'Asia/Novosibirsk',
|
||||
'Omsk' => 'Asia/Omsk',
|
||||
'Oral' => 'Asia/Oral',
|
||||
'Pacific SA Standard Time' => 'America/Santiago',
|
||||
'Pacific Standard Time' => 'America/Los_Angeles',
|
||||
'Pacific Standard Time (Mexico)' => 'America/Tijuana',
|
||||
'Pakistan' => 'Asia/Karachi',
|
||||
'Pakistan Standard Time' => 'Asia/Karachi',
|
||||
'Palau' => 'Pacific/Palau',
|
||||
'Papua_New_Guinea' => 'Pacific/Port_Moresby',
|
||||
'Paraguay' => 'America/Asuncion',
|
||||
'Peru' => 'America/Lima',
|
||||
'Philippines' => 'Asia/Manila',
|
||||
'Phoenix_Islands' => 'Pacific/Enderbury',
|
||||
'Pierre_Miquelon' => 'America/Miquelon',
|
||||
'Pitcairn' => 'Pacific/Pitcairn',
|
||||
'Ponape' => 'Pacific/Ponape',
|
||||
'Qyzylorda' => 'Asia/Qyzylorda',
|
||||
'Reunion' => 'Indian/Reunion',
|
||||
'Romance Standard Time' => 'Europe/Paris',
|
||||
'Rothera' => 'Antarctica/Rothera',
|
||||
'Russian Standard Time' => 'Europe/Moscow',
|
||||
'SA Eastern Standard Time' => 'Etc/GMT+3',
|
||||
'SA Pacific Standard Time' => 'America/Bogota',
|
||||
'SA Western Standard Time' => 'America/La_Paz',
|
||||
'SE Asia Standard Time' => 'Asia/Bangkok',
|
||||
'Sakhalin' => 'Asia/Sakhalin',
|
||||
'Samara' => 'Europe/Samara',
|
||||
'Samarkand' => 'Asia/Samarkand',
|
||||
'Samoa' => 'Pacific/Apia',
|
||||
'Samoa Standard Time' => 'Pacific/Apia',
|
||||
'Seychelles' => 'Indian/Mahe',
|
||||
'Shevchenko' => 'Asia/Aqtau',
|
||||
'Singapore' => 'Asia/Singapore',
|
||||
'Singapore Standard Time' => 'Asia/Singapore',
|
||||
'Solomon' => 'Pacific/Guadalcanal',
|
||||
'South Africa Standard Time' => 'Africa/Johannesburg',
|
||||
'South_Georgia' => 'Atlantic/South_Georgia',
|
||||
'Sri Lanka Standard Time' => 'Asia/Colombo',
|
||||
'Suriname' => 'America/Paramaribo',
|
||||
'Sverdlovsk' => 'Asia/Yekaterinburg',
|
||||
'Syowa' => 'Antarctica/Syowa',
|
||||
'Tahiti' => 'Pacific/Tahiti',
|
||||
'Taipei' => 'Asia/Taipei',
|
||||
'Taipei Standard Time' => 'Asia/Taipei',
|
||||
'Tajikistan' => 'Asia/Dushanbe',
|
||||
'Tashkent' => 'Asia/Tashkent',
|
||||
'Tasmania Standard Time' => 'Australia/Hobart',
|
||||
'Tbilisi' => 'Asia/Tbilisi',
|
||||
'Tokelau' => 'Pacific/Fakaofo',
|
||||
'Tokyo Standard Time' => 'Asia/Tokyo',
|
||||
'Tonga' => 'Pacific/Tongatapu',
|
||||
'Tonga Standard Time' => 'Pacific/Tongatapu',
|
||||
'Truk' => 'Pacific/Truk',
|
||||
'Turkey' => 'Europe/Istanbul',
|
||||
'Turkmenistan' => 'Asia/Ashgabat',
|
||||
'Tuvalu' => 'Pacific/Funafuti',
|
||||
'US/Eastern' => 'America/New_York',
|
||||
'US Eastern Standard Time' => 'Etc/GMT+5',
|
||||
'US Mountain Standard Time' => 'America/Phoenix',
|
||||
'Uralsk' => 'Asia/Oral',
|
||||
'Uruguay' => 'America/Montevideo',
|
||||
'Urumqi' => 'Asia/Urumqi',
|
||||
'Uzbekistan' => 'Asia/Tashkent',
|
||||
'Vanuatu' => 'Pacific/Efate',
|
||||
'Venezuela' => 'America/Caracas',
|
||||
'Venezuela Standard Time' => 'America/Caracas',
|
||||
'Vladivostok' => 'Asia/Vladivostok',
|
||||
'Vladivostok Standard Time' => 'Asia/Vladivostok',
|
||||
'Volgograd' => 'Europe/Volgograd',
|
||||
'Vostok' => 'Antarctica/Vostok',
|
||||
'W. Australia Standard Time' => 'Australia/Perth',
|
||||
'W. Central Africa Standard Time' => 'Africa/Lagos',
|
||||
'W. Europe Standard Time' => 'Europe/Berlin',
|
||||
'Wake' => 'Pacific/Wake',
|
||||
'Wallis' => 'Pacific/Wallis',
|
||||
'West Asia Standard Time' => 'Asia/Tashkent',
|
||||
'West Pacific Standard Time' => 'Pacific/Port_Moresby',
|
||||
'Yakutsk' => 'Asia/Yakutsk',
|
||||
'Yakutsk Standard Time' => 'Asia/Yakutsk',
|
||||
'Yekaterinburg' => 'Asia/Yekaterinburg',
|
||||
'Yerevan' => 'Asia/Yerevan',
|
||||
'Yukon' => 'America/Yakutat',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array Map of timezones acceptable by DateTimeZone but not strtotime.
|
||||
*/
|
||||
protected $_invalid_legacy = array(
|
||||
'US/Eastern' => true,
|
||||
);
|
||||
|
||||
/**
|
||||
* @var array|bool List of system identifiers or false if none available.
|
||||
*/
|
||||
protected $_identifiers = false;
|
||||
|
||||
/**
|
||||
* Initialize local cache and identifiers.
|
||||
*
|
||||
* @param Ai1ec_Registry_Object $registry Registry to use.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( Ai1ec_Registry_Object $registry ) {
|
||||
parent::__construct( $registry );
|
||||
$this->_cache = $this->_registry->get( 'cache.memory' );
|
||||
$this->_init_identifiers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default timezone to use in input/output.
|
||||
*
|
||||
* Approach is as follows:
|
||||
* - check user profile for timezone preference;
|
||||
* - if user has no preference - check site for timezone selection;
|
||||
* - if site has no selection - raise notice and use 'UTC'.
|
||||
*
|
||||
* @return string Olson timezone string identifier.
|
||||
*/
|
||||
public function get_default_timezone() {
|
||||
static $default_timezone = null;
|
||||
if ( null === $default_timezone ) {
|
||||
$candidates = array();
|
||||
$candidates[] = (string)$this->_registry->get( 'model.meta-user' )
|
||||
->get_current( 'ai1ec_timezone' );
|
||||
$candidates[] = (string)$this->_registry->get( 'model.option' )
|
||||
->get( 'timezone_string' );
|
||||
$candidates[] = (string)$this->_registry->get( 'model.option' )
|
||||
->get( 'gmt_offset' );
|
||||
$candidates = array_filter( $candidates, 'strlen' );
|
||||
foreach ( $candidates as $timezone ) {
|
||||
$timezone = $this->get_name( $timezone );
|
||||
if ( false !== $timezone ) {
|
||||
$default_timezone = $timezone;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( null === $default_timezone ) {
|
||||
$default_timezone = 'UTC';
|
||||
$this->_registry->get( 'notification.admin' )->store(
|
||||
sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Please select site timezone in %s <em>Timezone</em> dropdown menu.'
|
||||
),
|
||||
'<a href="' . ai1ec_admin_url( 'options-general.php' ) .
|
||||
'">' . Ai1ec_I18n::__( 'Settings' ) . '</a>'
|
||||
),
|
||||
'error'
|
||||
);
|
||||
}
|
||||
}
|
||||
return $default_timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to decode GMT offset to some Olson timezone.
|
||||
*
|
||||
* @param float $zone GMT offset.
|
||||
*
|
||||
* @return string Valid Olson timezone name (UTC is last resort).
|
||||
*/
|
||||
public function decode_gmt_timezone( $zone ) {
|
||||
$auto_zone = timezone_name_from_abbr( null, $zone * 3600, true );
|
||||
if ( false !== $auto_zone ) {
|
||||
return $auto_zone;
|
||||
}
|
||||
$auto_zone = timezone_name_from_abbr(
|
||||
null,
|
||||
( (int) $zone ) * 3600,
|
||||
true
|
||||
);
|
||||
if ( false !== $auto_zone ) {
|
||||
return $auto_zone;
|
||||
}
|
||||
$this->_registry->get( 'notification.admin' )->store(
|
||||
sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Timezone "UTC%+d" is not recognized. Please %suse valid%s timezone name, until then events will be created in UTC timezone.'
|
||||
),
|
||||
$zone,
|
||||
'<a href="' . ai1ec_admin_url( 'options-general.php' ) . '">',
|
||||
'</a>'
|
||||
),
|
||||
'error'
|
||||
);
|
||||
return 'UTC';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get valid timezone name from input.
|
||||
*
|
||||
* @param string $zone Name to check/parse.
|
||||
*
|
||||
* @return string Timezone name to use
|
||||
*/
|
||||
public function get_name( $zone ) {
|
||||
if ( is_numeric( $zone ) ) {
|
||||
$decoded_zone = $this->decode_gmt_timezone( $zone );
|
||||
if ( 'UTC' !== $decoded_zone ) {
|
||||
$message = sprintf(
|
||||
Ai1ec_I18n::__(
|
||||
'Selected timezone "UTC%+d" will be treated as %s.'
|
||||
),
|
||||
$zone,
|
||||
$decoded_zone
|
||||
);
|
||||
$this->_registry->get( 'notification.admin' )
|
||||
->store( $message );
|
||||
}
|
||||
$zone = $decoded_zone;
|
||||
}
|
||||
if ( false === $this->_identifiers ) {
|
||||
return $zone; // anything should do, as zones are not supported
|
||||
}
|
||||
if ( ! isset( $this->_identifiers[$zone] ) ) {
|
||||
$zone = $this->_olson_lookup( $zone );
|
||||
$valid_legacy = false;
|
||||
try {
|
||||
new DateTimeZone( $zone ); // throw away instantly
|
||||
$valid_legacy = true;
|
||||
} catch ( Exception $excpt ) {
|
||||
$valid_legacy = false;
|
||||
}
|
||||
if ( ! $valid_legacy || isset( $this->_invalid_legacy[$zone] ) ) {
|
||||
return $this->guess_zone( $zone );
|
||||
}
|
||||
$this->_identifiers[$zone] = $zone;
|
||||
unset( $valid_legacy );
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Quick map look-up to discard zones that have limited recognition.
|
||||
*
|
||||
* @param string $zone Name of timezone to lookup.
|
||||
*
|
||||
* @return string Timezone name to use. Might be the same as $zone.
|
||||
*/
|
||||
protected function _olson_lookup( $zone ) {
|
||||
if ( isset( $this->_zones[$zone] ) ) {
|
||||
return $this->_zones[$zone];
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if timezone is set in wp_option
|
||||
*
|
||||
*/
|
||||
public function is_timezone_not_set() {
|
||||
$timezone = $this->_registry->get( 'model.option' )
|
||||
->get( 'timezone_string' );
|
||||
return empty( $timezone );
|
||||
}
|
||||
|
||||
/**
|
||||
* Render options for select in settings
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_timezones( $only_zones = false ) {
|
||||
$zones = DateTimeZone::listIdentifiers();
|
||||
if (
|
||||
empty( $zones )
|
||||
) {
|
||||
return array();
|
||||
}
|
||||
if ( ! $only_zones ) {
|
||||
$manual = __( 'Manual Offset', AI1EC_PLUGIN_NAME );
|
||||
$options = array();
|
||||
$options[$manual][] = array(
|
||||
'text' => __( 'Choose your timezone', AI1EC_PLUGIN_NAME ),
|
||||
'value' => '',
|
||||
'args' => array(
|
||||
'selected' => 'selected'
|
||||
)
|
||||
);
|
||||
}
|
||||
foreach ( $zones as $zone ) {
|
||||
$exploded_zone = explode( '/', $zone );
|
||||
if ( ! isset( $exploded_zone[1] ) && ! $only_zones ) {
|
||||
$exploded_zone[1] = $exploded_zone[0];
|
||||
$exploded_zone[0] = $manual;
|
||||
}
|
||||
$optgroup = $exploded_zone[0];
|
||||
unset( $exploded_zone[0] );
|
||||
$options[$optgroup][] = array(
|
||||
'text' => implode( '/', $exploded_zone ),
|
||||
'value' => $zone,
|
||||
);
|
||||
}
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
||||
/**
|
||||
* Guess valid timezone identifier from arbitrary input.
|
||||
*
|
||||
* @param string $meta_name Arbitrary input.
|
||||
*
|
||||
* @return string|bool Parsed timezone name or false if none found.
|
||||
*/
|
||||
public function guess_zone( $meta_name ) {
|
||||
if ( isset( $this->_zones[$meta_name] ) ) {
|
||||
return $this->_zones[$meta_name];
|
||||
}
|
||||
$name_variants = array(
|
||||
strtr( $meta_name, ' ', '_' ),
|
||||
strtr( $meta_name, '_', ' ' ),
|
||||
);
|
||||
if ( false !== ( $parenthesis_pos = strpos( $meta_name, '(' ) ) ) {
|
||||
foreach ( $name_variants as $name ) {
|
||||
$name_variants[] = substr( $name, 0, $parenthesis_pos - 1 );
|
||||
}
|
||||
}
|
||||
foreach ( $name_variants as $name ) {
|
||||
if ( isset( $this->_zones[$name] ) ) {
|
||||
// cache to avoid future lookups and return
|
||||
$this->_zones[$meta_name] = $this->_zones[$name];
|
||||
return $this->_zones[$name];
|
||||
}
|
||||
}
|
||||
if (
|
||||
isset( $meta_name{0} ) &&
|
||||
'(' === $meta_name{0} &&
|
||||
$closing_pos = strpos( $meta_name, ')' )
|
||||
) {
|
||||
$meta_name = trim( substr( $meta_name, $closing_pos + 1 ) );
|
||||
return $this->guess_zone( $meta_name );
|
||||
}
|
||||
if (
|
||||
false === strpos( $meta_name, ' Standard ' ) &&
|
||||
false !== ( $time_pos = strpos( $meta_name, ' Time' ) )
|
||||
) {
|
||||
$meta_name = substr( $meta_name, 0, $time_pos ) .
|
||||
' Standard' . substr( $meta_name, $time_pos );
|
||||
return $this->guess_zone( $meta_name );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get timezone object instance.
|
||||
*
|
||||
* @param string $timezone Name of timezone to get instance for.
|
||||
*
|
||||
* @return DateTimeZone Instance of timezone object.
|
||||
*
|
||||
* @throws Ai1ec_Date_Timezone_Exception If an error occurs.
|
||||
*/
|
||||
public function get( $timezone ) {
|
||||
if ( 'sys.default' === $timezone ) {
|
||||
$timezone = $this->get_default_timezone();
|
||||
}
|
||||
$name = $this->get_name( $timezone );
|
||||
if ( ! $name ) {
|
||||
$name = $this->get_name( $this->get_default_timezone() );
|
||||
}
|
||||
$zone = $this->_cache->get( $name, null );
|
||||
if ( null === $zone ) {
|
||||
$exception = null;
|
||||
try {
|
||||
$zone = new DateTimeZone( $name );
|
||||
} catch ( Exception $invalid_tz ) {
|
||||
$exception = $invalid_tz;
|
||||
}
|
||||
if ( null !== $exception ) {
|
||||
throw new Ai1ec_Date_Timezone_Exception( $exception->getMessage() );
|
||||
}
|
||||
$this->_cache->set( $name, $zone );
|
||||
}
|
||||
return $zone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add system identifiers to object registry.
|
||||
*
|
||||
* @return bool Success
|
||||
*/
|
||||
protected function _init_identifiers() {
|
||||
$identifiers = DateTimeZone::listIdentifiers();
|
||||
if ( ! $identifiers ) {
|
||||
return false;
|
||||
}
|
||||
$mapped = array();
|
||||
foreach ( $identifiers as $zone ) {
|
||||
$zone = (string)$zone;
|
||||
$mapped[$zone] = true;
|
||||
$this->_zones[$zone] = $zone;
|
||||
}
|
||||
unset( $identifiers, $zone );
|
||||
$this->_identifiers = $mapped;
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user