Commit aa5c9622 by seldaek

+ Improved parsing of array() to support real php array syntax as well as…

+ Improved parsing of array() to support real php array syntax as well as variables as array keys, thanks to acecream for the help + Improved parsing of named parameters that can now be quoted git-svn-id: http://svn.dwoo.org/trunk@340 0598d79b-80c4-4d41-97ba-ac86fbbd088b
parent 8eb1d240
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
count (just a helper that counts anything). It won't affect you unless count (just a helper that counts anything). It won't affect you unless
you built some plugin depending on isArray, in which case you should you built some plugin depending on isArray, in which case you should
check all works fine still check all works fine still
+ Improved parsing of array() to support real php array syntax as well
as variables as array keys, thanks to acecream for the help
+ Improved parsing of named parameters that can now be quoted
* Fixed parsing of quoted keywords in if statements, like 'not' was * Fixed parsing of quoted keywords in if statements, like 'not' was
parsed as ! because using {if not $foo} is valid, but it was impossible parsed as ! because using {if not $foo} is valid, but it was impossible
to use them even as string. to use them even as string.
......
...@@ -1357,7 +1357,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1357,7 +1357,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
} elseif ($first==='%' && preg_match('#^%[a-z]#i', $substr)) { } elseif ($first==='%' && preg_match('#^%[a-z]#i', $substr)) {
// const // const
$out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer); $out = $this->parseConst($in, $from, $to, $parsingParams, $curBlock, $pointer);
} elseif ($first==='"' || $first==="'") { } elseif (($first==='"' || $first==="'") && !(is_array($parsingParams) && preg_match('#^([\'"])[a-z0-9_]+\1\s*=>?(?:\s+|[^=])#i', $substr))) {
// string // string
$out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer); $out = $this->parseString($in, $from, $to, $parsingParams, $curBlock, $pointer);
} elseif (preg_match('/^[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)?('.(is_array($parsingParams)||$curBlock!='root'?'':'\s+[^(]|').'\s*\(|\s*'.$this->rdr.'|\s*;)/i', $substr)) { } elseif (preg_match('/^[a-z][a-z0-9_]*(?:::[a-z][a-z0-9_]*)?('.(is_array($parsingParams)||$curBlock!='root'?'':'\s+[^(]|').'\s*\(|\s*'.$this->rdr.'|\s*;)/i', $substr)) {
...@@ -1397,7 +1397,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1397,7 +1397,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if ($this->debug) echo 'TAG PARSING ENDED<br />'; if ($this->debug) echo 'TAG PARSING ENDED<br />';
$pointer += strlen($this->rd); $pointer += strlen($this->rd);
return false; return false;
} elseif (is_array($parsingParams) && preg_match('#^([a-z0-9_]+\s*=)(?:\s+|[^=]).*#i', $substr, $match)) { } elseif (is_array($parsingParams) && preg_match('#^(([\'"]?)[a-z0-9_]+\2\s*='.($curBlock === 'array' ? '>?':'').')(?:\s+|[^=]).*#i', $substr, $match)) {
// named parameter // named parameter
if ($this->debug) echo 'NAMED PARAM FOUND<br />'; if ($this->debug) echo 'NAMED PARAM FOUND<br />';
$len = strlen($match[1]); $len = strlen($match[1]);
...@@ -1408,7 +1408,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1408,7 +1408,7 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$pointer += $len; $pointer += $len;
} }
$output = array(trim(substr(trim($match[1]), 0, -1)), $this->parse($in, $from+$len, $to, false, 'namedparam', $pointer)); $output = array(trim($match[1], " \t\r\n=>'\""), $this->parse($in, $from+$len, $to, false, 'namedparam', $pointer));
$parsingParams[] = $output; $parsingParams[] = $output;
return $parsingParams; return $parsingParams;
...@@ -1509,6 +1509,17 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1509,6 +1509,17 @@ class Dwoo_Compiler implements Dwoo_ICompiler
$out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out); $out = preg_replace('#\(is_string\(\$tmp=(.+?)\) \? htmlspecialchars\(\$tmp, ENT_QUOTES, \$this->charset\) : \$tmp\)#', '$1', $out);
} }
$out = Dwoo_Compiler::PHP_OPEN. $echo . $out . $operator . implode(' ', $value) . Dwoo_Compiler::PHP_CLOSE; $out = Dwoo_Compiler::PHP_OPEN. $echo . $out . $operator . implode(' ', $value) . Dwoo_Compiler::PHP_CLOSE;
} else if ($curBlock === 'array' && is_array($parsingParams) && preg_match('#^(\s*=>?\s*)#', $substr, $match)) {
// parse namedparam with var as name (only for array)
if ($this->debug) echo 'VARIABLE NAMED PARAM (FOR ARRAY) FOUND<br />';
$len = strlen($match[1]);
$var = $out[count($out)-1];
$pointer += $len;
$output = array($var[0], $this->parse($substr, $len, null, false, 'namedparam', $pointer));
$parsingParams[] = $output;
return $parsingParams;
} }
} }
...@@ -1661,6 +1672,8 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1661,6 +1672,8 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if ($func === 'if' || $func === 'elseif' || $func === 'tif') { if ($func === 'if' || $func === 'elseif' || $func === 'tif') {
$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr); $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'condition', $ptr);
} elseif ($func === 'array') {
$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'array', $ptr);
} else { } else {
$params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr); $params = $this->parse($paramstr, $ptr, strlen($paramstr), $params, 'function', $ptr);
} }
...@@ -1674,10 +1687,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler ...@@ -1674,10 +1687,10 @@ class Dwoo_Compiler implements Dwoo_ICompiler
if (is_array($p) && is_array($p[1])) { if (is_array($p) && is_array($p[1])) {
$state |= 2; $state |= 2;
} else { } else {
if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m)) { if (($state & 2) && preg_match('#^(["\'])(.+?)\1$#', $p[0], $m) && $func !== 'array') {
$params[$k] = array($m[2], array('true', 'true')); $params[$k] = array($m[2], array('true', 'true'));
} else { } else {
if ($state & 2) { if ($state & 2 && $func !== 'array') {
throw new Dwoo_Compilation_Exception($this, 'You can not use an unnamed parameter after a named one'); throw new Dwoo_Compilation_Exception($this, 'You can not use an unnamed parameter after a named one');
} }
$state |= 1; $state |= 1;
......
...@@ -26,13 +26,11 @@ ...@@ -26,13 +26,11 @@
function Dwoo_Plugin_array_compile(Dwoo_Compiler $compiler, array $rest=array()) function Dwoo_Plugin_array_compile(Dwoo_Compiler $compiler, array $rest=array())
{ {
$out = array(); $out = array();
foreach ($rest as $k=>$v) { foreach ($rest as $key => $value) {
if (is_numeric($k)) { if (!is_numeric($key) && !strstr($key, '$this->scope')) {
$out[] = $k.'=>'.$v; $key = "'".$key."'";
} else {
$out[] = '"'.$k.'"=>'.$v;
} }
$out[] = $key.'=>'.$value;
} }
return 'array('.implode(', ', $out).')'; return 'array('.implode(', ', $out).')';
} }
\ No newline at end of file
...@@ -119,6 +119,14 @@ class CompilerTests extends PHPUnit_Framework_TestCase ...@@ -119,6 +119,14 @@ class CompilerTests extends PHPUnit_Framework_TestCase
$this->assertEquals('34boo5foo3', $this->dwoo->get($tpl, array(), $this->compiler)); $this->assertEquals('34boo5foo3', $this->dwoo->get($tpl, array(), $this->compiler));
} }
public function testQuotedNamedParameters()
{
$tpl = new Dwoo_Template_String('{assign \'value\'=reverse(array("foo"=3,boo=5, 3=4), true) "var"=arr}{foreach $arr k v}{$k}{$v}{/foreach}');
$tpl->forceCompilation();
$this->assertEquals('34boo5foo3', $this->dwoo->get($tpl, array(), $this->compiler));
}
public function testMixedParameters() public function testMixedParameters()
{ {
$tpl = new Dwoo_Template_String('{assign value=array(3, boo=5, 3=4) var=arr}{foreach $arr k v}{$k}{$v}{/foreach}'); $tpl = new Dwoo_Template_String('{assign value=array(3, boo=5, 3=4) var=arr}{foreach $arr k v}{$k}{$v}{/foreach}');
...@@ -132,7 +140,7 @@ class CompilerTests extends PHPUnit_Framework_TestCase ...@@ -132,7 +140,7 @@ class CompilerTests extends PHPUnit_Framework_TestCase
*/ */
public function testMixedParametersWrongOrder() public function testMixedParametersWrongOrder()
{ {
$tpl = new Dwoo_Template_String("{array(boo=5, 3)}"); $tpl = new Dwoo_Template_String("{assign value=5, 3)}");
$tpl->forceCompilation(); $tpl->forceCompilation();
$this->dwoo->get($tpl, array(), $this->compiler); $this->dwoo->get($tpl, array(), $this->compiler);
} }
...@@ -570,7 +578,7 @@ replace="BAR" ...@@ -570,7 +578,7 @@ replace="BAR"
$this->assertEquals('valid', $dwoo->get($tpl, array(), $this->compiler)); $this->assertEquals('valid', $dwoo->get($tpl, array(), $this->compiler));
} }
public function testCallingMethodOnPropery() public function testCallingMethodOnProperty()
{ {
$tpl = new Dwoo_Template_String('{getobj()->instance->Bar("hoy")}'); $tpl = new Dwoo_Template_String('{getobj()->instance->Bar("hoy")}');
$tpl->forceCompilation(); $tpl->forceCompilation();
......
...@@ -27,8 +27,11 @@ class HelperTests extends PHPUnit_Framework_TestCase ...@@ -27,8 +27,11 @@ class HelperTests extends PHPUnit_Framework_TestCase
$tpl = new Dwoo_Template_String('{if array(hoy=3,5="foo",bar=moo) === $test}true{/if}'); $tpl = new Dwoo_Template_String('{if array(hoy=3,5="foo",bar=moo) === $test}true{/if}');
$tpl->forceCompilation(); $tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>3, 5=>"foo", "bar"=>"moo"), 'baz'=>'baz'), $this->compiler)); $this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>3, 5=>"foo", "bar"=>"moo")), $this->compiler));
}
public function testAssociativeArray2()
{
$tpl = new Dwoo_Template_String('{if array(hoy=3,5=array( $tpl = new Dwoo_Template_String('{if array(hoy=3,5=array(
"foo" "foo"
frack frack
...@@ -36,6 +39,38 @@ class HelperTests extends PHPUnit_Framework_TestCase ...@@ -36,6 +39,38 @@ class HelperTests extends PHPUnit_Framework_TestCase
) bar=moo) === $test}true{/if}'); ) bar=moo) === $test}true{/if}');
$tpl->forceCompilation(); $tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>3, 5=>array("foo", "frack", 18), "bar"=>"moo"), 'baz'=>'baz'), $this->compiler)); $this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>3, 5=>array("foo", "frack", 18), "bar"=>"moo")), $this->compiler));
}
public function testNumericKeysDontOverlap()
{
$tpl = new Dwoo_Template_String('{if array(1=2 2=3 1=4) === $test}true{/if}');
$tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array(1=>4, 2=>3)), $this->compiler));
}
public function testAssociativeArrayPhpStyle()
{
$tpl = new Dwoo_Template_String('{if array("hoy"=>3,5="foo",\'bar\'=moo) === $test}true{/if}');
$tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>3, 5=>"foo", "bar"=>"moo"), 'baz'=>'baz'), $this->compiler));
}
public function testAssociativeArrayWithVarAsKey()
{
$tpl = new Dwoo_Template_String('{$var="hoy"}{if array($var=>hey) === $test}true{/if}');
$tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array("hoy"=>'hey')), $this->compiler));
}
public function testAssociativeArrayWithMixedOrderDefinedKeys()
{
$tpl = new Dwoo_Template_String('{if array(5="foo", 3=moo) === $test}true{/if}');
$tpl->forceCompilation();
$this->assertEquals('true', $this->dwoo->get($tpl, array('test'=>array(5=>"foo", 3=>"moo")), $this->compiler));
} }
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment