Code

Added edit frame
[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     $smarty = get_smarty();
36     $smarty->fetch(get_template_path("templates/element_stop.tpl",TRUE,dirname(__FILE__)));
38     $this -> dump_ = "";
39     foreach($this->pap as $key => $object){
40       if(is_object($object)){
41         $this->dump_ .= preg_replace("/>/",">\n",$object->execute()); 
42       }
43     }
44     
46     /* Create html results */
47     $smarty = get_smarty();
48     $smarty->assign("Contents",$this->dump_);
49     $ret = $smarty->fetch(get_template_path("templates/edit_frame_base.tpl",TRUE,dirname(__FILE__)));
50     return ($ret);
51   }
54   /* This function walks through the object tree generated by the "Parse" class.
55    * All Commands will be resolved and grouped. So the Commands and their 
56    *  parameter are combined. Like "IF" and ":comparator"...
57    */  
58   function doDump_($node_id, $prefix, $last,$num = 1)
59   {
60     /* Indicates that current comman will only be valid for a single line. 
61      *  this command type will be removed from mode_stack after displaying it.
62      */
63     $rewoke_last = FALSE;
65     /* Get node */ 
66     $node = $this->nodes_[$node_id];
68     /* This closes the last mode */
69     if($node['class'] == "block-start"){
70       $tmp = array_pop($this->mode_stack);
71       $this->handle_elements($tmp,$node_id);
72       $this->handle_elements(array("TYPE" => "block_start"),$node_id);
73     }
75     /* This closes the last mode */
76     if($node['class'] == "block-end"){
77       $tmp = array_pop($this->mode_stack);
78       $this->handle_elements($tmp,$node_id);
79       $this->handle_elements(array("TYPE" => "block_end"),$node_id);
80     }
82     /* Semicolon indicates a new command */
83     if($node['class'] == "semicolon"){
84       $tmp =array_pop($this->mode_stack);
85       $this->handle_elements($tmp,$node_id);
86     }
88     /* Handle comments */
89     if($node['class'] == "comment"){
90       $this->mode_stack[] = array("TYPE" => $node['class']);
91       $rewoke_last = TRUE;
92     }
94     /* Handle identifiers */
95     $identifiers = array("else","if","elsif","end","reject","redirect","vacation","keep","discard","comment","fileinto","require","stop");
96     if($node['class'] == "identifier" && in_array($node['text'],$identifiers)){
97       $this->mode_stack[] = array("TYPE" => $node['text']); 
98     }
100     /* Add current node to current command stack */
101     end($this->mode_stack);
102     $key = key($this->mode_stack);
103     $this->mode_stack[$key]['ELEMENTS'][] = $node;
105     /* Remove last mode from mode stack, cause it was only valid for a single line */
106     if($rewoke_last){
107       $tmp =array_pop($this->mode_stack);
108       $this->handle_elements($tmp,$node_id);
109     }
111     /* If this is a sub element, just call this for all childs */       
112     if(isset($this->childs_[$node_id])){
113       $childs = $this->childs_[$node_id];
114       for ($i=0; $i<count($childs); ++$i)
115       {
116         $c_last = false;
117         if ($i+1 == count($childs))
118         {
119           $c_last = true;
120         }
121         $this->doDump_($childs[$i], "", $num);
122       }
123     }
124   }
127   /* Create a class for each resolved object.
128    * And append this class to a list of objects.
129    */
130   function handle_elements($data,$id)
131   {
132     if(!isset($data['TYPE'])){
133       return;
134     }
135     $type = $data['TYPE'];
136     
137     $class_name= "sieve_".$type ;
138     if(class_exists($class_name)){
139       $this->pap[] = new $class_name($data,$id);
140     }else{
141       echo "<font color='red'>Missing : ".$class_name."</font>"."<br>";
142     }
143   }
145   function save_object()
146   {
147     foreach($this->pap as $key => $obj){
149       if(in_array(get_class($obj),array("sieve_if","sieve_elsif","sieve_vacation","sieve_comment","sieve_reject","sieve_fileinto","sieve_require","sieve_redirect"))){
150         $this->pap[$key]->save_object();
151       }
152     }
153   }
155   /* Need to be reviewed */
156   function get_sieve_script()
157   {
158     $tmp ="";
159     if(count($this->pap)){
160       $buffer = "";    
161       foreach($this->pap as $part)  {
162         if(get_class($part) == "sieve_block_end"){
163           $buffer = substr($buffer,0,strlen($buffer)-(strlen(SIEVE_INDENT_TAB)));
164         }
165         $tmp2 = $part->get_sieve_script_part();
167         if(get_class($part) == "sieve_reject"){
168           $tmp.=$tmp2;
169         }else{
171           $tmp3 = split("\n",$tmp2);
172           foreach($tmp3 as $str){
173             $str2 = trim($str);
174             if(empty($str2)) continue;
175             $tmp.= $buffer.$str."\n";
176           }
177         }
178         if(get_class($part) == "sieve_block_start"){
179           $buffer .= SIEVE_INDENT_TAB;
180         }
181       }
182     }
183     if(!preg_match("/Generated by GOsa - Gonicus System Administrator/",$tmp)){
184       $tmp = "#Generated by GOsa - Gonicus System Administrator \n ".$tmp;
185     }
186     return($tmp);
187   }
189   function Add_Element()
190   {
191     $tmp = array("ELEMENTS" => array(array("class" => "qouted-string","text"=> "Bla bla, later more")));
192     $this->pap[] = new sieve_comment($tmp,rand(1000,100000));
193   }
197 /* Create valid sieve string/string-list 
198  *  out of a given array
199  */
200 function sieve_create_strings($data)
202   $ret = "";
203   if(is_array($data)){
204     if(count($data) == 1){
205       $ret = "\"";
206       foreach($data as $dat){
207         $ret .=$dat;
208       }
209       $ret.="\"";
210     }else{
211       foreach($data as $dat){
212         $ret.= "\"";
213         $ret.=$dat;
214         $ret.="\", ";
215       }
216       $ret = preg_replace("/,$/","",trim($ret));
217       $ret = "[".$ret."]";
218     }
219   }else{
221     $Multiline = preg_match("/\n/",$data);
222     $data = preg_replace("/\r/","",$data);;
224     if($Multiline){
225       $ret = "text: \r\n".$data."\r\n.\r\n";
226     }else{
227       $ret = "\"".$data."\"";
228     }
229   }
230   $ret = preg_replace("/\"\"/","\"",$ret);
231   $ret = preg_replace("/\n/","\r\n",$ret);
232   
233   return($ret);
236 /* This checks if there is a string at the current position 
237  *  in the token array. 
238  * If there is a string list at the current position,
239  *  this function will return a complete list of all
240  *  strings used in this list.
241  * It also returns an offset of the last token position 
242  */
243 function sieve_get_strings($data,$id)
245   $ret = array();
246   if($data[$id]['class'] == "left-bracket"){
247     while($data[$id]['class']  != "right-bracket" && $id < count($data)){
248       
249       if($data[$id]['class'] == "quoted-string"){
250         $ret[] = $data[$id]['text'];
251       }
252       $id ++;
253     }
254   }elseif($data[$id]['class'] == "quoted-string"){
255     $ret[] = $data[$id]['text'];
256   }elseif($data[$id]['class'] == "number"){
257     $ret[] = $data[$id]['text'];
258   }
259   return(array("OFFSET" => $id, "STRINGS" => $ret));
262 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
263 ?>