This commit is contained in:
bzick 2014-06-28 21:08:20 +04:00
parent 2cc9ffdf62
commit 6b8ddd4ecc
3 changed files with 72 additions and 36 deletions

View File

@ -137,21 +137,20 @@ class Compiler
$p = array("index" => false, "first" => false, "last" => false); $p = array("index" => false, "first" => false, "last" => false);
$key = null; $key = null;
$before = $body = array(); $before = $body = array();
$prepend = "";
if ($tokens->is(T_VARIABLE)) { if ($tokens->is(T_VARIABLE)) {
$from = $scope->tpl->parseTerm($tokens, $is_var); $from = $scope->tpl->parseTerm($tokens, $is_var);
if($is_var) { if($is_var) {
$check = '!empty('.$from.')'; $check = '!empty('.$from.')';
$prepend = "";
} else { } else {
$scope["var"] = $scope->tpl->tmpVar(); $scope["var"] = $scope->tpl->tmpVar();
$prepend = $scope["var"].' = (array)('.$from.')'; $prepend = $scope["var"].' = (array)('.$from.')';
$from = $check = $scope["var"]; $from = $check = $scope["var"];
} }
} elseif ($tokens->is('[')) { } elseif ($tokens->is('[')) {
$from = $scope->tpl->parseArray($tokens); $count = 0;
$scope["var"] = $scope->tpl->tmpVar(); $from = $scope->tpl->parseArray($tokens, $count);
$prepend = $scope["var"].' = (array)('.$from.')'; $check = $count;
$from = $check = $scope["var"];
} else { } else {
throw new UnexpectedTokenException($tokens, null, "tag {foreach}"); throw new UnexpectedTokenException($tokens, null, "tag {foreach}");
} }

View File

