X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Fsieve%2Fclass_My_Tree.inc;h=645188fc283be7b43d8019c907e7a1c2cd57eb2b;hb=e720ccc6f0cc4f577e59ae27a76b08c933d0155d;hp=28ac518bd9bce6075f48a2356254bce04d4ed3d5;hpb=9d45792ebfea9693b701a01fdf6c40b4075f6dba;p=gosa.git diff --git a/include/sieve/class_My_Tree.inc b/include/sieve/class_My_Tree.inc index 28ac518bd..645188fc2 100644 --- a/include/sieve/class_My_Tree.inc +++ b/include/sieve/class_My_Tree.inc @@ -15,13 +15,26 @@ class My_Tree extends Tree var $mode_stack = array(); var $pap = array(); + var $parent = NULL; + 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); + /************** + * Handle new elements + **************/ /* Only parse the tokens once */ if(!count($this->pap)){ @@ -32,14 +45,16 @@ class My_Tree extends Tree } /* Create html results */ - $this->dump_ ="
"; + $smarty = get_smarty(); + + $this -> dump_ = ""; foreach($this->pap as $key => $object){ if(is_object($object)){ $this->dump_ .= preg_replace("/>/",">\n",$object->execute()); } } - $this->dump_ .= "
"; - return $this->dump_; + + return($this->dump_); } @@ -61,14 +76,14 @@ class My_Tree extends Tree 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 */ @@ -128,7 +143,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.""."
"; } @@ -136,46 +151,462 @@ class My_Tree extends Tree function save_object() { + reset($this->pap); foreach($this->pap as $key => $obj){ - if(in_array(get_class($obj),array("sieve_if","sieve_elsif","sieve_vacation","sieve_comment","sieve_reject","sieve_fileinto","sieve_require","sieve_redirect"))){ - $this->pap[$key]->save_object(); + if(in_array(get_class($obj),array("sieve_if", + "sieve_elsif", + "sieve_vacation", + "sieve_comment", + "sieve_reject", + "sieve_fileinto", + "sieve_require", + "sieve_redirect"))){ + + + if(isset($this->pap[$key]) && method_exists($this->pap[$key],"save_object")){ + $this->pap[$key]->save_object(); + } + } + } + } + + + /* Remove the object at the given position */ + function remove_object($key_id) + { + $class = get_class($this->pap[$key_id]); + 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]); + } + }else{ + unset($this->pap[$key_id]); + } + $tmp = array(); + foreach($this->pap as $element){ + $tmp[] = $element; + } + $this->pap = $tmp; + } + + + /* This function moves a given element to another position. + * Single elements like "keep;" will simply be moved one posisition down/up. + * Multiple elements like if-elsif-else will be moved as block. + * + * $key_id specified the element that should be moved. + * $direction specifies to move elements "up" or "down" + */ + function move_up_down($key_id,$direction = "down") + { + + /* Get the current element to decide what to move. */ + $e_class = get_class($this->pap[$key_id]); + + if(in_array($e_class,array("sieve_if"))){ + $block_start= $key_id; + $block_end = $this->get_block_end($key_id); + + /* Depending on the direction move up down */ + if($direction == "down"){ + $next_free = $this->_get_next_free_move_slot($block_end,$direction); + }else{ + $next_free = $this->_get_next_free_move_slot($block_start,$direction); + } + + /* Move the given block */ + $this->move_multiple_elements($block_start,$block_end,$next_free); + } + + if(in_array($e_class,array( "sieve_stop", + "sieve_keep", + "sieve_require", + "sieve_comment", + "sieve_vacation", + "sieve_stop", + "sieve_reject", + "sieve_fileinto", + "sieve_redirect", + "sieve_discard"))){ + $this->move_single_element($key_id,$this->_get_next_free_move_slot($key_id,$direction)); + } + } + + + /* Move the given block to position */ + function move_multiple_elements($start,$end,$to) + { + /* Use class names for testing */ + $data = $this->pap; + + /* Get block to move */ + $block_to_move = array_slice($data,$start, ($end - $start +1)); + + /* We want do move this block up */ + if($end > $to){ + + /* Get start block */ + $start_block = array_slice($data,0,$to); + + /* Get Get all elements between the block to move + * and next free position + */ + $block_to_free = array_slice($data,$to ,$start - $to ); + $block_to_end = array_slice($data,$end+1); + $new = array(); + foreach($start_block as $block){ + $new[] = $block; + } + foreach($block_to_move as $block){ + $new[] = $block; + } + foreach($block_to_free as $block){ + $new[] = $block; + } + foreach($block_to_end as $block){ + $new[] = $block; + } + $old = $this->pap; + $this->pap = $new; + } + + + /* We want to move this block down. */ + if($to > $end){ + + /* Get start block */ + $start_block = array_slice($data,0,$start); + + /* Get Get all elements between the block to move + * and next free position + */ + $block_to_free = array_slice($data,$end +1,($to - $end )); + + /* Get the rest + */ + $block_to_end = array_slice($data,$to+1); + + $new = array(); + foreach($start_block as $block){ + $new[] = $block; + } + foreach($block_to_free as $block){ + $new[] = $block; + } + foreach($block_to_move as $block){ + $new[] = $block; + } + foreach($block_to_end as $block){ + $new[] = $block; + } + $old = $this->pap; + $this->pap = $new; + } + } + + + /* This function returns the id of the element + * where the current block ends + */ + function get_block_end($start) + { + /* 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","sieve_elsif","sieve_else"))){ + + $class = get_class($this->pap[$start]); + $next_class = get_class($this->pap[$start+1]); + $block_depth = 0; + + $end = FALSE; + + while(!$end && $start < count($this->pap)){ + + if($class == "sieve_block_start"){ + $block_depth ++; + } + + if($class == "sieve_block_end"){ + $block_depth --; + } + + if( $block_depth == 0 && + $class == "sieve_block_end" && + !in_array($next_class,array("sieve_else","sieve_elsif"))){ + $end = TRUE; + $start --; + } + $start ++; + $class = get_class($this->pap[$start]); + + if(isset($this->pap[$start+1])){ + $next_class = get_class($this->pap[$start+1]); + }else{ + $next_class =""; + } + } + } + return($start); + } + + + /* This function moves the single element at + * position $from to position $to. + */ + function move_single_element($from,$to) + { + if($from == $to) { + return; + } + + $ret = array(); + $tmp = $this->pap; + + $begin = array(); + $middle = array(); + $end = array(); + $element = $this->pap[$from]; + + if($from > $to ){ + + /* Get all element in fron to element to move */ + if($from != 0){ + $begin = array_slice($tmp,0,$to); + } + + /* Get all elements between */ + $middle = array_slice($tmp,$to , ($from - ($to) )); + + /* Get the rest */ + $end = array_slice($tmp,$from+1); + + foreach($begin as $data){ + $ret[] = $data; + } + $ret[] = $element; + foreach($middle as $data){ + $ret[] = $data; + } + foreach($end as $data){ + $ret[] = $data; + } + $this->pap = $ret; + } + if($from < $to ){ + + /* Get all element in fron to element to move */ + if($from != 0){ + $begin = array_slice($tmp,0,$from); + } + + /* Get all elements between */ + $middle = array_slice($tmp,$from+1 , ($to - ($from))); + + /* Get the rest */ + $end = array_slice($tmp,$to+1); + + foreach($begin as $data){ + $ret[] = $data; + } + foreach($middle as $data){ + $ret[] = $data; + } + $ret[] = $element; + foreach($end as $data){ + $ret[] = $data; + } + $this->pap = $ret; + } + } + + + /* Returns the next free position where we + * can add a new sinle element + * $key_id = Current position + * $direction = Forward or backward. + */ + function _get_next_free_move_slot($key_id,$direction) + { + $last_class = ""; + $current_class =""; + $next_class = ""; + + /* After this elements we can add new elements + * without having any trouble. + */ + $allowed_to_add_after = array("sieve_keep", + "sieve_require", + "sieve_stop", + "sieve_reject", + "sieve_fileinto", + "sieve_redirect", + "sieve_discard", + "sieve_comment", + "sieve_block_start" + ); + + /* Before this elements we can add new elements + * without having any trouble. + */ + $allowed_to_add_before = array("sieve_keep", + "sieve_require", + "sieve_stop", + "sieve_reject", + "sieve_fileinto", + "sieve_comment", + "sieve_redirect", + "sieve_discard", + "sieve_if", + "sieve_block_end" + ); + + if($direction == "down"){ + + $test = $this->pap; + while($key_id < count($test)){ + if(($key_id+1) == count($test)) { + return($key_id); + } + $key_id ++; + $current_class = get_class($test[$key_id]); + if(in_array($current_class, $allowed_to_add_after)){ + return($key_id); + } + } + }else{ + + $test = $this->pap; + if($key_id == 0) { + return($key_id); } + $key_id --; + while($key_id >=0 ){ + $current_class = get_class($test[$key_id]); + if(in_array($current_class, $allowed_to_add_before)){ + return($key_id); + } + $key_id --; + } + return(0); } } + /* Need to be reviewed */ function get_sieve_script() { $tmp =""; if(count($this->pap)){ - $tmp = "#Generated by GOsa - Gonicus System Administrator\n"; $buffer = ""; foreach($this->pap as $part) { if(get_class($part) == "sieve_block_end"){ $buffer = substr($buffer,0,strlen($buffer)-(strlen(SIEVE_INDENT_TAB))); } $tmp2 = $part->get_sieve_script_part(); - $tmp3 = split("\n",$tmp2); - foreach($tmp3 as $str){ - $str2 = trim($str); - if(empty($str2)) continue; - $tmp.= $buffer.$str."\n"; + + if(get_class($part) == "sieve_reject"){ + $tmp.=$tmp2; + }else{ + + $tmp3 = split("\n",$tmp2); + foreach($tmp3 as $str){ + $str2 = trim($str); + if(empty($str2)) continue; + $tmp.= $buffer.$str."\n"; + } } if(get_class($part) == "sieve_block_start"){ $buffer .= SIEVE_INDENT_TAB; } } } + if(!preg_match("/Generated by GOsa - Gonicus System Administrator/",$tmp)){ + $tmp = "#Generated by GOsa - Gonicus System Administrator \n ".$tmp; + } return($tmp); } + + function check() + { + $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); + } + + + /* We are forced to add a new require. + * This function is called by the + * sieveElement_Classes->parent->add_require() + */ + function add_require($str) + { + $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); + } + } } /* 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)){ @@ -195,9 +626,19 @@ function sieve_create_strings($data) $ret = "[".$ret."]"; } }else{ - $ret = "\"".$data."\""; + + $Multiline = preg_match("/\n/",$data); + $data = preg_replace("/\r/","",$data);; + + if($Multiline && !$force_string){ + $ret = "text: \r\n".$data."\r\n.\r\n"; + }else{ + $ret = "\"".$data."\""; + } } $ret = preg_replace("/\"\"/","\"",$ret); + $ret = preg_replace("/\n/","\r\n",$ret); + return($ret); } @@ -223,7 +664,12 @@ function sieve_get_strings($data,$id) $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)); }