Code

Updated add element handling.
[gosa.git] / include / sieve / class_sieveManagement.inc
1 <?php
2 /*
3    This code is part of GOsa (https://gosa.gonicus.de)
4    Copyright (C) 2003-2007 - Fabian Hickert <hickert@gonicus.de>
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
22 /* The sieve management class displays a list of sieve 
23  *  scripts for the given mail account. 
24  * The account is identified by the parents uid attribute. 
25  *
26  *  $config       The config object
27  *  $dn           The object edited 
28  *  $parent       The parent object that provides the uid attribute 
29  */
30 class sieveManagement extends plugin
31 {
32   var $parent = NULL;
33   var $scripts= array();  
34   var $uattrib = "uid";
35   var $current_script  = -1;
36   var $current_handler = NULL;
37   var $script_to_delete =-1;
38   var $sieve_handle = NULL; 
39   var $Script_Error = "";
40   var $Sieve_Error = "";
41   var $create_script = FALSE;
43   /* To add new elements we need to know 
44    *  Where to add the element              -> add_new_id
45    *  Whould we add above or below this id  -> add_above_below
46    *  What kind of element should we add    -> add_element_type
47    */
48   var $add_new_element    = FALSE;
49   var $add_new_id         = -1;
50   var $add_above_below    = "below";
51   var $add_element_type   = "sieve_comment";
53   /* If this variable is TRUE, this indicates that we have the 
54    *  import dialog opened. 
55    */
56   var $Import_Script = FALSE;
58   /* Initialize the class and load all sieve scripts 
59    *  try to parse them and display errors 
60    */ 
61   function sieveManagement($config,$dn,$parent,$uattrib)
62   {
63     /* Check given parameter */
64     if(!isset($parent->$uattrib)){
65       trigger_error("Sieve Management implementation error. Parameter 4 must be part of the given parent element.");
66     }
68     $this->uattrib = $uattrib;
69     $this->parent = $parent;
70     plugin::plugin($config,$dn);
72     /* Get sieve, if this fail abort class initialization */
73     if(!$this->sieve_handle = $this->get_sieve()){
74       return;
75     }
78     /* Get all sieve scripts names */
79     if($this->sieve_handle->sieve_listscripts()){
80       if (is_array($this->sieve_handle->response)){
81         foreach($this->sieve_handle->response as $key => $name){
83           $data = array();
84           $data['NAME'] = $name;
86           if($key == "ACTIVE" && $key === "ACTIVE"){
87             $data['ACTIVE'] = TRUE;
88           }else{
89             $data['ACTIVE'] = FALSE;
90           }
91           $this->scripts[] = $data;          
92         }
93       } 
94     }
96     /* Get script contents */
97     foreach($this->scripts as $key => $script){
98       $p = new My_Parser($this);
99       $this->sieve_handle->sieve_getscript($script['NAME']);
101       $script = "";
102       foreach($this->sieve_handle->response as $line){
103         $script.=$line;
104       }
106       $this->scripts[$key]['IS_NEW'] = FALSE;;
107       $this->scripts[$key]['SCRIPT'] = $script;
108       $this->scripts[$key]['ORIG_SCRIPT'] = $script;
109       $this->scripts[$key]['MSG']   = "";
110       $ret = $p->parse($script);
111       if(!$ret){
112         $this->scripts[$key]['STATUS']   = FALSE;
113         $this->scripts[$key]['MODE']    = "Source";
114         $this->scripts[$key]['MSG'] = _("Parse failed")."<font color='red'>".$p->status_text."</font>";
115       }else{
116         $this->scripts[$key]['STATUS']   = TRUE;
117         $this->scripts[$key]['MODE']    = "Structured";
118         $this->scripts[$key]['MSG'] = _("Parse successful");
119       }
120       $this->scripts[$key]['PARSER'] = $p;
121       $this->scripts[$key]['EDITED'] = FALSE;
122     }
123     $this->sieve_handle = $this->sieve_handle;
124   }
127   /* Return a sieve class handle,
128    *  false if login fails
129    */
130   function get_sieve()
131   {
132     
133     /* Connect to sieve class and try to get all available sieve scripts */
134     if(isset($this->config->data['SERVERS']['IMAP'][$this->parent->gosaMailServer])){
135       $cfg=  $this->config->data['SERVERS']['IMAP'][$this->parent->gosaMailServer];
136       $this->Sieve_Error = "";
138       $uattrib = $this->uattrib;
140       /* Log into the mail server */
141       $this->sieve_handle= new sieve(
142           $cfg["sieve_server"], 
143           $cfg["sieve_port"], 
144           $this->parent->$uattrib, 
145           $cfg["password"], 
146           $cfg["admin"]);
148       /* Try to login */
149       if (!@$this->sieve_handle->sieve_login()){
150         $this->Sieve_Error = $this->sieve_handle->error_raw;
151         return(FALSE);
152       }
153       return($this->sieve_handle);
154     }else{
155       $this->Sieve_Error = sprintf(_("The specified mail server '%s' does not exist within the GOsa configuration."),
156         $this->parent->gosaMailServer);
157       return(FALSE);
158     }
159   }
162   /* Handle sieve list 
163    */
164   function execute()
165   {
166     /***************
167      * Create a new Script 
168      ***************/
170     /* Force opening the add script dialog */
171     if(isset($_POST['create_new_script'])){
172       $this->create_script = TRUE;
173     }
175     /* Close add script dialog, without adding a new one */
176     if(isset($_POST['create_script_cancel'])){
177       $this->create_script = FALSE;
178     }
180     /* Display create script dialog 
181      *  handle posts, display warnings if specified 
182      *  name is not useable. 
183      * Create a new script with given name
184      */
185     if($this->create_script){
186     
187       /* Set initial name or used posted name if available */
188       $name = "";
189       if(isset($_POST['NewScriptName'])){
190         $name = trim($_POST['NewScriptName']);
191       }
192  
193       /* Check given name */ 
194       $err = "";
196       /* Is given name in lower case characters ? */
197       if(isset($_POST['create_script_save'])){
198         if(!strlen($name)){
199           $err = _("You should specify a name for your new script.");
200         }
201         /* Is given name in lower case characters ? */
202         if($name != strtolower($name)){
203           $err = _("Only lower case names are allowed here.");
204         }
206         /* Only chars are allowed here */
207         if(preg_match("/[^a-z]/i",$name)){
208           $err = _("Only a-z are allowed in script names.");
209         }
211         $tmp = $this->get_used_script_names();
212         if(in_array_ics($name,$tmp)){
213           $err =_("The specified name is already in use.");
214         }
215       }
217       /* Create script if everything is ok */
218       if($this->create_script && isset($_POST['create_script_save']) && $err == "" ){
220         /* Close dialog */
221         $this->create_script = FALSE;
223         /* Script contents to use */
224         $script = "/*New script */".
225                   "stop;";
227         /* Create a new parser and initialize default values */
228         $p = new My_Parser($this);
229         $ret = $p->parse($script);
230         $sc['SCRIPT'] = $script;
231         $sc['ORIG_SCRIPT'] = $script;
232         $sc['IS_NEW'] = TRUE;
233         $sc['MSG']   = "";
234         if(!$ret){
235           $sc['STATUS']   = FALSE;
236           $sc['MODE']    = "Source";
237           $sc['MSG'] = _("Parse failed")."<font color='red'>".$p->status_text."</font>";
238         }else{
239           $sc['STATUS']   = TRUE;
240           $sc['MODE']    = "Structured";
241           $sc['MSG'] = _("Parse successful");
242         }
243         $sc['PARSER'] = $p;
244         $sc['EDITED'] = TRUE;
245         $sc['ACTIVE'] = FALSE;
246         $sc['NAME']   = $name;
247       
248         /* Add script */
249         $this->scripts[$name] = $sc;
250       }else{
251       
252         /* Display dialog to enter new script name */
253         $smarty = get_smarty();
254         $smarty->assign("NewScriptName",$name);
255         $smarty->assign("Error",$err);
256         return($smarty->fetch(get_template_path("templates/create_script.tpl",TRUE,dirname(__FILE__))));
257       }
258     }
261     /*************
262      * Handle several posts 
263      *************/
265     $once = TRUE;
266     foreach($_POST as $name => $value){
268       /* Edit script requested */
269       if(preg_match("/^editscript_/",$name) && $once && !$this->current_handler){
270         $script = preg_replace("/^editscript_/","",$name);
271         $script = preg_replace("/_(x|y)/","",$script);
272         $once = FALSE;
274         $this->current_script = $script;
275         $this->current_handler = $this->scripts[$script]['PARSER'];
276         $this->scripts[$script]['SCRIPT_BACKUP'] = $this->scripts[$script]['SCRIPT'];
277       }
279       /* remove script requested */
280       if($this->parent->acl_is_writeable("sieveManagement") && preg_match("/^delscript_/",$name) && $once && !$this->current_handler){
281         $script = preg_replace("/^delscript_/","",$name);
282         $script = preg_replace("/_(x|y)/","",$script);
283         $once = FALSE;
284         $this->script_to_delete = $script;  
285       }
287       /* Activate script */
288       if($this->parent->acl_is_writeable("sieveManagement") && preg_match("/^active_script_/",$name) && $once && !$this->current_handler){
289         $script = preg_replace("/^active_script_/","",$name);
290         $script = preg_replace("/_(x|y)/","",$script);
291         $once = FALSE;
293         /* We can only activate existing scripts */
294         if(!$this->scripts[$script]['IS_NEW']){
296           /* Get sieve */
297           if(!$this->sieve_handle = $this->get_sieve()){
298             print_red(
299                 sprintf(
300                   _("Can't log into SIEVE server. Server says '%s'."),
301                   to_string($this->Sieve_Error)));
302           }
304           /* Try to activate the given script and update 
305            *  class script array. 
306            */
307           if(!$this->sieve_handle->sieve_setactivescript($this->scripts[$script]['NAME'])){
308             print_red(sprintf(_("Can't activate sieve script on server. Server says '%s'."),to_string($this->sieve_handle->error_raw)));
309           }else{
310             foreach($this->scripts as $key => $data){
311               if($key == $script){
312                 $this->scripts[$key]['ACTIVE'] = TRUE;
313               }else{
314                 $this->scripts[$key]['ACTIVE'] = FALSE;
315               }
316             }
317           }
318         }
319       }
320     }
322     
323     /*************
324      * Remove script handling 
325      *************/
327     /* Remove aborted */
328     if(isset($_POST['delete_cancel'])){
329       $this->script_to_delete = -1;
330     }
332     /* Remove confirmed */
333     if($this->parent->acl_is_writeable("sieveManagement") && isset($_POST['delete_script_confirm'])){
335       $script = $this->scripts[$this->script_to_delete];
337       /* Just remove from array if it is a new script */
338       if($script['IS_NEW']){
339         unset($this->scripts[$this->script_to_delete]);
340       }else{
342         /* Get sieve */
343         if(!$this->sieve_handle = $this->get_sieve()){
344           print_red(
345               sprintf(
346                 _("Can't log into SIEVE server. Server says '%s'."),
347                 to_string($this->Sieve_Error)));
348         }
350         if(!$this->sieve_handle->sieve_deletescript($this->scripts[$this->script_to_delete]['NAME'])){
351           print_red(sprintf(_("Can't remove sieve script from server. Server says '%s'."),to_string($this->sieve_handle->error_raw)));
352         }else{
353           unset($this->scripts[$this->script_to_delete]);
354         }
355       }
356       $this->script_to_delete = -1;
357     }
359     /* Display confirm dialog */
360     if($this->script_to_delete != -1){
361       $smarty = get_smarty();
362       $smarty->assign("Warning",
363           sprintf(_("You are going to remove the sieve script '%s' from your mail server."),
364             $this->scripts[$this->script_to_delete]['NAME']));
365       return($smarty->fetch(get_template_path("templates/remove_script.tpl",TRUE,dirname(__FILE__))));
366     }
369     /**************
370      * Save script changes 
371      **************/
373     /* Abort saving */
374     if(isset($_POST['cancel_sieve_changes'])){
375       $tmp = $this->scripts[$this->current_script]['SCRIPT_BACKUP'];
376       $this->scripts[$this->current_script]['SCRIPT'] = $tmp;
377       $this->scripts[$this->current_script]['PARSER']->parse($tmp);
378       $this->current_handler = NULL;
379     }
381     /* Save currently edited sieve script. */
382     if($this->parent->acl_is_writeable("sieveManagement") && 
383        isset($_POST['save_sieve_changes']) && 
384        is_object($this->current_handler)){
385       $chk = $this->current_handler->check();
386       if(!count($chk)){
388         $sc = $this->scripts[$this->current_script]['SCRIPT'];
389         $p = new My_Parser($this);
390         if($p -> parse($sc)){
392           if($this->scripts[$this->current_script]['MODE'] == "Source-Only"){
393             $this->scripts[$this->current_script]['MODE'] = "Source";
394           }
395   
396           $this->scripts[$this->current_script]['PARSER'] = $p;
397           $this->scripts[$this->current_script]['EDITED'] = TRUE;
398           $this->scripts[$this->current_script]['STATUS'] = TRUE;
399           $this->scripts[$this->current_script]['MSG'] = _("Edited");
400           $this->current_handler = NULL;
401         }else{
402           print_red($p->status_text);;
403         }
404       }else{
405         foreach($chk as $msgs){
406           print_red(sprintf(_("Please fix all errors before saving. Last error was : %s"),$msgs));
407         }
408       }
409     }
412     /*************
413      * Display edit dialog 
414      *************/
416     /* Display edit dialog, depending on Mode display different uis
417      */
418     if($this->current_handler){
420         if(isset($_POST['Import_Script'])){
421           $this->Import_Script = TRUE;
422         }
424         if(isset($_POST['Import_Script_Cancel'])){
425           $this->Import_Script = FALSE;
426         }
428         if(isset($_POST['Import_Script_Save']) && isset($_FILES['Script_To_Import'])){
430           $file     = $_FILES['Script_To_Import'];
432           if($file['size'] == 0){
433             print_red(_("Specified file seams to empty."));
434           }elseif(!file_exists($file['tmp_name'])){
435             print_red(_("Upload failed, somehow nothing was uploaded or the temporary file can't be accessed."));
436           }elseif(!is_readable ($file['tmp_name'])){
437             print_red(sprintf(_("Can't open file '%s' to read uploaded file contents."),$file['tmp_name']));
438           }else{
439             
440             
441  
442             $contents = file_get_contents($file['tmp_name']);
443            
444             $this->scripts[$this->current_script]['SCRIPT'] = $contents;
445             if(!$this->current_handler->parse($contents)){
446               $this->scripts[$this->current_script]['MODE'] = "Source";
447             }else{
448               $this->scripts[$this->current_script]['MODE'] = "Structured";
449             }
450             $this->Script_Error = "";
451             $this->Import_Script = FALSE;
452           }
453         }
455         if($this->Import_Script){
456           $smarty = get_smarty();
457           $str = $smarty->fetch(get_template_path("templates/import_script.tpl",TRUE,dirname(__FILE__)));
458           return($str);
459         }
460   
462         /* Create dump of current sieve script */
463         if(isset($_POST['Save_Copy'])){
465             /* force download dialog */
466             header("Content-type: application/tiff\n");
467             if (preg_match('/MSIE 5.5/', $HTTP_USER_AGENT) ||
468                     preg_match('/MSIE 6.0/', $HTTP_USER_AGENT)) {
469                 header('Content-Disposition: filename="dump.script"');
470             } else {
471                 header('Content-Disposition: attachment; filename="dump.script"');
472             }
473             header("Content-transfer-encoding: binary\n");
474             header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
475             header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT");
476             header("Cache-Control: no-cache");
477             header("Pragma: no-cache");
478             header("Cache-Control: post-check=0, pre-check=0");
479             echo $this->scripts[$this->current_script]['SCRIPT'];
480             exit();
481         }
484       /****
485        * Add new element to ui
486        ****/
488       /* Abort add dialog */ 
489       if(isset($_POST['select_new_element_type_cancel'])){
490         $this->add_new_element = FALSE;
491       }
493       /* Add a new element */
494       if($this->add_new_element){
496         $element_types= array(
497             "sieve_keep"      => _("Keep"),
498             "sieve_comment"   => _("Comment"),
499             "sieve_fileinto"  => _("File into"),
500             "sieve_keep"      => _("Keep"),
501             "sieve_discard"   => _("Discard"),
502             "sieve_redirect"  => _("Redirect"),
503             "sieve_reject"    => _("Reject"),
504             "sieve_require"   => _("Require"),
505             "sieve_stop"      => _("Stop"),
506             "sieve_vacation"  => _("Vacation message"),
507             "sieve_if"        => _("If"));
510         /* Element selected */
511         if(isset($_POST['element_type']) && isset($element_types[$_POST['element_type']]) 
512            || isset($_POST['element_type']) &&in_array($_POST['element_type'],array("sieve_else","sieve_elsif"))){
513           $this->add_element_type = $_POST['element_type'];
514         }
516         /* Create new element and add it to
517          *  the selected position 
518          */
519         if(isset($_POST['select_new_element_type'])){
520           if($this->add_new_element_to_current_script($this->add_element_type,$this->add_new_id,$this->add_above_below)){
521             $this->add_new_element = FALSE;
522           }else{
523             print_red(_("Failed to add new element."));
524           }
525         }
526       }
528       /* Only display select dialog if it is necessary */
529       if($this->add_new_element){
530         $smarty = get_smarty();
531     
532         $add_else_elsif = FALSE;
534         /* Check if we should add else/elsif to the select box 
535          *  or not. We can't add else twice!.
536          */
537         if($this->add_above_below == "below"){
539           /* Get posistion of the current element 
540            */
541           foreach($this->current_handler->tree_->pap as $key => $obj){
542         
543             if($obj->object_id == $this->add_new_id && in_array(get_class($obj),array("sieve_if","sieve_elsif"))){
544   
545               /* Get block start/end */
546               $end_id = $this->current_handler->tree_->get_block_end($key);
547               $else_found = FALSE;
548               $elsif_found = FALSE;
549           
550               /* Check if there is already an else in this block 
551                */
552               for($i =  $key ; $i < $end_id ; $i ++){
553                 if(get_class($this->current_handler->tree_->pap[$i]) == "sieve_else"){
554                   $else_found = TRUE;
555                 }
556                 if(get_class($this->current_handler->tree_->pap[$i]) == "sieve_elsif"){
557                   $elsif_found = TRUE;
558                 }
559               }
560   
561               /* Only allow adding 'else' if there is currently 
562                *  no 'else' statement. And don't allow adding 
563                *  'else' before 'elseif'
564                */ 
565               if(!$else_found && (!(get_class($obj) == "sieve_if" && $elsif_found))){
566                 $element_types['sieve_else'] = _("Else");
567               }
568               $element_types['sieve_elsif'] = _("Else if");
569             }
570           }
571         }
573         $smarty->assign("element_types",$element_types );
574         $smarty->assign("element_type",$this->add_element_type);
575         $str = $smarty->fetch(get_template_path("templates/add_element.tpl",TRUE,dirname(__FILE__)));
576         return($str);
577       }
581       /****************
582        * Handle test posts 
583        ****************/
585       /* handle some special posts from test elements 
586        */
587       foreach($_POST as $name => $value){
588         if(preg_match("/^Add_Test_Object_/",$name)) {
589           $name = preg_replace("/^Add_Test_Object_/","",$name);
590           $name = preg_replace("/_(x|y)$/","",$name);
592           $test_types_to_add = array(
593               "address" =>_("Address"),
594               "header"  =>_("Header"),
595               "envelope"=>_("Envelope"),
596               "size"    =>_("Size"),
597               "exists"  =>_("Exists"),
598               "allof"   =>_("All of"),
599               "anyof"   =>_("Any of"),
600               "true"    =>_("True"),
601               "false"   =>_("False"));
603           $smarty = get_smarty();
604           $smarty->assign("ID",$name);
605           $smarty->assign("test_types_to_add",$test_types_to_add);
606           $ret = $smarty->fetch(get_template_path("templates/select_test_type.tpl",TRUE,dirname(__FILE__)));
607           return($ret);
608         }
609       }
611       $current = $this->scripts[$this->current_script];
613       /* Create html results */
614       $smarty = get_smarty();
615       $smarty->assign("Mode",$current['MODE']);
616       if($current['MODE'] == "Structured"){
617         $smarty->assign("Contents",$this->current_handler->tree_->execute());
618       }else{
619         $smarty->assign("Contents",$current['SCRIPT']);
620       }
621       $smarty->assign("Script_Error",$this->Script_Error);
622       $ret = $smarty->fetch(get_template_path("templates/edit_frame_base.tpl",TRUE,dirname(__FILE__)));
623       return($ret);
624     }
627     /* Create list of available sieve scripts 
628      */
629     $List = new divSelectBox("sieveManagement");
630     foreach($this->scripts as $key => $script){
631   
632       $edited =  $script['EDITED'];
633       $active =  $script['ACTIVE'];
634       
635       $field1 = array("string" => "&nbsp;",
636                       "attach" => "style='width:20px;'");  
637       if($active){
638         $field1 = array("string" => "<img src='images/true.png' alt='"._("Active")."' 
639                                       title='"._("This script is marked as active")."'>",
640                         "attach" => "style='width:20px;'");  
641       }
642       $field2 = array("string" => $script['NAME']);  
643       $field3 = array("string" => $script['MSG']);
644       $field4 = array("string" => _("Script length")."&nbsp;:&nbsp;".strlen($script['SCRIPT']));
646       if($this->parent->acl_is_writeable("sieveManagement")){
647         $del = "<input type='image' name='delscript_".$key."' src='images/edittrash.png'
648                   title='"._("Remove script")."'>";
649       }else{
650         $del = "<img src='images/empty' alt=' '>";
651       }
653       if($active || $script['IS_NEW'] || !$this->parent->acl_is_writeable("sieveManagement")){
654         $activate = "<img src='images/empty' alt=' '>";
655       }else{
656         $activate = "<input type='image' name='active_script_".$key."' src='images/true.png'
657                        title='"._("Activate script")."'>";
658       }
660       $field6 = array("string" => $activate."<input type='image' name='editscript_".$key."' src='images/edit.png'
661                         title='"._("Edit script")."'>".$del,
662                       "attach" => "style='border-right:0px; width:70px;'");
663       $List ->AddEntry(array($field1,$field2,$field3,$field4,$field6)); 
664     }
665  
666     /* If the uattrib is empty   (Attribute to use for authentification with sieve)
667      *  Display a message that the connection can't be established.
668      */
669     $uattrib = $this->uattrib;
670     $smarty = get_smarty();
672     if(!$this->get_sieve()){
673       $smarty->assign("Sieve_Error",sprintf(
674         _("Can't log into SIEVE server. Server says '%s'."),
675           to_string($this->Sieve_Error)));
676     }else{
677       $smarty->assign("Sieve_Error","");
678     }
680     $smarty->assign("uattrib_empty",empty($this->parent->$uattrib));
681     $smarty->assign("List",$List->DrawList());
682     return($smarty->fetch(get_template_path("templates/management.tpl",TRUE,dirname(__FILE__))));
683   }
686   /* Add a new element to the currently opened script editor.
687    * The insert position is specified by 
688    */
689   function add_new_element_to_current_script($type,$id,$position)
690   {
691     /* Test given data */
692     if(!in_array_ics($position,array("above","below"))){
693       trigger_error("Can't add new element with \$position=".$position.". Only 'above','below' are allowed here.");
694       return(FALSE);
695     }
696     if(!is_numeric($id)){
697       trigger_error("Can't add new element, given id is not numeric.");
698       return(FALSE);
699     }
700     $tmp = get_declared_classes();  
701     if(!in_array($type,$tmp)){
702       if(!empty($type)){
703         trigger_error("Can't add new element, given \$class=".$class." does not exists.");
704       }
705       return(FALSE);
706     }
707     if(!is_object($this->current_handler) || get_class($this->current_handler) != "My_Parser"){
708       trigger_error("Can't add new element, there is no valid script editor opened.");
709       return(FALSE);
710     }
712     /* These element types are allowed to be added here */
713     $element_types= array(
714         "sieve_keep"      => _("Keep"),
715         "sieve_comment"   => _("Comment"),
716         "sieve_fileinto"  => _("File into"),
717         "sieve_keep"      => _("Keep"),
718         "sieve_discard"   => _("Discard"),
719         "sieve_redirect"  => _("Redirect"),
720         "sieve_reject"    => _("Reject"),
721         "sieve_require"   => _("Require"),
722         "sieve_stop"      => _("Stop"),
723         "sieve_vacation"  => _("Vacation message"),
724         "sieve_if"        => _("If"));
726     /* Check if we should add else/elsif to the select box
727      *  or not. We can't add else twice!.
728      */
730     /* Get posistion of the current element
731      */
732     foreach($this->current_handler->tree_->pap as $key => $obj){
734       if($obj->object_id == $id && in_array(get_class($obj),array("sieve_if","sieve_elsif"))){
736         /* Get block start/end */
737         $end_id = $this->current_handler->tree_->get_block_end($key);
738         $else_found = FALSE;
739         $elsif_found = FALSE;
741         /* Check if there is already an else in this block
742          */
743         for($i =  $key ; $i < $end_id ; $i ++){
744           if(get_class($this->current_handler->tree_->pap[$i]) == "sieve_else"){
745             $else_found = TRUE;
746           }
747           if(get_class($this->current_handler->tree_->pap[$i]) == "sieve_elsif"){
748             $elsif_found = TRUE;
749           }
750         }
752         if($this->add_above_below == "below"){
754           /* Only allow adding 'else' if there is currently
755            *  no 'else' statement. And don't allow adding
756            *  'else' before 'elseif'
757            */
758           if(!$else_found && (!(get_class($obj) == "sieve_if" && $elsif_found))){
759             $element_types['sieve_else'] = _("Else");
760           }
761           $element_types['sieve_elsif'] = _("Else if");
762         }else{
763          
764           /* Allow adding elsif above elsif */ 
765           if(in_array(get_class($obj),array("sieve_elsif"))){
766             $element_types['sieve_elsif'] = _("Else if");
767           }
768         }
769       }
770     }
772     if(!isset($element_types[$type])){
773       print_red(sprintf(_("Can't add the specified element at the given position.")));
774       return;
775     }
778     /* Create elements we should add 
779      * -Some element require also surrounding block elements
780      */
781     $parent = $this->current_handler->tree_;
782     if($this->add_element_type == "sieve_if"){
783       $ele[] = new $this->add_element_type(NULL, preg_replace("/[^0-9]/","",microtime()),$parent);
784       $ele[] = new sieve_block_start(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
785       $ele[] = new sieve_block_end(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
786     }elseif($this->add_element_type == "sieve_else"){
787       $ele[] = new sieve_block_end(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
788       $ele[] = new $this->add_element_type(NULL, preg_replace("/[^0-9]/","",microtime()),$parent);
789       $ele[] = new sieve_block_start(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
790     }elseif($this->add_element_type == "sieve_elsif"){
791       $ele[] = new sieve_block_end(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
792       $ele[] = new $this->add_element_type(NULL, preg_replace("/[^0-9]/","",microtime()),$parent);
793       $ele[] = new sieve_block_start(NULL,preg_replace("/[^0-9]/","",microtime()),$parent);
794     }else{
795       $ele[] = new $this->add_element_type(NULL, preg_replace("/[^0-9]/","",microtime()),$parent);
796     }
798     /* Get index of the element identified by object_id == $id; 
799      */
800     $index = -1;
801     $data = $this->current_handler->tree_->pap;
802     foreach($data as $key => $obj){
803       if($obj->object_id == $id && $index==-1){
804         $index = $key;
805       }
806     }
808     /* Tell to user that we couldn't find the given object 
809      *  so we can't add an element. 
810      */
811     if($index == -1 ){
812       trigger_error("Can't add new element, specified \$id=".$id." could not be found in object tree.");
813       return(FALSE);
814     }
816     /* We have found the specified object_id 
817      *  and want to detect the next free position 
818      *  to insert the new element.
819      */
820     if($position == "above"){
821       $direction ="up";
822       $next_free = $this->current_handler->tree_->_get_next_free_move_slot($index,$direction,TRUE);
823     }else{
824       $direction = "down";
825       $next_free = $this->current_handler->tree_->_get_next_free_move_slot($index,$direction,TRUE);
826     }
827     /* This is extremly necessary, cause some objects 
828      *  updates the tree objects ... Somehow i should change this ... 
829      */
830     $data = $this->current_handler->tree_->pap;
831     $start = $end = array();
833     if($position == "above"){
834       $start = array_slice($data,0,$next_free);
835       $end   = array_slice($data,$next_free);
836     }else{
837       $start = array_slice($data,0,$next_free+1);
838       $end   = array_slice($data,$next_free+1);
839     }
841     $new = array();
842     foreach($start as $obj){
843       $new[] = $obj;
844     }
845     foreach($ele as $el){
846       $new[] = $el;
847     }
848     foreach($end as $obj){
849       $new[] = $obj;
850     }
851     $data= $new;
852     $this->current_handler->tree_->pap = $data;
853     return(TRUE);
854   }
858   function save_object()
859   {
860     if($this->current_handler){
862       if(isset($_GET['Add_Object_Top_ID'])){
863         $this->add_new_element    = TRUE;
864         $this->add_new_id         = $_GET['Add_Object_Top_ID'];
865         $this->add_above_below    = "above";
866       }  
868       if(isset($_GET['Add_Object_Bottom_ID'])){
869         $this->add_new_element    = TRUE;
870         $this->add_new_id         = $_GET['Add_Object_Bottom_ID'];
871         $this->add_above_below    = "below";
872       }  
874       if(isset($_GET['Remove_Object_ID'])){
875         $found_id = -1;
876         foreach($this->current_handler->tree_->pap as $key => $element){
877           if($element->object_id == $_GET['Remove_Object_ID']){
878             $found_id = $key;
879           }
880         }
881         if($found_id != -1 ){
882           $this->current_handler->tree_->remove_object($found_id);  
883         }
884       }  
885  
886       if(isset($_GET['Move_Up_Object_ID'])){
887         $found_id = -1;
888         foreach($this->current_handler->tree_->pap as $key => $element){
889           if($element->object_id == $_GET['Move_Up_Object_ID']){
890             $found_id = $key;
891           }
892         }
893         if($found_id != -1 ){
894           $this->current_handler->tree_->move_up_down($found_id,"up");
895         }
896       }  
897  
898       if(isset($_GET['Move_Down_Object_ID'])){
899         $found_id = -1;
900         foreach($this->current_handler->tree_->pap as $key => $element){
901           if($element->object_id == $_GET['Move_Down_Object_ID']){
902             $found_id = $key;
903           }
904         }
905         if($found_id != -1 ){
906           $this->current_handler->tree_->move_up_down($found_id,"down");
907         }
908       }  
909   
911       /* Check if there is an add object requested 
912        */
913       $data = $this->current_handler->tree_->pap;
914       $once = TRUE;
915       foreach($_POST as $name => $value){
916         foreach($data as $key => $obj){
917           if(isset($obj->object_id) && preg_match("/^Add_Object_Top_".$obj->object_id."_/",$name) && $once){
918             $once = FALSE;
919             $this->add_element_type   =  $_POST['element_type_'.$obj->object_id];
920             $this->add_new_element    = FALSE;
921             $this->add_new_id         = $obj->object_id;
922             $this->add_above_below    = "above";
923             $this->add_new_element_to_current_script($this->add_element_type,$this->add_new_id,$this->add_above_below);
924           }
925           if(isset($obj->object_id) && preg_match("/^Add_Object_Bottom_".$obj->object_id."_/",$name) && $once){
926             $once = FALSE;
927             $this->add_element_type   =  $_POST['element_type_'.$obj->object_id];
928             $this->add_new_element    = FALSE;
929             $this->add_new_id         = $obj->object_id;
930             $this->add_above_below    = "below";
931             $this->add_new_element_to_current_script($this->add_element_type,$this->add_new_id,$this->add_above_below);
932           }
933         
934           if(isset($obj->object_id) && preg_match("/^Remove_Object_".$obj->object_id."_/",$name) && $once){
935             $once = FALSE;
936             $this->current_handler->tree_->remove_object($key);
937           }
938           if(isset($obj->object_id) && preg_match("/^Move_Up_Object_".$obj->object_id."_/",$name) && $once){
939             $this->current_handler->tree_->move_up_down($key,"up");
940             $once = FALSE;
941           }
942           if(isset($obj->object_id) && preg_match("/^Move_Down_Object_".$obj->object_id."_/",$name) && $once){
943             $this->current_handler->tree_->move_up_down($key,"down");
944             $once = FALSE;
945           }
946         }
947       }
949       /* Skip Mode changes and Parse tests 
950        *  if we are currently in a subdialog 
951        */
953       $this->current_handler->save_object();
954       $Mode = $this->scripts[$this->current_script]['MODE'];
955       $skip_mode_change = false;
956       if(in_array($Mode,array("Source-Only","Source"))){
957         if(isset($_POST['script_contents'])){
958           $sc = stripslashes($_POST['script_contents']);
959           $this->scripts[$this->current_script]['SCRIPT'] = $sc;
960           $p = new My_Parser($this);
961           if($p -> parse($sc)){
962             $this->Script_Error = "";
963           } else {
964             $this->Script_Error = $p->status_text;
965             $skip_mode_change = TRUE;
966           }
967         }
968       }
969       if(in_array($Mode,array("Structured"))){
970         $sc = $this->current_handler->get_sieve_script();
971         $this->scripts[$this->current_script]['SCRIPT'] = $sc;
972         $p = new My_Parser($this);
973         if($p -> parse($sc)){
974           $this->Script_Error = "";
975         } else {
976           $this->Script_Error = $p->status_text;
977           $skip_mode_change = TRUE;
978         }
979       }
980       if(!$skip_mode_change){
981         if($this->scripts[$this->current_script]['MODE'] != "Source-Only"){
982           $old_mode = $this->scripts[$this->current_script]['MODE'];
983           if(isset($_POST['View_Source'])){
984             $this->scripts[$this->current_script]['MODE'] = "Source";
985           }
986           if(isset($_POST['View_Structured'])){
987             $this->scripts[$this->current_script]['MODE'] = "Structured";
988           }
989           $new_mode = $this->scripts[$this->current_script]['MODE'];
991           if($old_mode != $new_mode){
993             $sc = $this->scripts[$this->current_script]['SCRIPT'];
994             $p = new My_Parser($this);
996             if($p -> parse($sc)){
997               $this->current_handler->parse($sc);
998               $this->Script_Error = "";
999             } else {
1000               $this->Script_Error = $p->status_text;
1001             }
1002           } 
1003         }
1004       }
1005     }
1006   }
1008   
1009   function get_used_script_names()
1010   {
1011     $ret = array();
1012     foreach($this->scripts as $script){
1013       $ret[] = $script['NAME'];
1014     }
1015     return($ret);
1016   }
1020   function save()
1021   {
1022     /* Get sieve */
1023     if(!$this->sieve_handle = $this->get_sieve()){
1024       print_red(
1025           sprintf(
1026             _("Can't log into SIEVE server. Server says '%s'."),
1027             to_string($this->Sieve_Error)));
1028       return;
1029     }
1031     $everything_went_fine = TRUE;
1033     foreach($this->scripts as $key => $script){
1034       if($script['EDITED']){
1035         $data = $this->scripts[$key]['SCRIPT'];
1036         if(!$this->sieve_handle->sieve_sendscript($script['NAME'], addcslashes ($data,"\\"))){
1037           gosa_log("Failed to save sieve script named '".$script['NAME']."': ".to_string($this->sieve_handle->error_raw));
1038           $everything_went_fine = FALSE;
1039           print_red(to_string($this->sieve_handle->error_raw));
1040           $this->scripts[$key]['MSG'] = "<font color='red'>".
1041                                            _("Failed to save sieve script").": ".
1042                                            to_string($this->sieve_handle->error_raw).
1043                                            "</font>";
1044         }
1045       }
1046     }
1047     return($everything_went_fine);
1048   }
1050 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1051 ?>