Code

a8f9aa740e24a1066dae7eca9ae4f8531c8b0659
[gosa.git] / include / sieve / class_My_Tree.inc
1 <?php
5 /* This class is inherited from the original 'Tree'
6  *  class written by Heiko Hund.
7  * It is partly rewritten to create a useable html interface 
8  *  for each single sieve token. 
9  * This gives us the ability to edit existing sieve filters. 
10  */
11 class My_Tree extends Tree
12 {
13   var $dumpFn_;
14   var $dump_;
16   var $mode_stack = array();
17   var $pap              = array();
20   /* Create a html interface for the current sieve filter 
21    */
22   function dump()
23   {
24     error_reporting(E_ALL);
26     /* Only parse the tokens once */
27     if(!count($this->pap)){
28       $this->dump_ = "";
29       $this->mode_stack = array();
30       $this->pap = array();
31       $this->doDump_(0, '', true);
32     }
34     /* Create html results */
35     $this->dump_ ="<table width='100%'><tr><td style='background-color:#BBBBBB;border: 0px;padding-left:20px;'>";
36     foreach($this->pap as $key => $object){
37       if(is_object($object)){
38         $this->dump_ .= preg_replace("/>/",">\n",$object->execute()); 
39       }
40     }
41     $this->dump_ .= "</td></tr></table>";
42     return $this->dump_;
43   }
46   /* This function walks through the object tree generated by the "Parse" class.
47    * All Commands will be resolved and grouped. So the Commands and their 
48    *  parameter are combined. Like "IF" and ":comparator"...
49    */  
50   function doDump_($node_id, $prefix, $last,$num = 1)
51   {
52     /* Indicates that current comman will only be valid for a single line. 
53      *  this command type will be removed from mode_stack after displaying it.
54      */
55     $rewoke_last = FALSE;
57     /* Get node */ 
58     $node = $this->nodes_[$node_id];
60     /* This closes the last mode */
61     if($node['class'] == "block-start"){
62       $tmp = array_pop($this->mode_stack);
63       $this->handle_elements($tmp,$node_id);
64       $this->handle_elements(array("TYPE" => "block_start"),$node_id);
65     }
67     /* This closes the last mode */
68     if($node['class'] == "block-end"){
69       $tmp = array_pop($this->mode_stack);
70       $this->handle_elements($tmp,$node_id);
71       $this->handle_elements(array("TYPE" => "block_end"),$node_id);
72     }
74     /* Semicolon indicates a new command */
75     if($node['class'] == "semicolon"){
76       $tmp =array_pop($this->mode_stack);
77       $this->handle_elements($tmp,$node_id);
78     }
80     /* Handle comments */
81     if($node['class'] == "comment"){
82       $this->mode_stack[] = array("TYPE" => $node['class']);
83       $rewoke_last = TRUE;
84     }
86     /* Handle identifiers */
87     $identifiers = array("if","elsif","end","reject","redirect","vacation","keep","discard","comment","fileinto","require","stop");
88     if($node['class'] == "identifier" && in_array($node['text'],$identifiers)){
89       $this->mode_stack[] = array("TYPE" => $node['text']); 
90     }
92     /* Add current node to current command stack */
93     end($this->mode_stack);
94     $key = key($this->mode_stack);
95     $this->mode_stack[$key]['ELEMENTS'][] = $node;
97     /* Remove last mode from mode stack, cause it was only valid for a single line */
98     if($rewoke_last){
99       $tmp =array_pop($this->mode_stack);
100       $this->handle_elements($tmp,$node_id);
101     }
103     /* If this is a sub element, just call this for all childs */       
104     if(isset($this->childs_[$node_id])){
105       $childs = $this->childs_[$node_id];
106       for ($i=0; $i<count($childs); ++$i)
107       {
108         $c_last = false;
109         if ($i+1 == count($childs))
110         {
111           $c_last = true;
112         }
113         $this->doDump_($childs[$i], "", $num);
114       }
115     }
116   }
119   /* Create a class for each resolved object.
120    * And append this class to a list of objects.
121    */
122   function handle_elements($data,$id)
123   {
124     if(!isset($data['TYPE'])){
125       return;
126     }
127     $type = $data['TYPE'];
128     
129     $class_name= "sieve_".$type ;
130     if(class_exists($class_name)){
131       $this->pap[] = new $class_name($data,$id);
132     }else{
133       echo "<font color='red'>Missing : ".$class_name."</font>"."<br>";
134     }
135   }
137   function save_object()
138   {
139     foreach($this->pap as $key => $obj){
141       if(in_array(get_class($obj),array("sieve_if","sieve_elsif","sieve_vacation","sieve_comment","sieve_reject","sieve_fileinto","sieve_require","sieve_redirect"))){
142         $this->pap[$key]->save_object();
143       }
144     }
145   }
147   /* Need to be reviewed */
148   function get_sieve_script()
149   {
150     $tmp ="";
151     if(count($this->pap)){
152       $tmp = "#Generated by GOsa - Gonicus System Administrator\n";
153       $buffer = "";    
154       foreach($this->pap as $part)  {
155         if(get_class($part) == "sieve_block_end"){
156           $buffer = substr($buffer,0,strlen($buffer)-(strlen(SIEVE_INDENT_TAB)));
157         }
158         $tmp2 = $part->get_sieve_script_part();
159         $tmp3 = split("\n",$tmp2);
160         foreach($tmp3 as $str){
161           $str2 = trim($str);
162           if(empty($str2)) continue;
163           $tmp.= $buffer.$str."\n";
164         }
165         if(get_class($part) == "sieve_block_start"){
166           $buffer .= SIEVE_INDENT_TAB;
167         }
168       }
169     }
170     return($tmp);
171   }
175 /* Create valid sieve string/string-list 
176  *  out of a given array
177  */
178 function sieve_create_strings($data)
180   $ret = "";
181   if(is_array($data)){
182     if(count($data) == 1){
183       $ret = "\"";
184       foreach($data as $dat){
185         $ret .=$dat;
186       }
187       $ret.="\"";
188     }else{
189       foreach($data as $dat){
190         $ret.= "\"";
191         $ret.=$dat;
192         $ret.="\", ";
193       }
194       $ret = preg_replace("/,$/","",trim($ret));
195       $ret = "[".$ret."]";
196     }
197   }else{
198     $ret = "\"".$data."\"";
199   }
200   $ret = preg_replace("/\"\"/","\"",$ret);
201   return($ret);
204 /* This checks if there is a string at the current position 
205  *  in the token array. 
206  * If there is a string list at the current position,
207  *  this function will return a complete list of all
208  *  strings used in this list.
209  * It also returns an offset of the last token position 
210  */
211 function sieve_get_strings($data,$id)
213   $ret = array();
214   if($data[$id]['class'] == "left-bracket"){
215     while($data[$id]['class']  != "right-bracket" && $id < count($data)){
216       
217       if($data[$id]['class'] == "quoted-string"){
218         $ret[] = $data[$id]['text'];
219       }
220       $id ++;
221     }
222   }elseif($data[$id]['class'] == "quoted-string"){
223     $ret[] = $data[$id]['text'];
224   }elseif($data[$id]['class'] == "number"){
225     $ret[] = $data[$id]['text'];
226   }
227   return(array("OFFSET" => $id, "STRINGS" => $ret));
230 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
231 ?>