------------------------------------------------------------
revno: 1111
committer: Roger Martin <[email protected]>
branch nick: aikiframework
timestamp: Sat 2012-02-25 23:20:11 +0100
message:
  changing engine_v8
modified:
  libs/Engine_v8.php


--
lp:aikiframework
https://code.launchpad.net/~aikiframework-devel/aikiframework/trunk

Your team Aiki Framework Developers is subscribed to branch lp:aikiframework.
To unsubscribe from this branch go to 
https://code.launchpad.net/~aikiframework-devel/aikiframework/trunk/+edit-subscription
=== modified file 'libs/Engine_v8.php'
--- libs/Engine_v8.php	2012-02-19 20:19:24 +0000
+++ libs/Engine_v8.php	2012-02-25 22:20:11 +0000
@@ -20,24 +20,273 @@
  * update aiki_widgets inner join aiki_widget_porsi on aiki_widgets.father_widget=aiki_widget_porsi.id set parent_widget= aiki_widget_porsi.widget_name
  */
 
-if (!defined('IN_AIKI')) {
+if (!defined('IN_AIKI')) {	
+
 	die('No direct script access allowed');
-}
+} 
+	
+
+/*
+ * move to aiki, so all engine case share this code
+ */
+
+function aiki_get_markup_codes($which){
+	/* @TODO this complicate array can be generated by a auxiliary programs, who with a given
+	 * syntax ( for example (TAG(TRUE-BLOCK)else(FALSE-BLOCK)TAG) calculate array
+	 */
+	
+	// 0  begin regex
+	// 1  end regex
+	// 2  else literal
+	// 3  end search string with %s
+	// 4  begin signal (first character of a begin tag)
+	// 5  trim characters that will be deleted from tag.
+	// 6  first character from true-block
+	
+   $markups= array (
+        //  (TAG()TRUE-BLOCK)else(FALSE-BLOCK)TAG)
+		"aiki" => array("\([A-z0-9_]*\(", "\)[A-z0-9]*\)", ")else(", ")%s)","(", "#\((.*)\(#","" ),				
+		//  (TAG( para {TRUE-BLOCK}else{FALSE-BLOCK})TAG)
+		"aiki2" => array("\([A-z0-9_]*\(", "\}\)[A-z0-9]*\)", "})else({", "})%s)","(", "#\((.*)\(#","" ),
+		// (TAG(COND){true-block}else{false-block}TAG)
+		"(c)"=> array("\([A-z0-9_]+\(","\}[A-z0-9]+\)", "}else{", "}%s)", "(","#\((.*)\(#", "{" ),
+		// <%TAG(COND){true-block}else{false-block}%>
+		"<%"=> array("<%[A-z0-9_]+\(","\}%>", "}else{", "}%>", "<","#<%(.*)\(#","" )
+		);
+
+	return ( isset ($markups[$which]) ? $markups[$which] : $markups["aiki"] );	
+	
+}
+
+/**
+ * extract the first markup 
+ * return array
+ *     0 => text before tag
+ *     1 => tag
+ *     2 => array of parameters
+ *     3 => true-block
+ *     4 => false-block
+ *     5 => text after tag
+ */
+
+function extract_markup(&$string, $markup)  {
+		
+	if (!is_array($markup) ){
+		$markup= aiki_get_markup_codes($markup);
+	}
+				
+	if ( !preg_match_all(	
+			"#{$markup[0]}|{$markup[1]}|". preg_quote($markup[2])."#",
+			$string,
+			$matches,
+			PREG_OFFSET_CAPTURE)) {
+		return $string ;
+	};
+	
+	$matches= $matches[0];
+	$max= count($matches);
+	preg_match ( $markup[5], $matches[0][0],$temp);
+	$tag = $temp[1];	
+	
+	$search= sprintf( $markup[3], $tag );	
+	$level = 0;
+	$else  = 0; // where start the else block
+	
+	for($i=1;$i<$max;$i++){
+		$found = $matches[$i][0]; // for comodity		
+		if ( $found==$markup[2] ) {
+			if ($level==0 ){ // else are in the middle
+				$else= $matches[$i][1];
+			}
+		} elseif ($level==0 && $found==$search ) {
+			// we found ending tag
+			$offset= strlen($search);
+			$start = $matches[0][1]+$offset;	
+			$elselen= strlen($markup[2]);	
+			$trueBlock= ( $else ? substr( $string,$start, $else-$start) : substr( $string,$start, $matches[$i][1]-$start));
+			$parameters = extract_parameters( $trueBlock, $markup[6]);			
+			return array( 											
+				substr( $string,0,$start-$offset ),
+				$tag,
+				$parameters[0],
+				$parameters[1],
+				( $else ? substr( $string,$else+$elselen, $matches[$i][1]-$else-$elselen) : NULL), 
+				substr($string, $matches[$i][1]+$offset));
+		} elseif ( $found[0] =="(" ){
+			$level++;
+		} else {
+			$level--;
+		}			
+	}	
+	return $string;	
+}
+
+
+function eval_parameters( $originals ){
+	
+	$ret = array();
+	$temp= false;
+	
+	foreach ( $originals as $input){
+			if ( $input==="" )         { $ret[]="";}
+			elseif ( $input==="0" )    { $ret[]=0;}
+			elseif ( $input==="false" ){ $ret[]=false;}	
+			elseif ( $input==="true"  ){ $ret[]=true;}	
+			elseif ( $input[0]=="'" || $input[0]=='"' ) { $ret[]= substr($input,1,-1);}
+			elseif ( preg_match('#^\s*[+\-]?[1-9][0-9]*\s*$#', $input, $temp))       { $ret[]= (int)   $input;}
+			elseif ( preg_match('#^\s*[+\-]?[1-9][0-9]*\.[0-9]*\s*$#', $input, $temp)){ $ret[]= (float) $input;}		
+			elseif ( preg_match('#^\{\s*"[^"]+"\s*\:\s*"[^"]*"#',$input, $temp)){ $ret[]= json_decode($input);}
+			elseif ( $input[0]=="{") { 
+				$temp = extract_parameters( substr($input,1,-1));
+				$ret[]= eval_parameters( $temp[0] );}
+			elseif ( preg_match ('#^\s*aiki\-\>(.*)$#',$input,$temp )){
+				$ret[]= "calling aiki->".$temp[1]; //@TODO implements
+			}elseif ( preg_match ('#^\s*([A-z_0-9]+)\(.*$#', $input, $temp )){				
+				// @TODO check if it is a allowed functions
+				$ret[] = "calling {$temp[1]}";
+				
+			} else {
+				$ret[]=$input;
+			}
+	}
+	
+	return $ret;
+		
+}
+
+
+/**
+ * extract the parameters present at the begining of text
+ * @return array
+ *     0 => array of parameters.
+ *     1 => rest of string
+ * example: extract_parameters ( "foo'bar",foo(bar),{foo,bar,foo()} ) rest"
+ *   return a array 
+ *        0=>array ( "foo'bar", "foo(bar)", "{foo,bar,foo()}")
+ *        1=> " rest"
+ */
+
+function extract_parameters( $string, $find="") {	
+		
+	$max= strlen($string);
+	
+	$state= 0;
+	$current= false;
+	$end = false;	
+	$level =0;
+	$ret= array();
+	
+	
+	for($i=0; $i<$max && !$end; $i++){
+		$add = false;
+		$char = $string[$i];
+		
+		switch ( $char ){
+				
+			case "'": 
+				switch ($state){					
+					case 0: $state=1; break;
+					case 1: if ($level==0 && !$escaped ){ $add= true;}					
+				}					
+				break;
+			case '"':
+				switch ($state){
+					case 0: $state=2; break;
+					case 2: if ( $level==0 && !$escaped ) { $add= true;}
+				}				
+				break;
+			// do we found a other arg?
+			case ',':
+				if (($state==0 || $state==3) && $level==0) { 
+					$add = true;
+					$char= false;
+				}
+				break;
+			
+			// we a begin (
+			case '(':
+			case '{':
+				if ($state==0 || $state==3) {
+					$level++;
+					$state=3;
+				}
+				break;		
+			
+			// do we found a ending { ?
+			case '}':
+			case ')':
+				if ($state==0 || $state ==3 ) {					
+					if ( $level == 0 ) { 
+						$add = true;
+						$end = true;
+						$char = false;
+					} elseif ($level==1) {								
+						$add = true;
+						$level=0;;
+					} else {
+					   $level--;
+					}			
+				}
+				break;			
+			case " ":										
+			    break;		
+			default :
+				if ( $state== 0 ){
+					$state=3;
+				}						
+		}	
+		
+		if ( $state != 0 ){
+			$current .= $char;
+		}
+				
+		if ( $add ){
+			if ( $current !== false ){
+				$ret[]    = $current;
+				$current  = false;
+			} 
+			$state    = 0;			
+		}
+		
+		$escaped= ( $char=="\\" );
+	} // for
+	if ( $current !== false ){		
+		$ret[]    = $current;
+	}
+	
+	// for the (a,b) { begin ..supress the { @TODO improve.
+    if ( $find !="") {		
+		$temp = stripos ($string,$find,$i);
+		if ( $temp !==false ){
+			$i=$temp+1;
+		}
+    }
+		
+	return array ( $ret, substr( $string,$i));
+}
+
 
 class engine_v8 {
 
+    // engine parameters
+	private $convert_widgets;
+	private $markup_codes;
+	
+	private $parsers; // array of parser (markup=>callback)
+	
 	private $widget_css;
 	private $widget_html;
-
+		
 	/*
 	 * Create layout
 	 */
 
-	function layout( $parameters ){
+	function layout( $parameters = NULL ){
 		global $db, $aiki;
 
-		// Initialize
-		
+		// Parameters
+		$this->load_parameters($parameters);
+												
 		// @TODO javascript? id for some elements?
 		$this->target = array(
 			"body"=>"" ,
@@ -88,7 +337,7 @@
 				if ( $parent->have_css == 1) {
 					$this->target["css"][] = $parent->id;
 				}
-				$this->target[$parent->widget_target] .= $this->parse($parent->id);
+				$this->target[$parent->widget_target] .= $this->parseWidget($parent->id);
 
 				// children..
 				/* @TODO..a function */
@@ -96,17 +345,60 @@
 					foreach ($descendants as $descendant){
 						if ( $aiki->url->match($descendant->display_urls) && !$aiki->url->match($descendant->kill_urls) ) {
 							$this->target["css"][] = $descendant->id;
-							$this->target[$descendant->widget_target] .= $this->parse($descendant->id);
+							$this->target[$descendant->widget_target] .= $this->parseWidget($descendant->id);
 						}
 					}
 				}
 			}
 		}
 
+        // finally make html.
 		return $this->render_html();
 	}
 
 
