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);
25 $this->dump_ = "";
26 $this->mode_stack = array();
27 $this->pap = array();
28 $this->doDump_(0, '', true);
30 $this->dump_ ="<table width='100%'><tr><td style='background-color:#BBBBBB;border: 0px;padding-left:20px;'>";
31 foreach($this->pap as $object){
32 if(is_object($object)){
33 $this->dump_ .= preg_replace("/>/",">\n",$object->execute());
34 }
35 }
36 $this->dump_ .= "</td></tr></table>";
37 return $this->dump_;
38 }
41 /* This function walks through the object tree generated by the "Parse" class.
42 * All Commands will be resolved and grouped. So the Commands and their
43 * parameter are combined. Like "IF" and ":comparator"...
44 */
45 function doDump_($node_id, $prefix, $last,$num = 1)
46 {
47 /* Indicates that current comman will only be valid for a single line.
48 * this command type will be removed from mode_stack after displaying it.
49 */
50 $rewoke_last = FALSE;
52 /* Get node */
53 $node = $this->nodes_[$node_id];
55 /* This closes the last mode */
56 if($node['class'] == "block-start"){
57 $tmp = array_pop($this->mode_stack);
58 $this->handle_elements($tmp,$node_id);
59 $this->handle_elements(array("TYPE" => "block_start"),$node_id);
60 }
62 /* This closes the last mode */
63 if($node['class'] == "block-end"){
64 $tmp = array_pop($this->mode_stack);
65 $this->handle_elements($tmp,$node_id);
66 $this->handle_elements(array("TYPE" => "block_end"),$node_id);
67 }
69 /* Semicolon indicates a new command */
70 if($node['class'] == "semicolon"){
71 $tmp =array_pop($this->mode_stack);
72 $this->handle_elements($tmp,$node_id);
73 }
75 /* Handle comments */
76 if($node['class'] == "comment"){
77 $this->mode_stack[] = array("TYPE" => $node['class']);
78 $rewoke_last = TRUE;
79 }
81 /* Handle identifiers */
82 $identifiers = array("if","elsif","end","reject","redirect","vacation","keep","discard","comment","fileinto","require","stop");
83 if($node['class'] == "identifier" && in_array($node['text'],$identifiers)){
84 $this->mode_stack[] = array("TYPE" => $node['text']);
85 }
87 /* Add current node to current command stack */
88 end($this->mode_stack);
89 $key = key($this->mode_stack);
90 $this->mode_stack[$key]['ELEMENTS'][] = $node;
92 /* Remove last mode from mode stack, cause it was only valid for a single line */
93 if($rewoke_last){
94 $tmp =array_pop($this->mode_stack);
95 $this->handle_elements($tmp,$node_id);
96 }
98 /* If this is a sub element, just call this for all childs */
99 if(isset($this->childs_[$node_id])){
100 $childs = $this->childs_[$node_id];
101 for ($i=0; $i<count($childs); ++$i)
102 {
103 $c_last = false;
104 if ($i+1 == count($childs))
105 {
106 $c_last = true;
107 }
108 $this->doDump_($childs[$i], "", $num);
109 }
110 }
111 }
114 /* Create a class for each resolved object.
115 * And append this class to a list of objects.
116 */
117 function handle_elements($data,$id)
118 {
119 if(!isset($data['TYPE'])){
120 return;
121 }
122 $type = $data['TYPE'];
124 $class_name= "sieve_".$type ;
125 if(class_exists($class_name)){
126 $this->pap[] = new $class_name($data,$id);
127 }else{
128 echo "<font color='red'>Missing : ".$class_name."</font>"."<br>";
129 }
130 }
131 }
134 /* This checks if there is a string at the current position
135 * in the token array.
136 * If there is a string list at the current position,
137 * this function will return a complete list of all
138 * strings used in this list.
139 * It also returns an offset of the last token position
140 */
141 function sieve_get_strings($data,$id)
142 {
143 $ret = array();
144 if($data[$id]['class'] == "left-bracket"){
145 while($data[$id]['class'] != "right-bracket" && $id < count($data)){
147 if($data[$id]['class'] == "quoted-string"){
148 $ret[] = $data[$id]['text'];
149 }
150 $id ++;
151 }
152 }elseif($data[$id]['class'] == "quoted-string"){
153 $ret[] = $data[$id]['text'];
154 }elseif($data[$id]['class'] == "number"){
155 $ret[] = $data[$id]['text'];
156 }
157 return(array("OFFSET" => $id, "STRINGS" => $ret));
158 }
160 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
161 ?>