X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Fsieve%2Fclass_My_Tree.inc;h=ee1276a36ac3c1aba3c85281c0f2aa6b0bd2696b;hb=4ef5a0ec2c799536446dd29d5d828488cc14608f;hp=826817b88778fd5c649ee4abf2656356de6d9130;hpb=5646ccb89227486fe2db0515bebe0d48c6075a92;p=gosa.git diff --git a/include/sieve/class_My_Tree.inc b/include/sieve/class_My_Tree.inc index 826817b88..ee1276a36 100644 --- a/include/sieve/class_My_Tree.inc +++ b/include/sieve/class_My_Tree.inc @@ -15,90 +15,26 @@ class My_Tree extends Tree var $mode_stack = array(); var $pap = array(); + var $parent = NULL; - var $add_new = FALSE; - var $add_new_id = 0; - var $add_type = "top"; - var $add_element_type = ""; + function My_Tree(&$root,$parent) + { + $this->parent = $parent; + $this->_construct($root); + } + + function execute() + { + return($this->dump()); + } /* Create a html interface for the current sieve filter */ function dump() { - error_reporting(E_ALL); - $element_types= array( - "sieve_keep" => _("Keep"), - "sieve_comment" => _("Comment"), - "sieve_fileinto" => _("File into"), - "sieve_keep" => _("Keep"), - "sieve_redirect" => _("Redirect"), - "sieve_reject" => _("Reject"), - "sieve_require" => _("Require"), - "sieve_stop" => _("Stop"), - "sieve_vacation" => _("Vacation message"), - "sieve_if" => _("If")); - - - if($this->add_new && isset($_POST['element_type']) && isset($element_types[$_POST['element_type']])){ - $this->add_element_type = $_POST['element_type']; - } - - - if($this->add_new && isset($_POST['select_new_element_type'])){ - - $ele = new $this->add_element_type(NULL, preg_replace("/[^0-9]/","",microtime())); - $start = $end = array(); - $found = false; - - if($this->add_type == "top"){ - foreach($this->pap as $key => $obj){ - if($obj->object_id == $this->add_new_id){ - $found = true; - } - if(!$found){ - $start[] = $obj; - }else{ - $end[] = $obj; - } - } - }else{ - foreach($this->pap as $key => $obj){ - if(!$found){ - $start[] = $obj; - }else{ - $end[] = $obj; - } - if($obj->object_id == $this->add_new_id){ - $found = true; - } - } - } - - if($found){ - $new = array(); - foreach($start as $obj){ - $new[] = $obj; - } - $new[] = $ele; - foreach($end as $obj){ - $new[] = $obj; - } - $this->pap = $new; - $this->add_new = FALSE; - }else{ - print_red(_("Something went wrong while adding a new entry.")); - } - } - - if($this->add_new){ - - $smarty = get_smarty(); - $smarty->assign("element_types",$element_types ); - $smarty->assign("element_type",$this->add_element_type); - - $str = $smarty->fetch(get_template_path("templates/add_element.tpl",TRUE,dirname(__FILE__))); - return($str); - } + /************** + * Handle new elements + **************/ /* Only parse the tokens once */ if(!count($this->pap)){ @@ -106,23 +42,52 @@ class My_Tree extends Tree $this->mode_stack = array(); $this->pap = array(); $this->doDump_(0, '', true); + + /* Add left elements */ + if(count($this->mode_stack)){ + foreach($this->mode_stack as $element){ + $this->handle_elements( $element,preg_replace("/[^0-9]/","",microtime())); + } + } } /* Create html results */ $smarty = get_smarty(); + $block_indent_start = $smarty->fetch(get_template_path("templates/block_indent_start.tpl",TRUE,dirname(__FILE__))); + $block_indent_stop = $smarty->fetch(get_template_path("templates/block_indent_stop.tpl",TRUE,dirname(__FILE__))); + $this -> dump_ = ""; + $ends = array(); + $ends_complete_block = array(); + foreach($this->pap as $key => $object){ if(is_object($object)){ + + $end = $this->get_block_end($key,false); + $end2 = $this->get_block_end($key); + if($end != $key && in_array(get_class($object),array("sieve_if"))){ + $ends_complete_block[$end2] = $end2; + $this->dump_ .= "
"; + $this->dump_ .= "
"; + } + if(isset($ends[$key])){ + $this->dump_ .= $block_indent_stop; + } $this->dump_ .= preg_replace("/>/",">\n",$object->execute()); + if($end != $key && in_array(get_class($object),array("sieve_if","sieve_else","sieve_elsif"))) { + $ends[$end] = $end; + $this->dump_ .= $block_indent_start; + } + + if(isset($ends_complete_block[$key])){ + $this->dump_ .= "
"; + $this->dump_ .= "
"; + } } } - /* Create html results */ - $smarty = get_smarty(); - $smarty->assign("Contents",$this->dump_); - $ret = $smarty->fetch(get_template_path("templates/edit_frame_base.tpl",TRUE,dirname(__FILE__))); - return ($ret); + return($this->dump_); } @@ -140,18 +105,31 @@ class My_Tree extends Tree /* Get node */ $node = $this->nodes_[$node_id]; + /* Get last element class and type */ + $last_class = ""; + $last_type = ""; + if(count($this->mode_stack)){ + $key = key($this->mode_stack); + $tmp = array_reverse($this->mode_stack[$key]['ELEMENTS']); + $last_class = $tmp[key($tmp)]['class']; + + if(isset($this->mode_stack[$key]['TYPE'])){ + $last_type = $this->mode_stack[$key]['TYPE']; + } + } + /* This closes the last mode */ if($node['class'] == "block-start"){ $tmp = array_pop($this->mode_stack); $this->handle_elements($tmp,$node_id); - $this->handle_elements(array("TYPE" => "block_start"),$node_id); + $this->handle_elements(array("TYPE" => "block_start"),preg_replace("/[^0-9]/","",microtime())); } /* This closes the last mode */ if($node['class'] == "block-end"){ $tmp = array_pop($this->mode_stack); $this->handle_elements($tmp,$node_id); - $this->handle_elements(array("TYPE" => "block_end"),$node_id); + $this->handle_elements(array("TYPE" => "block_end"),preg_replace("/[^0-9]/","",microtime())); } /* Semicolon indicates a new command */ @@ -160,22 +138,42 @@ class My_Tree extends Tree $this->handle_elements($tmp,$node_id); } - /* Handle comments */ - if($node['class'] == "comment"){ - $this->mode_stack[] = array("TYPE" => $node['class']); - $rewoke_last = TRUE; + /* We can't handle comments within if tag right now */ + if(!in_array_ics($last_type,array("if","elsif"))){ + + /* Comments require special attention. + * We do not want to create a single comment element + * foreach each "#comment" string found in the script. + * Sometimes comments are used like this + * # This is a comment + * # and it still is a comment + * # ... + * So we combine them to one single comment. + */ + if($last_class != "comment" && $node['class'] == "comment"){ + $tmp =array_pop($this->mode_stack); + $this->handle_elements($tmp,$node_id); + $this->mode_stack[] = array("TYPE" => $node['class']); + } + + if($last_class == "comment" && $node['class'] != "comment"){ + $tmp =array_pop($this->mode_stack); + $this->handle_elements($tmp,$node_id); + } } /* Handle identifiers */ - $identifiers = array("else","if","elsif","end","reject","redirect","vacation","keep","discard","comment","fileinto","require","stop"); + $identifiers = array("else","if","elsif","end","reject","redirect","vacation","keep","discard","fileinto","require","stop"); if($node['class'] == "identifier" && in_array($node['text'],$identifiers)){ $this->mode_stack[] = array("TYPE" => $node['text']); } - /* Add current node to current command stack */ - end($this->mode_stack); - $key = key($this->mode_stack); - $this->mode_stack[$key]['ELEMENTS'][] = $node; + if(!($last_type == "if" && $node['class'] == "comment")){ + /* Add current node to current command stack */ + end($this->mode_stack); + $key = key($this->mode_stack); + $this->mode_stack[$key]['ELEMENTS'][] = $node; + } /* Remove last mode from mode stack, cause it was only valid for a single line */ if($rewoke_last){ @@ -211,7 +209,7 @@ class My_Tree extends Tree $class_name= "sieve_".$type ; if(class_exists($class_name)){ - $this->pap[] = new $class_name($data,$id); + $this->pap[] = new $class_name($data,$id,$this); }else{ echo "Missing : ".$class_name.""."
"; } @@ -236,51 +234,28 @@ class My_Tree extends Tree $this->pap[$key]->save_object(); } } - - $once = TRUE; - foreach($_POST as $name => $value){ - - if(isset($obj->object_id) && preg_match("/^Remove_Object_".$obj->object_id."_/",$name) && $once){ - $once = FALSE; - $this->remove_object($key); - } - if(isset($obj->object_id) && preg_match("/^Move_Up_Object_".$obj->object_id."_/",$name) && $once){ - $this->move_up_down($key,"up"); - $once = FALSE; - } - if(isset($obj->object_id) && preg_match("/^Move_Down_Object_".$obj->object_id."_/",$name) && $once){ - $this->move_up_down($key,"down"); - $once = FALSE; - } - if(isset($obj->object_id) && preg_match("/^Add_Object_Top_".$obj->object_id."_/",$name) && $once){ - $this->add_new_object($obj->object_id,"top"); - $once = FALSE; - } - if(isset($obj->object_id) && preg_match("/^Add_Object_Bottom_".$obj->object_id."_/",$name) && $once){ - $this->add_new_object($obj->object_id,"bottom"); - $once = FALSE; - } - } } } - /* Add a new object at the given position */ - function add_new_object($id,$top_bottom = "bottom") - { - $this->add_new = TRUE; - $this->add_new_id = $id; - $this->add_type = $top_bottom; - } - - /* Remove the object at the given position */ function remove_object($key_id) { + if(count($this->pap) == 1){ + print_red(_("Can't remove last element.")); + return; + } + + if(!isset($this->pap[$key_id])){ + trigger_error(_("Can't remove element with object_id=".$key_id.", there is no object with this identifier. Remove aborted.")); + return(false); + } + $class = get_class($this->pap[$key_id]); - if(in_array($class,array("sieve_if"))){ + if(in_array($class,array("sieve_if","sieve_elsif","sieve_else"))){ $block_start= $key_id; $block_end = $this->get_block_end($key_id); + for($i = $block_start ; $i <= $block_end ; $i ++ ){ unset($this->pap[$i]); } @@ -325,7 +300,9 @@ class My_Tree extends Tree if(in_array($e_class,array( "sieve_stop", "sieve_keep", - "sieve_require", + "sieve_require", + "sieve_comment", + "sieve_vacation", "sieve_stop", "sieve_reject", "sieve_fileinto", @@ -411,12 +388,12 @@ class My_Tree extends Tree /* This function returns the id of the element * where the current block ends */ - function get_block_end($start) + function get_block_end($start,$complete = TRUE) { /* Only execute if this is a really a block element. * Block elements is only sieve_if */ - if(in_array(get_class($this->pap[$start]),array("sieve_if"))){ + if(in_array(get_class($this->pap[$start]),array("sieve_if","sieve_elsif","sieve_else"))){ $class = get_class($this->pap[$start]); $next_class = get_class($this->pap[$start+1]); @@ -434,15 +411,30 @@ class My_Tree extends Tree $block_depth --; } - if( $block_depth == 0 && - $class == "sieve_block_end" && - !in_array($next_class,array("sieve_else","sieve_elsif"))){ - $end = TRUE; - $start --; + if($complete){ + if( $block_depth == 0 && + $class == "sieve_block_end" && + !in_array($next_class,array("sieve_else","sieve_elsif"))){ + $end = TRUE; + $start --; + } + }else{ + + if( $block_depth == 0 && + $class == "sieve_block_end" ){ + $end = TRUE; + $start --; + } } + $start ++; $class = get_class($this->pap[$start]); - $next_class = get_class($this->pap[$start+1]); + + if(isset($this->pap[$start+1])){ + $next_class = get_class($this->pap[$start+1]); + }else{ + $next_class =""; + } } } return($start); @@ -524,7 +516,7 @@ class My_Tree extends Tree * $key_id = Current position * $direction = Forward or backward. */ - function _get_next_free_move_slot($key_id,$direction) + function _get_next_free_move_slot($key_id,$direction,$include_self = FALSE) { $last_class = ""; $current_class =""; @@ -566,7 +558,11 @@ class My_Tree extends Tree if(($key_id+1) == count($test)) { return($key_id); } - $key_id ++; + + if(!$include_self){ + $key_id ++; + } + $include_self = FALSE; $current_class = get_class($test[$key_id]); if(in_array($current_class, $allowed_to_add_after)){ return($key_id); @@ -578,7 +574,9 @@ class My_Tree extends Tree if($key_id == 0) { return($key_id); } - $key_id --; + if(!$include_self){ + $key_id --; + } while($key_id >=0 ){ $current_class = get_class($test[$key_id]); if(in_array($current_class, $allowed_to_add_before)){ @@ -603,14 +601,19 @@ class My_Tree extends Tree } $tmp2 = $part->get_sieve_script_part(); - if(get_class($part) == "sieve_reject"){ - $tmp.=$tmp2; - }else{ - - $tmp3 = split("\n",$tmp2); - foreach($tmp3 as $str){ - $str2 = trim($str); - if(empty($str2)) continue; + $tmp3 = split("\n",$tmp2); + foreach($tmp3 as $str){ + $str2 = trim($str); + + /* If the current line only contains an '.' + * we must skip the line indent. + * The text: statement uses a single '.' to mark the text end. + * This '.' must be the only char in the current line, no + * whitespaces are allowed here. + */ + if($str2 == "."){ + $tmp.=$str."\n"; + }else{ $tmp.= $buffer.$str."\n"; } } @@ -620,28 +623,79 @@ class My_Tree extends Tree } } if(!preg_match("/Generated by GOsa - Gonicus System Administrator/",$tmp)){ - $tmp = "#Generated by GOsa - Gonicus System Administrator \n ".$tmp; +# $tmp = "#Generated by GOsa - Gonicus System Administrator \n ".$tmp; } return($tmp); } - function Add_Element() + function check() { - $tmp = array("ELEMENTS" => array(array("class" => "qouted-string","text"=> "Bla bla, later more"))); - $this->pap[] = new sieve_comment($tmp,rand(1000,100000)); + $msgs = array(); + + /* Some logical checks. + * like : only sieve_comment can appear before require. + */ + + /* Ensure that there are no command before require + * - Get id of last require tag + * - Collect object types in from of this tag. + * - Check if there are tags collected that are not allowed + */ + $last_found_at = -1; + $objs = array(); + foreach($this->pap as $key => $obj){ + if(get_class($obj) == "sieve_require"){ + $last_found_at = $key; + } + } + foreach($this->pap as $key => $obj){ + if($key == $last_found_at) break; + if(!in_array(get_class($obj),array("sieve_comment","sieve_require"))){ + $objs[] = get_class($obj); + } + } + if(count($objs) && $last_found_at != -1){ + $str = _("Require must be the first command in the script."); + $msgs[] = $str; + print_red($str);; + } + + foreach($this->pap as $obj){ + $o_msgs = $obj->check(); + foreach($o_msgs as $o_msg){ + $msgs[] = $o_msg; + } + } + return($msgs); } - function check() + + /* We are forced to add a new require. + * This function is called by the + * sieveElement_Classes->parent->add_require() + */ + function add_require($str) { - $msgs = array(); - foreach($this->pap as $obj){ - - $o_msgs = $obj->check(); - foreach($o_msgs as $o_msg){ - $msgs[] = $o_msg; - } - } - return($msgs); + $require_id = -1; + foreach($this->pap as $key => $obj){ + if(get_class($obj) == "sieve_require"){ + $require_id = $key; + } + } + + /* No require found, add one */ + if($require_id == -1){ + $require = new sieve_require(NULL,preg_replace("/[^0-9]/","",microtime()),$this); + $require -> Add_Require($str); + $new = array(); + $new[] = $require; + foreach($this->pap as $obj){ + $new[] = $obj; + } + $this->pap = $new; + } else { + $this->pap[$require_id]->Add_Require($str); + } } } @@ -649,7 +703,7 @@ class My_Tree extends Tree /* Create valid sieve string/string-list * out of a given array */ -function sieve_create_strings($data) +function sieve_create_strings($data,$force_string = FALSE) { $ret = ""; if(is_array($data)){ @@ -673,7 +727,7 @@ function sieve_create_strings($data) $Multiline = preg_match("/\n/",$data); $data = preg_replace("/\r/","",$data);; - if($Multiline){ + if($Multiline && !$force_string){ $ret = "text: \r\n".$data."\r\n.\r\n"; }else{ $ret = "\"".$data."\""; @@ -681,7 +735,7 @@ function sieve_create_strings($data) } $ret = preg_replace("/\"\"/","\"",$ret); $ret = preg_replace("/\n/","\r\n",$ret); - + return($ret); } @@ -696,18 +750,24 @@ function sieve_get_strings($data,$id) { $ret = array(); if($data[$id]['class'] == "left-bracket"){ - while($data[$id]['class'] != "right-bracket" && $id < count($data)){ - + while(isset($data[$id]) && $data[$id]['class'] != "right-bracket" && $id < count($data)){ + if($data[$id]['class'] == "quoted-string"){ $ret[] = $data[$id]['text']; } + $id ++; } }elseif($data[$id]['class'] == "quoted-string"){ $ret[] = $data[$id]['text']; }elseif($data[$id]['class'] == "number"){ $ret[] = $data[$id]['text']; + }elseif($data[$id]['class'] == "multi-line"){ + $str = trim(preg_replace("/^text:/","",$data[$id]['text'])); + $str = trim(preg_replace("/\.$/","",$str)); + $ret[] = $str; } + return(array("OFFSET" => $id, "STRINGS" => $ret)); }