Code

Added value checks for sieve test elements
[gosa.git] / include / sieve / class_sieveElement_If.inc
1 <?php
4 class sieve_if 
5 {
6   var $_parsed  = array();
7   var $TYPE     = "if";
8   var $object_id     = -1;
10   var $address_parts    = array();
11   var $comparators      = array();
12   var $match_types      = array();
13   var $operators        = array();
14   var $parent           = NULL;
15   
16   /* Initialize class 
17    *  $elements   contains all tokens that belongs to this if/else tag
18    *  $object_id  cotains an unique tag id, to be able to create uniqe html post names
19    */
20   function sieve_if($elements,$object_id,$parent)
21   {
22     $this->parent = $parent;
23     $this->object_id       = $object_id;
24   
25     /* Possible address parts we can select */
26     $this->address_parts = array( 
27         ":all"       => _("Complete adress")."&nbsp;("._("Default").")",
28         ":domain"    => _("Domian part") ,
29         ":localpart" => _("Local part"));
31     /* comparator type */
32     $this->comparators   = array( 
33         "i;ascii-casemap" => _("Case insensitive")."&nbsp;("._("Default").")",
34         "i;octet"         => _("Case sensitive"),
35         "i;ascii-numeric" => _("Numeric"));
37     /* Match types */
38     $this->match_types  = array(  
39         ":is"         => _("is"),
40         ":regex"      => _("regex"),
41         ":contains"   => _("contains"),
42         ":matches"    => _("matches"),
43         ":count"      => _("count"),
44         ":value"      => _("value is"));
46     /* Operators */
47     $this->operators = array(     
48         "lt"  => _("less than"),
49         "le"  => _("less or equal"),
50         "eq"  => _("equals"),
51         "ge"  => _("greater or equal"),
52         "gt"  => _("greater than"),
53         "ne"  => _("not equal"));
55     /* Skip parsing if this element is new */
56     if($elements != NULL){
58       /* Remove comments from tests */  
59       $tmp = array();
60       foreach($elements['ELEMENTS'] as $ele){
61         if($ele['class'] != "comment"){
62           $tmp[] = $ele;
63         }
64       }
65       $elements['ELEMENTS'] = $tmp;
67       if($elements!=NULL){
68         $this->elements = $elements;
69         $this->_parsed  = $this->_parse($elements['ELEMENTS'],1);
70       }
71     }
72   }
75   /* Returns the sieve script for this 
76    *  if/else tag.
77    */
78   function get_sieve_script_part()
79   {
80     $tmp = $this->TYPE." ".$this->get_sieve_script_part_recursive($parsed = NULL,$id = 1,$obj_id=1);
81     return($tmp);
82   } 
85   /* Return error msgs */
86   function check()
87   {
88     $check = $this->check_recursive();
89     return($check);
90   }
91  
93   /* Recursivly fetch all error msgs */
94   function check_recursive($parsed = NULL,$id = 1,$obj_id=1)
95   {
96     $ret = array();
97     if($parsed == NULL){
98       $parsed = $this->_parsed;
99     }
101     /* Walk through all elements */
102     foreach($parsed as $key => $data){
104       /* Create elements */
105       switch($key)
106       {
107         /*******************
108          * Allof / Anyof
109          *******************/
110         case "anyof" :
111         case "allof" :
112         { 
113           foreach($data as $key2 => $dat){
114             if(($key2 === "Inverse") && ($key2 == "Inverse")){
115               continue;
116             }
117             $msgs = $this->check_recursive($dat, ($id +1),$key2);
119             foreach($msgs as $msg){
120               $ret[] = $msg;
121             }
122           }
123           break;
124         }
126         /*******************
127          * True / False
128          *******************/
130         case "true" :
131         case "false" : 
132         {
133           /* Can't fail anyway */
134           break;
135         }
136     
137         /*******************
138          * Default
139          *******************/
141         default: 
142         {
143           if(isset($data['LastError']) && !empty($data['LastError'])){
144             $ret[] = $data['LastError'];
145           }
146         }
147       }
148     }
149     return($ret);
150   }
151  
153   /* Recursivly create a sieve script out of the given 
154    *  tags and tokens provided by $parsed.
155    *  $id       specifies the depth of the current element.
156    *  $obj_id   is the current tag-id handled by this function
157    */
158   function get_sieve_script_part_recursive($parsed = NULL,$id = 1,$obj_id=1)
159   {
160     $script ="";
161     if($parsed == NULL){
162       $parsed = $this->_parsed;
163     }
166     if(!is_array($parsed)){
167       return;
168     }
170     /* Walk through all elements */
171     foreach($parsed as $key => $data){
173       /* Create Inverse Tag */
174       if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
175         $Inverse = TRUE;
176       }else{
177         $Inverse = FALSE;
178       }
180       /* Create elements */
181       switch($key)
182       {
184         /*******************
185          * True / False
186          *******************/
188         case "true" :
189         case "false" :
190         {
191           /* Invert this test if required */
192           if($Inverse){
193             $script .= "not ";
194           }
195           $script .= $key;
196           break;
197         }
200         /*******************
201          * Address
202          *******************/
204         case "address" :   
205         {
206           /* [not] address 
207                         [address-part: tag] 
208                         [comparator: tag] 
209                         [match-type: tag] 
210                         <header-list: string-list> 
211                         <key-list: string-list> 
212           */
214           /* Invert this test if required */
215           if($Inverse){
216             $script .= "not ";
217           }
218   
219           $script .="address ";
220  
221           /* Add address part tag */ 
222           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
223             $script .= $data['Address_Part']." ";
224           }
226           /* Add comparator */
227           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
228             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
229           }
230     
231           /* Add match type */
232           $script .= $data['Match_type']." ";
234           /* Add special match type for count and value */
235           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
236             $script .= sieve_create_strings($data['Match_type_value'])." ";
237           }
239           $script .= sieve_create_strings($data['Key_List']);
240           $script .= " ";
241           $script .= sieve_create_strings($data['Value_List']);
242           break;
243         }
246         /*******************
247          * Header
248          *******************/
250         case "header" :   
251         {
252           /* [not] header   
253                 [comparator: tag] 
254                 [match-type: tag] 
255                 <header-names: string-list> 
256                 <key-list: string-list>
257           */
259           /* Invert ? */
260           if($Inverse){
261             $script .= "not ";
262           }
263   
264           $script .="header ";
265  
266           /* Add address part tag */ 
267           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
268             $script .= $data['Address_Part']." ";
269           }
271           /* Add comparator */
272           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
273             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
274           }
275     
276           /* Add match type */
277           $script .= $data['Match_type']." ";
279           /* Add special match type for count and value */
280           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
281             $script .= sieve_create_strings($data['Match_type_value'])." ";
282           }
284           $script .= sieve_create_strings($data['Key_List']);
285           $script .= " ";
286           $script .= sieve_create_strings($data['Value_List']);
287           break;
288         }
291         /*******************
292          * Envelope
293          *******************/
295         case "envelope" :   
296         {
297           /* [not]  envelope 
298                     [address-part: tag] 
299                     [comparator: tag] 
300                     [match-type: tag] 
301                     <envelope-part: string-list> 
302                     <key-list: string-list> 
303           */
305           /* Invert */
306           if($Inverse){
307             $script .= "not ";
308           }
309   
310           $script .="envelope ";
311  
312           /* Add address part tag */ 
313           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
314             $script .= $data['Address_Part']." ";
315           }
317           /* Add comparator */
318           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
319             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
320           }
321     
322           /* Add match type */
323           $script .= $data['Match_type']." ";
325           /* Add special match type for count and value */
326           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
327             $script .= sieve_create_strings($data['Match_type_value'])." ";
328           }
330           $script .= sieve_create_strings($data['Key_List']);
331           $script .= " ";
332           $script .= sieve_create_strings($data['Value_List']);
333           break;
334         }
337         /*******************
338          * Exists
339          *******************/
340         case "exists" : 
341         {
342           /* [not] exists 
343               <header-names: string-list> 
344           */
346           /* Invert ? */
347           if($Inverse){
348             $script .= "not ";
349           }
351           $script .= "exists ".sieve_create_strings($data['Values']);
352           break;
353         }
356         /*******************
357          * Size
358          *******************/
359         case "size" : 
360         {
361           /* [not] size 
362                 <":over" / ":under"> 
363                 <limit: number> 
364           */
366           /* Invert ? */
367           if($Inverse){
368             $script .= "not ";
369           }
370  
371           /* Add size test */ 
372           $script .="size ";
373           $script .=$data['Match_type']." ";
374           foreach($data['Value_List'] as $val){
375             $script .= $val." ";
376           }
377           break;
378         }
381         /*******************
382          * Allof
383          *******************/
384         case "anyof" :
385         case "allof" :
386         {
387           /* allof <tests: test-list>
388              anyof <tests: test-list> */
390  
391           /* Add spaces, to indent the code.*/ 
392           $block = "\n";
393           for($i = 0 ; $i < $id ; $i ++){
394             $block .= SIEVE_INDENT_TAB;
395           }          
397           /* Add allof/anyof tag */
398           if($Inverse){
399             $script .= "not ";
400           }
401           $script.= $key." ( ";
403           /* Add each test parameter */
404           foreach($data as $key2 => $dat){
405             if(($key2 === "Inverse") && ($key2 == "Inverse")){
406               continue;
407             }
408             $script.= $block.$this->get_sieve_script_part_recursive($dat, ($id +1),$key2).", ";
409           }
410     
411           /* Remove last _,_ and close the tag */
412           $script = preg_replace("/,$/","",trim($script));
413           $script.= $block.")";
414           break ;
415         }
417         default :
418         {
419           $script .= "THERE IS SOME IMPLEMENTATION MISSING FOR SIEVE SCRIPT CREATION :".$key;
420         }
421       }
422     }
423     return($script);
424   }
426   
427   function add_test($data,$type)
428   {
429     switch($type)
430     {
431       case "header" : 
432       case "address" : 
433       case "envelope" : 
434       {
435         /* Add to Tree */
436         $values = array(        "Inverse"         => FALSE,
437                                 "Comparator"      => "",
438                                 "Expert"          => FALSE,
439                                 "LastError"       => "",
440                                 "Match_type"      => ":contains",
441                                 "Match_type_value"=> "",
442                                 "Key_List"        => array(_("emtpy")),
443                                 "Value_List"      => array(_("empty"))) ;
444         if($type == "address"){
445           $values["Address_Part"]    = ":all";
446         }
447         $data[$type]=$values;
449         $this->parent->add_require("relational");
450         if($type == "envelope"){
451           $this->parent->add_require("envelope");
452         }
453     
455         break;
456       }
457       case "allof" :
458       case "anyof" :
459       {
460         $data[$type] = array("Inverse" => FALSE);
461         break;
462       }
463       case "size" :
464       {
465         $tmp= array( 
466             "Inverse"    => FALSE,
467             "Match_type" => ":over",
468             "Value_List" => array("1M"));
470         $tmp['LastError'] = "";
471         $data[$type] = $tmp;
472         break;
473       }
474       case "true":
475       {
476         $data['true'] = "true";
477         $data['true']['LastError'] = "";
478         break;
479       }
480       case "false":
481       {
482         $data['false'] = "false";
483         $data['false']['LastError'] = "";
484         break;
485       }
486       case "exists" :
487       {
488         $data['exists'] = array('Inverse' => FALSE,
489                                 'Values'  => array(_("Nothing specified right now")),
490                                 'LastError' => "");
491         break;
492       }
493       default : echo "Still buggy ";exit;
494     }
496     return($data);
497   }
500   /* Ensure that all changes made on the ui 
501    *  will be saved. 
502    */
503   function save_object()
504   {
505   
506     if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$this->object_id])){
507       $this->_parsed = $this->add_test($this->_parsed,$_POST["test_type_to_add_".$this->object_id]);
508     }
510     $tmp = $this->save_object_recursive($parsed = NULL,$id = 1,$obj_id=1);
511     $this->_parsed = $tmp;
512   }
515   /* Recursivly save all ui changes for the 
516    *  tags and tokens provided by $parsed.
517    *  $id       specifies the depth of the current element.
518    *  $obj_id   is the current tag-id handled by this function
519    */
520   function save_object_recursive($parsed = NULL,$id = 1,$obj_id=1)
521   {
522     /* Variable initialization */ 
523     $ret ="";
524     if($parsed == NULL){
525       $parsed = $this->_parsed;
526     }
528     if(!is_array($parsed)) return;
530     /* Walk through all elements */
531     foreach($parsed as $key => $data){
533       /* Id used to have unique html names */
534       $element_id = $this->object_id."_".$id."_".$obj_id;
535       
536       foreach($_POST as $name => $value){
537         if(preg_match("/Remove_Test_Object_".$element_id."_(x|y)/",$name)) {
538           return(false); 
539         }
540       }
542       
543       if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$element_id])){
544         $parsed[$key][] = $this->add_test(array(),$_POST["test_type_to_add_".$element_id]);
545       }
547       /* Create elements */
548       switch($key)
549       {
550         /*******************
551          * Address 
552          *******************/
554         case "envelope" :
555         case "header" : 
556         case "address" : 
557         {
558           /* [not] address 
559                         [address-part: tag] 
560                         [comparator: tag] 
561                         [match-type: tag] 
562                         <header-list: string-list> 
563                         <key-list: string-list> 
564           */
566           /* Possible address parts we can select */
567           $address_parts = $this->address_parts;
568           $comparators   = $this->comparators;
569           $match_types   = $this->match_types; 
570           $operators     = $this->operators;
572           $parsed[$key]['LastError'] = "";
574           /* Toggle Inverse ? */
575           if(isset($_POST['toggle_inverse_'.$element_id])){
576             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
577           }
579           /* Check if we want to toggle the expert mode */
580           if(isset($_POST['Toggle_Expert_'.$element_id])){
581             $parsed[$key]['Expert'] = !$parsed[$key]['Expert'];
582           }
584           /* Get address part */
585           if(isset($_POST['address_part_'.$element_id])){
586             $ap = $_POST['address_part_'.$element_id];
588             if(!isset($address_parts[$ap])){
589               $parsed[$key]['LastError'] = _("Invalid type of address part.") ;
590             }
591             $parsed[$key]['Address_Part'] = $ap;
592           }
594           /* Check if match type has changed */
595           if(isset($_POST['matchtype_'.$element_id])){
596             $mt = $_POST['matchtype_'.$element_id];
598             if(!isset($match_types[$mt])){
599               $parsed[$key]['LastError'] = _("Invalid match type given.");
600             }
601             if($mt == ":regex"){
602               $this->parent->add_require("regex");
603             }
604             if($mt == ":count"){
605               $this->parent->add_require("comparator-i;ascii-numeric");
606             }
607             $parsed[$key]['Match_type'] = $mt;
608           }
610           /* Get the comparator tag, if posted */
611           if(isset($_POST['comparator_'.$element_id])){
612             $cp = $_POST['comparator_'.$element_id];
614             if(!isset($comparators[$cp])){
615               $parsed[$key]['LastError'] = _("Invalid operator given.");
616             }
617             $parsed[$key]['Comparator'] = $cp;
619             if($cp == "i;ascii-numeric"){
620               $this->parent->add_require("comparator-i;ascii-numeric");
621             }
622           }
624           /* In case of :count and :value match types 
625            *  we have a special match operator we should save.
626            */
627           if(in_array($parsed[$key]['Match_type'],array(":value",":count"))){
628             if(isset($_POST['operator_'.$element_id])){
629               $op = $_POST['operator_'.$element_id];
631               if(!isset($operators[$op])){
632                 $parsed[$key]['LastError'] = _("Please specify a valid operator.");
633               }
634               $parsed[$key]['Match_type_value'] = $op;
635             }
636           }
638           /* Get the address fields we should check, they are seperated by , */
639           if(isset($_POST['keys_'.$element_id])){
640             $vls = stripslashes($_POST['keys_'.$element_id]);
641             $tmp = array();
643             $tmp2 = split(",",$vls);
644             foreach($tmp2 as $val){
645               $tmp[] = trim($val);
646   
647               if(preg_match("/\"/",$val)){
648                 $parsed[$key]['LastError'] = _("Invalid character found in address attribute. Quotes are not allowed here.");
649               }
650             }
651             $parsed[$key]['Key_List'] = $tmp;
652           }
654           /* Get the values should check for, they are seperated by , */
655           if(isset($_POST['values_'.$element_id])){
656             $vls = stripslashes($_POST['values_'.$element_id]);
657             $tmp = array();
659             $tmp2 = split(",",$vls);
660             foreach($tmp2 as $val){
661               $tmp[] = trim($val);
662               if(preg_match("/\"/",$val)){
663                 $parsed[$key]['LastError'] = _("Invalid character found in value attribute. Quotes are not allowed here.");
664               }
665             }
666             $parsed[$key]['Value_List'] = $tmp;
667           }
668           break;
669         }
670  
671         /*******************
672          * TRUE FALSE 
673          *******************/
675         case "true" :
676         case "false" : 
677         {
678           $name = 'boolean_'.$element_id;
679           if(isset($_POST[$name])){
680             $key2 = $_POST[$name];
681             
682             if($key != $key2) {
683               $parsed = array($key2 => $key2); 
684             }
685           }
686           break;
687         }
689         /*******************
690          * Exists 
691          *******************/
693         case "exists" :
694         {
695           /* Toggle Inverse ? */
696           if(isset($_POST['toggle_inverse_'.$element_id])){
697             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
698           }
700           /* get list of match values */
701           if(isset($_POST['Values_'.$element_id])){
702             $vls = stripslashes($_POST['Values_'.$element_id]);
703             $tmp = array();          
704   
705             $tmp2 = split(",",$vls);
706             foreach($tmp2 as $val){
707               $tmp[] = "\"".trim(preg_replace("/\"/","",$val))."\"";
708             }
709             $parsed['exists']['Values'] = $tmp;
710           }
711           break;
712         }
714         /*******************
715          * Size 
716          *******************/
718         case "size" :
719         {
720           $Match_types = array( ":over" => _("greater than") ,
721                                 ":under" => _("lower than"));
723           $Units       = array( "M" => _("Megabyte"),
724                                 "K" => _("Kilobyte"),
725                                 ""  => _("Bytes"));
727           /* Toggle Inverse ? */
728           if(isset($_POST['toggle_inverse_'.$element_id])){
729             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
730           }
732           /* Reset error */
733           $parsed[$key]['LastError'] ="";
735           /* Get match type */
736           if(isset($_POST['Match_type_'.$element_id])){
737             $mt = $_POST['Match_type_'.$element_id];
738             if(!isset($Match_types[$mt])){
739               $parsed[$key]['LastError'] = _("Please select a valid match type in the list box below.");
740             }
741             $parsed[$key]['Match_type'] = $mt;
742           }
744           /* Get old values */
745           $value = preg_replace("/[^0-9]*$/","",$parsed[$key]['Value_List'][0]);
746           $unit  = preg_replace("/^[0-9]*/","",$parsed[$key]['Value_List'][0]);
748           /* Get value */
749           if(isset($_POST['Value_'.$element_id])){
750             $vl = $_POST['Value_'.$element_id];
751          
752             if(!(is_numeric($vl) && preg_match("/^[0-9]*$/",$vl))){
753               $parsed[$key]['LastError'] = _("Only numeric values are allowed here.");
754             }
755             $value = preg_replace("/[^0-9]/","",$vl);
756           }        
758           /* Get unit */
759           if(isset($_POST['Value_Unit_'.$element_id])){
760             $ut = $_POST['Value_Unit_'.$element_id];
761        
762             if(!isset($Units[$ut])){
763               $parsed[$key]['LastError'] = _("No valid unit selected");
764             }
765             $unit = $ut;
766           }       
767           $parsed[$key]['Value_List'] = array(); 
768           $parsed[$key]['Value_List'][0] = $value.$unit;
769           break;
770         }
772         /*******************
773          * Allof 
774          *******************/
775      
776         case "allof" : 
777         {
778           if(isset($_POST['toggle_inverse_'.$element_id])){
779             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
780           }
781           foreach($data as $key2 => $dat){
782             if(($key2 === "Inverse") && ($key2 == "Inverse")){
783               continue;
784             }
785             $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
786             if($tmp_data != false){
787               $parsed[$key][$key2] = $tmp_data;
788             }else{
789               unset( $parsed[$key][$key2]);
790             }
791           }
792           break ;
793         } 
795         /*******************
796          * Anyof 
797          *******************/
798      
799         case "anyof" : 
800         {
801           if(isset($_POST['toggle_inverse_'.$element_id])){
802             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
803           }
804           foreach($data as $key2 => $dat){
805             if(($key2 === "Inverse") && ($key2 == "Inverse")){
806               continue;
807             }
808             $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
809             if($tmp_data != false){
810               $parsed[$key][$key2] = $tmp_data;
811             }else{
812               unset( $parsed[$key][$key2]);
813             }
814           }
815           break ;
816         } 
817       }
818     } 
819     return($parsed);
820   }  
823   /* Return html element for IF */ 
824   function execute()
825   {
826     /* Create title */
827     $name  = "<img alt='' src='images/small_filter.png' class='center'>";
828     $name .= "<b>"._("Condition")."</b>";
829     if($this->TYPE == "if"){
830       $name .= "&nbsp;-&nbsp;"._("If");
831     }elseif($this->TYPE == "elsif"){
832       $name .= "&nbsp;-&nbsp;"._("Else if");
833     }else{
834       $name .= "&nbsp;-&nbsp;"._("Else");
835     }
837     $smarty = get_smarty();
838     $smarty->assign("ID", $this->object_id);
840     /* Only display navigation elements if necessary */
841     if($this->TYPE == "if"){
842       $object_container = $smarty->fetch(get_template_path("templates/object_container.tpl",TRUE,dirname(__FILE__)));
843     }else{
844       $object_container = $smarty->fetch(get_template_path("templates/object_container_clear.tpl",TRUE,dirname(__FILE__)));
845     }
847     $smarty->assign("Name", $name);
848     $smarty->assign("Contents", $this->get_as_html());
850     if($this->TYPE == "if"){
851       $object = $smarty->fetch(get_template_path("templates/element_if.tpl",TRUE,dirname(__FILE__)));
852     }else{
853       $object = $smarty->fetch(get_template_path("templates/element_elsif.tpl",TRUE,dirname(__FILE__)));
854     }
855     $str = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($object,"\\"),$object_container);
856     return($str);
857   }
859   
860   /* Returns all elements as html */
861   function get_as_html($parsed = NULL,$id = 1,$obj_id=1)
862   {
863     $ret ="";
864     if($parsed == NULL){
865       $parsed = $this->_parsed;
866     }
868     if((!is_array($parsed)) || !count($parsed)) {
869       $smarty = get_smarty();
870       $smarty->assign("ID",$this->object_id);
871       $smarty->assign("DisplayAdd",TRUE);
872       $smarty->assign("DisplayDel",FALSE);
873       $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
874       $ret .= preg_replace("/%%OBJECT_CONTENT%%/",_("Empty"),$str);
875       return($ret);
876     }
878     /* Walk through all elements */
879     foreach($parsed as $key => $data){
881       /* Create Inverse Tag */
882       if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
883         $Inverse = TRUE;
884       }else{
885         $Inverse = FALSE;
886       }
888       /* Id used to have unique html names */
889       $element_id = $this->object_id."_".$id."_".$obj_id;
891       /* Create elements */
892       switch($key)
893       {
894   
895         /*******************
896          * TRUE FALSE 
897          *******************/
899         case "true" :
900         case "false" : 
901         { 
902           /* Inverse element if required */
903           if($Inverse){        
904             if($key == "true"){
905               $key = "false";
906             }else{
907               $key = "true";
908             }           
909           }
911           /* Get template */
912           $smarty = get_smarty();
913           $smarty->assign("values"    , array("false" => _("False"), "true" => _("True")));
914           $smarty->assign("selected"  , $key); 
915           $smarty->assign("ID"  , $element_id); 
916           $ret .= $smarty->fetch(get_template_path("templates/element_boolean.tpl",TRUE,dirname(__FILE__)));
917           break;
918         }
921         /*******************
922          * Header 
923          *******************/
925         case "header": 
926         {
927           $address_parts = $this->address_parts;
928           $comparators   = $this->comparators;
929           $match_types   = $this->match_types; 
930           $operators     = $this->operators;
932           $smarty = get_smarty();
933           $smarty->assign("comparators",$comparators);
934           $smarty->assign("match_types",$match_types);
935           $smarty->assign("operators",$operators);
936           $smarty->assign("LastError",$data['LastError']);
937           $smarty->assign("match_type", $data['Match_type']);
938           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
939           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
941           $keys = "";
942           foreach($data['Key_List'] as $key){
943             $keys .= $key.", ";
944           }
945           $keys = preg_replace("/,$/","",trim($keys));
946    
947           $values = "";
948           foreach($data['Value_List'] as $key){
949             $values .= $key.", ";
950           }
951           $values = preg_replace("/,$/","",trim($values));
953           $smarty->assign("keys",$keys);
954           $smarty->assign("Inverse",$Inverse);
955           $smarty->assign("values",$values);
956           $smarty->assign("Expert", $data['Expert']);
957  
958           $smarty->assign("ID"  , $element_id); 
959           $ret .= $smarty->fetch(get_template_path("templates/element_header.tpl",TRUE,dirname(__FILE__)));
960           break;
961         }
964         /*******************
965          * Envelope 
966          *******************/
968         case "envelope":
969         {
970           $address_parts = $this->address_parts;
971           $comparators   = $this->comparators;
972           $match_types   = $this->match_types; 
973           $operators     = $this->operators;
975           $smarty = get_smarty();
976           $smarty->assign("Inverse",$Inverse);
977           $smarty->assign("comparators",$comparators);
978           $smarty->assign("Expert", $data['Expert']);
979           $smarty->assign("match_types",$match_types);
980           $smarty->assign("operators",$operators);
981           $smarty->assign("LastError",$data['LastError']);
982           $smarty->assign("match_type", $data['Match_type']);
983           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
984           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
986           $keys = "";
987           foreach($data['Key_List'] as $key){
988             $keys .= $key.", ";
989           }
990           $keys = preg_replace("/,$/","",trim($keys));
992           $values = "";
993           foreach($data['Value_List'] as $key){
994             $values .= $key.", ";
995           }
996           $values = preg_replace("/,$/","",trim($values));
997           $smarty->assign("keys",$keys);
998           $smarty->assign("values",$values);
1000           $smarty->assign("ID"  , $element_id); 
1001           $ret .= $smarty->fetch(get_template_path("templates/element_envelope.tpl",TRUE,dirname(__FILE__)));
1002           break;
1003         }
1006         /*******************
1007          * Address 
1008          *******************/
1010         case "address" : 
1011         {
1012           $address_parts = $this->address_parts;
1013           $comparators   = $this->comparators;
1014           $match_types   = $this->match_types; 
1015           $operators     = $this->operators;
1017           $smarty = get_smarty();
1018           $smarty->assign("Inverse",$Inverse);
1019           $smarty->assign("address_parts",$address_parts);
1020           $smarty->assign("comparators",$comparators);
1021           $smarty->assign("match_types",$match_types);
1022           $smarty->assign("LastError",$data['LastError']);
1023           $smarty->assign("operators",$operators);
1024           $smarty->assign("match_type", $data['Match_type']);
1025           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
1026           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
1027           $smarty->assign("address_part", $data['Address_Part']);
1028           $smarty->assign("Expert", $data['Expert']);
1029         
1030           $keys = "";
1031           foreach($data['Key_List'] as $key){
1032             $keys .= $key.", ";
1033           }
1034           $keys = preg_replace("/,$/","",trim($keys));
1035    
1036           $values = "";
1037           foreach($data['Value_List'] as $key){
1038             $values .= $key.", ";
1039           }
1040           $values = preg_replace("/,$/","",trim($values));
1042           $smarty->assign("keys",$keys);
1043           $smarty->assign("values", $values);
1044           $smarty->assign("ID"  , $element_id); 
1045           $str = $smarty->fetch(get_template_path("templates/element_address.tpl",TRUE,dirname(__FILE__)));
1046           $ret .= $str;
1047           break;
1048         }
1049       
1051         /*******************
1052          * Size 
1053          *******************/
1054         
1055         case "size" : 
1056         {
1057           $Match_types = array( ":over" => _("greater than") , 
1058                                 ":under" => _("lower than"));
1060           $Units       = array( "M" => _("Megabyte"),
1061                                 "K" => _("Kilobyte"),
1062                                 ""  => _("Bytes"));
1064           $Match_type   = $data['Match_type'];
1065           $Value        = preg_replace("/[^0-9]/","",$data['Value_List'][0]);
1066           $Value_Unit   = preg_replace("/[0-9]/","",$data['Value_List'][0]);
1067        
1068           $LastError = "";
1069           if(isset($data['LastError'])){
1070             $LastError = $data['LastError'];
1071           }
1072  
1073           $smarty = get_smarty();
1074           $smarty->assign("Inverse",$Inverse);
1075           $smarty->assign("LastError",$LastError);
1076           $smarty->assign("Match_types",$Match_types);
1077           $smarty->assign("Units",$Units);
1078           $smarty->assign("Match_type",$Match_type);
1079           $smarty->assign("Value",$Value);
1080           $smarty->assign("Value_Unit",$Value_Unit);
1081           $smarty->assign("ID"  , $element_id); 
1082           $ret .= $smarty->fetch(get_template_path("templates/element_size.tpl",TRUE,dirname(__FILE__)));
1083           break;
1084         }
1085         
1086         /*******************
1087          * Exists 
1088          *******************/
1089         
1090         case "exists" : 
1091         {
1092           $LastError = "";
1093           if(isset($data['LastError'])){
1094             $LastError = $data['LastError'];
1095           }
1096  
1097           $Values = "";
1098           foreach($data['Values'] as $val){
1099             $Values .= $val.", ";
1100           }
1101           $Values = preg_replace("/,$/","",trim($Values));
1103           $smarty = get_smarty();
1104           $smarty->assign("LastError",$LastError);
1105           $smarty->assign("Values",$Values);
1106           $smarty->assign("Inverse",$Inverse);
1107           $smarty->assign("ID"  , $element_id); 
1108           $ret .= $smarty->fetch(get_template_path("templates/element_exists.tpl",TRUE,dirname(__FILE__)));
1109           break;
1110         }
1111   
1113         /*******************
1114          * All of   
1115          *******************/
1117         case "allof" : 
1118         {
1119           $Contents = ""; 
1120           foreach($data as $key => $dat){
1121             if(($key === "Inverse") && ($key == "Inverse")){
1122               continue;
1123             }
1124             $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
1125           }
1127           $smarty = get_smarty();
1128           $smarty->assign("ID"  , $element_id); 
1129           $smarty->assign("DisplayAdd",TRUE);
1130           $smarty->assign("DisplayDel",FALSE);
1131           $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1132           $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/",_("Click here to add a new test"),$cont_tmp);
1134           $smarty->assign("Inverse",$Inverse);
1135           $smarty->assign("Contents",$cont_tmp.$Contents);
1136           $smarty->assign("ID"  , $element_id); 
1137           $allof_tmp = $smarty->fetch(get_template_path("templates/element_allof.tpl",TRUE,dirname(__FILE__)));
1139           $ret = $allof_tmp;
1140           break ;
1141         } 
1144         /*******************
1145          * Any of   
1146          *******************/
1148         case "anyof" : 
1149         {
1150           $Contents = ""; 
1151           foreach($data as $key => $dat){
1152             if(($key === "Inverse") && ($key == "Inverse")){
1153               continue;
1154             }
1155             $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
1156           }
1157           $smarty = get_smarty();
1158           $smarty->assign("ID"  , $element_id); 
1159           $smarty->assign("DisplayAdd",TRUE);
1160           $smarty->assign("DisplayDel",FALSE);
1161           $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1162           $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/",_("Klick here to add a new test"),$cont_tmp);
1164           $smarty->assign("Inverse",$Inverse);
1165           $smarty->assign("Contents",$cont_tmp.$Contents);
1166           $allof_tmp = $smarty->fetch(get_template_path("templates/element_anyof.tpl",TRUE,dirname(__FILE__)));
1168           $ret = $allof_tmp;
1170           break ;
1171         } 
1172         default : 
1173         {
1174           trigger_error(_("Unhandled switch type"));
1175         }
1176       }
1177     }
1178     
1179     if(!isset($smarty)){
1180       $smarty =get_smarty();
1181     }
1183     $smarty->assign("ID",$element_id);
1184     $smarty->assign("DisplayAdd",FALSE);
1185     $smarty->assign("DisplayDel",TRUE);
1186     $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1187     $ret = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($ret,"\\"),$str);
1188     return($ret);
1189   }
1192   /* Parse given token identified by $data[$id] 
1193    *  and return the parsed tokens. 
1194    */
1195   function _parse($data,$id = 0)
1196   {
1197     $av_match_type = array();
1198     foreach($this->match_types as $name => $description){
1199       $av_match_type[] = $name;
1200     }
1201     $av_match_type[] = ":over";
1202     $av_match_type[] = ":under";
1206     $av_methods= array("address","allof","anyof","exists","false","header","not","size","true","envelope");
1207     $type = $data[$id]['text'];
1208     $tmp = array();
1210     /* Is there an identifier named 'not' to inverse this filter ? */
1211     $Inverse = FALSE;
1212     if($data[$id]['class'] == "identifier" && $data[$id]['text'] == "not"){
1213       $Inverse = TRUE;
1214       $id ++;
1215       $type = $data[$id]['text'];
1216     }
1218     switch($type)
1219     {
1221       /****************
1222        * Parse - Envelope / Header / Address
1223        ****************/ 
1225       case "envelope" : 
1226       case "header":
1227       case "address" : 
1228       {
1229         /* Address matches are struckture as follows :
1230            [not] 
1231            address 
1232                   [address-part: tag]           all|localpart|domain|user|detail
1233                   [comparator: tag]             i;octet i;ascii-casemap i;ascii-numeric
1234                   [match-type: tag]             is|contains|matches|count|value 
1235                   <header-list: string-list> 
1236                   <key-list: string-list>   
1237           */ 
1238    
1239         
1240         $part     = "(:all|:localpart|:domain)";
1241         $operator = "(:regex|:contains|:is|:matches|:count|:value)";
1242         $value_op = "(lt|le|eq|ge|gt|ne)";
1244         $Address_Part     = "";
1245         $Comparator       = "";        
1246         $Match_type       = "";    
1247         $Match_type_value = "";
1248   
1249         $Key_List         = array();
1250         $Value_List       = array();
1251   
1252         for($i = 0 ; $i < count($data) ; $i ++){
1253          
1254           /* Get next node */ 
1255           $node = $data[$i];
1256   
1257           /* Check address part definition */
1258           if($node['class'] == "tag" && preg_match("/".$part."/i",$node['text'])){
1259             $Address_Part = $node['text'];
1260           }
1262           /* Check for match type  */
1263           elseif($node['class'] == "tag" && preg_match("/".$operator."/i",$node['text'])){
1264             $Match_type = $node['text'];
1266             /* Get value operator */
1267             if(in_array($Match_type,array(":value",":count"))){
1268               $i ++;        
1269               $node = $data[$i];
1271               if($node['class'] == "quoted-string" && preg_match("/".$value_op."/",$node['text'])){
1272                 $Match_type_value = $node['text'];
1273               }
1274             }
1275           } 
1277           /* Check for a comparator */
1278           elseif($node['class'] == "tag" && preg_match("/comparator/",$node['text'])){
1279             $i ++;
1280             $node = $data[$i];
1281             $Comparator = $node['text'];
1282           }
1283   
1284           /* Check for Key_List */  
1285           elseif(count(sieve_get_strings($data,$i))){
1286             $tmp2 = sieve_get_strings($data,$i);
1287             $i =  $tmp2['OFFSET'];
1289             if(!count($Key_List)){
1290               $Key_List = $tmp2['STRINGS'];
1291             }else{
1292               $Value_List = $tmp2['STRINGS']; 
1293             }
1294           } 
1295       
1296         }
1297  
1298          
1299         /* Add to Tree */ 
1300         $values = array( "Inverse"         => $Inverse,
1301                                 "Comparator"      => $Comparator,
1302                                 "Expert"          => FALSE,
1303                                 "Match_type"      => $Match_type,
1304                                 "Match_type_value"=> $Match_type_value,
1305                                 "Key_List"        => $Key_List,
1306                                 "Value_List"      => $Value_List) ;
1307         if($type == "address"){
1308           $values["Address_Part"]    = $Address_Part;
1309         }
1310         $tmp[$type] = $values;
1311         $tmp[$type]['LastError'] = "";
1312         break;
1313       }
1316       /****************
1317        * Parse - Size
1318        ****************/ 
1320       case "size":
1321       {
1322     
1323         $ops = "(:over|:under)";
1325         $Match_type = "";
1327         for($i = $id ; $i < count($data); $i++){
1329           /* Get current node */
1330           $node = $data[$i];
1332           /* Get tag (under / over) */
1333           if($node['class'] == "tag" && preg_match("/".$ops."/",$node['text'])){
1334             $Match_type = $node['text'];
1335           }
1336           
1337           /* Get Value_List, the value that we want to match for */
1338           elseif(count(sieve_get_strings($data,$i))){
1339             $tmp2 = sieve_get_strings($data,$i);
1340             $i =  $tmp2['OFFSET'];
1341           
1342             $Value_List = $tmp2['STRINGS'];
1343           } 
1344         }        
1345     
1346         $tmp[$type]= array( "Inverse"    => $Inverse,
1347                             "Match_type" => $Match_type,
1348                             "Value_List" => $Value_List);
1349         $tmp[$type]['LastError'] = "";
1350         break;
1351       }
1354       /****************
1355        * Parse - True / False
1356        ****************/ 
1358       case "true": 
1359       {
1360         $tmp['true'] = "true";
1361         $tmp['true']['LastError'] = "";
1362         break;
1363       }
1364       case "false":
1365       {
1366         $tmp['false'] = "false";
1367         $tmp['false']['LastError'] = "";
1368         break;
1369       }
1372       /****************
1373        * Parse - Exists
1374        ****************/ 
1376       case "exists":
1377       {
1378         
1379         /* Skip first values, [if,not,exists] */
1380         $node = $data[$id];
1381         while(in_array($node['text'],array("if","not","exists"))){
1382           $id ++;
1383           $node = $data[$id];
1384         }
1386         /* Get values */
1387         $tmp2 = sieve_get_strings($data,$id);
1388   
1389         
1390         $tmp['exists'] = array('Inverse' => $Inverse,
1391                                'Values'  => $tmp2['STRINGS']);
1392         $tmp[$type]['LastError'] = "";
1393         break;
1394       }
1397       /****************
1398        * Parse - Allof
1399        ****************/ 
1401       case "allof" :
1402       {
1403         /* Get parameter and recursivly call this method 
1404          *  for each parameter 
1405          */
1406         $id ++;
1407         $tmp2 = $this->get_parameter($data,$id);
1408         
1409         foreach($tmp2 as $parameter){
1410           $tmp['allof'][] = $this->_parse($parameter);
1411         }
1412         $tmp['allof']['Inverse'] = $Inverse;
1413         break;
1414       }
1417       /****************
1418        * Parse - Anyof
1419        ****************/ 
1421       case "anyof" :
1422       {
1423         /* Get parameter and recursivly call this method 
1424          *  for each parameter 
1425          */
1426         $id ++;
1427         $tmp2 = $this->get_parameter($data,$id);
1429         foreach($tmp2 as $parameter){
1430           $tmp['anyof'][] = $this->_parse($parameter);
1431         }
1432         $tmp['anyof']['Inverse'] = $Inverse;
1433         break;
1434       }
1435       default : $tmp[$id] = $type; 
1436     }
1437     
1438     return($tmp); 
1439   }
1442   function get_parameter($data,$id)
1443   {
1444     $par = array();
1445     $open_brakets = 0;
1446     $next = NULL;
1447     $num = 0;
1448     for($i = $id ; $i < count($data) ; $i++ ){
1449       if(in_array($data[$i]['class'],array("left-parant","left-bracket"))){
1450         $open_brakets ++;
1451       }
1452       if($data[$i]['class'] == "comma" && $open_brakets == 1){
1453         $num ++;
1454       }
1455       if(!in_array($data[$i]['class'],array("comma","left-parant","right-parant")) || $open_brakets >1 ){
1456         $par[$num][] = $data[$i];
1457       }
1458       if(in_array($data[$i]['class'],array("right-parant","right-bracket"))){
1459         $open_brakets --;
1460       }
1461     }
1462     return($par);
1463   }
1466 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1467 ?>