Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
+57
-19
@@ -117,7 +117,7 @@ class _Lang extends \IPS\Node\Model
|
||||
static::$multitons[ $id ] = static::constructFromData( $lang );
|
||||
}
|
||||
|
||||
static::$outputSalt = uniqid();
|
||||
static::$outputSalt = mt_rand();
|
||||
|
||||
static::$gotAll = TRUE;
|
||||
}
|
||||
@@ -513,6 +513,11 @@ class _Lang extends \IPS\Node\Model
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached preferred date format
|
||||
*/
|
||||
protected $preferredDateFormat = NULL;
|
||||
|
||||
/**
|
||||
* Get the preferred date format for this locale
|
||||
@@ -521,11 +526,16 @@ class _Lang extends \IPS\Node\Model
|
||||
*/
|
||||
public function preferredDateFormat()
|
||||
{
|
||||
/* Make sure the locale has been set, important for things like the js date_format variable */
|
||||
$this->setLocale();
|
||||
if( $this->preferredDateFormat === NULL )
|
||||
{
|
||||
/* Make sure the locale has been set, important for things like the js date_format variable */
|
||||
$this->setLocale();
|
||||
|
||||
$date = new \IPS\DateTime('1992-03-04');
|
||||
return str_replace( array( '1992', '92', '03', '3', $date->strFormat('%B'), '04', ' 4', '4' ), array( 'YY', 'YY', 'MM', 'MM', 'MM', 'DD', 'DD', 'DD' ), $date->localeDate() );
|
||||
$date = new \IPS\DateTime('1992-03-04');
|
||||
$this->preferredDateFormat = str_replace( array( '1992', '92', '03', '3', $date->strFormat('%B'), $date->strFormat('%b'), '04', ' 4', '4' ), array( 'YY', 'YY', 'MM', 'MM', 'MM', 'MM', 'DD', 'DD', 'DD' ), $date->localeDate() );
|
||||
}
|
||||
|
||||
return $this->preferredDateFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -694,7 +704,7 @@ class _Lang extends \IPS\Node\Model
|
||||
/* Get it */
|
||||
if( isset( $this->outputStack[ $key ] ) )
|
||||
{
|
||||
return htmlspecialchars( $key, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', FALSE );
|
||||
return htmlspecialchars( $key, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', FALSE );
|
||||
}
|
||||
|
||||
$id = md5( 'ipslang_' . static::$outputSalt . $key . json_encode( $options ) );
|
||||
@@ -718,12 +728,25 @@ class _Lang extends \IPS\Node\Model
|
||||
* @li % is an ending wildcard, so anything that BEGINS with the number supplied will match
|
||||
* @li # (optional) will be replaced with the actual value
|
||||
* @example {# [1:test][*2:tests][%3:no tests][?:finals]} will result in 1 test, 2 tests, 12 tests, 3 no tests, 35 no tests, 8 finals
|
||||
* @example {!1#[1:January][2:February][3:March][4:April][5:May][6:June][7:July][8:August][9:September][10:October][11:November][12:December]} {0#}
|
||||
* @example {!#[?:%s liked]} %s
|
||||
*/
|
||||
public function pluralize( $string, $params )
|
||||
{
|
||||
$i = 0;
|
||||
$openCurly = '--' . mt_rand() . '--';
|
||||
$closeCurly = '--' . mt_rand() . '--';
|
||||
|
||||
/* Prevent nested { } breaking the syntax */
|
||||
$string = preg_replace_callback( '/(\{!(?:.+?)?(?:\d+?)?\#\[)(.*?)(\]\})/', function( $matches ) use ( $openCurly, $closeCurly )
|
||||
{
|
||||
$replaced = str_replace( '{', $openCurly, $matches[2] );
|
||||
$replaced = str_replace( '}', $closeCurly, $replaced );
|
||||
return $matches[1] . $replaced . $matches[3];
|
||||
}, $string );
|
||||
|
||||
$numberFormatter = array( $this, 'formatNumber' );
|
||||
return preg_replace_callback( '/\{!?(\d+?)?#(.*?)\}/', function( $format ) use ( $params, $i, $numberFormatter )
|
||||
return preg_replace_callback( '/\{!?(\d+?)?#(.*?)\}/', function( $format ) use ( $params, $i, $numberFormatter, $openCurly, $closeCurly )
|
||||
{
|
||||
$originalNumber = $format[1];
|
||||
if ( !$format[1] or $format[1] == '!' )
|
||||
@@ -736,10 +759,14 @@ class _Lang extends \IPS\Node\Model
|
||||
$params[ $format[1] ] = call_user_func( $numberFormatter, $params[ $format[1] ] );
|
||||
$fallback = NULL;
|
||||
$value = NULL;
|
||||
$token = '--' . mt_rand() . '--';
|
||||
|
||||
/* We want to ensure that manually escaped # are not switched */
|
||||
$format[2] = str_replace( '\#', $token, $format[2] );
|
||||
|
||||
/* This regex is tricky: It matches [ followed by anything NOT : until :, then any character, then everything that is not a [ until ] */
|
||||
preg_match_all( '/\[([^:]+):(.[^\[]*)\]/', $format[2], $matches );
|
||||
|
||||
|
||||
foreach ( $matches[1] as $k => $v )
|
||||
{
|
||||
if ( $v == '?' )
|
||||
@@ -768,7 +795,10 @@ class _Lang extends \IPS\Node\Model
|
||||
$return = str_replace( "!{$originalNumber}#", '', $return );
|
||||
$return = str_replace( array( "{$format[1]}#", '#' ), $params[ $format[1] ], $return );
|
||||
$return = preg_replace( '/\[.+\]/', ( $value === NULL ? $fallback : $value ), $return );
|
||||
return $return;
|
||||
|
||||
$return = str_replace( $token, '#', $return );
|
||||
$return = str_replace( $openCurly, '{', $return );
|
||||
return str_replace( $closeCurly, '}', $return );
|
||||
}, $string );
|
||||
}
|
||||
|
||||
@@ -778,16 +808,10 @@ class _Lang extends \IPS\Node\Model
|
||||
* @param number $number The number to format
|
||||
* @param int $decimals Number of decimal places
|
||||
* @return string
|
||||
* @note number_format in PHP < 5.4.0 is not multibyte safe, so we have to work around this deficiency
|
||||
*/
|
||||
public function formatNumber( $number, $decimals=0 )
|
||||
{
|
||||
$placeholders = array( '@', '~' );
|
||||
$replacements = array( $this->locale['decimal_point'], $this->locale['thousands_sep'] );
|
||||
|
||||
$result = number_format( floatval( $number ), floatval( $decimals ), $placeholders[0], $placeholders[1] );
|
||||
|
||||
return str_replace( $placeholders, $replacements, $result );
|
||||
return number_format( floatval( $number ), floatval( $decimals ), $this->locale['decimal_point'], $this->locale['thousands_sep'] );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -837,6 +861,8 @@ class _Lang extends \IPS\Node\Model
|
||||
$return = $matches[1];
|
||||
for ( $i = 0; $i<count( $items ); $i++ )
|
||||
{
|
||||
/* Pluralize can be used after, so avoid triggering the '#', '#[...]' syntax there */
|
||||
$items[ $i ] = preg_replace( '/#(\s|\[)/', '\#\1', $items[ $i ] );
|
||||
$upper = FALSE;
|
||||
if ( $i == 0 )
|
||||
{
|
||||
@@ -1679,7 +1705,7 @@ class _Lang extends \IPS\Node\Model
|
||||
$sprintf = array_map(
|
||||
function ( $val ) use ( $replacement )
|
||||
{
|
||||
return htmlspecialchars( trim( $val ), ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', false );
|
||||
return htmlspecialchars( trim( $val ), ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false );
|
||||
},
|
||||
( is_array(
|
||||
$values[ 'options' ][ 'sprintf' ]
|
||||
@@ -1752,9 +1778,21 @@ class _Lang extends \IPS\Node\Model
|
||||
$replacement = mb_strtolower( $replacement );
|
||||
}
|
||||
|
||||
if ( isset( $values[ 'options' ][ 'seotitle' ] ) )
|
||||
{
|
||||
$replacement = \IPS\Http\Url\Friendly::seoTitle( $replacement );
|
||||
}
|
||||
|
||||
if ( isset( $values[ 'options' ][ 'json' ] ) )
|
||||
{
|
||||
$replacement = mb_substr( json_encode( $replacement ), 1, -1 );
|
||||
if( isset( $values['options']['jsonEscape'] ) )
|
||||
{
|
||||
$replacement = mb_substr( json_encode( $replacement, JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS ), 1, -1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
$replacement = mb_substr( json_encode( $replacement ), 1, -1 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $values[ 'options' ][ 'striptags' ] ) )
|
||||
@@ -1764,7 +1802,7 @@ class _Lang extends \IPS\Node\Model
|
||||
|
||||
if ( isset( $values[ 'options' ][ 'escape' ] ) )
|
||||
{
|
||||
$replacement = htmlspecialchars( $replacement, ENT_QUOTES | \IPS\HTMLENTITIES, 'UTF-8', false );
|
||||
$replacement = htmlspecialchars( $replacement, ENT_QUOTES | ENT_DISALLOWED, 'UTF-8', false );
|
||||
}
|
||||
|
||||
if ( isset( $values['options']['escape'] ) and isset( $values['options']['json'] ) )
|
||||
|
||||
Reference in new issue
Block a user