Code

d929e3fbe08acb8ba50e4585b161e2d967d9f6a6
[gosa.git] / gosa-plugins / mail / personal / mail / 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 address")."&nbsp;("._("Default").")",
28         ":domain"    => _("Domain 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"      => _("reg-ex"),
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     if($parsed === NULL) {
102         return(array(_("Can't save empty tests.")));
103     }
105     /* Walk through all elements */
106     foreach($parsed as $key => $data){
108       /* Create elements */
109       switch($key)
110       {
111         /*******************
112          * Allof / Anyof
113          *******************/
114         case "anyof" :
115         case "allof" :
116         { 
117           foreach($data as $key2 => $dat){
118             if(($key2 === "Inverse") && ($key2 == "Inverse")){
119               continue;
120             }
121             $msgs = $this->check_recursive($dat, ($id +1),$key2);
123             foreach($msgs as $msg){
124               $ret[] = $msg;
125             }
126           }
127           break;
128         }
130         /*******************
131          * True / False
132          *******************/
134         case "true" :
135         case "false" : 
136         {
137           /* Can't fail anyway */
138           break;
139         }
140     
141         /*******************
142          * Default
143          *******************/
145         default: 
146         {
147           if(isset($data['LastError']) && !empty($data['LastError'])){
148             $ret[] = $data['LastError'];
149           }
150         }
151       }
152     }
153     return($ret);
154   }
155  
157   /* Recursivly create a sieve script out of the given 
158    *  tags and tokens provided by $parsed.
159    *  $id       specifies the depth of the current element.
160    *  $obj_id   is the current tag-id handled by this function
161    */
162   function get_sieve_script_part_recursive($parsed = NULL,$id = 1,$obj_id=1)
163   {
164     $script ="";
165     if($parsed === NULL){
166       $parsed = $this->_parsed;
167     }
170     if(!is_array($parsed)){
171       return;
172     }
174     /* Walk through all elements */
175     foreach($parsed as $key => $data){
177       /* Create Inverse Tag */
178       if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
179         $Inverse = TRUE;
180       }else{
181         $Inverse = FALSE;
182       }
184       /* Create elements */
185       switch($key)
186       {
188         /*******************
189          * True / False
190          *******************/
192         case "true" :
193         case "false" :
194         {
195           /* Invert this test if required */
196           if($Inverse){
197             $script .= "not ";
198           }
199           $script .= $key;
200           break;
201         }
204         /*******************
205          * Address
206          *******************/
208         case "address" :   
209         {
210           /* [not] address 
211                         [address-part: tag] 
212                         [comparator: tag] 
213                         [match-type: tag] 
214                         <header-list: string-list> 
215                         <key-list: string-list> 
216           */
218           /* Invert this test if required */
219           if($Inverse){
220             $script .= "not ";
221           }
222   
223           $script .="address ";
224  
225           /* Add address part tag */ 
226           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
227             $script .= $data['Address_Part']." ";
228           }
230           /* Add comparator */
231           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
232             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
233           }
234     
235           /* Add match type */
236           $script .= $data['Match_type']." ";
238           /* Add special match type for count and value */
239           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
240             $script .= sieve_create_strings($data['Match_type_value'])." ";
241           }
243           $script .= sieve_create_strings($data['Key_List']);
244           $script .= " ";
245           $script .= sieve_create_strings($data['Value_List']);
246           break;
247         }
250         /*******************
251          * Header
252          *******************/
254         case "header" :   
255         {
256           /* [not] header   
257                 [comparator: tag] 
258                 [match-type: tag] 
259                 <header-names: string-list> 
260                 <key-list: string-list>
261           */
263           /* Invert ? */
264           if($Inverse){
265             $script .= "not ";
266           }
267   
268           $script .="header ";
269  
270           /* Add address part tag */ 
271           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
272             $script .= $data['Address_Part']." ";
273           }
275           /* Add comparator */
276           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
277             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
278           }
279     
280           /* Add match type */
281           $script .= $data['Match_type']." ";
283           /* Add special match type for count and value */
284           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
285             $script .= sieve_create_strings($data['Match_type_value'])." ";
286           }
288           $script .= sieve_create_strings($data['Key_List']);
289           $script .= " ";
290           $script .= sieve_create_strings($data['Value_List']);
291           break;
292         }
295         /*******************
296          * Envelope
297          *******************/
299         case "envelope" :   
300         {
301           /* [not]  envelope 
302                     [address-part: tag] 
303                     [comparator: tag] 
304                     [match-type: tag] 
305                     <envelope-part: string-list> 
306                     <key-list: string-list> 
307           */
309           /* Invert */
310           if($Inverse){
311             $script .= "not ";
312           }
313   
314           $script .="envelope ";
315  
316           /* Add address part tag */ 
317           if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
318             $script .= $data['Address_Part']." ";
319           }
321           /* Add comparator */
322           if(!empty($data['Comparator']) && $data['Comparator'] != ""){
323             $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
324           }
325     
326           /* Add match type */
327           $script .= $data['Match_type']." ";
329           /* Add special match type for count and value */
330           if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
331             $script .= sieve_create_strings($data['Match_type_value'])." ";
332           }
334           $script .= sieve_create_strings($data['Key_List']);
335           $script .= " ";
336           $script .= sieve_create_strings($data['Value_List']);
337           break;
338         }
341         /*******************
342          * Exists
343          *******************/
344         case "exists" : 
345         {
346           /* [not] exists 
347               <header-names: string-list> 
348           */
350           /* Invert ? */
351           if($Inverse){
352             $script .= "not ";
353           }
355           $script .= "exists ".sieve_create_strings($data['Values']);
356           break;
357         }
360         /*******************
361          * Size
362          *******************/
363         case "size" : 
364         {
365           /* [not] size 
366                 <":over" / ":under"> 
367                 <limit: number> 
368           */
370           /* Invert ? */
371           if($Inverse){
372             $script .= "not ";
373           }
374  
375           /* Add size test */ 
376           $script .="size ";
377           $script .=$data['Match_type']." ";
378           foreach($data['Value_List'] as $val){
379             $script .= $val." ";
380           }
381           break;
382         }
385         /*******************
386          * Allof
387          *******************/
388         case "anyof" :
389         case "allof" :
390         {
391           /* allof <tests: test-list>
392              anyof <tests: test-list> */
394  
395           /* Add spaces, to indent the code.*/ 
396           $block = "\n";
397           for($i = 0 ; $i < $id ; $i ++){
398             $block .= SIEVE_INDENT_TAB;
399           }          
401           /* Add allof/anyof tag */
402           if($Inverse){
403             $script .= "not ";
404           }
405           $script.= $key." ( ";
407           /* Add each test parameter */
408           foreach($data as $key2 => $dat){
409             if(($key2 === "Inverse") && ($key2 == "Inverse")){
410               continue;
411             }
412             $script.= $block.$this->get_sieve_script_part_recursive($dat, ($id +1),$key2).", ";
413           }
414     
415           /* Remove last _,_ and close the tag */
416           $script = preg_replace("/,$/","",trim($script));
417           $script.= $block.")";
418           break ;
419         }
421         default :
422         {
423           $script .= "THERE IS SOME IMPLEMENTATION MISSING FOR SIEVE SCRIPT CREATION :".$key;
424         }
425       }
426     }
427     return($script);
428   }
430   
431   function add_test($data,$type)
432   {
433     switch($type)
434     {
435       case "header" : 
436       case "address" : 
437       case "envelope" : 
438       {
439         /* Add to Tree */
440         $values = array(        "Inverse"         => FALSE,
441                                 "Comparator"      => "",
442                                 "Expert"          => FALSE,
443                                 "LastError"       => "",
444                                 "Match_type"      => ":contains",
445                                 "Match_type_value"=> "",
446                                 "Key_List"        => array(_("empty")),
447                                 "Value_List"      => array(_("empty"))) ;
448         if($type == "address"){
449           $values["Address_Part"]    = ":all";
450         }
451         $data[$type]=$values;
453         $this->parent->add_require("relational");
454         if($type == "envelope"){
455           $this->parent->add_require("envelope");
456         }
457     
459         break;
460       }
461       case "allof" :
462       case "anyof" :
463       {
464         $data[$type] = array("Inverse" => FALSE);
465         break;
466       }
467       case "size" :
468       {
469         $tmp= array( 
470             "Inverse"    => FALSE,
471             "Match_type" => ":over",
472             "Value_List" => array("1M"));
474         $tmp['LastError'] = "";
475         $data[$type] = $tmp;
476         break;
477       }
478       case "true":
479       {
480         $data['true'] = "true";
481         $data['true']['LastError'] = "";
482         break;
483       }
484       case "false":
485       {
486         $data['false'] = "false";
487         $data['false']['LastError'] = "";
488         break;
489       }
490       case "exists" :
491       {
492         $data['exists'] = array('Inverse' => FALSE,
493                                 'Values'  => array(_("Nothing specified right now")),
494                                 'LastError' => "");
495         break;
496       }
497       default : echo "Still buggy ";exit;
498     }
500     return($data);
501   }
504   /* Ensure that all changes made on the ui 
505    *  will be saved. 
506    */
507   function save_object()
508   {
509   
510     if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$this->object_id])){
511       $this->_parsed = $this->add_test($this->_parsed,$_POST["test_type_to_add_".$this->object_id]);
512     }
514     $tmp = $this->save_object_recursive($parsed = NULL,$id = 1,$obj_id=1);
515     $this->_parsed = $tmp;
516   }
519   /* Recursivly save all ui changes for the 
520    *  tags and tokens provided by $parsed.
521    *  $id       specifies the depth of the current element.
522    *  $obj_id   is the current tag-id handled by this function
523    */
524   function save_object_recursive($parsed = NULL,$id = 1,$obj_id=1)
525   {
526     /* Variable initialization */ 
527     $ret ="";
528     if($parsed === NULL){
529       $parsed = $this->_parsed;
530     }
532     if(!is_array($parsed)) {
533       return;
534     }
536     /* Walk through all elements */
537     foreach($parsed as $key => $data){
539       /* Id used to have unique html names */
540       $element_id = $this->object_id."_".$id."_".$obj_id;
541       
542       foreach($_POST as $name => $value){
543         if(preg_match("/Remove_Test_Object_".$element_id."/",$name)) {
544           return(false); 
545         }
546       }
548       
549       if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$element_id])){
550         $parsed[$key][] = $this->add_test(array(),$_POST["test_type_to_add_".$element_id]);
551       }
553       /* Create elements */
554       switch($key)
555       {
556         /*******************
557          * Address 
558          *******************/
560         case "envelope" :
561         case "header" : 
562         case "address" : 
563         {
564           /* [not] address 
565                         [address-part: tag] 
566                         [comparator: tag] 
567                         [match-type: tag] 
568                         <header-list: string-list> 
569                         <key-list: string-list> 
570           */
572           /* Possible address parts we can select */
573           $address_parts = $this->address_parts;
574           $comparators   = $this->comparators;
575           $match_types   = $this->match_types; 
576           $operators     = $this->operators;
578           $parsed[$key]['LastError'] = "";
580           /* Toggle Inverse ? */
581           if(isset($_POST['toggle_inverse_'.$element_id])){
582             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
583           }
585           /* Check if we want to toggle the expert mode */
586           if(isset($_POST['Toggle_Expert_'.$element_id])){
587             $parsed[$key]['Expert'] = !$parsed[$key]['Expert'];
588           }
590           /* Get address part */
591           if(isset($_POST['address_part_'.$element_id])){
592             $ap = $_POST['address_part_'.$element_id];
594             if(!isset($address_parts[$ap])){
595               $parsed[$key]['LastError'] = _("Invalid type of address part.") ;
596             }
597             $parsed[$key]['Address_Part'] = $ap;
598           }
600           /* Check if match type has changed */
601           if(isset($_POST['matchtype_'.$element_id])){
602             $mt = $_POST['matchtype_'.$element_id];
604             if(!isset($match_types[$mt])){
605               $parsed[$key]['LastError'] = _("Invalid match type given.");
606             }
607             if($mt == ":regex"){
608               $this->parent->add_require("regex");
609             }
610             if($mt == ":count"){
611               $this->parent->add_require("comparator-i;ascii-numeric");
612             }
613             $parsed[$key]['Match_type'] = $mt;
614           }
616           /* Get the comparator tag, if posted */
617           if(isset($_POST['comparator_'.$element_id])){
618             $cp = $_POST['comparator_'.$element_id];
620             if(!isset($comparators[$cp])){
621               $parsed[$key]['LastError'] = _("Invalid operator given.");
622             }
623             $parsed[$key]['Comparator'] = $cp;
625             if($cp == "i;ascii-numeric"){
626               $this->parent->add_require("comparator-i;ascii-numeric");
627             }
628           }
630           /* In case of :count and :value match types 
631            *  we have a special match operator we should save.
632            */
633           if(in_array($parsed[$key]['Match_type'],array(":value",":count"))){
634             if(isset($_POST['operator_'.$element_id])){
635               $op = $_POST['operator_'.$element_id];
637               if(!isset($operators[$op])){
638                 $parsed[$key]['LastError'] = _("Please specify a valid operator.");
639               }
640               $parsed[$key]['Match_type_value'] = $op;
641             }
642           }
644           /* Get the address fields we should check, they are seperated by , */
645           if(isset($_POST['keys_'.$element_id])){
646             $vls = stripslashes($_POST['keys_'.$element_id]);
647             $tmp = array();
649             $tmp2 = explode(",",$vls);
650             foreach($tmp2 as $val){
651               $tmp[] = trim($val);
652   
653               if(preg_match("/\"/",$val)){
654                 $parsed[$key]['LastError'] = _("Invalid character found in address attribute. Quotes are not allowed here.");
655               }
656             }
657             $parsed[$key]['Key_List'] = $tmp;
658           }
660           /* Get the values should check for, they are seperated by , */
661           if(isset($_POST['values_'.$element_id])){
662             $vls = stripslashes($_POST['values_'.$element_id]);
663             $tmp = array();
665             $tmp2 = explode(",",$vls);
666             foreach($tmp2 as $val){
667               $tmp[] = trim($val);
668               if(preg_match("/\"/",$val)){
669                 $parsed[$key]['LastError'] = _("Invalid character found in value attribute. Quotes are not allowed here.");
670               }
671             }
672             $parsed[$key]['Value_List'] = $tmp;
673           }
674           break;
675         }
676  
677         /*******************
678          * TRUE FALSE 
679          *******************/
681         case "true" :
682         case "false" : 
683         {
684           $name = 'boolean_'.$element_id;
685           if(isset($_POST[$name])){
686             $key2 = $_POST[$name];
687             
688             if($key != $key2) {
689               $parsed = array($key2 => $key2); 
690             }
691           }
692           break;
693         }
695         /*******************
696          * Exists 
697          *******************/
699         case "exists" :
700         {
701           /* Toggle Inverse ? */
702           if(isset($_POST['toggle_inverse_'.$element_id])){
703             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
704           }
706           /* get list of match values */
707           if(isset($_POST['Values_'.$element_id])){
708             $vls = stripslashes($_POST['Values_'.$element_id]);
709             $tmp = array();          
710   
711             $tmp2 = explode(",",$vls);
712             foreach($tmp2 as $val){
713               $tmp[] = "\"".trim(preg_replace("/\"/","",$val))."\"";
714             }
715             $parsed['exists']['Values'] = $tmp;
716           }
717           break;
718         }
720         /*******************
721          * Size 
722          *******************/
724         case "size" :
725         {
726           $Match_types = array( ":over" => _("greater than") ,
727                                 ":under" => _("lower than"));
729           $Units       = array( "M" => _("Megabyte"),
730                                 "K" => _("Kilobyte"),
731                                 ""  => _("Bytes"));
733           /* Toggle Inverse ? */
734           if(isset($_POST['toggle_inverse_'.$element_id])){
735             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
736           }
738           /* Reset error */
739           $parsed[$key]['LastError'] ="";
741           /* Get match type */
742           if(isset($_POST['Match_type_'.$element_id])){
743             $mt = $_POST['Match_type_'.$element_id];
744             if(!isset($Match_types[$mt])){
745               $parsed[$key]['LastError'] = _("Please select a valid match type in the list box below.");
746             }
747             $parsed[$key]['Match_type'] = $mt;
748           }
750           /* Get old values */
751           $value = preg_replace("/[^0-9]*$/","",$parsed[$key]['Value_List'][0]);
752           $unit  = preg_replace("/^[0-9]*/","",$parsed[$key]['Value_List'][0]);
754           /* Get value */
755           if(isset($_POST['Value_'.$element_id])){
756             $vl = $_POST['Value_'.$element_id];
757          
758             if(!(is_numeric($vl) && preg_match("/^[0-9]*$/",$vl))){
759               $parsed[$key]['LastError'] = _("Only numeric values are allowed here.");
760             }
761             $value = preg_replace("/[^0-9]/","",$vl);
762           }        
764           /* Get unit */
765           if(isset($_POST['Value_Unit_'.$element_id])){
766             $ut = $_POST['Value_Unit_'.$element_id];
767        
768             if(!isset($Units[$ut])){
769               $parsed[$key]['LastError'] = _("No valid unit selected");
770             }
771             $unit = $ut;
772           }       
773           $parsed[$key]['Value_List'] = array(); 
774           $parsed[$key]['Value_List'][0] = $value.$unit;
775           break;
776         }
778         /*******************
779          * Allof 
780          *******************/
781      
782         case "allof" : 
783         {
784           if(isset($_POST['toggle_inverse_'.$element_id])){
785             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
786           }
787           foreach($data as $key2 => $dat){
788             if(($key2 === "Inverse") && ($key2 == "Inverse")){
789               continue;
790             }
791             $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
792             if($tmp_data != false){
793               $parsed[$key][$key2] = $tmp_data;
794             }else{
795               unset( $parsed[$key][$key2]);
796             }
797           }
798           break ;
799         } 
801         /*******************
802          * Anyof 
803          *******************/
804      
805         case "anyof" : 
806         {
807           if(isset($_POST['toggle_inverse_'.$element_id])){
808             $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
809           }
810           foreach($data as $key2 => $dat){
811             if(($key2 === "Inverse") && ($key2 == "Inverse")){
812               continue;
813             }
814             $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
815             if($tmp_data != false){
816               $parsed[$key][$key2] = $tmp_data;
817             }else{
818               unset( $parsed[$key][$key2]);
819             }
820           }
821           break ;
822         } 
823       }
824     } 
825     return($parsed);
826   }  
829   /* Return html element for IF */ 
830   function execute()
831   {
832     /* Create title */
833     $name  = "<img alt='' src='images/lists/action.png' class='center'>";
834     $name .= "<b>"._("Condition")."</b>";
835     if($this->TYPE == "if"){
836       $name .= "&nbsp;-&nbsp;"._("If");
837     }elseif($this->TYPE == "elsif"){
838       $name .= "&nbsp;-&nbsp;"._("Else If");
839     }else{
840       $name .= "&nbsp;-&nbsp;"._("Else");
841     }
843     $smarty = get_smarty();
844     $smarty->assign("ID", $this->object_id);
846     /* Get navigation element container */
847     $object_container = $smarty->fetch(get_template_path("templates/object_container.tpl",TRUE,dirname(__FILE__)));
849     $smarty->assign("Name", $name);
850     $smarty->assign("Contents", $this->get_as_html());
852     if($this->TYPE == "if"){
853       $object = $smarty->fetch(get_template_path("templates/element_if.tpl",TRUE,dirname(__FILE__)));
854     }else{
855       $object = $smarty->fetch(get_template_path("templates/element_elsif.tpl",TRUE,dirname(__FILE__)));
856     }
857     $str = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($object,"\\"),$object_container);
858     return($str);
859   }
861   
862   /* Returns all elements as html */
863   function get_as_html($parsed = NULL,$id = 1,$obj_id=1)
864   {
865     $ret ="";
866     if($parsed === NULL){
867       $parsed = $this->_parsed;
868     }
870     if((!is_array($parsed)) || !count($parsed)) {
871       $smarty = get_smarty();
872       $smarty->assign("ID",$this->object_id);
873       $smarty->assign("DisplayAdd",TRUE);
874       $smarty->assign("DisplayDel",FALSE);
875       $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
876       $ret .= preg_replace("/%%OBJECT_CONTENT%%/",_("Empty"),$str);
877       return($ret);
878     }
880     /* Walk through all elements */
881     foreach($parsed as $key => $data){
883       /* Create Inverse Tag */
884       if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
885         $Inverse = TRUE;
886       }else{
887         $Inverse = FALSE;
888       }
890       /* Id used to have unique html names */
891       $element_id = $this->object_id."_".$id."_".$obj_id;
893       /* Create elements */
894       switch($key)
895       {
896   
897         /*******************
898          * TRUE FALSE 
899          *******************/
901         case "true" :
902         case "false" : 
903         { 
904           /* Inverse element if required */
905           if($Inverse){        
906             if($key == "true"){
907               $key = "false";
908             }else{
909               $key = "true";
910             }           
911           }
913           /* Get template */
914           $smarty = get_smarty();
915           $smarty->assign("values"    , array("false" => _("False"), "true" => _("True")));
916           $smarty->assign("selected"  , $key); 
917           $smarty->assign("ID"  , $element_id); 
918           $ret .= $smarty->fetch(get_template_path("templates/element_boolean.tpl",TRUE,dirname(__FILE__)));
919           break;
920         }
923         /*******************
924          * Header 
925          *******************/
927         case "header": 
928         {
929           $address_parts = $this->address_parts;
930           $comparators   = $this->comparators;
931           $match_types   = $this->match_types; 
932           $operators     = $this->operators;
934           $smarty = get_smarty();
935           $smarty->assign("comparators",$comparators);
936           $smarty->assign("match_types",$match_types);
937           $smarty->assign("operators",$operators);
938           $smarty->assign("LastError",$data['LastError']);
939           $smarty->assign("match_type", $data['Match_type']);
940           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
941           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
943           $keys = "";
944           foreach($data['Key_List'] as $key){
945             $keys .= $key.", ";
946           }
947           $keys = preg_replace("/,$/","",trim($keys));
948    
949           $values = "";
950           foreach($data['Value_List'] as $key){
951             $values .= $key.", ";
952           }
953           $values = preg_replace("/,$/","",trim($values));
955           $smarty->assign("keys",$keys);
956           $smarty->assign("Inverse",$Inverse);
957           $smarty->assign("values",$values);
958           $smarty->assign("Expert", $data['Expert']);
959  
960           $smarty->assign("ID"  , $element_id); 
961           $ret .= $smarty->fetch(get_template_path("templates/element_header.tpl",TRUE,dirname(__FILE__)));
962           break;
963         }
966         /*******************
967          * Envelope 
968          *******************/
970         case "envelope":
971         {
972           $address_parts = $this->address_parts;
973           $comparators   = $this->comparators;
974           $match_types   = $this->match_types; 
975           $operators     = $this->operators;
977           $smarty = get_smarty();
978           $smarty->assign("Inverse",$Inverse);
979           $smarty->assign("comparators",$comparators);
980           $smarty->assign("Expert", $data['Expert']);
981           $smarty->assign("match_types",$match_types);
982           $smarty->assign("operators",$operators);
983           $smarty->assign("LastError",$data['LastError']);
984           $smarty->assign("match_type", $data['Match_type']);
985           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
986           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
988           $keys = "";
989           foreach($data['Key_List'] as $key){
990             $keys .= $key.", ";
991           }
992           $keys = preg_replace("/,$/","",trim($keys));
994           $values = "";
995           foreach($data['Value_List'] as $key){
996             $values .= $key.", ";
997           }
998           $values = preg_replace("/,$/","",trim($values));
999           $smarty->assign("keys",$keys);
1000           $smarty->assign("values",$values);
1002           $smarty->assign("ID"  , $element_id); 
1003           $ret .= $smarty->fetch(get_template_path("templates/element_envelope.tpl",TRUE,dirname(__FILE__)));
1004           break;
1005         }
1008         /*******************
1009          * Address 
1010          *******************/
1012         case "address" : 
1013         {
1014           $address_parts = $this->address_parts;
1015           $comparators   = $this->comparators;
1016           $match_types   = $this->match_types; 
1017           $operators     = $this->operators;
1019           $smarty = get_smarty();
1020           $smarty->assign("Inverse",$Inverse);
1021           $smarty->assign("address_parts",$address_parts);
1022           $smarty->assign("comparators",$comparators);
1023           $smarty->assign("match_types",$match_types);
1024           $smarty->assign("LastError",$data['LastError']);
1025           $smarty->assign("operators",$operators);
1026           $smarty->assign("match_type", $data['Match_type']);
1027           $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
1028           $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
1029           $smarty->assign("address_part", $data['Address_Part']);
1030           $smarty->assign("Expert", $data['Expert']);
1031         
1032           $keys = "";
1033           foreach($data['Key_List'] as $key){
1034             $keys .= $key.", ";
1035           }
1036           $keys = preg_replace("/,$/","",trim($keys));
1037    
1038           $values = "";
1039           foreach($data['Value_List'] as $key){
1040             $values .= $key.", ";
1041           }
1042           $values = preg_replace("/,$/","",trim($values));
1044           $smarty->assign("keys",$keys);
1045           $smarty->assign("values", $values);
1046           $smarty->assign("ID"  , $element_id); 
1047           $str = $smarty->fetch(get_template_path("templates/element_address.tpl",TRUE,dirname(__FILE__)));
1048           $ret .= $str;
1049           break;
1050         }
1051       
1053         /*******************
1054          * Size 
1055          *******************/
1056         
1057         case "size" : 
1058         {
1059           $Match_types = array( ":over" => _("greater than") , 
1060                                 ":under" => _("lower than"));
1062           $Units       = array( "M" => _("Megabyte"),
1063                                 "K" => _("Kilobyte"),
1064                                 ""  => _("Bytes"));
1066           $Match_type   = $data['Match_type'];
1067           $Value        = preg_replace("/[^0-9]/","",$data['Value_List'][0]);
1068           $Value_Unit   = preg_replace("/[0-9]/","",$data['Value_List'][0]);
1069        
1070           $LastError = "";
1071           if(isset($data['LastError'])){
1072             $LastError = $data['LastError'];
1073           }
1074  
1075           $smarty = get_smarty();
1076           $smarty->assign("Inverse",$Inverse);
1077           $smarty->assign("LastError",$LastError);
1078           $smarty->assign("Match_types",$Match_types);
1079           $smarty->assign("Units",$Units);
1080           $smarty->assign("Match_type",$Match_type);
1081           $smarty->assign("Value",$Value);
1082           $smarty->assign("Value_Unit",$Value_Unit);
1083           $smarty->assign("ID"  , $element_id); 
1084           $ret .= $smarty->fetch(get_template_path("templates/element_size.tpl",TRUE,dirname(__FILE__)));
1085           break;
1086         }
1087         
1088         /*******************
1089          * Exists 
1090          *******************/
1091         
1092         case "exists" : 
1093         {
1094           $LastError = "";
1095           if(isset($data['LastError'])){
1096             $LastError = $data['LastError'];
1097           }
1098  
1099           $Values = "";
1100           foreach($data['Values'] as $val){
1101             $Values .= $val.", ";
1102           }
1103           $Values = preg_replace("/,$/","",trim($Values));
1105           $smarty = get_smarty();
1106           $smarty->assign("LastError",$LastError);
1107           $smarty->assign("Values",$Values);
1108           $smarty->assign("Inverse",$Inverse);
1109           $smarty->assign("ID"  , $element_id); 
1110           $ret .= $smarty->fetch(get_template_path("templates/element_exists.tpl",TRUE,dirname(__FILE__)));
1111           break;
1112         }
1113   
1115         /*******************
1116          * All of   
1117          *******************/
1119         case "allof" : 
1120         {
1121           $Contents = ""; 
1122           foreach($data as $key => $dat){
1123             if(($key === "Inverse") && ($key == "Inverse")){
1124               continue;
1125             }
1126             $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
1127           }
1129           $smarty = get_smarty();
1130           $smarty->assign("ID"  , $element_id); 
1131           $smarty->assign("DisplayAdd",TRUE);
1132           $smarty->assign("DisplayDel",FALSE);
1133           $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1134           $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/","<b>"._("Click here to add a new test")."</b>",$cont_tmp);
1136           $smarty->assign("Inverse",$Inverse);
1137           $smarty->assign("Contents",$cont_tmp.$Contents);
1138           $smarty->assign("ID"  , $element_id); 
1139           $allof_tmp = $smarty->fetch(get_template_path("templates/element_allof.tpl",TRUE,dirname(__FILE__)));
1141           $ret = $allof_tmp;
1142           break ;
1143         } 
1146         /*******************
1147          * Any of   
1148          *******************/
1150         case "anyof" : 
1151         {
1152           $Contents = ""; 
1153           foreach($data as $key => $dat){
1154             if(($key === "Inverse") && ($key == "Inverse")){
1155               continue;
1156             }
1157             $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
1158           }
1159           $smarty = get_smarty();
1160           $smarty->assign("ID"  , $element_id); 
1161           $smarty->assign("DisplayAdd",TRUE);
1162           $smarty->assign("DisplayDel",FALSE);
1163           $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1164           $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/",_("Click here to add a new test"),$cont_tmp);
1166           $smarty->assign("Inverse",$Inverse);
1167           $smarty->assign("Contents",$cont_tmp.$Contents);
1168           $allof_tmp = $smarty->fetch(get_template_path("templates/element_anyof.tpl",TRUE,dirname(__FILE__)));
1170           $ret = $allof_tmp;
1172           break ;
1173         } 
1174         default : 
1175         {
1176           trigger_error(_("Unknown switch type"));
1177         }
1178       }
1179     }
1180     
1181     if(!isset($smarty)){
1182       $smarty =get_smarty();
1183     }
1185     $smarty->assign("ID",$element_id);
1186     $smarty->assign("DisplayAdd",FALSE);
1187     $smarty->assign("DisplayDel",TRUE);
1188     $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
1189     $ret = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($ret,"\\"),$str);
1190     return($ret);
1191   }
1194   /* Parse given token identified by $data[$id] 
1195    *  and return the parsed tokens. 
1196    */
1197   function _parse($data,$id = 0)
1198   {
1199     $av_match_type = array();
1200     foreach($this->match_types as $name => $description){
1201       $av_match_type[] = $name;
1202     }
1203     $av_match_type[] = ":over";
1204     $av_match_type[] = ":under";
1208     $av_methods= array("address","allof","anyof","exists","false","header","not","size","true","envelope");
1209     $type = $data[$id]['text'];
1210     $tmp = array();
1212     /* Is there an identifier named 'not' to inverse this filter ? */
1213     $Inverse = FALSE;
1214     if($data[$id]['class'] == "identifier" && $data[$id]['text'] == "not"){
1215       $Inverse = TRUE;
1216       $id ++;
1217       $type = $data[$id]['text'];
1218     }
1220     switch($type)
1221     {
1223       /****************
1224        * Parse - Envelope / Header / Address
1225        ****************/ 
1227       case "envelope" : 
1228       case "header":
1229       case "address" : 
1230       {
1231         /* Address matches are struckture as follows :
1232            [not] 
1233            address 
1234                   [address-part: tag]           all|localpart|domain|user|detail
1235                   [comparator: tag]             i;octet i;ascii-casemap i;ascii-numeric
1236                   [match-type: tag]             is|contains|matches|count|value 
1237                   <header-list: string-list> 
1238                   <key-list: string-list>   
1239           */ 
1240    
1241         
1242         $part     = "(:all|:localpart|:domain)";
1243         $operator = "(:regex|:contains|:is|:matches|:count|:value)";
1244         $value_op = "(lt|le|eq|ge|gt|ne)";
1246         $Address_Part     = "";
1247         $Comparator       = "";        
1248         $Match_type       = "";    
1249         $Match_type_value = "";
1250   
1251         $Key_List         = array();
1252         $Value_List       = array();
1253   
1254         for($i = 0 ; $i < count($data) ; $i ++){
1255          
1256           /* Get next node */ 
1257           $node = $data[$i];
1258   
1259           /* Check address part definition */
1260           if($node['class'] == "tag" && preg_match("/".$part."/i",$node['text'])){
1261             $Address_Part = $node['text'];
1262           }
1264           /* Check for match type  */
1265           elseif($node['class'] == "tag" && preg_match("/".$operator."/i",$node['text'])){
1266             $Match_type = $node['text'];
1268             /* Get value operator */
1269             if(in_array($Match_type,array(":value",":count"))){
1270               $i ++;        
1271               $node = $data[$i];
1273               if($node['class'] == "quoted-string" && preg_match("/".$value_op."/",$node['text'])){
1274                 $Match_type_value = $node['text'];
1275               }
1276             }
1277           } 
1279           /* Check for a comparator */
1280           elseif($node['class'] == "tag" && preg_match("/comparator/",$node['text'])){
1281             $i ++;
1282             $node = $data[$i];
1283             $Comparator = $node['text'];
1284           }
1285   
1286           /* Check for Key_List */  
1287           elseif(count(sieve_get_strings($data,$i))){
1288             $tmp2 = sieve_get_strings($data,$i);
1289             $i =  $tmp2['OFFSET'];
1291             if(!count($Key_List)){
1292               $Key_List = $tmp2['STRINGS'];
1293             }else{
1294               $Value_List = $tmp2['STRINGS']; 
1295             }
1296           } 
1297       
1298         }
1299  
1300          
1301         /* Add to Tree */ 
1302         $values = array( "Inverse"         => $Inverse,
1303                                 "Comparator"      => $Comparator,
1304                                 "Expert"          => FALSE,
1305                                 "Match_type"      => $Match_type,
1306                                 "Match_type_value"=> $Match_type_value,
1307                                 "Key_List"        => $Key_List,
1308                                 "Value_List"      => $Value_List) ;
1309         if($type == "address"){
1310           $values["Address_Part"]    = $Address_Part;
1311         }
1312         $tmp[$type] = $values;
1313         $tmp[$type]['LastError'] = "";
1314         break;
1315       }
1318       /****************
1319        * Parse - Size
1320        ****************/ 
1322       case "size":
1323       {
1324     
1325         $ops = "(:over|:under)";
1327         $Match_type = "";
1329         for($i = $id ; $i < count($data); $i++){
1331           /* Get current node */
1332           $node = $data[$i];
1334           /* Get tag (under / over) */
1335           if($node['class'] == "tag" && preg_match("/".$ops."/",$node['text'])){
1336             $Match_type = $node['text'];
1337           }
1338           
1339           /* Get Value_List, the value that we want to match for */
1340           elseif(count(sieve_get_strings($data,$i))){
1341             $tmp2 = sieve_get_strings($data,$i);
1342             $i =  $tmp2['OFFSET'];
1343           
1344             $Value_List = $tmp2['STRINGS'];
1345           } 
1346         }        
1347     
1348         $tmp[$type]= array( "Inverse"    => $Inverse,
1349                             "Match_type" => $Match_type,
1350                             "Value_List" => $Value_List);
1351         $tmp[$type]['LastError'] = "";
1352         break;
1353       }
1356       /****************
1357        * Parse - True / False
1358        ****************/ 
1360       case "true": 
1361       {
1362         $tmp['true'] = "true";
1363         $tmp['true']['LastError'] = "";
1364         break;
1365       }
1366       case "false":
1367       {
1368         $tmp['false'] = "false";
1369         $tmp['false']['LastError'] = "";
1370         break;
1371       }
1374       /****************
1375        * Parse - Exists
1376        ****************/ 
1378       case "exists":
1379       {
1380         
1381         /* Skip first values, [if,not,exists] */
1382         $node = $data[$id];
1383         while(in_array($node['text'],array("if","not","exists"))){
1384           $id ++;
1385           $node = $data[$id];
1386         }
1388         /* Get values */
1389         $tmp2 = sieve_get_strings($data,$id);
1390   
1391         
1392         $tmp['exists'] = array('Inverse' => $Inverse,
1393                                'Values'  => $tmp2['STRINGS']);
1394         $tmp[$type]['LastError'] = "";
1395         break;
1396       }
1399       /****************
1400        * Parse - Allof
1401        ****************/ 
1403       case "allof" :
1404       {
1405         /* Get parameter and recursivly call this method 
1406          *  for each parameter 
1407          */
1408         $id ++;
1409         $tmp2 = $this->get_parameter($data,$id);
1410         
1411         foreach($tmp2 as $parameter){
1412           $tmp['allof'][] = $this->_parse($parameter);
1413         }
1414         $tmp['allof']['Inverse'] = $Inverse;
1415         break;
1416       }
1419       /****************
1420        * Parse - Anyof
1421        ****************/ 
1423       case "anyof" :
1424       {
1425         /* Get parameter and recursivly call this method 
1426          *  for each parameter 
1427          */
1428         $id ++;
1429         $tmp2 = $this->get_parameter($data,$id);
1431         foreach($tmp2 as $parameter){
1432           $tmp['anyof'][] = $this->_parse($parameter);
1433         }
1434         $tmp['anyof']['Inverse'] = $Inverse;
1435         break;
1436       }
1437       default : $tmp[$id] = $type; 
1438     }
1439     
1440     return($tmp); 
1441   }
1444   function get_parameter($data,$id)
1445   {
1446     $par = array();
1447     $open_brakets = 0;
1448     $next = NULL;
1449     $num = 0;
1450     for($i = $id ; $i < count($data) ; $i++ ){
1451       if(in_array($data[$i]['class'],array("left-parant","left-bracket"))){
1452         $open_brakets ++;
1453       }
1454       if($data[$i]['class'] == "comma" && $open_brakets == 1){
1455         $num ++;
1456       }
1457       if(!in_array($data[$i]['class'],array("comma","left-parant","right-parant")) || $open_brakets >1 ){
1458         $par[$num][] = $data[$i];
1459       }
1460       if(in_array($data[$i]['class'],array("right-parant","right-bracket"))){
1461         $open_brakets --;
1462       }
1463     }
1464     return($par);
1465   }
1468 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1469 ?>