@@ -0,0 +1,216 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Time and date internationalization management library
|
||||
*
|
||||
* @author Timely Network Inc
|
||||
* @since 2012.10.09
|
||||
*
|
||||
* @package AllInOneCalendar
|
||||
* @subpackage AllInOneCalendar.Lib.Utility
|
||||
*/
|
||||
class Ai1ec_Time_I18n_Utility extends Ai1ec_Base {
|
||||
|
||||
/**
|
||||
* @var char Separator to wrap unique keys and avoid collisions
|
||||
* EOT is used instead of NUL, as NUL is used by `date()`
|
||||
* functions family as guard and causes memory leaks.
|
||||
*/
|
||||
protected $_separator = "\004";
|
||||
|
||||
/**
|
||||
* @var array Map of keys, used by date methods
|
||||
*/
|
||||
protected $_keys = array();
|
||||
|
||||
/**
|
||||
* @var array Map of keys for substition
|
||||
*/
|
||||
protected $_skeys = array();
|
||||
|
||||
/**
|
||||
* @var string Format to use when calling `date_i18n()`
|
||||
*/
|
||||
protected $_format = NULL;
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Memory_Utility Parsed time entries
|
||||
*/
|
||||
protected $_memory = NULL;
|
||||
|
||||
/**
|
||||
* @var Ai1ec_Memory_Utility Parsed format entries
|
||||
*/
|
||||
protected $_transf = NULL;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initialize internal memory objects and date keys.
|
||||
*
|
||||
* @param Ai1ec_Memory_Utility $memory Optionally inject memory to use
|
||||
*
|
||||
* @return void Constructor does not return
|
||||
*/
|
||||
public function __construct(
|
||||
Ai1ec_Registry_Object $registry,
|
||||
Ai1ec_Cache_Memory $memory = null
|
||||
) {
|
||||
parent::__construct( $registry );
|
||||
if ( NULL === $memory ) {
|
||||
$memory = $this->_registry->get( 'cache.memory', 120 ); // 30 * 4
|
||||
}
|
||||
$this->_memory = $memory;
|
||||
$this->_transf = $this->_registry->get( 'cache.memory' );
|
||||
$this->_keys = $this->_initialize_keys();
|
||||
$this->_skeys = $this->_initialize_keys(
|
||||
$this->_separator,
|
||||
$this->_separator
|
||||
);
|
||||
$this->_format = implode( $this->_separator, $this->_keys );
|
||||
}
|
||||
|
||||
/**
|
||||
* format method
|
||||
*
|
||||
* Convenient wrapper for `date_i18n()`, which caches both faster format
|
||||
* version and response for {$timestamp} and {$is_gmt} combination.
|
||||
*
|
||||
* @param string $format Format string to output timestamp in
|
||||
* @param int $timestamp UNIX timestamp to output in given format
|
||||
* @param bool $is_gmt Set to true, to treat {$timestamp} as GMT
|
||||
*
|
||||
* @return string Formatted date-time entry
|
||||
*/
|
||||
public function format( $format, $timestamp = false, $is_gmt = false ) {
|
||||
$time_elements = $this->parse( $timestamp, $is_gmt );
|
||||
$local_format = $this->_safe_format( $format );
|
||||
return str_replace( $this->_skeys, $time_elements, $local_format );
|
||||
}
|
||||
|
||||
/**
|
||||
* parse method
|
||||
*
|
||||
* Parse given timestamp into I18n date/time values map.
|
||||
*
|
||||
* @param int $timestamp Timestamp to parse
|
||||
* @param bool $is_gmt Set to true, to treat value as present in GMT
|
||||
*
|
||||
* @return array Map of date format keys and corresponding time values
|
||||
*/
|
||||
public function parse( $timestamp = false, $is_gmt = false ) {
|
||||
$timestamp = (int)$timestamp;
|
||||
if ( $timestamp <= 0 ) {
|
||||
$timestamp = $this->_registry->get( 'date.system' )->current_time();
|
||||
}
|
||||
$cache_key = $timestamp . "\0" . $is_gmt;
|
||||
if ( NULL === ( $record = $this->_memory->get( $cache_key ) ) ) {
|
||||
$record = array_combine(
|
||||
$this->_keys,
|
||||
explode(
|
||||
$this->_separator,
|
||||
date_i18n( $this->_format, $timestamp, $is_gmt )
|
||||
)
|
||||
);
|
||||
$this->_memory->set( $cache_key, $record );
|
||||
}
|
||||
return $record;
|
||||
}
|
||||
|
||||
/**
|
||||
* _safe_format method
|
||||
*
|
||||
* Prepare safe format value, to use in substitutions.
|
||||
* In prepared string special values are wrapped by {$_separator} to allow
|
||||
* fast replacement methods, using binary search.
|
||||
*
|
||||
* @param string $format Given format to polish
|
||||
*
|
||||
* @return string Modified format, with special keys wrapped in bin fields
|
||||
*/
|
||||
protected function _safe_format( $format ) {
|
||||
if ( NULL === ( $safe = $this->_transf->get( $format ) ) ) {
|
||||
$safe = '';
|
||||
$state = 0;
|
||||
$separator = $this->_separator;
|
||||
$length = strlen( $format );
|
||||
for ( $index = 0; $index < $length; $index++ ) {
|
||||
if ( $state > 0 ) {
|
||||
--$state;
|
||||
}
|
||||
$current = $format{$index};
|
||||
if ( 0 === $state ) {
|
||||
if ( '\\' === $current ) {
|
||||
$state = 2;
|
||||
} elseif ( isset( $this->_keys[$current] ) ) {
|
||||
$current = $separator . $current . $separator;
|
||||
}
|
||||
}
|
||||
if ( 2 !== $state ) {
|
||||
$safe .= $current;
|
||||
}
|
||||
}
|
||||
$this->_transf->set( $format, $safe );
|
||||
}
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* _initialize_keys method
|
||||
*
|
||||
* Prepare list of keys, used by date functions.
|
||||
* Optionally wrap values (keys are the same, always).
|
||||
*
|
||||
* @param string $prepend Prefix to date key
|
||||
* @param string $append Suffix to date key
|
||||
*
|
||||
* @return array Map of date keys
|
||||
*/
|
||||
protected function _initialize_keys( $prepend = '', $append = '' ) {
|
||||
$keys = array(
|
||||
'd',
|
||||
'D',
|
||||
'j',
|
||||
'l',
|
||||
'N',
|
||||
'S',
|
||||
'w',
|
||||
'z',
|
||||
'W',
|
||||
'F',
|
||||
'm',
|
||||
'M',
|
||||
'n',
|
||||
't',
|
||||
'L',
|
||||
'o',
|
||||
'Y',
|
||||
'y',
|
||||
'a',
|
||||
'A',
|
||||
'B',
|
||||
'g',
|
||||
'G',
|
||||
'h',
|
||||
'H',
|
||||
'i',
|
||||
's',
|
||||
'u',
|
||||
'e',
|
||||
'I',
|
||||
'O',
|
||||
'P',
|
||||
'T',
|
||||
'Z',
|
||||
'c',
|
||||
'r',
|
||||
'U',
|
||||
);
|
||||
$map = array();
|
||||
foreach ( $keys as $key ) {
|
||||
$map[$key] = $prepend . $key . $append;
|
||||
}
|
||||
return $map;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user