Code

Added DNS and DHCP enable disable options into setup step 2
[gosa.git] / include / sieve / class_sieveElement_If.inc
index 18964bef50dce03566463a789caaa0c780105aa5..acdcb94d5d6abd1b101abd8efcfb1010236d3fa7 100644 (file)
@@ -5,63 +5,891 @@ class sieve_if
 {
   var $_parsed         = array();
   var $TYPE    = "if";
+  var $object_id     = -1;
 
-  function sieve_if($elements)
+  var $address_parts    = array();
+  var $comparators      = array();
+  var $match_types      = array();
+  var $operators        = array();
+  var $parent           = NULL;
+  
+  /* Initialize class 
+   *  $elements   contains all tokens that belongs to this if/else tag
+   *  $object_id  cotains an unique tag id, to be able to create uniqe html post names
+   */
+  function sieve_if($elements,$object_id,$parent)
+  {
+    $this->parent = $parent;
+    $this->object_id       = $object_id;
+  
+    /* Possible address parts we can select */
+    $this->address_parts = array( 
+        ":all"       => _("Complete address")." ("._("Default").")",
+        ":domain"    => _("Domain part") ,
+        ":localpart" => _("Local part"));
+
+    /* comparator type */
+    $this->comparators   = array( 
+        "i;ascii-casemap" => _("Case insensitive")." ("._("Default").")",
+        "i;octet"         => _("Case sensitive"),
+        "i;ascii-numeric" => _("Numeric"));
+
+    /* Match types */
+    $this->match_types  = array(  
+        ":is"         => _("is"),
+        ":regex"      => _("regex"),
+        ":contains"   => _("contains"),
+        ":matches"    => _("matches"),
+        ":count"      => _("count"),
+        ":value"      => _("value is"));
+
+    /* Operators */
+    $this->operators = array(     
+        "lt"  => _("less than"),
+        "le"  => _("less or equal"),
+        "eq"  => _("equals"),
+        "ge"  => _("greater or equal"),
+        "gt"  => _("greater than"),
+        "ne"  => _("not equal"));
+
+    /* Skip parsing if this element is new */
+    if($elements != NULL){
+
+      /* Remove comments from tests */  
+      $tmp = array();
+      foreach($elements['ELEMENTS'] as $ele){
+        if($ele['class'] != "comment"){
+          $tmp[] = $ele;
+        }
+      }
+      $elements['ELEMENTS'] = $tmp;
+
+      if($elements!=NULL){
+        $this->elements = $elements;
+        $this->_parsed  = $this->_parse($elements['ELEMENTS'],1);
+      }
+    }
+  }
+
+
+  /* Returns the sieve script for this 
+   *  if/else tag.
+   */
+  function get_sieve_script_part()
   {
-    $this->elements = $elements;
-    $this->_parsed = $this->_parse($elements['ELEMENTS'],1);
+    $tmp = $this->TYPE." ".$this->get_sieve_script_part_recursive($parsed = NULL,$id = 1,$obj_id=1);
+    return($tmp);
+  } 
+
+
+  /* Return error msgs */
+  function check()
+  {
+    $check = $this->check_recursive();
+    return($check);
+  }
+
+  /* Recursivly fetch all error msgs */
+  function check_recursive($parsed = NULL,$id = 1,$obj_id=1)
+  {
+    $ret = array();
+    if($parsed == NULL){
+      $parsed = $this->_parsed;
+    }
+
+    if($parsed == NULL) {
+        return(array(_("Can't save empty tests.")));
+    }
+
+    /* Walk through all elements */
+    foreach($parsed as $key => $data){
+
+      /* Create elements */
+      switch($key)
+      {
+        /*******************
+         * Allof / Anyof
+         *******************/
+        case "anyof" :
+        case "allof" :
+        { 
+          foreach($data as $key2 => $dat){
+            if(($key2 === "Inverse") && ($key2 == "Inverse")){
+              continue;
+            }
+            $msgs = $this->check_recursive($dat, ($id +1),$key2);
+
+            foreach($msgs as $msg){
+              $ret[] = $msg;
+            }
+          }
+          break;
+        }
+
+        /*******************
+         * True / False
+         *******************/
+
+        case "true" :
+        case "false" : 
+        {
+          /* Can't fail anyway */
+          break;
+        }
+    
+        /*******************
+         * Default
+         *******************/
+
+        default: 
+        {
+          if(isset($data['LastError']) && !empty($data['LastError'])){
+            $ret[] = $data['LastError'];
+          }
+        }
+      }
+    }
+    return($ret);
   }
+
+  /* Recursivly create a sieve script out of the given 
+   *  tags and tokens provided by $parsed.
+   *  $id       specifies the depth of the current element.
+   *  $obj_id   is the current tag-id handled by this function
+   */
+  function get_sieve_script_part_recursive($parsed = NULL,$id = 1,$obj_id=1)
+  {
+    $script ="";
+    if($parsed == NULL){
+      $parsed = $this->_parsed;
+    }
+
+
+    if(!is_array($parsed)){
+      return;
+    }
+
+    /* Walk through all elements */
+    foreach($parsed as $key => $data){
+
+      /* Create Inverse Tag */
+      if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
+        $Inverse = TRUE;
+      }else{
+        $Inverse = FALSE;
+      }
+
+      /* Create elements */
+      switch($key)
+      {
+
+        /*******************
+         * True / False
+         *******************/
+
+        case "true" :
+        case "false" :
+        {
+          /* Invert this test if required */
+          if($Inverse){
+            $script .= "not ";
+          }
+          $script .= $key;
+          break;
+        }
+
+
+        /*******************
+         * Address
+         *******************/
+
+        case "address" :   
+        {
+          /* [not] address 
+                        [address-part: tag] 
+                        [comparator: tag] 
+                        [match-type: tag] 
+                        <header-list: string-list> 
+                        <key-list: string-list> 
+          */
+
+          /* Invert this test if required */
+          if($Inverse){
+            $script .= "not ";
+          }
+  
+          $script .="address ";
+          /* Add address part tag */ 
+          if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
+            $script .= $data['Address_Part']." ";
+          }
+
+          /* Add comparator */
+          if(!empty($data['Comparator']) && $data['Comparator'] != ""){
+            $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
+          }
+    
+          /* Add match type */
+          $script .= $data['Match_type']." ";
+
+          /* Add special match type for count and value */
+          if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
+            $script .= sieve_create_strings($data['Match_type_value'])." ";
+          }
+
+          $script .= sieve_create_strings($data['Key_List']);
+          $script .= " ";
+          $script .= sieve_create_strings($data['Value_List']);
+          break;
+        }
+
+
+        /*******************
+         * Header
+         *******************/
+
+        case "header" :   
+        {
+          /* [not] header   
+                [comparator: tag] 
+                [match-type: tag] 
+                <header-names: string-list> 
+                <key-list: string-list>
+          */
+
+          /* Invert ? */
+          if($Inverse){
+            $script .= "not ";
+          }
+  
+          $script .="header ";
+          /* Add address part tag */ 
+          if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
+            $script .= $data['Address_Part']." ";
+          }
+
+          /* Add comparator */
+          if(!empty($data['Comparator']) && $data['Comparator'] != ""){
+            $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
+          }
+    
+          /* Add match type */
+          $script .= $data['Match_type']." ";
+
+          /* Add special match type for count and value */
+          if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
+            $script .= sieve_create_strings($data['Match_type_value'])." ";
+          }
+
+          $script .= sieve_create_strings($data['Key_List']);
+          $script .= " ";
+          $script .= sieve_create_strings($data['Value_List']);
+          break;
+        }
+
+
+        /*******************
+         * Envelope
+         *******************/
+
+        case "envelope" :   
+        {
+          /* [not]  envelope 
+                    [address-part: tag] 
+                    [comparator: tag] 
+                    [match-type: tag] 
+                    <envelope-part: string-list> 
+                    <key-list: string-list> 
+          */
+
+          /* Invert */
+          if($Inverse){
+            $script .= "not ";
+          }
+  
+          $script .="envelope ";
+          /* Add address part tag */ 
+          if(!empty($data['Address_Part']) && $data['Address_Part'] != ":all"){
+            $script .= $data['Address_Part']." ";
+          }
+
+          /* Add comparator */
+          if(!empty($data['Comparator']) && $data['Comparator'] != ""){
+            $script .= preg_replace('/\"\"/',"\"", ":comparator \"".$data['Comparator']."\" ");
+          }
+    
+          /* Add match type */
+          $script .= $data['Match_type']." ";
+
+          /* Add special match type for count and value */
+          if(in_array($data['Match_type'], array(":value",":count")) && !empty($data['Match_type_value'])) {
+            $script .= sieve_create_strings($data['Match_type_value'])." ";
+          }
+
+          $script .= sieve_create_strings($data['Key_List']);
+          $script .= " ";
+          $script .= sieve_create_strings($data['Value_List']);
+          break;
+        }
+
+
+        /*******************
+         * Exists
+         *******************/
+        case "exists" : 
+        {
+          /* [not] exists 
+              <header-names: string-list> 
+          */
+
+          /* Invert ? */
+          if($Inverse){
+            $script .= "not ";
+          }
+
+          $script .= "exists ".sieve_create_strings($data['Values']);
+          break;
+        }
+
+
+        /*******************
+         * Size
+         *******************/
+        case "size" : 
+        {
+          /* [not] size 
+                <":over" / ":under"> 
+                <limit: number> 
+          */
+
+          /* Invert ? */
+          if($Inverse){
+            $script .= "not ";
+          }
+          /* Add size test */ 
+          $script .="size ";
+          $script .=$data['Match_type']." ";
+          foreach($data['Value_List'] as $val){
+            $script .= $val." ";
+          }
+          break;
+        }
+
+
+        /*******************
+         * Allof
+         *******************/
+        case "anyof" :
+        case "allof" :
+        {
+          /* allof <tests: test-list>
+             anyof <tests: test-list> */
+
+          /* Add spaces, to indent the code.*/ 
+          $block = "\n";
+          for($i = 0 ; $i < $id ; $i ++){
+            $block .= SIEVE_INDENT_TAB;
+          }          
+
+          /* Add allof/anyof tag */
+          if($Inverse){
+            $script .= "not ";
+          }
+          $script.= $key." ( ";
+
+          /* Add each test parameter */
+          foreach($data as $key2 => $dat){
+            if(($key2 === "Inverse") && ($key2 == "Inverse")){
+              continue;
+            }
+            $script.= $block.$this->get_sieve_script_part_recursive($dat, ($id +1),$key2).", ";
+          }
+    
+          /* Remove last _,_ and close the tag */
+          $script = preg_replace("/,$/","",trim($script));
+          $script.= $block.")";
+          break ;
+        }
+
+        default :
+        {
+          $script .= "THERE IS SOME IMPLEMENTATION MISSING FOR SIEVE SCRIPT CREATION :".$key;
+        }
+      }
+    }
+    return($script);
+  }
+
+  
+  function add_test($data,$type)
+  {
+    switch($type)
+    {
+      case "header" : 
+      case "address" : 
+      case "envelope" : 
+      {
+        /* Add to Tree */
+        $values = array(        "Inverse"         => FALSE,
+                                "Comparator"      => "",
+                                "Expert"          => FALSE,
+                                "LastError"       => "",
+                                "Match_type"      => ":contains",
+                                "Match_type_value"=> "",
+                                "Key_List"        => array(_("emtpy")),
+                                "Value_List"      => array(_("empty"))) ;
+        if($type == "address"){
+          $values["Address_Part"]    = ":all";
+        }
+        $data[$type]=$values;
+
+        $this->parent->add_require("relational");
+        if($type == "envelope"){
+          $this->parent->add_require("envelope");
+        }
+    
+
+        break;
+      }
+      case "allof" :
+      case "anyof" :
+      {
+        $data[$type] = array("Inverse" => FALSE);
+        break;
+      }
+      case "size" :
+      {
+        $tmp= array( 
+            "Inverse"    => FALSE,
+            "Match_type" => ":over",
+            "Value_List" => array("1M"));
+
+        $tmp['LastError'] = "";
+        $data[$type] = $tmp;
+        break;
+      }
+      case "true":
+      {
+        $data['true'] = "true";
+        $data['true']['LastError'] = "";
+        break;
+      }
+      case "false":
+      {
+        $data['false'] = "false";
+        $data['false']['LastError'] = "";
+        break;
+      }
+      case "exists" :
+      {
+        $data['exists'] = array('Inverse' => FALSE,
+                                'Values'  => array(_("Nothing specified right now")),
+                                'LastError' => "");
+        break;
+      }
+      default : echo "Still buggy ";exit;
+    }
+
+    return($data);
+  }
+
+
+  /* Ensure that all changes made on the ui 
+   *  will be saved. 
+   */
+  function save_object()
+  {
+  
+    if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$this->object_id])){
+      $this->_parsed = $this->add_test($this->_parsed,$_POST["test_type_to_add_".$this->object_id]);
+    }
+
+    $tmp = $this->save_object_recursive($parsed = NULL,$id = 1,$obj_id=1);
+    $this->_parsed = $tmp;
+  }
+
+
+  /* Recursivly save all ui changes for the 
+   *  tags and tokens provided by $parsed.
+   *  $id       specifies the depth of the current element.
+   *  $obj_id   is the current tag-id handled by this function
+   */
+  function save_object_recursive($parsed = NULL,$id = 1,$obj_id=1)
+  {
+    /* Variable initialization */ 
+    $ret ="";
+    if($parsed == NULL){
+      $parsed = $this->_parsed;
+    }
+
+    if(!is_array($parsed)) {
+      return;
+    }
+
+    /* Walk through all elements */
+    foreach($parsed as $key => $data){
+
+      /* Id used to have unique html names */
+      $element_id = $this->object_id."_".$id."_".$obj_id;
+      
+      foreach($_POST as $name => $value){
+        if(preg_match("/Remove_Test_Object_".$element_id."_(x|y)/",$name)) {
+          return(false); 
+        }
+      }
+
+      
+      if(isset($_POST['add_type']) && isset($_POST["test_type_to_add_".$element_id])){
+        $parsed[$key][] = $this->add_test(array(),$_POST["test_type_to_add_".$element_id]);
+      }
+
+      /* Create elements */
+      switch($key)
+      {
+        /*******************
+         * Address 
+         *******************/
+
+        case "envelope" :
+        case "header" : 
+        case "address" : 
+        {
+          /* [not] address 
+                        [address-part: tag] 
+                        [comparator: tag] 
+                        [match-type: tag] 
+                        <header-list: string-list> 
+                        <key-list: string-list> 
+          */
+
+          /* Possible address parts we can select */
+          $address_parts = $this->address_parts;
+          $comparators   = $this->comparators;
+          $match_types   = $this->match_types; 
+          $operators     = $this->operators;
+
+          $parsed[$key]['LastError'] = "";
+
+          /* Toggle Inverse ? */
+          if(isset($_POST['toggle_inverse_'.$element_id])){
+            $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
+          }
+
+          /* Check if we want to toggle the expert mode */
+          if(isset($_POST['Toggle_Expert_'.$element_id])){
+            $parsed[$key]['Expert'] = !$parsed[$key]['Expert'];
+          }
+
+          /* Get address part */
+          if(isset($_POST['address_part_'.$element_id])){
+            $ap = $_POST['address_part_'.$element_id];
+
+            if(!isset($address_parts[$ap])){
+              $parsed[$key]['LastError'] = _("Invalid type of address part.") ;
+            }
+            $parsed[$key]['Address_Part'] = $ap;
+          }
+
+          /* Check if match type has changed */
+          if(isset($_POST['matchtype_'.$element_id])){
+            $mt = $_POST['matchtype_'.$element_id];
+
+            if(!isset($match_types[$mt])){
+              $parsed[$key]['LastError'] = _("Invalid match type given.");
+            }
+            if($mt == ":regex"){
+              $this->parent->add_require("regex");
+            }
+            if($mt == ":count"){
+              $this->parent->add_require("comparator-i;ascii-numeric");
+            }
+            $parsed[$key]['Match_type'] = $mt;
+          }
+
+          /* Get the comparator tag, if posted */
+          if(isset($_POST['comparator_'.$element_id])){
+            $cp = $_POST['comparator_'.$element_id];
+
+            if(!isset($comparators[$cp])){
+              $parsed[$key]['LastError'] = _("Invalid operator given.");
+            }
+            $parsed[$key]['Comparator'] = $cp;
+
+            if($cp == "i;ascii-numeric"){
+              $this->parent->add_require("comparator-i;ascii-numeric");
+            }
+          }
+
+          /* In case of :count and :value match types 
+           *  we have a special match operator we should save.
+           */
+          if(in_array($parsed[$key]['Match_type'],array(":value",":count"))){
+            if(isset($_POST['operator_'.$element_id])){
+              $op = $_POST['operator_'.$element_id];
+
+              if(!isset($operators[$op])){
+                $parsed[$key]['LastError'] = _("Please specify a valid operator.");
+              }
+              $parsed[$key]['Match_type_value'] = $op;
+            }
+          }
+
+          /* Get the address fields we should check, they are seperated by , */
+          if(isset($_POST['keys_'.$element_id])){
+            $vls = stripslashes($_POST['keys_'.$element_id]);
+            $tmp = array();
+
+            $tmp2 = split(",",$vls);
+            foreach($tmp2 as $val){
+              $tmp[] = trim($val);
+  
+              if(preg_match("/\"/",$val)){
+                $parsed[$key]['LastError'] = _("Invalid character found in address attribute. Quotes are not allowed here.");
+              }
+            }
+            $parsed[$key]['Key_List'] = $tmp;
+          }
+
+          /* Get the values should check for, they are seperated by , */
+          if(isset($_POST['values_'.$element_id])){
+            $vls = stripslashes($_POST['values_'.$element_id]);
+            $tmp = array();
+
+            $tmp2 = split(",",$vls);
+            foreach($tmp2 as $val){
+              $tmp[] = trim($val);
+              if(preg_match("/\"/",$val)){
+                $parsed[$key]['LastError'] = _("Invalid character found in value attribute. Quotes are not allowed here.");
+              }
+            }
+            $parsed[$key]['Value_List'] = $tmp;
+          }
+          break;
+        }
+        /*******************
+         * TRUE FALSE 
+         *******************/
+
+        case "true" :
+        case "false" : 
+        {
+          $name = 'boolean_'.$element_id;
+          if(isset($_POST[$name])){
+            $key2 = $_POST[$name];
+            
+            if($key != $key2) {
+              $parsed = array($key2 => $key2); 
+            }
+          }
+          break;
+        }
+
+        /*******************
+         * Exists 
+         *******************/
+
+        case "exists" :
+        {
+          /* Toggle Inverse ? */
+          if(isset($_POST['toggle_inverse_'.$element_id])){
+            $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
+          }
+
+          /* get list of match values */
+          if(isset($_POST['Values_'.$element_id])){
+            $vls = stripslashes($_POST['Values_'.$element_id]);
+            $tmp = array();          
+  
+            $tmp2 = split(",",$vls);
+            foreach($tmp2 as $val){
+              $tmp[] = "\"".trim(preg_replace("/\"/","",$val))."\"";
+            }
+            $parsed['exists']['Values'] = $tmp;
+          }
+          break;
+        }
+
+        /*******************
+         * Size 
+         *******************/
+
+        case "size" :
+        {
+          $Match_types = array( ":over" => _("greater than") ,
+                                ":under" => _("lower than"));
+
+          $Units       = array( "M" => _("Megabyte"),
+                                "K" => _("Kilobyte"),
+                                ""  => _("Bytes"));
+
+          /* Toggle Inverse ? */
+          if(isset($_POST['toggle_inverse_'.$element_id])){
+            $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
+          }
+
+          /* Reset error */
+          $parsed[$key]['LastError'] ="";
+
+          /* Get match type */
+          if(isset($_POST['Match_type_'.$element_id])){
+            $mt = $_POST['Match_type_'.$element_id];
+            if(!isset($Match_types[$mt])){
+              $parsed[$key]['LastError'] = _("Please select a valid match type in the list box below.");
+            }
+            $parsed[$key]['Match_type'] = $mt;
+          }
+
+          /* Get old values */
+          $value = preg_replace("/[^0-9]*$/","",$parsed[$key]['Value_List'][0]);
+          $unit  = preg_replace("/^[0-9]*/","",$parsed[$key]['Value_List'][0]);
+
+          /* Get value */
+          if(isset($_POST['Value_'.$element_id])){
+            $vl = $_POST['Value_'.$element_id];
+         
+            if(!(is_numeric($vl) && preg_match("/^[0-9]*$/",$vl))){
+              $parsed[$key]['LastError'] = _("Only numeric values are allowed here.");
+            }
+            $value = preg_replace("/[^0-9]/","",$vl);
+          }        
+
+          /* Get unit */
+          if(isset($_POST['Value_Unit_'.$element_id])){
+            $ut = $_POST['Value_Unit_'.$element_id];
+       
+            if(!isset($Units[$ut])){
+              $parsed[$key]['LastError'] = _("No valid unit selected");
+            }
+            $unit = $ut;
+          }       
+          $parsed[$key]['Value_List'] = array(); 
+          $parsed[$key]['Value_List'][0] = $value.$unit;
+          break;
+        }
+
+        /*******************
+         * Allof 
+         *******************/
+     
+        case "allof" : 
+        {
+          if(isset($_POST['toggle_inverse_'.$element_id])){
+            $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
+          }
+          foreach($data as $key2 => $dat){
+            if(($key2 === "Inverse") && ($key2 == "Inverse")){
+              continue;
+            }
+            $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
+            if($tmp_data != false){
+              $parsed[$key][$key2] = $tmp_data;
+            }else{
+              unset( $parsed[$key][$key2]);
+            }
+          }
+          break ;
+        } 
+
+        /*******************
+         * Anyof 
+         *******************/
+     
+        case "anyof" : 
+        {
+          if(isset($_POST['toggle_inverse_'.$element_id])){
+            $parsed[$key]['Inverse'] = !$parsed[$key]['Inverse'];
+          }
+          foreach($data as $key2 => $dat){
+            if(($key2 === "Inverse") && ($key2 == "Inverse")){
+              continue;
+            }
+            $tmp_data = $this->save_object_recursive($dat, ($id +1),$key2."-".$obj_id);
+            if($tmp_data != false){
+              $parsed[$key][$key2] = $tmp_data;
+            }else{
+              unset( $parsed[$key][$key2]);
+            }
+          }
+          break ;
+        } 
+      }
+    } 
+    return($parsed);
+  }  
 
 
   /* Return html element for IF */ 
   function execute()
   {
     /* Create title */
-    $name  = "<img src='images/small_filter.png' class='center'>";
+    $name  = "<img alt='' src='images/small_filter.png' class='center'>";
     $name .= "<b>"._("Condition")."</b>";
     if($this->TYPE == "if"){
       $name .= "&nbsp;-&nbsp;"._("If");
+    }elseif($this->TYPE == "elsif"){
+      $name .= "&nbsp;-&nbsp;"._("Else If");
     }else{
       $name .= "&nbsp;-&nbsp;"._("Else");
     }
 
-    /* Create new html block */
-    $str  ="<table cellspacing=0 width='100%'>
-              <tr>
-                <td style='width:100%;background-color:#DDDDDD; padding:5px; border: solid 2px #AAAAAA;'>".
-                  $name;
-    $str .= $this->get_as_html();  
-  
-    $str .= "   </td>
-              </tr>
-            </table>";
+    $smarty = get_smarty();
+    $smarty->assign("ID", $this->object_id);
+
+    /* Get navigation element container */
+    $object_container = $smarty->fetch(get_template_path("templates/object_container.tpl",TRUE,dirname(__FILE__)));
+
+    $smarty->assign("Name", $name);
+    $smarty->assign("Contents", $this->get_as_html());
+
+    if($this->TYPE == "if"){
+      $object = $smarty->fetch(get_template_path("templates/element_if.tpl",TRUE,dirname(__FILE__)));
+    }else{
+      $object = $smarty->fetch(get_template_path("templates/element_elsif.tpl",TRUE,dirname(__FILE__)));
+    }
+    $str = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($object,"\\"),$object_container);
     return($str);
   }
 
   
   /* Returns all elements as html */
