1 <?php
2 /*!
3 \brief mail plugin
4 \author Fabian Hicker <Fabian.Hickert@GONICUS.de>
5 \version 2.6.2
6 \date 03.12.2007
8 This class provides the functionality to read and write all attributes
9 relevant for gosaMailAccounts from/to the LDAP.
10 It does syntax checking and displays the formulars required.
11 Special handling like sieve or imap actions will be implemented
12 by the mailMethods.
15 Functions :
17 - mailAccount (&$config, $dn= NULL)
18 - execute()
19 - save_object()
20 - get_vacation_templates()
21 - addForwarder($address)
22 - delForwarder($addresses)
23 - addAlternate($address)
24 - delAlternate($addresses)
25 - prepare_vacation_template($contents)
26 - display_forward_dialog()
27 - remove_from_parent()
28 - save()
29 - check()
30 - adapt_from_template($dn, $skip= array())
31 - getCopyDialog()
32 - saveCopyDialog()
33 - PrepareForCopyPaste($source)
34 - get_multi_edit_values()
35 - multiple_check()
36 - set_multi_edit_values($values)
37 - init_multiple_support($attrs,$all)
38 - get_multi_init_values()
39 - multiple_execute()
40 - multiple_save_object()
41 - make_name($attrs)
42 - plInfo()
45 */
47 class mailAccount extends plugin
48 {
49 /* Definitions */
50 var $plHeadline = "Mail";
51 var $plDescription = "This does something";
52 var $view_logged = FALSE;
53 var $is_account = FALSE;
54 var $initially_was_account = FALSE;
56 /* GOsa mail attributes */
57 var $mail = "";
58 var $gosaVacationStart = 0;
59 var $gosaVacationStop = 0;
60 var $gosaMailAlternateAddress = array();
61 var $gosaMailForwardingAddress = array();
62 var $gosaMailDeliveryMode = "[L ]";
63 var $gosaMailServer = "";
64 var $gosaMailQuota = "";
65 var $gosaMailMaxSize = "";
66 var $gosaVacationMessage = "";
67 var $gosaSpamSortLevel = "";
68 var $gosaSpamMailbox = "";
70 /* The methods defaults */
71 var $mailMethod = NULL;
72 var $MailDomain = "";
73 var $sieveManagementUsed = FALSE;
74 var $vacationTemplates = array();
75 var $sieve_management = NULL;
76 var $forward_dialog = FALSE;
77 var $initial_uid = "";
78 var $mailDomainPart = "";
79 var $mailDomainParts = array();
80 var $MailBoxes = array("INBOX");
82 /* Used LDAP attributes && classes */
83 var $attributes= array(
84 "mail", "gosaMailServer","gosaMailQuota", "gosaMailMaxSize","gosaMailForwardingAddress",
85 "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox","gosaMailAlternateAddress",
86 "gosaVacationStart","gosaVacationStop", "gosaVacationMessage", "gosaMailAlternateAddress",
87 "gosaMailForwardingAddress");
88 var $objectclasses= array("gosaMailAccount");
90 var $multiple_support = TRUE;
92 /*! \brief Initialize the mailAccount
93 */
94 function __construct (&$config, $dn= NULL)
95 {
96 plugin::plugin($config,$dn);
98 /* Intialize the used mailMethod
99 */
100 $tmp = new mailMethod($config,$this);
101 $this->mailMethod = $tmp->get_method();
102 $this->mailMethod->fixAttributesOnLoad();
103 $this->mailDomainParts = $this->mailMethod->getMailDomains();
104 $this->SpamLevels = $this->mailMethod->getSpamLevels();
106 /* Remember account status
107 */
108 $this->initially_was_account = $this->is_account;
110 /* Initialize vacation settings
111 */
112 if(empty($this->gosaVacationStart)){
113 $this->gosaVacationStart = time();
114 $this->gosaVacationStop = time();
115 }
117 /* Read vacation templates
118 */
119 $this->vacationTemplates = $this->get_vacation_templates();
121 /* Initialize configured values
122 */
123 if($this->is_account){
125 if($this->mailMethod->connect() && $this->mailMethod->account_exists()){
127 /* Read quota */
128 $this->gosaMailQuota = $this->mailMethod->getQuota($this->gosaMailQuota);
129 if($this->mailMethod->is_error()){
130 msg_dialog::display(_("Mail error"), sprintf(_("Cannot read quota settings! Error was: %s."),
131 $this->mailMethod->get_error()), ERROR_DIALOG);
132 }
134 /* Read mailboxes */
135 $this->MailBoxes = $this->mailMethod->getMailboxList($this->MailBoxes);
136 if($this->mailMethod->is_error()){
137 msg_dialog::display(_("Mail error"), sprintf(_("Cannot get list of mailboxes! Error was: %s."),
138 $this->mailMethod->get_error()), ERROR_DIALOG);
139 }
141 }elseif(!$this->mailMethod->is_connected()){
142 msg_dialog::display(_("Mail error"), sprintf(_("Cannot connect mail method! Error was: %s."),
143 $this->mailMethod->get_error()), ERROR_DIALOG);
144 }elseif(!$this->mailMethod->account_exists()){
145 msg_dialog::display(_("Mail error"), sprintf(_("Mailbox '%s' doesn't exists on mail server: %s."),
146 $this->mailMethod->get_account_id(),$this->gosaMailServer), ERROR_DIALOG);
147 }
149 /* If the doamin part is selectable, we have to split the mail address
150 */
151 if($this->mailMethod->domainSelectionEnabled()){
152 $this->mailDomainPart = preg_replace("/^[^@]*+@/","",$this->mail);
153 $this->mail = preg_replace("/@.*$/","\\1",$this->mail);
154 if(!in_array($this->mailDomainPart,$this->mailDomainParts)){
155 $this->mailDomainParts[] = $this->mailDomainPart;
156 }
157 }
159 /* Load attributes containing arrays */
160 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
161 $this->$val= array();
162 if (isset($this->attrs["$val"]["count"])){
163 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
164 array_push($this->$val, $this->attrs["$val"][$i]);
165 }
166 }
167 }
168 }
170 /* Intialize sieveManagement if necessary */
171 if($this->mailMethod->allowSieveManagement()){
172 $this->mailboxList = &$this->MailBoxes;
173 $this->sieve_management = new sieveManagement($this->config,$this->dn,$this,$this->mailMethod->getUAttrib());
174 }
176 /* Get global filter config used in add local forward
177 */
178 if (!session::is_set("mailfilter")){
179 $ui= get_userinfo();
180 $base= get_base_from_people($ui->dn);
181 $mailfilter= array( "depselect" => $base,
182 "muser" => "",
183 "regex" => "*");
184 session::set("mailfilter", $mailfilter);
185 }
187 /* Disconnect mailMethod. Connect on demand later.
188 */
189 $this->mailMethod->disconnect();
190 }
193 function execute()
194 {
195 /* Call parent execute */
196 $display = plugin::execute();
198 /* Log view */
199 if($this->is_account && !$this->view_logged){
200 $this->view_logged = TRUE;
201 new log("view","users/".get_class($this),$this->dn);
202 }
205 /****************
206 Account status
207 ****************/
209 if(isset($_POST['modify_state'])){
210 if($this->is_account && $this->acl_is_removeable() && $this->mailMethod->accountRemoveAble()){
211 $this->is_account= FALSE;
212 }elseif(!$this->is_account && $this->acl_is_createable() && $this->mailMethod->accountCreateable()){
213 $this->is_account= TRUE;
214 }
215 }
216 if(!$this->multiple_support_active){
217 if (!$this->is_account && $this->parent === NULL){
218 $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\"> <b>".
219 msgPool::noValidExtension(_("Mail"))."</b>";
220 $display.= back_to_main();
221 return ($display);
222 }
223 if ($this->parent !== NULL){
224 if ($this->is_account){
225 $reason = "";
226 if(!$this->mailMethod->accountRemoveable($reason)){
227 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
228 }else{
229 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),msgPool::featuresEnabled(_("Mail")));
230 }
231 } else {
232 $reason = "";
233 if(!$this->mailMethod->accountCreateable($reason)){
234 $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
235 }else{
236 $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),msgPool::featuresDisabled(_("Mail")));
237 }
238 return ($display);
239 }
240 }
241 }
243 /****************
244 Sieve Management Dialog
245 ****************/
246 if($this->mailMethod->allowSieveManagement()){
247 if(isset($_POST['sieveManagement'])
248 && preg_match("/C/",$this->gosaMailDeliveryMode)
249 && $this->acl_is_writeable("sieveManagement")
250 && $this->mailMethod->allowSieveManagement()) {
251 $this->dialog = $this->sieve_management;
252 }
253 if(isset($_POST['sieve_cancel'])){
254 $this->dialog = FALSE;
255 }
256 if(isset($_POST['sieve_finish'])){
257 $this->sieve_management = $this->dialog;
258 $this->dialog = FALSE;
259 }
260 if(is_object($this->dialog)){
261 $this->dialog->save_object();
262 return($this->dialog->execute());
263 }
264 }
266 /****************
267 Forward addresses
268 ****************/
269 if (isset($_POST['add_local_forwarder'])){
270 $this->forward_dialog= TRUE;
271 $this->dialog= TRUE;
272 }
273 if (isset($_POST['add_locals_cancel'])){
274 $this->forward_dialog= FALSE;
275 $this->dialog= FALSE;
276 }
277 if (isset($_POST['add_locals_finish'])){
278 if (isset($_POST['local_list'])){
279 if($this->acl_is_writeable("gosaMailForwardingAddress")){
280 foreach ($_POST['local_list'] as $val){
281 if (!in_array ($val, $this->gosaMailAlternateAddress) &&
282 $val != $this->mail){
283 $this->addForwarder($val);
284 $this->is_modified= TRUE;
285 }
286 }
287 }
288 $this->forward_dialog= FALSE;
289 $this->dialog= FALSE;
290 } else {
291 msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
292 }
293 }
294 if (isset($_POST['add_forwarder'])){
295 if ($_POST['forward_address'] != ""){
296 $address= $_POST['forward_address'];
297 $valid= FALSE;
298 if (!tests::is_email($address)){
299 if (!tests::is_email($address, TRUE)){
300 if ($this->is_template){
301 $valid= TRUE;
302 } else {
303 msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
304 "","","your-address@your-domain.com"),ERROR_DIALOG);
305 }
306 }
307 } elseif ($address == $this->mail
308 || in_array($address, $this->gosaMailAlternateAddress)) {
309 msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
310 } else {
311 $valid= TRUE;
312 }
313 if ($valid){
314 if($this->acl_is_writeable("gosaMailForwardingAddress")){
315 $this->addForwarder ($address);
316 $this->is_modified= TRUE;
317 }
318 }
319 }
320 }
321 if (isset($_POST['delete_forwarder'])){
322 $this->delForwarder ($_POST['forwarder_list']);
323 }
324 if ($this->forward_dialog){
325 return($this->display_forward_dialog());
326 }
329 /****************
330 Alternate addresses
331 ****************/
333 if (isset($_POST['add_alternate'])){
334 $valid= FALSE;
335 if (!tests::is_email($_POST['alternate_address'])){
336 if ($this->is_template){
337 if (!(tests::is_email($_POST['alternate_address'], TRUE))){
338 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),"","","your-domain@your-domain.com"),ERROR_DIALOG);
339 } else {
340 $valid= TRUE;
341 }
342 } else {
343 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),"","","your-domain@your-domain.com"),ERROR_DIALOG);
344 }
345 } else {
346 $valid= TRUE;
347 }
348 if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
349 $ui= get_userinfo();
350 if ($user != $ui->username){
351 msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))." ".
352 sprintf(_("Address is already in use by user '%s'."), $user), ERROR_DIALOG);
353 }
354 }
355 }
356 if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
357 $this->delAlternate ($_POST['alternates_list']);
358 }
360 /****************
361 SMARTY- Assign smarty variables
362 ****************/
363 $smarty = get_smarty();
364 $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
365 $tmp = $this->plInfo();
366 foreach($tmp['plProvidedAcls'] as $name => $transl){
367 $smarty->assign("$name"."ACL", $this->getacl($name,$SkipWrite));
368 }
369 foreach($this->attributes as $attr){
370 $smarty->assign($attr,$this->$attr);
371 }
372 $smarty->assign("quotaEnabled", $this->mailMethod->quotaEnabled());
373 if($this->mailMethod->is_connected()){
374 $smarty->assign("quotaUsage", $this->mailMethod->getQuotaUsage());
375 }else{
376 $smarty->assign("quotaUsage", _("Unknown"));
377 }
378 $smarty->assign("gosaMailQuota",$this->gosaMailQuota);
379 $smarty->assign("domainSelectionEnabled", $this->mailMethod->domainSelectionEnabled());
380 $smarty->assign("MailDomains", $this->mailDomainParts);
381 $smarty->assign("MailDomain" , $this->mailDomainPart);
382 $smarty->assign("MailServers", $this->mailMethod->getMailServers());
383 $smarty->assign("allowSieveManagement", $this->mailMethod->allowSieveManagement());
384 $smarty->assign("own_script", $this->sieveManagementUsed);
386 /* _Multiple users vars_ */
387 foreach($this->attributes as $attr){
388 $u_attr = "use_".$attr;
389 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
390 }
391 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
392 $u_attr = "use_".$attr;
393 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
394 }
397 /****************
398 SMARTY- Assign flags
399 ****************/
401 $types = array(
402 "V"=>"use_vacation",
403 "S"=>"use_spam_filter",
404 "R"=>"use_mailsize_limit",
405 "I"=>"drop_own_mails",
406 "C"=>"own_script");
407 foreach($types as $option => $varname){
408 if (preg_match("/".$option."/", $this->gosaMailDeliveryMode)) {
409 $smarty->assign($varname, "checked");
410 } else {
411 $smarty->assign($varname, "");
412 }
413 }
414 if (!preg_match("/L/", $this->gosaMailDeliveryMode)) {
415 $smarty->assign("only_local", "checked");
416 } else {
417 $smarty->assign("only_local", "");
418 }
421 /****************
422 Smarty- Vacation settings
423 ****************/
424 $smarty->assign("rangeEnabled", FALSE);
425 $smarty->assign("template", "");
426 if (count($this->vacationTemplates)){
427 $smarty->assign("show_templates", "true");
428 $smarty->assign("vacationtemplates", $this->vacationTemplates);
429 if (isset($_POST['vacation_template'])){
430 $smarty->assign("template", $_POST['vacation_template']);
431 }
432 } else {
433 $smarty->assign("show_templates", "false");
434 }
436 /* Vacation range assigments
437 */
438 if($this->mailMethod->vacationRangeEnabled()){
439 $smarty->assign("rangeEnabled", TRUE);
440 if($this->gosaVacationStop ==0){
441 $date= getdate(time());
442 $date["mday"]++;
443 }else{
444 $date= getdate($this->gosaVacationStop);
445 }
446 $smarty->assign("end_day", $date["mday"]);
447 $smarty->assign("end_month", $date["mon"]-1);
448 $smarty->assign("end_year", $date["year"]);
450 if($this->gosaVacationStart == 0){
451 $date= getdate(time());
452 }else{
453 $date= getdate($this->gosaVacationStart);
454 }
455 $smarty->assign("start_day", $date["mday"]);
456 $smarty->assign("start_month", $date["mon"]-1);
457 $smarty->assign("start_year", $date["year"]);
458 $days= array();
459 for($d= 1; $d<32; $d++){
460 $days[$d]= $d;
461 }
462 $years= array();
463 for($y= $date['year']-10; $y<$date['year']+10; $y++){
464 $years[]= $y;
465 }
466 $months= msgPool::months();
467 $smarty->assign("months", $months);
468 $smarty->assign("years", $years);
469 $smarty->assign("days", $days);
471 }
473 /* fill filter settings
474 */
475 $smarty->assign("spamlevel", $this->SpamLevels);
476 $smarty->assign("spambox" , $this->MailBoxes);
478 $smarty->assign("multiple_support",$this->multiple_support_active);
479 return($display.$smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
480 }
484 /* Save data to object */
485 function save_object()
486 {
487 if (isset($_POST['mailTab'])){
489 /* Save ldap attributes */
490 plugin::save_object();
492 /* Get posted mail domain part, if necessary
493 */
494 if($this->mailMethod->domainSelectionEnabled() && isset($_POST['MailDomain'])){
495 if(in_array(get_post('MailDomain'), $this->mailDomainParts)){
496 $this->mailDomainPart = get_post('MailDomain');
497 }
498 }
500 /* Import vacation message?
501 */
502 if (isset($_POST["import_vacation"]) && isset($this->vacationTemplates[$_POST["vacation_template"]])){
503 if($this->multiple_support_active){
504 $contents = file_get_contents($_POST["vacation_template"]);
505 }else{
506 $contents = $this->prepare_vacation_template(file_get_contents($_POST["vacation_template"]));
507 }
508 $this->gosaVacationMessage= htmlspecialchars($contents);
509 }
511 /* Handle flags
512 */
513 if(isset($_POST['own_script'])){
514 if(!preg_match("/C/",$this->gosaMailDeliveryMode)){
515 $str= preg_replace("/[\[\]]/","",$this->gosaMailDeliveryMode);
516 $this->gosaMailDeliveryMode = "[".$str."C]";
517 }
518 }else{
520 /* Assemble mail delivery mode
521 The mode field in ldap consists of values between braces, this must
522 be called when 'mail' is set, because checkboxes may not be set when
523 we're in some other dialog.
525 Example for gosaMailDeliveryMode [LR ]
526 L - Local delivery
527 R - Reject when exceeding mailsize limit
528 S - Use spam filter
529 V - Use vacation message
530 C - Use custm sieve script
531 I - Only insider delivery */
533 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
536 /* Handle delivery flags */
537 if($this->acl_is_writeable("gosaMailDeliveryModeL")){
538 if(!preg_match("/L/",$tmp) && !isset($_POST['only_local'])){
539 $tmp.="L";
540 }elseif(preg_match("/L/",$tmp) && isset($_POST['only_local'])){
541 $tmp = preg_replace("/L/","",$tmp);
542 }
543 }
544 $opts = array(
545 "R" => "use_mailsize_limit",
546 "S" => "use_spam_filter",
547 "V" => "use_vacation",
548 "C" => "own_script",
549 "I" => "drop_own_mails");
551 foreach($opts as $flag => $post){
552 if($this->acl_is_writeable("gosaMailDeliveryMode".$flag)){
553 if(!preg_match("/".$flag."/",$tmp) && isset($_POST[$post])){
554 $tmp.= $flag;
555 }elseif(preg_match("/".$flag."/",$tmp) && !isset($_POST[$post])){
556 $tmp = preg_replace("/".$flag."/","",$tmp);
557 }
558 }
559 }
561 $tmp= "[$tmp]";
562 if ($this->gosaMailDeliveryMode != $tmp){
563 $this->is_modified= TRUE;
564 }
565 $this->gosaMailDeliveryMode= $tmp;
566 if($this->mailMethod->vacationRangeEnabled()){
567 if($this->acl_is_writeable("gosaVacationMessage") && preg_match("/V/",$this->gosaMailDeliveryMode)){
568 if(isset($_POST['gosaVacationStart'])){
569 $this->gosaVacationStart = $_POST['gosaVacationStart'];
570 }
571 if(isset($_POST['gosaVacationStop'])){
572 $this->gosaVacationStop = $_POST['gosaVacationStop'];
573 }
574 }
575 }
576 }
577 }
578 }
581 /*! \brief Parse vacation templates and build up an array
582 containing 'filename' => 'description'.
583 Used to fill vacation dropdown box.
584 @return Array All useable vacation templates.
585 */
586 function get_vacation_templates()
587 {
588 $vct = array();
589 if ($this->config->get_cfg_value("vacationTemplateDirectory") != ""){
590 $dir= $this->config->get_cfg_value("vacationTemplateDirectory");
591 if (is_dir($dir) && is_readable($dir)){
592 $dh = opendir($dir);
593 while($file = readdir($dh)){
594 $description= "";
595 if (is_file($dir."/".$file)){
596 $fh = fopen($dir."/".$file, "r");
597 $line= fgets($fh, 256);
598 if (!preg_match('/^DESC:/', $line)){
599 msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
600 }else{
601 $description= trim(preg_replace('/^DESC:\s*/', '', $line));
602 }
603 fclose ($fh);
604 }
605 if ($description != ""){
606 $vct["$dir/$file"]= $description;
607 }
608 }
609 closedir($dh);
610 }
611 }
612 return($vct);
613 }
616 /*! \brief Adds the given mail address to the list of mail forwarders
617 */
618 function addForwarder($address)
619 {
620 if(empty($address)) return;
621 if($this->acl_is_writeable("gosaMailForwardingAddress")){
622 $this->gosaMailForwardingAddress[]= $address;
623 $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
624 sort ($this->gosaMailForwardingAddress);
625 reset ($this->gosaMailForwardingAddress);
626 $this->is_modified= TRUE;
627 }else{
628 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
629 }
630 }
633 /*! \brief Removes the given mail address from the list of mail forwarders
634 */
635 function delForwarder($addresses)
636 {
637 if($this->acl_is_writeable("gosaMailForwardingAddress")){
638 $this->gosaMailForwardingAddress= array_remove_entries ($addresses, $this->gosaMailForwardingAddress);
639 $this->is_modified= TRUE;
640 }else{
641 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
642 }
643 }
646 /*! \brief Add given mail address to the list of alternate adresses ,
647 . check if this mal address is used, skip adding in this case
648 */
649 function addAlternate($address)
650 {
651 if(empty($address)) return;
652 if($this->acl_is_writeable("gosaMailAlternateAddress")){
653 $ldap= $this->config->get_ldap_link();
654 $address= strtolower($address);
656 /* Is this address already assigned in LDAP? */
657 $ldap->cd ($this->config->current['BASE']);
658 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)".
659 "(alias=$address)(gosaMailAlternateAddress=$address)))", array("uid"));
660 if ($ldap->count() > 0){
661 $attrs= $ldap->fetch ();
662 return ($attrs["uid"][0]);
663 }
664 if (!in_array($address, $this->gosaMailAlternateAddress)){
665 $this->gosaMailAlternateAddress[]= $address;
666 $this->is_modified= TRUE;
667 }
668 sort ($this->gosaMailAlternateAddress);
669 reset ($this->gosaMailAlternateAddress);
670 return ("");
671 }else{
672 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
673 }
674 }
677 /*! \brief Removes the given mail address from the alternate addresses list
678 */
679 function delAlternate($addresses)
680 {
681 if($this->acl_is_writeable("gosaMailAlternateAddress")){
682 $this->gosaMailAlternateAddress= array_remove_entries ($addresses,$this->gosaMailAlternateAddress);
683 $this->is_modified= TRUE;
684 }else{
685 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
686 }
687 }
690 /*! \brief Prepare importet vacation string. \
691 . Replace placeholder like %givenName a.s.o.
692 @param string Vacation string
693 @return string Completed vacation string
694 */
695 private function prepare_vacation_template($contents)
696 {
697 /* Replace attributes */
698 $attrs = array();
699 $obj = NULL;
700 if(isset($this->parent->by_object['user'])){
701 $attrs = $this->parent->by_object['user']->attributes;
702 $obj = $this->parent->by_object['user'];
703 }else{
704 $obj = new user($this->config,$this->dn);
705 $attrs = $obj->attributes;
706 }
707 if($obj){
708 foreach ($attrs as $val){
709 if(preg_match("/dateOfBirth/",$val)){
710 if($obj->use_dob){
711 $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
712 }
713 }else {
714 $contents= preg_replace("/%$val/",
715 $obj->$val, $contents);
716 }
718 /* Replace vacation start and end time */
719 if(preg_match("/%start/",$contents)){
720 $contents = preg_replace("/%start/",date("d.m.Y",$this->gosaVacationStart),$contents);
721 }
722 if(preg_match("/%end/",$contents)){
723 $contents = preg_replace("/%end/",date("d.m.Y",$this->gosaVacationStop),$contents);
724 }
725 }
726 }
727 $contents = ltrim(preg_replace("/^DESC:.*$/m","",$contents),"\n ");
728 return($contents);
729 }
732 /*! \brief Displays a dialog that allows mail address selection.
733 */
734 function display_forward_dialog()
735 {
736 restore_error_handler();
738 $smarty = get_smarty();
739 $ldap= $this->config->get_ldap_link();
741 /* Save data */
742 $mailfilter= session::get("mailfilter");
743 foreach( array("depselect", "muser", "regex") as $type){
744 if (isset($_POST[$type])){
745 $mailfilter[$type]= $_POST[$type];
746 }
747 }
748 if (isset($_GET['search'])){
749 $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
750 if ($s == "**"){
751 $s= "*";
752 }
753 $mailfilter['regex']= $s;
754 }
755 session::set("mailfilter", $mailfilter);
757 /* Get actual list */
758 $mailusers= array ();
759 if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
760 $regex= $mailfilter['regex'];
761 $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
762 } else {
763 $filter= "";
764 }
765 if ($mailfilter['muser'] != ""){
766 $user= $mailfilter['muser'];
767 $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
768 }
770 /* Add already present people to the filter */
771 $exclude= "";
772 foreach ($this->gosaMailForwardingAddress as $mail){
773 $exclude.= "(mail=$mail)";
774 }
775 if ($exclude != ""){
776 $filter.= "(!(|$exclude))";
777 }
778 $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'],
779 array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
780 $ldap->cd($mailfilter['depselect']);
781 $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
782 while ($attrs= $ldap->fetch()){
783 if(preg_match('/%/', $attrs['mail'][0])){
784 continue;
785 }
786 $name= $this->make_name($attrs);
787 $mailusers[$attrs['mail'][0]]= $name."<".
788 $attrs['mail'][0].">";
789 }
790 natcasesort ($mailusers);
791 reset ($mailusers);
793 /* Show dialog */
794 $smarty->assign("search_image", get_template_path('images/lists/search.png'));
795 $smarty->assign("usearch_image", get_template_path('images/lists/search-user.png'));
796 $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
797 $smarty->assign("infoimage", get_template_path('images/info.png'));
798 $smarty->assign("launchimage", get_template_path('images/lists/action.png'));
799 $smarty->assign("mailusers", $mailusers);
800 if (isset($_POST['depselect'])){
801 $smarty->assign("depselect", $_POST['depselect']);
802 }
803 $smarty->assign("deplist", $this->config->idepartments);
804 $smarty->assign("apply", apply_filter());
805 $smarty->assign("alphabet", generate_alphabet());
806 $smarty->assign("hint", print_sizelimit_warning());
807 foreach( array("depselect", "muser", "regex") as $type){
808 $smarty->assign("$type", $mailfilter[$type]);
809 }
810 $smarty->assign("hint", print_sizelimit_warning());
811 $display= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
812 return ($display);
813 }
816 /*! \brief Removes the mailAccount extension from ldap
817 */
818 function remove_from_parent()
819 {
820 /* Cancel if there's nothing to do here */
821 if (!$this->initially_was_account){
822 return;
823 }
825 /* If domain part was selectable, contruct mail address */
826 if($this->mailMethod->domainSelectionEnabled()){
827 $this->mail = $this->mail."@".$this->mailDomainPart;
828 }
830 /* Remove GOsa attributes */
831 plugin::remove_from_parent();
833 /* Zero arrays */
834 $this->attrs['gosaMailAlternateAddress'] = array();
835 $this->attrs['gosaMailForwardingAddress']= array();
838 $this->mailMethod->fixAttributesOnRemove();
839 $this->cleanup();
841 @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,$this->attributes, "Save");
842 $ldap= $this->config->get_ldap_link();
843 $ldap->cd($this->dn);
844 $ldap->modify ($this->attrs);
846 /* Add "view" to logging class */
847 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
848 if (!$ldap->success()){
849 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
850 }
852 /* Let the mailMethod remove this mailbox, e.g. from imap and
853 update shared folder membership, ACL may need to be updated.
854 */
855 if (!$this->is_template){
857 if(!$this->mailMethod->connect()){
858 msg_dialog::display(_("Mail error"), sprintf(_("Cannot connect mail method! Error was: %s."),
859 $this->mailMethod->get_error()), ERROR_DIALOG);
860 }else{
861 if(!$this->mailMethod->deleteMailbox()){
862 msg_dialog::display(_("Mail error"), sprintf(_("Cannot remove mailbox! Error was: %s."),
863 $this->mailMethod->get_error()), ERROR_DIALOG);
864 }
865 if(!$this->mailMethod->updateSharedFolder()){
866 msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions! Error was: %s."),
867 $this->mailMethod->get_error()), ERROR_DIALOG);
868 }
869 }
870 }
871 $this->mailMethod->disconnect();
873 /* Optionally execute a command after we're done */
874 $this->handle_post_events("remove",array("uid" => $this->uid));
875 }
878 /*! \brief Save the mailAccount settings to the ldap database.
879 */
880 function save()
881 {
882 $ldap= $this->config->get_ldap_link();
884 /* If domain part was selectable, contruct mail address */
885 if($this->mailMethod->domainSelectionEnabled()){
886 $this->mail = $this->mail."@".$this->mailDomainPart;
887 }
889 /* Enforce lowercase mail address and trim whitespaces
890 */
891 $this->mail = trim(strtolower($this->mail));
893 /* Call parents save to prepare $this->attrs */
894 plugin::save();
896 /* Save arrays */
897 $this->attrs['gosaMailAlternateAddress'] = $this->gosaMailAlternateAddress;
898 $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
900 if(!$this->mailMethod->vacationRangeEnabled()){
901 $this->attrs['gosaVacationStart'] = $this->attrs['gosaVacationStop'] = array();
902 }elseif (!preg_match('/V/', $this->gosaMailDeliveryMode)){
903 unset($this->attrs['gosaVacationStart']);
904 unset($this->attrs['gosaVacationStop']);
905 }
907 /* Map method attributes */
908 $this->mailMethod->fixAttributesOnStore();
910 /* Save data to LDAP */
911 $ldap->cd($this->dn);
912 $this->cleanup();
913 $ldap->modify ($this->attrs);
915 if (!$ldap->success()){
916 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
917 }
919 /* Log last action */
920 if($this->initially_was_account){
921 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
922 }else{
923 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
924 }
926 /* Only do IMAP actions if we are not a template */
927 if (!$this->is_template){
928 $this->mailMethod->connect();
929 if(!$this->mailMethod->is_connected()){
930 msg_dialog::display(_("Mail error"), sprintf(_("Cannot connect mail method! Error was: %s."),
931 $this->mailMethod->get_error()), ERROR_DIALOG);
932 }else{
933 if(!$this->mailMethod->updateMailbox()){
934 msg_dialog::display(_("Mail error"), sprintf(_("Cannot update mailbox! Error was: %s."),
935 $this->mailMethod->get_error()), ERROR_DIALOG);
936 }
937 if(!$this->mailMethod->setQuota($this->gosaMailQuota)){
938 msg_dialog::display(_("Mail error"), sprintf(_("Cannot write quota settings! Error was: %s."),
939 $this->mailMethod->get_error()), ERROR_DIALOG);
940 }
942 if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){
945 /* Do not write sieve settings if this account is new and
946 doesn't seem to exist.
947 */
948 if(!$this->initially_was_account && !$this->mailMethod->account_exists()){
949 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,
950 "Skipping sieve settings, the account doesn't seem to be created already.</b>","");
951 }else{
952 if(!$this->mailMethod->saveSieveSettings()){
953 msg_dialog::display(_("Mail error"), $this->mailMethod->get_error(), ERROR_DIALOG);
954 }
955 }
956 }else{
958 echo "Check sieve management here";
960 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,
961 "User uses an own sieve script, skipping sieve update.".$str."</b>","");
962 }
964 if(!$this->mailMethod->updateSharedFolder()){
965 msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions! Error was: %s."),
966 $this->mailMethod->get_error()), ERROR_DIALOG);
967 }
968 }
969 }
970 $this->mailMethod->disconnect();
972 /* Optionally execute a command after we're done */
973 if ($this->initially_was_account == $this->is_account){
974 if ($this->is_modified){
975 $this->handle_post_events("modify", array("uid" => $this->uid));
976 }
977 } else {
978 $this->handle_post_events("add", array("uid" => $this->uid));
979 }
980 }
983 /*! \brief Check given values
984 */
985 function check()
986 {
987 if(!$this->is_account){
988 return(array());
989 }
991 $ldap= $this->config->get_ldap_link();
993 /* Call common method to give check the hook */
994 $message= plugin::check();
996 if(empty($this->gosaMailServer)){
997 $message[]= msgPool::noserver(_("Mail"));
998 }
1000 /* Mail address checks */
1001 $mail = $this->mail;
1002 if($this->mailMethod->domainSelectionEnabled()){
1003 $mail.= "@".$this->mailDomainPart;
1004 }
1006 if (empty($mail)){
1007 $message[]= msgPool::required(_("Primary address"));
1008 }
1009 if ($this->is_template){
1010 if (!tests::is_email($mail, TRUE)){
1011 $message[]= msgPool::invalid(_("Mail address"),"","","%givenName.%sn@your-domain.com");
1012 }
1013 } else {
1014 if (!tests::is_email($mail)){
1015 $message[]= msgPool::invalid(_("Mail address"),"","","your-address@your-domain.com");
1016 }
1017 }
1019 /* Check if this mail address is already in use */
1020 $ldap->cd($this->config->current['BASE']);
1021 $filter = "(&(!(objectClass=gosaUserTemplate))(!(uid=".$this->uid."))".
1022 "(objectClass=gosaMailAccount)".
1023 "(|(mail=".$mail.")(alias=".$mail.")(gosaMailAlternateAddress=".$mail.")))";
1024 $ldap->search($filter,array("uid"));
1025 if ($ldap->count() != 0){
1026 $message[]= msgPool::duplicated(_("Mail address"));
1027 }
1030 /* Check quota */
1031 if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
1032 if (!is_numeric($this->gosaMailQuota)) {
1033 $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
1034 } else {
1035 $this->gosaMailQuota= (int) $this->gosaMailQuota;
1036 }
1037 }
1039 /* Check rejectsize for integer */
1040 if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
1041 if (!is_numeric($this->gosaMailMaxSize)){
1042 $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
1043 } else {
1044 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
1045 }
1046 }
1048 /* Need gosaMailMaxSize if use_mailsize_limit is checked */
1049 if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){
1050 $message[]= msgPool::required(_("Mail reject size"));
1051 }
1053 if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
1054 $message[]= msgPool::required(_("Spam folder"));
1055 }
1057 if ($this->mailMethod->vacationRangeEnabled()
1058 && preg_match('/V/', $this->gosaMailDeliveryMode)
1059 && $this->gosaVacationStart > $this->gosaVacationStop){
1060 $message[]= msgPool::invalid(_("Vacation interval"));
1061 }
1062 return($message);
1063 }
1066 /*! \brief Adapt from template, using 'dn'
1067 */
1068 function adapt_from_template($dn, $skip= array())
1069 {
1070 plugin::adapt_from_template($dn, $skip);
1072 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
1074 if (in_array($val, $skip)){
1075 continue;
1076 }
1078 $this->$val= array();
1079 if (isset($this->attrs["$val"]["count"])){
1080 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
1081 $value= $this->attrs["$val"][$i];
1082 foreach (array("sn", "givenName", "uid") as $repl){
1083 if (preg_match("/%$repl/i", $value)){
1084 $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
1085 }
1086 }
1087 array_push($this->$val, strtolower(rewrite($value)));
1088 }
1089 }
1090 }
1091 $this->mail= strtolower(rewrite($this->mail));
1092 }
1095 /*! \brief Creates the mail part for the copy & paste dialog
1096 */
1097 function getCopyDialog()
1098 {
1099 if(!$this->is_account) return("");
1100 $smarty = get_smarty();
1101 $smarty->assign("mail",$this->mail);
1102 $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
1103 $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
1104 $str = $smarty->fetch(get_template_path("copypaste.tpl",TRUE, dirname(__FILE__)));
1106 $ret = array();
1107 $ret['status'] = "";
1108 $ret['string'] = $str;
1109 return($ret);
1110 }
1113 /*! \brief save_object for copy&paste vars
1114 */
1115 function saveCopyDialog()
1116 {
1117 if(!$this->is_account) return;
1119 /* Execute to save mailAlternateAddress && gosaMailForwardingAddress */
1120 $this->execute();
1121 if(isset($_POST['mail'])){
1122 $this->mail = $_POST['mail'];
1123 }
1124 }
1127 /*! \brief Prepare this account to be copied
1128 */
1129 function PrepareForCopyPaste($source)
1130 {
1131 plugin::PrepareForCopyPaste($source);
1133 /* Reset alternate mail addresses */
1134 $this->gosaMailAlternateAddress = array();
1135 }
1138 /*! \brief Prepare this class the be useable when editing multiple users at once
1139 */
1140 function get_multi_edit_values()
1141 {
1142 $ret = plugin::get_multi_edit_values();
1143 if(in_array("gosaMailQuota",$this->multi_boxes)){
1144 $ret['gosaMailQuota'] = $this->gosaMailQuota;
1145 }
1146 $flag_add = $flag_remove = array();
1147 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1148 $opts = array(
1149 "R" => "use_mailsize_limit",
1150 "S" => "use_spam_filter",
1151 "L" => "only_local",
1152 "V" => "use_vacation",
1153 "C" => "own_script",
1154 "I" => "drop_own_mails");
1155 foreach($opts as $flag => $post){
1156 if(in_array($post, $this->multi_boxes)){
1157 if(preg_match("/".$flag."/",$tmp)){
1158 $flag_add[] = $flag;
1159 }else{
1160 $flag_remove[] = $flag;
1161 }
1162 }
1163 }
1164 $ret['flag_add'] = $flag_add;
1165 $ret['flag_remove'] = $flag_remove;
1166 return($ret);
1167 }
1170 /*! \brief Check given input for multiple user edit
1171 */
1172 function multiple_check()
1173 {
1174 $message = plugin::multiple_check();
1176 if(empty($this->gosaMailServer) && in_array("gosaMailServer",$this->multi_boxes)){
1177 $message[]= msgPool::noserver(_("Mail"));
1178 }
1180 /* Check quota */
1181 if ($this->gosaMailQuota != '' && in_array("gosaMailQuota",$this->multi_boxes)){
1182 if (!is_numeric($this->gosaMailQuota)) {
1183 $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
1184 } else {
1185 $this->gosaMailQuota= (int) $this->gosaMailQuota;
1186 }
1187 }
1189 /* Check rejectsize for integer */
1190 if ($this->gosaMailMaxSize != '' && in_array("gosaMailMaxSize",$this->multi_boxes)){
1191 if (!is_numeric($this->gosaMailMaxSize)){
1192 $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
1193 } else {
1194 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
1195 }
1196 }
1198 if(empty($this->gosaSpamMailbox) && in_array("gosaSpamMailbox",$this->multi_boxes)){
1199 $message[]= msgPool::required(_("Spam folder"));
1200 }
1202 if ( in_array("use_vacation",$this->multi_boxes) &&
1203 preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart > $this->gosaVacationStop){
1204 $message[]= msgPool::invalid(_("Vacation interval"));
1205 }
1206 return($message);
1207 }
1210 /*! \brief ...
1211 */
1212 function set_multi_edit_values($values)
1213 {
1214 plugin::set_multi_edit_values($values);
1215 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1216 if(isset($values['flag_add'])){
1217 foreach($values['flag_add'] as $flag){
1218 if(!preg_match("/".$flag."/",$tmp)){
1219 $tmp .= $flag;
1220 }
1221 }
1222 }
1223 if(isset($values['flag_remove'])){
1224 foreach($values['flag_remove'] as $flag){
1225 if(preg_match("/".$flag."/",$tmp)){
1226 $tmp = preg_replace("/".$flag."/","",$tmp);
1227 }
1228 }
1229 }
1230 $this->gosaMailDeliveryMode = "[".$tmp."]";
1232 /* Set vacation message and replace placeholder like %givenName
1233 */
1234 if(isset($values['gosaVacationMessage'])){
1235 $this->gosaVacationMessage = $this->prepare_vacation_template($values['gosaVacationMessage']);
1236 }
1237 }
1240 /*! \brief Initialize plugin to be used as multiple edit class.
1241 */
1242 function init_multiple_support($attrs,$all)
1243 {
1244 plugin::init_multiple_support($attrs,$all);
1245 if(isset($this->multi_attrs['gosaMailQuota'])){
1246 $this->gosaMailQuota = $this->multi_attrs['gosaMailQuota'];
1247 }
1248 }
1251 /*! \brief
1252 */
1253 function get_multi_init_values()
1254 {
1255 $attrs = plugin::get_multi_init_values();
1256 $attrs['gosaMailQuota'] = $this->gosaMailQuota;
1257 return($attrs);
1258 }
1261 /*! \brief Display multiple edit dialog
1262 */
1263 function multiple_execute()
1264 {
1265 return($this->execute());
1266 }
1269 /*! \brief Save posts from multiple edit dialog
1270 */
1271 function multiple_save_object()
1272 {
1273 plugin::multiple_save_object();
1275 $this->save_object();
1276 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
1277 if(isset($_POST["use_".$attr])){
1278 $this->multi_boxes[] = $attr;
1279 }
1280 }
1281 }
1284 /*! \brief Creates the user names for the add_local_forward dialog
1285 */
1286 function make_name($attrs)
1287 {
1288 $name= "";
1289 if (isset($attrs['sn'][0])){
1290 $name= $attrs['sn'][0];
1291 }
1292 if (isset($attrs['givenName'][0])){
1293 if ($name != ""){
1294 $name.= ", ".$attrs['givenName'][0];
1295 } else {
1296 $name.= $attrs['givenName'][0];
1297 }
1298 }
1299 if ($name != ""){
1300 $name.= " ";
1301 }
1303 return ($name);
1304 }
1307 /*! \brief ACL settings
1308 */
1309 static function plInfo()
1310 {
1311 return (array(
1312 "plShortName" => _("Mail"),
1313 "plDescription" => _("Mail settings"),
1314 "plSelfModify" => TRUE,
1315 "plDepends" => array("user"), // This plugin depends on
1316 "plPriority" => 4, // Position in tabs
1317 "plSection" => array("personal" => _("My account")),
1318 "plCategory" => array("users"),
1319 "plOptions" => array(),
1321 "plProvidedAcls" => array(
1322 "mail" => _("Mail address"),
1323 "gosaMailServer" => _("Mail server"),
1324 "gosaMailQuota" => _("Quota size"),
1326 "gosaMailDeliveryModeV" => _("Add vacation information"), // This is flag of gosaMailDeliveryMode
1327 "gosaVacationMessage" => _("Vacation message"),
1329 "gosaMailDeliveryModeS" => _("Use spam filter"), // This is flag of gosaMailDeliveryMode
1330 "gosaSpamSortLevel" => _("Spam level"),
1331 "gosaSpamMailbox" => _("Spam mail box"),
1333 "sieveManagement" => _("Sieve management"),
1335 "gosaMailDeliveryModeR" => _("Reject due to mailsize"), // This is flag of gosaMailDeliveryMode
1336 "gosaMailMaxSize" => _("Mail max size"),
1338 "gosaMailForwardingAddress" => _("Forwarding address"),
1339 "gosaMailDeliveryModeL" => _("Local delivery"), // This is flag of gosaMailDeliveryMode
1340 "gosaMailDeliveryModeI" => _("No delivery to own mailbox "), // This is flag of gosaMailDeliveryMode
1341 "gosaMailAlternateAddress" => _("Mail alternative addresses"),
1343 "gosaMailForwardingAddress" => _("Forwarding address"),
1344 "gosaMailDeliveryModeC" => _("Use custom sieve script")) // This is flag of gosaMailDeliveryMode
1345 ));
1346 }
1349 }
1351 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1352 ?>