@ -133,7 +133,7 @@ class Template extends Render
/** /**
* @param string $tag * @param string $tag
* @return bool|\Fenom\Scope * @return bool|\Fenom\Tag
*/ */
public function getParentScope($tag) public function getParentScope($tag)
{ {
@ -1281,35 +1281,28 @@ class Template extends Render
public function parseArray(Tokenizer $tokens, &$count = 0) public function parseArray(Tokenizer $tokens, &$count = 0)
{ {
if ($tokens->is("[")) { if ($tokens->is("[")) {
$_arr = "array("; $arr = array();
$key = $val = false;
$tokens->next(); $tokens->next();
while ($tokens->valid()) { while ($tokens->valid()) {
if ($tokens->is(',') && $val) { if ($tokens->is(']')) {
$key = true;
$val = false;
$_arr .= $tokens->getAndNext() . ' ';
} elseif ($tokens->is(Tokenizer::MACRO_SCALAR, T_VARIABLE, T_STRING, T_EMPTY, T_ISSET, "(") && !$val) {
$_arr .= $this->parseExpr($tokens);
$key = false;
$val = true;
} elseif ($tokens->is('"') && !$val) {
$_arr .= $this->parseQuote($tokens);
$key = false;
$val = true;
} elseif ($tokens->is(T_DOUBLE_ARROW) && $val) {
$_arr .= ' ' . $tokens->getAndNext() . ' ';
$key = true;
$val = false;
} elseif (!$val && $tokens->is('[')) {
$_arr .= $this->parseArray($tokens);
$key = false;
$val = true;
} elseif ($tokens->is(']') && (!$key || $tokens->prev[0] === ',')) {
$tokens->next(); $tokens->next();
return $_arr . ')'; return 'array(' . implode(', ', $arr) . ')';
}
if ($tokens->is('[')) {
$arr[] = $this->parseArray($tokens);
$count++;
} else { } else {
break; $expr = $this->parseExpr($tokens);
if($tokens->is(T_DOUBLE_ARROW)) {
$tokens->next();
$arr[] = $expr.' => '.$this->parseExpr($tokens);
} else {
$arr[] = $expr;
}
$count++;
}
if($tokens->is(',')) {
$tokens->next();
} }
} }
} }

View File

@ -572,6 +572,30 @@ class TemplateTest extends TestCase
); );
} }
public static function providerArrays()
{
return array(
array('{var $arr = []}', array()),
array('{var $arr = [1]}', array(1)),
array('{var $arr = [1,]}', array(1)),
array('{var $arr = [1, 2, 3, 5]}', array(1, 2, 3, 5)),
array('{var $arr = [1, true, false, null, -1, 1.1, -2.2, 5, "str"]}', array(1, true, false, null, -1, 1.1, -2.2, 5, "str")),
array('{var $arr = [5 => 1, "two" => 2, 3]}', array(5 => 1, "two" => 2, 3)),
array('{var $arr = [1 + 1, 2 * 2, 3 / 3 + 7,]}', array(1 + 1, 2 * 2, 3 / 3 + 7)),
array('{var $arr = [$zero, $two => $one, $num.3 => $.const.PHP_VERSION]}', array(0, 2 => 1, "three" => PHP_VERSION)),
array('{var $arr = [5 - 1 => 1, "two"|up => "two"|low, 3 => count([1,2])]}', array(4 => 1, "TWO" => "two", 3 => 2)),
array('{var $arr = [[1]]}', array(array(1))),
array('{var $arr = [[],[]]}', array(array(),array())),
array('{var $arr = [1, [2, 3], 5]}', array(1, array(2, 3), 5)),
array('{var $arr = [1, [true, false, null, -1, 1.1, -2.2, 5], "str"]}', array(1, array(true, false, null, -1, 1.1, -2.2, 5), "str")),
array('{var $arr = [5 => [1, "two" => 2], 3]}', array(5 => array(1, "two" => 2), 3)),
array('{var $arr = [1 + 1, [2 * 2, 3 / 3 + 7,],]}', array(1 + 1, array(2 * 2, 3 / 3 + 7))),
array('{var $arr = [$zero, [$two => $one, $num.3 => $.const.PHP_VERSION]]}', array(0, array(2 => 1, "three" => PHP_VERSION))),
array('{var $arr = [5 - 1 => 1, ["two"|up => ("two"|low ~ "..."), 3 => count([1,2])]]}', array(4 => 1, array("TWO" => "two...", 3 => 2))),
);
}
public static function providerTernary() public static function providerTernary()
{ {
$a = array( $a = array(
@ -683,6 +707,7 @@ class TemplateTest extends TestCase
), ),
array('Foreach: {foreach $empty as $k => $e} {$k} => {$e}, {/foreach} end', $a, 'Foreach: end'), array('Foreach: {foreach $empty as $k => $e} {$k} => {$e}, {/foreach} end', $a, 'Foreach: end'),
array('Foreach: {foreach [] as $k => $e} {$k} => {$e}, {/foreach} end', $a, 'Foreach: end'), array('Foreach: {foreach [] as $k => $e} {$k} => {$e}, {/foreach} end', $a, 'Foreach: end'),
array('Foreach: {foreach $unexists as $k => $e} {$k} => {$e}, {/foreach} end', $a, 'Foreach: end'),
array( array(
'Foreach: {foreach $empty as $k => $e} {$k} => {$e}, {foreachelse} empty {/foreach} end', 'Foreach: {foreach $empty as $k => $e} {$k} => {$e}, {foreachelse} empty {/foreach} end',
$a, $a,
@ -1276,14 +1301,14 @@ class TemplateTest extends TestCase
try { try {
var_dump( var_dump(
$this->fenom->compileCode( $this->fenom->compileCode(
'{var $a = [3, 5,6]}' '{foreach $fff as $k}{/foreach}'
)->getBody() )->getBody()
); );
} catch (\Exception $e) { } catch (\Exception $e) {
print_r($e->getMessage() . "\n" . $e->getTraceAsString()); print_r($e->getMessage() . "\n" . $e->getTraceAsString());
while ($e->getPrevious()) { while ($e->getPrevious()) {
$e = $e->getPrevious(); $e = $e->getPrevious();
print_r("\n\n" . $e->getMessage() . "\n" . $e->getTraceAsString()); print_r("\n\n" . $e->getMessage() . " in {$e->getFile()}:{$e->getLine()}\n" . $e->getTraceAsString());
} }
} }
exit; exit;
@ -1419,6 +1444,25 @@ class TemplateTest extends TestCase
$this->execError($code, $exception, $message, $options); $this->execError($code, $exception, $message, $options);
} }
/**
* @dataProvider providerArrays
* @group arrays
*/
public function testArrays($code, $vars)
{
$v = $this->getVars();
$v['vars'] = $vars;
$this->exec($code.'{if $arr === $vars}equal{/if}', $v, 'equal');
}
/**
* @dataProvider providerCreateVarInvalid
*/
// public function testCreateVarInvalid($code, $exception, $message, $options = 0)
// {
// $this->execError($code, $exception, $message, $options);
// }
/** /**
* @group ternary * @group ternary
* @dataProvider providerTernary * @dataProvider providerTernary