mirror of
https://github.com/Mibew/handlebars.php.git
synced 2025-05-03 02:26:41 +03:00
Add segment-literal notation for expressions
This commit is contained in:
parent
6a3e666258
commit
b4c019372b
52
src/Handlebars/Context.php
Executable file → Normal file
52
src/Handlebars/Context.php
Executable file → Normal file
@ -11,6 +11,7 @@
|
|||||||
* @author Behrooz Shabani <everplays@gmail.com>
|
* @author Behrooz Shabani <everplays@gmail.com>
|
||||||
* @author Chris Gray <chris.w.gray@gmail.com>
|
* @author Chris Gray <chris.w.gray@gmail.com>
|
||||||
* @author Ulrik Lystbaek <ulrik@bettertaste.dk>
|
* @author Ulrik Lystbaek <ulrik@bettertaste.dk>
|
||||||
|
* @author Dmitriy Simushev <simushevds@gmail.com>
|
||||||
* @copyright 2012 (c) ParsPooyesh Co
|
* @copyright 2012 (c) ParsPooyesh Co
|
||||||
* @copyright 2013 (c) Behrooz Shabani
|
* @copyright 2013 (c) Behrooz Shabani
|
||||||
* @copyright 2013 (c) f0ruD A
|
* @copyright 2013 (c) f0ruD A
|
||||||
@ -38,6 +39,17 @@ namespace Handlebars;
|
|||||||
class Context
|
class Context
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of charcters that cannot be used in identifiers.
|
||||||
|
*/
|
||||||
|
const NOT_VALID_NAME_CHARS = '!"#%&\'()*+,./;<=>@[\\]^`{|}~';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of characters that cannot be used in identifiers in segment-literal
|
||||||
|
* notation.
|
||||||
|
*/
|
||||||
|
const NOT_VALID_SEGMENT_NAME_CHARS = "]";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var array stack for context only top stack is available
|
* @var array stack for context only top stack is available
|
||||||
*/
|
*/
|
||||||
@ -179,13 +191,14 @@ class Context
|
|||||||
/**
|
/**
|
||||||
* Get a available from current context
|
* Get a available from current context
|
||||||
* Supported types :
|
* Supported types :
|
||||||
* variable , ../variable , variable.variable , .
|
* variable , ../variable , variable.variable , variable.[variable] , .
|
||||||
*
|
*
|
||||||
* @param string $variableName variable name to get from current context
|
* @param string $variableName variable name to get from current context
|
||||||
* @param boolean $strict strict search? if not found then throw exception
|
* @param boolean $strict strict search? if not found then throw exception
|
||||||
*
|
*
|
||||||
* @throws \InvalidArgumentException in strict mode and variable not found
|
* @throws \InvalidArgumentException in strict mode and variable not found
|
||||||
* @throws \RuntimeException if supplied argument is a malformed quoted string
|
* @throws \RuntimeException if supplied argument is a malformed quoted string
|
||||||
|
* @throws \InvalidArgumentException if variable name is invalid
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function get($variableName, $strict = false)
|
public function get($variableName, $strict = false)
|
||||||
@ -228,7 +241,7 @@ class Context
|
|||||||
} elseif ($variableName == '@key') {
|
} elseif ($variableName == '@key') {
|
||||||
$current = $this->lastKey();
|
$current = $this->lastKey();
|
||||||
} else {
|
} else {
|
||||||
$chunks = explode('.', $variableName);
|
$chunks = $this->_splitVariableName($variableName);
|
||||||
foreach ($chunks as $chunk) {
|
foreach ($chunks as $chunk) {
|
||||||
if (is_string($current) and $current == '') {
|
if (is_string($current) and $current == '') {
|
||||||
return $current;
|
return $current;
|
||||||
@ -275,4 +288,39 @@ class Context
|
|||||||
return $value;
|
return $value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits variable name to chunks.
|
||||||
|
*
|
||||||
|
* @param string $variable_name Fully qualified name of a variable.
|
||||||
|
*
|
||||||
|
* @throws \InvalidArgumentException if variable name is invalid.
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function _splitVariableName($variable_name)
|
||||||
|
{
|
||||||
|
$bad_chars = preg_quote(self::NOT_VALID_NAME_CHARS, '/');
|
||||||
|
$bad_seg_chars = preg_quote(self::NOT_VALID_SEGMENT_NAME_CHARS, '/');
|
||||||
|
|
||||||
|
$name_pattern = "(?:[^" . $bad_chars . "\s]+)|(?:\[[^" . $bad_seg_chars . "]+\])";
|
||||||
|
$check_pattern = "/^((" . $name_pattern . ")\.)*(" . $name_pattern . ")\.?$/";
|
||||||
|
$get_pattern = "/(?:" . $name_pattern . ")/";
|
||||||
|
|
||||||
|
if (!preg_match($check_pattern, $variable_name)) {
|
||||||
|
throw new \InvalidArgumentException('variable name is invalid');
|
||||||
|
}
|
||||||
|
|
||||||
|
preg_match_all($get_pattern, $variable_name, $matches);
|
||||||
|
|
||||||
|
$chunks = array();
|
||||||
|
foreach ($matches[0] as $chunk) {
|
||||||
|
// Remove wrapper braces if needed
|
||||||
|
if ($chunk[0] == '[') {
|
||||||
|
$chunk = substr($chunk, 1, -1);
|
||||||
|
}
|
||||||
|
$chunks[] = $chunk;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $chunks;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -455,7 +455,7 @@ class Template
|
|||||||
public function parseArguments($string)
|
public function parseArguments($string)
|
||||||
{
|
{
|
||||||
$args = array();
|
$args = array();
|
||||||
preg_match_all('#(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $args);
|
preg_match_all('#(?:[^\'"\[\]\s]|\[.+?\])+|(?<!\\\\)("|\')(?:[^\\\\]|\\\\.)*?\1|\S+#s', $string, $args);
|
||||||
$args = isset($args[0])?$args[0]:array();
|
$args = isset($args[0])?$args[0]:array();
|
||||||
|
|
||||||
for ($x=0, $argc = count($args); $x<$argc;$x++) {
|
for ($x=0, $argc = count($args); $x<$argc;$x++) {
|
||||||
|
@ -476,12 +476,18 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
|||||||
{
|
{
|
||||||
$test = new stdClass();
|
$test = new stdClass();
|
||||||
$test->value = 'value';
|
$test->value = 'value';
|
||||||
$test->array = array('a' => '1', 'b' => '2');
|
$test->array = array(
|
||||||
|
'a' => '1',
|
||||||
|
'b' => '2',
|
||||||
|
'!"#%&\'()*+,./;<=>@[\\^`{|}~ ' => '3',
|
||||||
|
);
|
||||||
$context = new \Handlebars\Context($test);
|
$context = new \Handlebars\Context($test);
|
||||||
$this->assertEquals('value', $context->get('value'));
|
$this->assertEquals('value', $context->get('value'));
|
||||||
$this->assertEquals('value', $context->get('value', true));
|
$this->assertEquals('value', $context->get('value', true));
|
||||||
|
$this->assertEquals('value', $context->get('[value]', true));
|
||||||
$this->assertEquals('1', $context->get('array.a', true));
|
$this->assertEquals('1', $context->get('array.a', true));
|
||||||
$this->assertEquals('2', $context->get('array.b', true));
|
$this->assertEquals('2', $context->get('array.b', true));
|
||||||
|
$this->assertEquals('3', $context->get('array.[!"#%&\'()*+,./;<=>@[\\^`{|}~ ]', true));
|
||||||
$new = array('value' => 'new value');
|
$new = array('value' => 'new value');
|
||||||
$context->push($new);
|
$context->push($new);
|
||||||
$this->assertEquals('new value', $context->get('value'));
|
$this->assertEquals('new value', $context->get('value'));
|
||||||
@ -546,7 +552,9 @@ class HandlebarsTest extends \PHPUnit_Framework_TestCase
|
|||||||
array('arg1 "arg\"2" "\"arg3\""', array("arg1",'arg"2', '"arg3"')),
|
array('arg1 "arg\"2" "\"arg3\""', array("arg1",'arg"2', '"arg3"')),
|
||||||
array("'arg1 arg2'", array("arg1 arg2")),
|
array("'arg1 arg2'", array("arg1 arg2")),
|
||||||
array("arg1 arg2 'arg number 3'", array("arg1","arg2","arg number 3")),
|
array("arg1 arg2 'arg number 3'", array("arg1","arg2","arg number 3")),
|
||||||
array('arg1 "arg\"2" "\\\'arg3\\\'"', array("arg1",'arg"2', "'arg3'"))
|
array('arg1 "arg\"2" "\\\'arg3\\\'"', array("arg1",'arg"2', "'arg3'")),
|
||||||
|
array('arg1 arg2.[value\'s "segment"].val', array("arg1", 'arg2.[value\'s "segment"].val')),
|
||||||
|
array('"arg1.[value 1]" arg2', array("arg1.[value 1]", 'arg2')),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user