[limb-svn] r6401 - in 3.x/trunk/limb/macro: src tests/cases
svn at limb-project.com
svn at limb-project.com
Tue Oct 9 14:41:58 MSD 2007
Author: serega
Date: 2007-10-09 14:41:58 +0400 (Tue, 09 Oct 2007)
New Revision: 6401
URL: http://fisheye.limb-project.com/changelog/limb/?cs=6401
Modified:
3.x/trunk/limb/macro/src/lmbMacroBlockAnalizer.class.php
3.x/trunk/limb/macro/src/lmbMacroExpression.class.php
3.x/trunk/limb/macro/tests/cases/lmbMacroOutputExpressionTest.class.php
Log:
-- added ability to have function calls in output expressions.
Modified: 3.x/trunk/limb/macro/src/lmbMacroBlockAnalizer.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroBlockAnalizer.class.php 2007-10-09 10:19:18 UTC (rev 6400)
+++ 3.x/trunk/limb/macro/src/lmbMacroBlockAnalizer.class.php 2007-10-09 10:41:58 UTC (rev 6401)
@@ -17,43 +17,11 @@
{
const BEFORE_CONTENT = 1;
const EXPRESSION = 2;
- const AFTER_CONTENT = 4;
+ const AFTER_CONTENT = 5;
- protected $regexp;
-
- function __construct()
- {
- $this->regexp = $this->_getRegexp();
- }
-
protected function _getRegexp()
{
- $regexp =
- // start at the beginning
- '/^' .
- // Pick up the portion of the string before the variable reference
- '((?s).*?)' .
- // Beginning of a variable reference
- preg_quote('{$', '/') .
- // Collect the entire variable reference into one subexpression
- '(' .
- // capture the contents of one or more fragments.
- '(' .
- // Anything thats not a quote or the end of the variable
- // reference can be in a fragment
- '[^"\'}]+' .
- ')+' .
- ')' .
- // end of a variable reference
- preg_quote('}', '/') .
- // Pick up the portion of the string after the variable reference
- // This portion may contain additional references; we only match
- // one at a time.
- '((?s).*)' .
- // Match until the end of the string
- '$/';
-
- return $regexp;
+ return '/^((?s).*?)'. preg_quote('{$', '/') . '((([^"\']+["\']?[^"\']?["\'])+)?[^}]+)' . preg_quote('}', '/') . '((?s).*)$/';
}
function parse($text, $observer)
@@ -65,7 +33,9 @@
return;
}
- while (preg_match($this->regexp, $text, $match))
+ $regexp = $this->_getRegexp();
+
+ while (preg_match($regexp, $text, $match))
{
if (strlen($match[self :: BEFORE_CONTENT]) > 0)
$observer->addLiteralFragment($match[self :: BEFORE_CONTENT]);
Modified: 3.x/trunk/limb/macro/src/lmbMacroExpression.class.php
===================================================================
--- 3.x/trunk/limb/macro/src/lmbMacroExpression.class.php 2007-10-09 10:19:18 UTC (rev 6400)
+++ 3.x/trunk/limb/macro/src/lmbMacroExpression.class.php 2007-10-09 10:41:58 UTC (rev 6401)
@@ -18,6 +18,10 @@
{
protected $tmp;
+ // used for parsing expression path items
+ protected $text;
+ protected $position;
+
function __construct($expression_str)
{
$this->expression_str = $expression_str;
@@ -26,6 +30,7 @@
function preGenerate($code)
{
$this->tmp = $code->getTempVarRef();
+ $var = $code->getTempVarRef();
// simple case if expression is just a variable
if(strpos($this->expression_str, '.') === false)
@@ -35,11 +40,13 @@
}
$expr = '';
- $items = explode('.', $this->expression_str);
+ $items = $this->_extractExpressionPathItems($this->expression_str);
//first item is variable itself
- $var = $items[0];
+ //$var = $items[0];
+ $expr .= $var . ' = ' . $items[0] . ';';
$code->writePHP($this->tmp . "='';");
+
for($i=1; $i<sizeof($items); $i++)
{
$item = $items[$i];
@@ -56,9 +63,61 @@
$code->writePHP($expr);
}
+ protected function _extractExpressionPathItems($text)
+ {
+ $this->text = $text;
+ $length = strlen($text);
+
+ $path_items = array();
+ do
+ {
+ $token = $this->_getToken('/\G("|\'|\.|[^\'"\.]+)/u');
+ if ($token === FALSE)
+ {
+ $path_items[] = $this->text;
+ break;
+ }
+
+ if ($token == '"' || $token == "'")
+ {
+ $string = $this->_getToken('/\G([^' . $token . ']*)' . $token . ',?/u');
+
+ if ($string === FALSE)
+ $this->context->raise("Expecting a closing quote in expression path item: " . $text);
+ }
+ elseif($token == '.')
+ {
+ $path_items[] = substr($this->text, 0, $this->position - 1);
+ $this->text = substr($this->text, $this->position);
+ $length = strlen($this->text);
+ $this->position = 0;
+ }
+ }
+ while($this->position < $length);
+
+ //ensures the last filter expression added
+ $path_items[] = substr($this->text, 0, $this->position );
+ $this->text = substr($this->text, $this->position);
+ $length = strlen($this->text);
+ $this->position = 0;
+
+ return $path_items;
+ }
+
function getValue()
{
return $this->tmp;
}
+
+ protected function _getToken($pattern)
+ {
+ if (preg_match($pattern, $this->text, $match, PREG_OFFSET_CAPTURE, $this->position))
+ {
+ $this->position += strlen($match[0][0]);
+ return $match[1][0];
+ }
+ else
+ return FALSE;
+ }
}
Modified: 3.x/trunk/limb/macro/tests/cases/lmbMacroOutputExpressionTest.class.php
===================================================================
--- 3.x/trunk/limb/macro/tests/cases/lmbMacroOutputExpressionTest.class.php 2007-10-09 10:19:18 UTC (rev 6400)
+++ 3.x/trunk/limb/macro/tests/cases/lmbMacroOutputExpressionTest.class.php 2007-10-09 10:41:58 UTC (rev 6401)
@@ -7,6 +7,30 @@
* @license LGPL http://www.gnu.org/copyleft/lesser.html
*/
+class lmbMacroOutputExpressionTestClass
+{
+ public $zoo;
+
+ function func1()
+ {
+ return 10;
+ }
+
+ function func2($param1, $param2)
+ {
+ return $param1 . ' - ' . $param2;
+ }
+
+ function func3($extra = '')
+ {
+ $res = array('zoo' => $this->zoo);
+ if($extra)
+ $res['extra'] = $extra;
+
+ return $res;
+ }
+}
+
class lmbMacroOutputExpressionsTest extends lmbBaseMacroTest
{
function testSimpleOutput()
@@ -114,5 +138,74 @@
$out = $tpl->render();
$this->assertEqual($out, '<h1>foo</h1>');
}
+
+ function testFunctionCallWithoutParamsInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func1()}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>10</h1>');
+ }
+
+ function testFunctionCallWithParamsInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func2("aaa", $#foo)}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $tpl->set('foo', 10);
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>aaa - 10</h1>');
+ }
+
+ function testPathAfterFunctionCallInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func3().zoo}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $object = new lmbMacroOutputExpressionTestClass();
+ $object->zoo = 30;
+ $tpl->set('bar', $object);
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>30</h1>');
+ }
+
+ function testPointInFuncParamsAndComplexPathInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func3(".").extra}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>.</h1>');
+ }
+
+ function testClosingBracketInFuncParamsAndComplexPathInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func3("}").extra}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>}</h1>');
+ }
+
+ function ToDo_testComplexVariableWithPathsInInFuncParamsInOutputExpression()
+ {
+ $code = '<h1>{$#bar->func2($#foo.var1, $#foo.var2).extra}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $tpl->set('foo', array('var1' => 10, 'var2' => 20));
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>10 - 20</h1>');
+ }
+
+ function ToDo_testNestedExpressionPaths()
+ {
+ $code = '<h1>{$#bar->func2($#foo.func2(10, 20), "aaa")}</h1>';
+ $tpl = $this->_createMacroTemplate($code, 'tpl.html');
+ $tpl->set('bar', new lmbMacroOutputExpressionTestClass());
+ $tpl->set('foo', new lmbMacroOutputExpressionTestClass());
+ $out = $tpl->render();
+ $this->assertEqual($out, '<h1>10 - 20 - "aaa"</h1>');
+ }
+
}
More information about the limb-svn
mailing list