You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@shindig.apache.org by ch...@apache.org on 2009/05/11 15:12:27 UTC

svn commit: r773553 - /incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php

Author: chabotc
Date: Mon May 11 13:12:27 2009
New Revision: 773553

URL: http://svn.apache.org/viewvc?rev=773553&view=rev
Log:
Add support for ternary operations, ie: $\{ViewerParam.likesRed \? 'Red' : 'Blue'\} expressions, including support for nested constructions

Modified:
    incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php

Modified: incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php
URL: http://svn.apache.org/viewvc/incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php?rev=773553&r1=773552&r2=773553&view=diff
==============================================================================
--- incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php (original)
+++ incubator/shindig/trunk/php/src/gadgets/templates/ExpressionParser.php Mon May 11 13:12:27 2009
@@ -30,7 +30,6 @@
 
 //TODO == seems to not be working correctly
 //TODO support unary expressions, ie: ${Foo * -Bar}, or simpler: ${!Foo}
-//TODO support ${Viewer.likesRed ? 'Red' : 'Blue'} type expressions
 //TODO support string variables, ie 'Red' and it's variants like 'Red\'' and '"Red"', etc
 
 class ExpressionException extends Exception {
@@ -59,8 +58,20 @@
    */
   static public function evaluate($expression, $dataContext) {
     self::$dataContext = $dataContext;
-    $postfix = self::infixToPostfix($expression);
-    $result = self::postfixEval($postfix);
+    if (strpos($expression, '?') !== false) {
+      // Quick and dirty support for Ternary operation ie: color="${ViewerData.likesRed ? 'Red' : 'Blue'}"
+      $parts = self::splitTernaryOperation($expression);
+      $condition = self::evaluate($parts[0], $dataContext);
+      if ($condition) {
+        return self::evaluate($parts[1], $dataContext);
+      } else {
+        return self::evaluate($parts[2], $dataContext);
+      }
+    } else {
+      // plain old single or binary expression, just evaluate it
+      $postfix = self::infixToPostfix($expression);
+      $result = self::postfixEval($postfix);
+    }
     return $result;
   }
 
@@ -112,6 +123,42 @@
   }
 
   /**
+   * Internal misc function that splits a Ternary operation into it's 3 parts, so given:
+   * ${ViewerParams.likesRed ? 'Red' : 'Blue'} it will return:
+   * array('0' => 'ViewerParams.likesRed', '1' => 'Red', '2' => 'Blue')
+   *
+   * @param string $expression
+   */
+  static private function splitTernaryOperation($expression) {
+    $result = array();
+    $pos = strpos($expression, '?');
+    $result[0] = substr($expression, 0, $pos - 1);
+    $expression = substr($expression, $pos + 1);
+    // Nesting detection is used so that ${Cur.id == 1 ? Cur.id == 2 ? 12 : 1  : 2} parses into it's correct components too, ie
+    // that expression would result in: Array ( [0] => Cur.id == 1 [1] => Cur.id == 2 ? 12 : 1 [2] => 2 ), which will case self::evaluate()
+    // to recurse on the the array element that contains a nested ternary expression
+    $nestCounter = 0;
+    for ($i = 0 ; $i < strlen($expression) ; $i++) {
+      $char = $expression[$i];
+      if ($char == '?') {
+        $nestCounter++;
+      } elseif ($char == ':') {
+        if ($nestCounter == 0) {
+          $result[1] = trim(substr($expression, 0, $i - 1));
+          $result[2] = trim(substr($expression, $i + 1));
+        } else {
+          $nestCounter--;
+        }
+      }
+    }
+    if (count($result) != 3) {
+      // if count != 3, the left and right parts of the ternary operation were never detected, ie an unbalanced or uncompleted expression
+      throw new ExpressionException("Unbalanced ternary operation");
+    }
+    return $result;
+  }
+
+  /**
    * Returns the string value of the (mixed) $val, ie:
    * on array, return "1, 2, 3, 4"
    * on int, return "1"