+	function load_parameters($parameters) {
+		// Parameters
+		if ( is_array( $parameters ) ){
+			$parameters= array();				
+		}	
+		
+		// set markup to use
+		$markup = isset($parmameters['markup'])	? $parmameters['markup'] : 'aiki';
+		$this->markup_codes    = aiki_get_markup_codes ($markup ) ;		
+		
+		// must convert widgets?
+		if  (isset($parmameter['convert-widgets'] )) {
+			$this->convert_widgets = 1;
+			$this->markup          = 'aiki';
+		}
+		
+		// set parsers
+		$this->parsers = array (
+		    ""            => "parse_vars",
+		    "widget"      => "parse_widget",
+			"permissions" => "parse_permissions",
+			"view"        => "parse_view",
+			"noaiki"      => "parse_noaiki",
+			"sql"         => "parse_sql",
+			"script"      => "parse_script",
+			"t"			  => "parse_t",
+			"__"		  => "parse_translate");
+		
+		if ( isset($parameters["parsers-allowed"]) ){
+			$this->parsers = array_intersect ( 
+				$this->parsers , 
+				array_flip(explode(",",$parameters["parsers-allowed"])) );
+		}
+		
+		if ( isset($parameters["parsers-disabled"]) ){
+			$this->parsers = array_diff_key ( 
+				$this->parsers , 
+				array_flip(explode(",",$parameters["parsers-disabled"])) );
+		}
+	}
+
+
 	function render_html(){	
 		global $aiki;
 		$html  = $aiki->Output->header($this->target['css'],  $this->target['header']);
@@ -121,84 +413,68 @@
 	 *  parse a given widget
 	 */
 
-	function parse($widgetID){
+
+	function parseWidget($widgetID){
 		global $aiki, $db;
 
-		// preParsers and postParser can be:
+		// high level parser  can be:
 		// regex (string)  => function | array(object,method).
 		// a numeric index => function | array(object,method).
+		// @TODO make a structure.
 
-		$preParsers = array (
-		    '/\[\$([a-z0-9_]+)\]/i'                    => array( $this, "parse_vars"),
+		$Parsers = array (
+		    // preparsers
+		    '/\(\([a-z0-9_]\)\)/i'                    => array( $this, "parse_vars"),
 		    '/\[GET\[([a-z0-9]+)\]\]/i'				   => array( $this, "parse_get"),
 		    '/\[POST\[([a-z0-9]+)\]\]/i'			   => array( $this, "parse_post"),
-		    "/\(template\(([a-z0-9_]*)\)template\)/Ui" => array( $this, "parse_template")) ;
-                
-		$postParsers =array (
-			 array ($aiki->languages,"L10n") ) ;  // added for test purpose only
-
-		// parsers are defined here
-		$parsers = array (
-		    "widget"      => "parse_widget",
-			"permissions" => "parse_permissions",
-			"view"        => "parse_view",
-			"noaiki"      => "parse_noaiki",
-			"sql"         => "parse_sql",
-			"script"      => "parse_script",
-			"t"			  => "parse_t",
-			"__"		  => "parse_translate");
-
+		    "/\(template\(([a-z0-9_]*)\)template\)/Ui" => array( $this, "parse_template"),
+		    
+		    // here we call the parse
+		    1 => array ($this, "parse" ),
+		    
+		    // post-parser		    
+		    array ($aiki->languages,"L10n") // added for test purpose only
+		    ) ;
+                			 		
 		$widgetData = $db->get_row ("SELECT widget,widget_name FROM aiki_widgets WHERE id=" . (int) $widgetID );
 		$widget    = $widgetData->widget;
 		$widgetName= $widgetData->widget_name;
-
-		// process pre-parsers.
-		foreach ( $preParsers as $pattern => $callback ){
-			if ( is_string($pattern) ){
-				$widget = preg_replace_callback ( $pattern, $callback, $widget);
-			} else {
-				$widget = call_user_func   ( $callback, $widget);
-			}
-		}
-
-		// now the normal parser.
-		$match = false;
-		$offset=0;
-		while ( $match = $aiki->outer_markup ( $widget,$offset ) ){
-			$parserToCall= $match[2];
-			$len        = strlen($parserToCall)+2;
-
-			// call parser
-			if ( isset( $parsers[ $parserToCall]) ){
-				$text    = substr($widget, $match[0]+ $len,$match[1]-$len );
-				$replace= call_user_func( array($this, $parsers[ $parserToCall] ), &$text);
-				if (is_int($replace) ){ // necesary for noaki
-					$offset += $replace;
-					continue;
-				}
-			} else {
-				// @TODO Error
-				$replace= t("Parser $parserToCall not found");
-			}
-
-			//Replacement.
-			$widget= substr($widget,0,$match[0]) . $replace . substr($widget,$match[0]+$match[1]+$len) ;
-		}
-		
-		
-		// process post-parsers.		
-		foreach ( $postParsers as $pattern => $callback ){		
-			if ( is_string($pattern) ){
-				$widget = preg_replace_callback ( $pattern, $callback, $widget);
-			} else {
-				$widget = call_user_func   ( $callback, $widget);
-			}
-		}
-		
+    
+		foreach ( $Parsers as $pattern => $callback ){
+			if ( is_string($pattern) ){
+				$widget = preg_replace_callback ( $pattern, $callback, $widget);
+			} else {
+				$widget = call_user_func   ( $callback, $widget);
+			}
+		}
+        
 		if ( is_debug_on() ){
 			return "\n<!-- start {$widgetName} ($widgetID) -->" . $widget . "\n<!-- end {$widgetName} ($widgetID) -->";
 		}		
-	    return $widget;
+    
+    }
+
+
+	function parse($text){
+		
+		// extract beign,tag,condition & true-block, else-block,rest
+		$match = extract_markup ( $widget,$this->markup_codes );
+		if (!is_array($match) ){
+			return $text;			
+		}
+		   	
+		$parserToCall= $match[2]; // for comodity
+		
+		if ( isset( $this->parsers[ $parserToCall]) ){
+			$result = call_user_func( array($this, $this->parsers[ $parserToCall] ), &$match[1], &$match[2]);
+		} else {
+			$result = t("Parser $parserToCall not found");
+		}
+						
+		// return begin+result+parse the the rest..				
+	    return $match[0].
+	           $result.
+	           $this->parse($match[3]);
 	}
 
 
@@ -254,7 +530,7 @@
 				'[$language]'  => $aiki->site->language(),		   
 				'[$page]'	  => $page,
 				'[$site_name]' => $aiki->site->site_name(),
-				'[$site]'	  => $aiki->site->get_site(),
+				'site'	       => $aiki->site->get_site(),
 				'[$view]'	  => $aiki->site->view(),
 				'[$direction]' => $aiki->languages->dir,
 				'[$insertedby_username]' => $aiki->membership->username,
@@ -298,11 +574,14 @@
 		return  is_null($id) ? "": $db->get_var ("SELECT widget FROM aiki_widgets WHERE id='$id'" );
 	}
 
-	function parse_script($code){
+	function parse_script($cond,$trueblock,$elseblock){
 		global $aiki;
-		return $aiki->AikiScript->parser($code,false);
+		return $aiki->AikiScript->parser($trueblock,false);
 	}
 
+	function parse_if($cond,$trueblock,$elseblock){	
+		return ( is_array($cond)? first($cond): $cond ) ? $trueblock : $elseblock  ;	
+	}
 
 	/**
 	 * translation
@@ -323,19 +602,14 @@
 	}
 
 
-
 	/*
 	 * Parse sql markup
 	 */
 
-	function parse_sql( &$text){
+	function parse_sql( $para, $true, $else ){
 		global $db;				
-		if ( strpos($text,"||")===false){
-			return $text;
-		}
-		list($select,$content)= explode("||", $text,2);
 		
-		$results = $db->get_results($select);
+		$results = $db->get_results($para[0]);
 
 		$html="";
 		if ($results) {
@@ -344,8 +618,10 @@
 				foreach ( $row as $field=>$value ){
 					$fields[ "[$field]" ]= $value;
 				}
-				$html .= strtr( $content, $fields);
+				$html .= strtr( $true, $fields);
 			}
+		} else {
+			return $else;
 		}
 		return $html;
 
@@ -356,10 +632,9 @@
 	 * @TODO implements trigger.
 	 */
 
-	private function parse_hits(&$hidData) {
+	private function parse_hits($hit, $true, $else ) {
 		global $db;
-
-		$hit = explode("|", $hitData);
+		
 		if ( len($hit) == 3 ){
 			$db->query(
 					"UPDATE {$hit[0]}".
@@ -372,41 +647,27 @@
 	}
 
 
-	function parse_widget( &$text ){
-
-		if ( strpos( $widget,"||")!== false ) {
-			list($wigetId, $select) = explode("||",$widget,2);
-		} else {
-			$widgetId= $widget ;
-		}
-
-		return  $this->parse($widgetId, $select);
+	function parse_widget( $cond, $true, $false ){
+		//@TODO
+		//return  $this->parse($widgetId, $select);
 	}
 
 
-	function parse_view( &$text){
+	function parse_view( $para, $true, $false){
 		global $aiki;
-		if ( strpos($text,"||") !== false ){
-			list($filter,$content) = explode("||", $text, 2);
-			if ($trim($filter)=="") {
-				return $text;
-			}
-		} else {
-			return $text;
-		}
 		
-		list($view,$language)= exlode("/",$filter."/*",2);
+		list($view,$language)= exlode("/",$filter[1]."/*",2);
 	
 		if  ( match_pair_one( $view, $aiki->site->view()) &&
 		      match_pair_one( $language, $aiki->site->language() )){
-			return $content;
+			return $true;
 		}
-		return "";
+		return $false;
 
 	}
 
 
-	function parse_permission($widget){
+	function parse_permission($para, $true, $false){
 		global $aiki, $db;
 		if ( strpos($widget,"||") !== false ){
 			list($filter,$content) = explode("||", $widget, 2);
@@ -434,9 +695,32 @@
 		return "";
 	}
 
-	function parse_noaiki(&$text){
-		return strlen($text) ;
-	}
+	function parse_noaiki(&$cond, &$text, $else){
+		return $text;
+	}
+
+
+	function convert_widget($widget){
+	
+		// no_loop
+		if ( trim($widget->normal_select)!="" ){
+			$loop="";
+			$bottom="";
+			$resul=false;
+			if ( preg_match ( "#\(noloop\((.*)\)noloop\)#m",$widget->widget,$resul)){
+				$loop= $resul[1];
+				$widget= str_replace($resul[0],"",$widget->widget);
+			}
+			if ( preg_match ( "#\(noloop_bottom\((.*)\)noloop_bottom\)#m",$widget->widget,$resul)){
+				$bottom= $resul[1];
+				$widget= str_replace($resul[0],"",$widget->widget);
+			}
+						
+			$widget->widget = "$loop(sql(\"{$widget->normal_select}\"||{$widget->widget})sql)$bottom";
+		}			
+		return $widget;
+	}
+
 
 
 }

_______________________________________________
Mailing list: https://launchpad.net/~aikiframework-devel
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~aikiframework-devel
More help   : https://help.launchpad.net/ListHelp

Reply via email to