all-in-one-event-calendar/lib/date/time-i18n.php
2017-11-09 17:36:04 +01:00

216 lines
6.1 KiB
PHP

<?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;
}
}