617 lines
28 KiB
PHP
617 lines
28 KiB
PHP
<?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;
|
|
}
|
|
|
|
}
|