[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