-  function get_as_html($parsed = NULL)
+  function get_as_html($parsed = NULL,$id = 1,$obj_id=1)
   {
-    $header_parts = array(":all",":localpart",":domain",":user",":detail");
-
-
     $ret ="";
     if($parsed == NULL){
       $parsed = $this->_parsed;
     }
 
+    if((!is_array($parsed)) || !count($parsed)) {
+      $smarty = get_smarty();
+      $smarty->assign("ID",$this->object_id);
+      $smarty->assign("DisplayAdd",TRUE);
+      $smarty->assign("DisplayDel",FALSE);
+      $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
+      $ret .= preg_replace("/%%OBJECT_CONTENT%%/",_("Empty"),$str);
+      return($ret);
+    }
+
     /* Walk through all elements */
     foreach($parsed as $key => $data){
 
       /* Create Inverse Tag */
-      if(isset($data['Inverse']) && $data['Inverse']){
-        $str_inverse = "<font color='red'><b>"._("Not")."</b></font>&nbsp;";
+      if(is_array($data) && isset($data['Inverse']) && $data['Inverse']){
         $Inverse = TRUE;
       }else{
-        $str_inverse = "";
         $Inverse = FALSE;
       }
 
+      /* Id used to have unique html names */
+      $element_id = $this->object_id."_".$id."_".$obj_id;
+
       /* Create elements */
       switch($key)
       {
@@ -73,75 +901,244 @@ class sieve_if
         case "true" :
         case "false" : 
         { 
-          /* Set default */
-          $type = TRUE;
-
-          /* Use false as default if element is false */
-          if($key == "false"){
-            $type = FALSE;
-          }
-  
           /* Inverse element if required */
           if($Inverse){        
-              $type = !$type;
+            if($key == "true"){
+              $key = "false";
+            }else{
+              $key = "true";
+            }           
           }
 
-          /* Return value */
-          if($type){
-              $ret = "<div><img src='images/true.png' class='center'>"._("Boolean true")."</div>";
-          }else{
-              $ret = "<div><img src='images/false.png' class='center'>"._("Boolean false")."</div>";
+          /* Get template */
+          $smarty = get_smarty();
+          $smarty->assign("values"    , array("false" => _("False"), "true" => _("True")));
+          $smarty->assign("selected"  , $key); 
+          $smarty->assign("ID"  , $element_id); 
+          $ret .= $smarty->fetch(get_template_path("templates/element_boolean.tpl",TRUE,dirname(__FILE__)));
+          break;
+        }
+
+
+        /*******************
+         * Header 
+         *******************/
+
+        case "header": 
+        {
+          $address_parts = $this->address_parts;
+          $comparators   = $this->comparators;
+          $match_types   = $this->match_types; 
+          $operators     = $this->operators;
+
+          $smarty = get_smarty();
+          $smarty->assign("comparators",$comparators);
+          $smarty->assign("match_types",$match_types);
+          $smarty->assign("operators",$operators);
+          $smarty->assign("LastError",$data['LastError']);
+          $smarty->assign("match_type", $data['Match_type']);
+          $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
+          $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
+
+          $keys = "";
+          foreach($data['Key_List'] as $key){
+            $keys .= $key.", ";
+          }
+          $keys = preg_replace("/,$/","",trim($keys));
+   
+          $values = "";
+          foreach($data['Value_List'] as $key){
+            $values .= $key.", ";
           }
+          $values = preg_replace("/,$/","",trim($values));
+
+          $smarty->assign("keys",$keys);
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("values",$values);
+          $smarty->assign("Expert", $data['Expert']);
+          $smarty->assign("ID"  , $element_id); 
+          $ret .= $smarty->fetch(get_template_path("templates/element_header.tpl",TRUE,dirname(__FILE__)));
+          break;
         }
-        break;
 
 
         /*******************
-         * Header  
+         * Envelope 
+         *******************/
+
+        case "envelope":
+        {
+          $address_parts = $this->address_parts;
+          $comparators   = $this->comparators;
+          $match_types   = $this->match_types; 
+          $operators     = $this->operators;
+
+          $smarty = get_smarty();
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("comparators",$comparators);
+          $smarty->assign("Expert", $data['Expert']);
+          $smarty->assign("match_types",$match_types);
+          $smarty->assign("operators",$operators);
+          $smarty->assign("LastError",$data['LastError']);
+          $smarty->assign("match_type", $data['Match_type']);
+          $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
+          $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
+
+          $keys = "";
+          foreach($data['Key_List'] as $key){
+            $keys .= $key.", ";
+          }
+          $keys = preg_replace("/,$/","",trim($keys));
+
+          $values = "";
+          foreach($data['Value_List'] as $key){
+            $values .= $key.", ";
+          }
+          $values = preg_replace("/,$/","",trim($values));
+          $smarty->assign("keys",$keys);
+          $smarty->assign("values",$values);
+
+          $smarty->assign("ID"  , $element_id); 
+          $ret .= $smarty->fetch(get_template_path("templates/element_envelope.tpl",TRUE,dirname(__FILE__)));
+          break;
+        }
+
+
+        /*******************
+         * Address 
          *******************/
 
         case "address" : 
         {
-          $ret ="";    
-          /* Create comparator */ 
-          $ret .= _("Match type")."&nbsp;";
-          $arr =array("i;octet" => _("Normal"),"i;ascii-casemap"=>_("Case sensitive"),"i;ascii-numeric"=>_("Numeric"));
-          $ret .= "<select>";
-          foreach($arr as $ar ){
-            $ret .= "<option value='".$ar."'>".$ar."</option>";
-          }
-          $ret .= "</select>";
-         
-          /* Create address part */ 
-          $ret.= _("Checking Header");
+          $address_parts = $this->address_parts;
+          $comparators   = $this->comparators;
+          $match_types   = $this->match_types; 
+          $operators     = $this->operators;
+
+          $smarty = get_smarty();
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("address_parts",$address_parts);
+          $smarty->assign("comparators",$comparators);
+          $smarty->assign("match_types",$match_types);
+          $smarty->assign("LastError",$data['LastError']);
+          $smarty->assign("operators",$operators);
+          $smarty->assign("match_type", $data['Match_type']);
+          $smarty->assign("operator"  , preg_replace("/\"/","",$data['Match_type_value']));
+          $smarty->assign("comparator", preg_replace("/\"/","",$data['Comparator']));
+          $smarty->assign("address_part", $data['Address_Part']);
+          $smarty->assign("Expert", $data['Expert']);
+        
+          $keys = "";
+          foreach($data['Key_List'] as $key){
+            $keys .= $key.", ";
+          }
+          $keys = preg_replace("/,$/","",trim($keys));
+   
+          $values = "";
+          foreach($data['Value_List'] as $key){
+            $values .= $key.", ";
+          }
+          $values = preg_replace("/,$/","",trim($values));
+
+          $smarty->assign("keys",$keys);
+          $smarty->assign("values", $values);
+          $smarty->assign("ID"  , $element_id); 
+          $str = $smarty->fetch(get_template_path("templates/element_address.tpl",TRUE,dirname(__FILE__)));
+          $ret .= $str;
           break;
         }
       
 
+        /*******************
+         * Size 
+         *******************/
+        
+        case "size" : 
+        {
+          $Match_types = array( ":over" => _("greater than") , 
+                                ":under" => _("lower than"));
+
+          $Units       = array( "M" => _("Megabyte"),
+                                "K" => _("Kilobyte"),
+                                ""  => _("Bytes"));
+
+          $Match_type   = $data['Match_type'];
+          $Value        = preg_replace("/[^0-9]/","",$data['Value_List'][0]);
+          $Value_Unit   = preg_replace("/[0-9]/","",$data['Value_List'][0]);
+       
+          $LastError = "";
+          if(isset($data['LastError'])){
+            $LastError = $data['LastError'];
+          }
+          $smarty = get_smarty();
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("LastError",$LastError);
+          $smarty->assign("Match_types",$Match_types);
+          $smarty->assign("Units",$Units);
+          $smarty->assign("Match_type",$Match_type);
+          $smarty->assign("Value",$Value);
+          $smarty->assign("Value_Unit",$Value_Unit);
+          $smarty->assign("ID"  , $element_id); 
+          $ret .= $smarty->fetch(get_template_path("templates/element_size.tpl",TRUE,dirname(__FILE__)));
+          break;
+        }
+        
+        /*******************
+         * Exists 
+         *******************/
+        
+        case "exists" : 
+        {
+          $LastError = "";
+          if(isset($data['LastError'])){
+            $LastError = $data['LastError'];
+          }
+          $Values = "";
+          foreach($data['Values'] as $val){
+            $Values .= $val.", ";
+          }
+          $Values = preg_replace("/,$/","",trim($Values));
+
+          $smarty = get_smarty();
+          $smarty->assign("LastError",$LastError);
+          $smarty->assign("Values",$Values);
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("ID"  , $element_id); 
+          $ret .= $smarty->fetch(get_template_path("templates/element_exists.tpl",TRUE,dirname(__FILE__)));
+          break;
+        }
+  
+
         /*******************
          * All of   
          *******************/
 
         case "allof" : 
         {
-          $ret = "<table width='100%'  cellspacing=0 cellpadding=0>
-                    <tr>
-                      <td style='text-align:center; vertical-align: middle; width:45px; 
-                                 background-color: #BDBDBD; border: solid 1px #EEEEEE'>".
-                        "<b>".$str_inverse._("All of")."</b>".
-                        "<img class='center' src='images/select_ogroup.png'>".
-                     "</td>";
-          $ret.= "    <td style='background-color:#BDBDBD ; border: solid 1px #EEEEEE'>";
+          $Contents = ""; 
           foreach($data as $key => $dat){
-            if($key == "Inverse" ){
+            if(($key === "Inverse") && ($key == "Inverse")){
               continue;
             }
-            $ret.=        $this->get_as_html($dat);
+            $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
           }
-          $ret.= "    </td>
-                    </tr>
-                  </table>";
+
+          $smarty = get_smarty();
+          $smarty->assign("ID"  , $element_id); 
+          $smarty->assign("DisplayAdd",TRUE);
+          $smarty->assign("DisplayDel",FALSE);
+          $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
+          $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/","<b>"._("Click here to add a new test")."</b>",$cont_tmp);
+
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("Contents",$cont_tmp.$Contents);
+          $smarty->assign("ID"  , $element_id); 
+          $allof_tmp = $smarty->fetch(get_template_path("templates/element_allof.tpl",TRUE,dirname(__FILE__)));
+
+          $ret = $allof_tmp;
           break ;
         } 
 
@@ -152,52 +1149,66 @@ class sieve_if
 
         case "anyof" : 
         {
-          $ret = "<table width='100%' cellspacing=0 cellpadding=0>
-                    <tr>
-                      <td style='text-align:center; vertical-align: middle; width:45px; 
-                                 background-color: #AAAAAA; border: solid 1px #EEEEEE'>".
-                        "<b>".$str_inverse._("Any of")."</b>".
-                        "<img class='center' src='images/select_department.png'>".
-                     "</td>";
-          $ret.= "    <td style='background-color: #AAAAAA ; border: solid 1px #EEEEEE'>";
+          $Contents = ""; 
           foreach($data as $key => $dat){
-            if($key == "Inverse" ){
+            if(($key === "Inverse") && ($key == "Inverse")){
               continue;
             }
-            $ret.=        $this->get_as_html($dat);
+            $Contents .=        $this->get_as_html($dat, ($id +1),$key."-".$obj_id);
           }
-          $ret.= "    </td>
-                    </tr>
-                  </table>";
+          $smarty = get_smarty();
+          $smarty->assign("ID"  , $element_id); 
+          $smarty->assign("DisplayAdd",TRUE);
+          $smarty->assign("DisplayDel",FALSE);
+          $cont_tmp = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
+          $cont_tmp = preg_replace("/%%OBJECT_CONTENT%%/",_("Click here to add a new test"),$cont_tmp);
+
+          $smarty->assign("Inverse",$Inverse);
+          $smarty->assign("Contents",$cont_tmp.$Contents);
+          $allof_tmp = $smarty->fetch(get_template_path("templates/element_anyof.tpl",TRUE,dirname(__FILE__)));
+
+          $ret = $allof_tmp;
+
           break ;
-        }
+        } 
         default : 
-          {
-            $ret = "<table width='100%'  cellspacing=0 cellpadding=0>
-                      <tr>
-                        <td style='background-color: #FEDCA9 ; border: solid 1px        #EEEEEE'>";
-            $ret.= $key."<br>"; 
-            $ret.= "    </td>
-                      </tr>
-                    </table>";
-
-          }
+        {
+          trigger_error(_("Unhandled switch type"));
+        }
       }
     }
+    
+    if(!isset($smarty)){
+      $smarty =get_smarty();
+    }
+
+    $smarty->assign("ID",$element_id);
+    $smarty->assign("DisplayAdd",FALSE);
+    $smarty->assign("DisplayDel",TRUE);
+    $str = $smarty->fetch(get_template_path("templates/object_test_container.tpl",TRUE,dirname(__FILE__)));
+    $ret = preg_replace("/%%OBJECT_CONTENT%%/",addcslashes($ret,"\\"),$str);
     return($ret);
   }
 
 
+  /* Parse given token identified by $data[$id] 
+   *  and return the parsed tokens. 
+   */
   function _parse($data,$id = 0)
   {
-    $av_methods   = array("address","allof","anyof","exists","false","header","not","size","true","envelope");
-    $av_match_type= array(":is",":contains",":matches",":over",":count",":value",":under");
-    
-    $type = $data[$id]['text'];
+    $av_match_type = array();
+    foreach($this->match_types as $name => $description){
+      $av_match_type[] = $name;
+    }
+    $av_match_type[] = ":over";
+    $av_match_type[] = ":under";
 
-    $tmp = array();
 
 
+    $av_methods= array("address","allof","anyof","exists","false","header","not","size","true","envelope");
+    $type = $data[$id]['text'];
+    $tmp = array();
+
     /* Is there an identifier named 'not' to inverse this filter ? */
     $Inverse = FALSE;
     if($data[$id]['class'] == "identifier" && $data[$id]['text'] == "not"){
@@ -208,7 +1219,11 @@ class sieve_if
 
     switch($type)
     {
-  
+
+      /****************
+       * Parse - Envelope / Header / Address
+       ****************/ 
+
       case "envelope" : 
       case "header":
       case "address" : 
@@ -225,7 +1240,7 @@ class sieve_if
    
         
         $part     = "(:all|:localpart|:domain)";
-        $operator = "(:contains|:is|:matches|:count|:value)";
+        $operator = "(:regex|:contains|:is|:matches|:count|:value)";
         $value_op = "(lt|le|eq|ge|gt|ne)";
 
         $Address_Part     = "";
@@ -251,16 +1266,16 @@ class sieve_if
             $Match_type = $node['text'];
 
             /* Get value operator */
-            if($Match_type == ":value"){
+            if(in_array($Match_type,array(":value",":count"))){
               $i ++;        
               $node = $data[$i];
-              
+
               if($node['class'] == "quoted-string" && preg_match("/".$value_op."/",$node['text'])){
                 $Match_type_value = $node['text'];
               }
             }
           } 
-  
+
           /* Check for a comparator */
           elseif($node['class'] == "tag" && preg_match("/comparator/",$node['text'])){
             $i ++;
@@ -286,6 +1301,7 @@ class sieve_if
         /* Add to Tree */ 
         $values = array( "Inverse"         => $Inverse,
                                 "Comparator"      => $Comparator,
+                                "Expert"          => FALSE,
                                 "Match_type"      => $Match_type,
                                 "Match_type_value"=> $Match_type_value,
                                 "Key_List"        => $Key_List,
@@ -294,10 +1310,15 @@ class sieve_if
           $values["Address_Part"]    = $Address_Part;
         }
         $tmp[$type] = $values;
+        $tmp[$type]['LastError'] = "";
         break;
       }
 
 
+      /****************
+       * Parse - Size
+       ****************/ 
+
       case "size":
       {
     
@@ -327,20 +1348,63 @@ class sieve_if
         $tmp[$type]= array( "Inverse"    => $Inverse,
                             "Match_type" => $Match_type,
                             "Value_List" => $Value_List);
+        $tmp[$type]['LastError'] = "";
         break;
       }
+
+
+      /****************
+       * Parse - True / False
+       ****************/ 
+
       case "true": 
       {
         $tmp['true'] = "true";
+        $tmp['true']['LastError'] = "";
         break;
       }
       case "false":
       {
         $tmp['false'] = "false";
+        $tmp['false']['LastError'] = "";
         break;
       }
+
+
+      /****************
+       * Parse - Exists
+       ****************/ 
+
+      case "exists":
+      {
+        
+        /* Skip first values, [if,not,exists] */
+        $node = $data[$id];
+        while(in_array($node['text'],array("if","not","exists"))){
+          $id ++;
+          $node = $data[$id];
+        }
+
+        /* Get values */
+        $tmp2 = sieve_get_strings($data,$id);
+  
+        
+        $tmp['exists'] = array('Inverse' => $Inverse,
+                               'Values'  => $tmp2['STRINGS']);
+        $tmp[$type]['LastError'] = "";
+        break;
+      }
+
+
+      /****************
+       * Parse - Allof
+       ****************/ 
+
       case "allof" :
       {
+        /* Get parameter and recursivly call this method 
+         *  for each parameter 
+         */
         $id ++;
         $tmp2 = $this->get_parameter($data,$id);
         
@@ -351,8 +1415,16 @@ class sieve_if
         break;
       }
 
+
+      /****************
+       * Parse - Anyof
+       ****************/ 
+
       case "anyof" :
       {
+        /* Get parameter and recursivly call this method 
+         *  for each parameter 
+         */
         $id ++;
         $tmp2 = $this->get_parameter($data,$id);
 
@@ -364,7 +1436,7 @@ class sieve_if
       }
       default : $tmp[$id] = $type; 
     }
-  
+    
     return($tmp); 
   }