1 <?php
2 /*! \brief mail plugin
3 \author Cajus Pollmeier <pollmeier@gonicus.de>
4 \version 2.00
5 \date 24.07.2003
7 This class provides the functionality to read and write all attributes
8 relevant for gosaMailAccounts from/to the LDAP. It does syntax checking
9 and displays the formulars required.
10 */
12 class mailAccount extends plugin
13 {
14 /* Definitions */
15 var $plHeadline = "Mail";
16 var $plDescription = "This does something";
17 var $method = "mailMethod";
19 var $gosaVacationStart = 0;
20 var $gosaVacationStop = 0;
21 var $view_logged = FALSE;
23 /* plugin specific values */
24 var $mail = "";
25 var $gosaMailAlternateAddress = array();
26 var $gosaMailForwardingAddress = array();
27 var $gosaMailDeliveryMode = "[L ]";
28 var $gosaMailServer = "";
29 var $gosaMailQuota = "";
30 var $gosaMailMaxSize = "";
31 var $gosaVacationMessage = "";
32 var $gosaSpamSortLevel = "";
33 var $gosaSpamMailbox = "";
35 var $quotaUsage = 0;
36 var $forward_dialog = FALSE;
37 var $folder_prefix = "";
38 var $mailboxList = array("INBOX");
39 var $default_permissions = "none";
40 var $member_permissions = "post";
41 var $members = array();
42 var $admins = array();
43 var $vacations = array();
44 var $perms = array( "lrs" => "read",
45 "lrsp" => "post",
46 "lrsip" => "append",
47 "lrswipcd" => "write",
48 "lrswipcda" => "all" );
50 /* attribute list for save action */
51 var $attributes= array("mail", "gosaMailServer", "gosaMailQuota", "gosaMailMaxSize","gosaMailForwardingAddress",
52 "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox","gosaMailAlternateAddress","gosaVacationStart","gosaVacationStop",
53 "gosaVacationMessage", "gosaMailAlternateAddress", "gosaMailForwardingAddress");
54 var $objectclasses= array("gosaMailAccount");
55 var $uid = "";
57 var $sieve_management = NULL;
58 var $multiple_support = TRUE;
60 /* constructor, if 'dn' is set, the node loads the given
61 'dn' from LDAP */
62 function mailAccount (&$config, $dn= NULL)
63 {
64 global $class_mapping;
66 $this->gosaVacationStart = time();
67 $this->gosaVacationStop = time();
69 /* Load bases attributes */
70 plugin::plugin($config, $dn);
72 /* Set uid */
73 if(isset($this->attrs['uid'])){
74 $this->uid = $this->attrs['uid'][0];
75 }
77 if(is_array($this->gosaMailServer) && isset($this->gosaMailServer[0])){
78 $this->gosaMailServer = $this->gosaMailServer[0];
79 }
81 /* Save initial account state */
82 $this->initially_was_account= $this->is_account;
84 /* Set mailMethod to the one defined in gosa.conf */
85 if (isset($this->config->current['MAILMETHOD'])){
86 $method= $this->config->current['MAILMETHOD'];
88 $cls = get_correct_class_name("mailMethod$method");
89 if ($cls && class_exists($cls)){
90 $this->method= $cls;
91 } else {
92 msg_dialog::display(_("Configuration error"), sprintf(_("Unkown mail method '%s' specified!"), $method), ERROR_DIALOG);
93 }
94 }
97 /* Create the account prefix user. user/
98 Preset folder prefix. Will change it later to respect
99 altnamespace. */
100 if (isset($this->config->current['CYRUSUNIXSTYLE']) && $this->config->current['CYRUSUNIXSTYLE'] == "true"){
101 $this->folder_prefix= "user/";
102 }elseif (isset($this->config->data['MAIN']['CYRUSUNIXSTYLE']) && $this->config->data['MAIN']['CYRUSUNIXSTYLE'] == "true"){
103 $this->folder_prefix= "user/";
104 } else {
105 $this->folder_prefix= "user.";
106 }
108 /* This is not a new account, parse additional attributes */
109 if (($dn !== NULL) && ($dn != "new") && $this->is_account){
111 /* Load attributes containing arrays */
112 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
113 $this->$val= array();
114 if (isset($this->attrs["$val"]["count"])){
115 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
116 array_push($this->$val, $this->attrs["$val"][$i]);
117 }
118 }
119 }
122 /* Only do IMAP actions if gosaMailServer attribute is set */
123 if (isset ($this->attrs["gosaMailServer"][0])){
125 $method = new $this->method($this->config);
126 $id = $method->uattrib;
128 /* Adapt attributes if needed */
129 $method->fixAttributesOnLoad($this);
131 /* FixAttributesOnLoad possibly creates an array out of gosaMailServer.
132 If the mail tab wasn't opened once before saving, the account can't be saved */
133 if(is_array($this->gosaMailServer)){
134 $this->gosaMailServer = $this->gosaMailServer[0];
135 }
137 if ($method->connect($this->attrs["gosaMailServer"][0])){
139 /* Update quota values */
140 $quota= $method->getQuota($this->folder_prefix.$this->$id);
142 if($quota){
143 if ($quota['gosaMailQuota'] == 2147483647){
144 $this->quotaUsage = "";
145 $this->gosaMailQuota = "";
146 } else {
147 $this->quotaUsage = $quota['quotaUsage'];
148 $this->gosaMailQuota = $quota['gosaMailQuota'];
149 }
150 }else{
151 $this->quotaUsage = "";
152 $this->gosaMailQuota = "";
153 }
155 /* Get mailboxes / folder like INBOX ..*/
156 $this->mailboxList= $method->getMailboxList($this->folder_prefix.$this->$id,$this->$id);
158 $method->disconnect();
159 }else{
160 /* Could not connect to ldap.
161 */
162 if (isset($this->attrs['gosaMailQuota'][0])){
163 $this->gosaMailQuota = $this->attrs['gosaMailQuota'][0];
164 }
165 }
166 }
167 }
169 /* Fill vacation array */
170 $this->vacation= array();
171 if (isset($this->config->current['VACATIONDIR'])){
172 $dir= $this->config->current['VACATIONDIR'];
173 if (is_dir($dir) && is_readable($dir)){
175 /* Look for files and build the vacation array */
176 $dh= opendir($dir);
177 while ($file = readdir($dh)){
178 $description= $this->parse_vacation("$dir/$file");
179 if ($description != ""){
180 $this->vacation["$dir/$file"]= $description;
181 }
182 }
183 closedir($dh);
184 }
185 }
187 /* Create sieve management class */
188 $method = new $this->method($this->config);
189 $id = $method->uattrib;
190 $this->sieve_management = new sieveManagement($this->config,$this->dn,$this,$id);
192 /* Get global filter config */
193 if (!session::is_set("mailfilter")){
194 $ui= get_userinfo();
195 $base= get_base_from_people($ui->dn);
196 $mailfilter= array( "depselect" => $base,
197 "muser" => "",
198 "regex" => "*");
199 session::set("mailfilter", $mailfilter);
200 }
201 }
204 function parse_vacation($file)
205 {
206 $desc= "";
208 if (is_file($file)){
209 $fh = fopen($file, "r");
210 $line= fgets($fh, 256);
212 if (!preg_match('/^DESC:/', $line)){
213 msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
214 return $desc;
215 }
216 fclose ($fh);
218 $desc= trim(preg_replace('/^DESC:\s*/', '', $line));
219 }
221 return $desc;
222 }
225 function execute()
226 {
227 /* Call parent execute */
228 plugin::execute();
230 /* Log view */
231 if($this->is_account && !$this->view_logged){
232 $this->view_logged = TRUE;
233 new log("view","users/".get_class($this),$this->dn);
234 }
236 /* Initialise vars */
238 /* Load templating engine */
239 $smarty= get_smarty();
240 $display= "";
242 /* Get available mailserver */
243 $mailserver= array();
244 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
245 $mailserver[]= $key;
246 }
248 /*
249 * Sieve Management
250 */
251 if(isset($_POST['sieveManagement'])
252 && preg_match("/C/",$this->gosaMailDeliveryMode)
253 && $this->acl_is_writeable("sieveManagement")) {
255 $this->dialog = $this->sieve_management;
256 }
258 /* Cancel sieve edit */
259 if(isset($_POST['sieve_cancel'])){
260 $this->dialog = FALSE;
261 }
263 /* Save sieve changes */
264 if(isset($_POST['sieve_finish'])){
265 $this->sieve_management = $this->dialog;
266 $this->dialog = FALSE;
267 }
269 if(is_object($this->dialog)){
270 $this->dialog->save_object();
271 return($this->dialog->execute());
272 }
275 /* Handle account state */
276 /* Do we need to flip is_account state? */
277 if(isset($_POST['modify_state'])){
278 if($this->is_account && $this->acl_is_removeable()){
279 $this->is_account= FALSE;
280 }elseif(!$this->is_account && $this->acl_is_createable()){
281 $this->is_account= TRUE;
282 }
283 }
285 /* Do we represent a valid account? */
286 if(!$this->multiple_support_active){
287 if (!$this->is_account && $this->parent === NULL){
288 $display= "<img alt=\"\" src=\"images/stop.png\" align=\"middle\"> <b>".
289 _("This account has no mail extensions.")."</b>";
291 $display.= back_to_main();
292 return ($display);
293 }
295 /* Show tab dialog headers */
296 if ($this->parent !== NULL){
297 if ($this->is_account){
298 if($this->accountDelegationsConfigured()){
299 $display= $this->show_disable_header(_("Remove mail account"),
300 _("This account can't be removed while there are delegations configured. Remove those delegations first."),TRUE,TRUE);
301 }else{
302 $display= $this->show_disable_header(_("Remove mail account"),
303 _("This account has mail features enabled. You can disable them by clicking below."));
304 }
305 } else {
306 $display= $this->show_enable_header(_("Create mail account"), _("This account has mail features disabled. You can enable them by clicking below."));
307 return ($display);
308 }
309 }
310 }
312 /* Forwarder subdialog */
314 /* Trigger forward add dialog? */
315 if (isset($_POST['add_local_forwarder'])){
316 $this->forward_dialog= TRUE;
317 $this->dialog= TRUE;
318 }
320 /* Cancel forward add dialog? */
321 if (isset($_POST['add_locals_cancel'])){
322 $this->forward_dialog= FALSE;
323 $this->dialog= FALSE;
324 }
326 /* Finished adding of locals? */
327 if (isset($_POST['add_locals_finish'])){
329 /* Check if we are able to write gosaMailForwardingAddress */
330 if($this->acl_is_writeable("gosaMailForwardingAddress")){
332 /* Walk through list of forwarders, ignore own addresses */
333 foreach ($_POST['local_list'] as $val){
334 if (!in_array ($val, $this->gosaMailAlternateAddress) &&
335 $val != $this->mail){
337 $this->addForwarder($val);
338 $this->is_modified= TRUE;
339 }
340 }
341 }
342 $this->forward_dialog= FALSE;
343 $this->dialog= FALSE;
344 }
346 /* Add forward email addresses */
347 if (isset($_POST['add_forwarder'])){
348 if ($_POST['forward_address'] != ""){
350 /* Valid email address specified? */
351 $address= $_POST['forward_address'];
352 $valid= FALSE;
353 if (!tests::is_email($address)){
354 if (!tests::is_email($address, TRUE)){
355 if ($this->is_template){
356 $valid= TRUE;
357 } else {
358 msg_dialog::display(_("Error"), _("Cannot add invalid mail address!"), ERROR_DIALOG);
359 }
360 }
361 } elseif ($address == $this->mail
362 || in_array($address, $this->gosaMailAlternateAddress)) {
364 msg_dialog::display(_("Error"),_("Cannot add your primary address to the list of forwarders.") , ERROR_DIALOG);
366 } else {
367 $valid= TRUE;
368 }
370 if ($valid){
372 /* Add it, if we are able to write gosaMailForwardingAddress */
373 if($this->acl_is_writeable("gosaMailForwardingAddress")){
374 $this->addForwarder ($address);
375 $this->is_modified= TRUE;
376 }
377 }
378 }
379 }
381 /* Delete forward email addresses */
382 if (isset($_POST['delete_forwarder'])){
383 $this->delForwarder ($_POST['forwarder_list']);
384 }
387 /* Add alternate email addresses */
388 if (isset($_POST['add_alternate'])){
390 $valid= FALSE;
391 if (!tests::is_email($_POST['alternate_address'])){
392 if ($this->is_template){
393 if (!(tests::is_email($_POST['alternate_address'], TRUE))){
394 msg_dialog::display(_("Error"), _("Cannot add invalid mail address!"), ERROR_DIALOG);
395 } else {
396 $valid= TRUE;
397 }
398 } else {
399 msg_dialog::display(_("Error"), _("Cannot add invalid mail address!"), ERROR_DIALOG);
400 }
402 } else {
403 $valid= TRUE;
404 }
406 if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
407 $ui= get_userinfo();
408 if ($user != $ui->username){
409 msg_dialog::display(_("Error"), sprintf(_("Cannot add mail address: it is already used by user '%s'."), $user), ERROR_DIALOG);
410 }
411 }
412 }
414 /* Delete alternate email addresses */
415 if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
416 $this->delAlternate ($_POST['alternates_list']);
417 }
420 /* Vacation message */
422 /* Import vacation message? */
423 if (isset($_POST["import_vacation"]) && isset($this->vacation[$_POST["vacation_template"]])){
426 /* Save message */
427 if($this->multiple_support_active){
428 $contents = file_get_contents($_POST["vacation_template"]);
429 }else{
430 $contents = $this->prepare_vacation_template(file_get_contents($_POST["vacation_template"]));
431 }
432 $this->gosaVacationMessage= htmlspecialchars($contents);
433 }
436 /* Display forward dialog if requested above */
438 /* Show forward add dialog */
439 if ($this->forward_dialog){
440 $ldap= $this->config->get_ldap_link();
442 /* Save data */
443 $mailfilter= session::get("mailfilter");
444 foreach( array("depselect", "muser", "regex") as $type){
445 if (isset($_POST[$type])){
446 $mailfilter[$type]= $_POST[$type];
447 }
448 }
449 if (isset($_GET['search'])){
450 $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
451 if ($s == "**"){
452 $s= "*";
453 }
454 $mailfilter['regex']= $s;
455 }
456 session::set("mailfilter", $mailfilter);
458 /* Get actual list */
459 $mailusers= array ();
460 if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
461 $regex= $mailfilter['regex'];
462 $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
463 } else {
464 $filter= "";
465 }
466 if ($mailfilter['muser'] != ""){
467 $user= $mailfilter['muser'];
468 $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
469 }
471 /* Add already present people to the filter */
472 $exclude= "";
473 foreach ($this->gosaMailForwardingAddress as $mail){
474 $exclude.= "(mail=$mail)";
475 }
476 if ($exclude != ""){
477 $filter.= "(!(|$exclude))";
478 }
480 $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'],
481 array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
482 $ldap->cd($mailfilter['depselect']);
483 $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
484 error_reporting (0);
485 while ($attrs= $ldap->fetch()){
486 if(preg_match('/%/', $attrs['mail'][0])){
487 continue;
488 }
489 $name= $this->make_name($attrs);
490 $mailusers[$attrs['mail'][0]]= $name."<".
491 $attrs['mail'][0].">";
492 }
493 error_reporting (E_ALL | E_STRICT);
494 natcasesort ($mailusers);
495 reset ($mailusers);
497 /* Show dialog */
498 $smarty->assign("search_image", get_template_path('images/search.png'));
499 $smarty->assign("usearch_image", get_template_path('images/search_user.png'));
500 $smarty->assign("tree_image", get_template_path('images/tree.png'));
501 $smarty->assign("infoimage", get_template_path('images/info.png'));
502 $smarty->assign("launchimage", get_template_path('images/small_filter.png'));
503 $smarty->assign("mailusers", $mailusers);
504 if (isset($_POST['depselect'])){
505 $smarty->assign("depselect", $_POST['depselect']);
506 }
507 $smarty->assign("deplist", $this->config->idepartments);
508 $smarty->assign("apply", apply_filter());
509 $smarty->assign("alphabet", generate_alphabet());
510 $smarty->assign("hint", print_sizelimit_warning());
511 foreach( array("depselect", "muser", "regex") as $type){
512 $smarty->assign("$type", $mailfilter[$type]);
513 }
514 $smarty->assign("hint", print_sizelimit_warning());
516 $display.= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
517 return ($display);
518 }
520 /* Display mail account tab */
522 $smarty->assign("mailServers", $mailserver);
523 $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
525 $tmp = $this->plInfo();
526 foreach($tmp['plProvidedAcls'] as $name => $transl){
527 $smarty->assign("$name"."ACL", $this->getacl($name,$SkipWrite));
528 }
530 foreach(array("gosaMailServer", "gosaMailQuota", "perms", "mail",
531 "gosaMailAlternateAddress", "gosaMailForwardingAddress",
532 "gosaVacationMessage", "gosaMailDeliveryMode", "gosaVacationStart",
533 "gosaVacationStop", "gosaMailMaxSize", "gosaSpamSortLevel", "gosaSpamMailbox") as $val){
534 $smarty->assign("$val", $this->$val);
535 }
537 if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){
538 $smarty->assign("quotausage", progressbar(round(($this->quotaUsage * 100)/ $this->gosaMailQuota),100,15,true));
539 $smarty->assign("quotadefined", "true");
540 } else {
541 $smarty->assign("quotadefined", "false");
542 }
544 /* Disable mail field if needed */
545 $method= new $this->method($this->config);
546 if ($method->uattrib == "mail" && $this->initially_was_account){
547 $smarty->assign("mailACL", preg_replace("/w/","",$this->getacl("mail",$SkipWrite)));
548 }
550 /* Disable/Enable range select, but do not disable them twice
551 * if they are already diabled by "use own sieve script"
552 */
553 if (preg_match('/V/', $this->gosaMailDeliveryMode) || preg_match("/C/",$this->gosaMailDeliveryMode)){
554 $smarty->assign('rangeEnabled', "");
555 } else {
556 $smarty->assign('rangeEnabled', "disabled");
557 }
559 if (!preg_match("/L/", $this->gosaMailDeliveryMode)) {
560 $smarty->assign("only_local", "checked");
561 } else {
562 $smarty->assign("only_local", "");
563 }
565 $types = array(
566 "V"=>"use_vacation",
567 "S"=>"use_spam_filter",
568 "R"=>"use_mailsize_limit",
569 "I"=>"drop_own_mails",
570 "C"=>"own_script");
572 /* Fill checkboxes */
573 foreach($types as $option => $varname){
574 if (preg_match("/".$option."/", $this->gosaMailDeliveryMode)) {
575 $smarty->assign($varname, "checked");
576 } else {
577 $smarty->assign($varname, "");
578 }
579 }
581 /* Display mail account tab */
582 if($this->gosaVacationStart ==0){
583 $date= getdate(time());
584 }else{
585 $date= getdate($this->gosaVacationStart);
586 }
587 $days= array();
588 for($d= 1; $d<32; $d++){
589 $days[$d]= $d;
590 }
591 $years= array();
592 for($y= $date['year']-10; $y<$date['year']+10; $y++){
593 $years[]= $y;
594 }
595 $months= array(_("January"), _("February"), _("March"), _("April"),
596 _("May"), _("June"), _("July"), _("August"), _("September"),
597 _("October"), _("November"), _("December"));
598 $smarty->assign("start_day", $date["mday"]);
599 $smarty->assign("days", $days);
600 $smarty->assign("months", $months);
601 $smarty->assign("start_month", $date["mon"]-1);
602 $smarty->assign("years", $years);
603 $smarty->assign("start_year", $date["year"]);
605 if($this->gosaVacationStop ==0){
606 $date= getdate(time());
607 $date["mday"]++;
608 }else{
609 $date= getdate($this->gosaVacationStop);
610 }
611 $smarty->assign("end_day", $date["mday"]);
612 $smarty->assign("end_month", $date["mon"]-1);
613 $smarty->assign("end_year", $date["year"]);
617 /* Have vacation templates? */
618 $smarty->assign("template", "");
619 if (count($this->vacation)){
620 $smarty->assign("show_templates", "true");
621 $smarty->assign("vacationtemplates", $this->vacation);
622 if (isset($_POST['vacation_template'])){
623 $smarty->assign("template", $_POST['vacation_template']);
624 }
625 } else {
626 $smarty->assign("show_templates", "false");
627 }
629 /* Fill spam selector */
630 $spamlevel= array();
631 for ($i= 0; $i<21; $i++){
632 $spamlevel[]= $i;
633 }
634 $smarty->assign("spamlevel", $spamlevel);
635 $smarty->assign("spambox", $this->mailboxList);
637 foreach($this->attributes as $attr){
638 $u_attr = "use_".$attr;
639 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
640 }
642 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
643 $u_attr = "use_".$attr;
644 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
645 }
647 $smarty->assign("multiple_support",$this->multiple_support_active);
648 $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
649 return ($display);
650 }
653 /* remove object from parent */
654 function remove_from_parent()
655 {
656 /* Cancel if there's nothing to do here */
657 if (!$this->initially_was_account){
658 return;
659 }
661 /* include global link_info */
662 $ldap= $this->config->get_ldap_link();
664 /* Remove and write to LDAP */
665 plugin::remove_from_parent();
667 /* Zero arrays */
668 $this->attrs['gosaMailAlternateAddress']= array();
669 $this->attrs['gosaMailForwardingAddress']= array();
671 /* Adapt attributes if needed */
672 $method= new $this->method($this->config);
673 $method->fixAttributesOnRemove($this);
675 @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,$this->attributes, "Save");
676 $ldap->cd($this->dn);
677 $this->cleanup();
679 $ldap->modify ($this->attrs);
681 /* Add "view" to logging class */
682 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
684 show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/mail account with dn '%s' failed."),$this->dn));
686 /* Connect to IMAP server for account deletion */
687 if ($this->gosaMailServer != ""){
688 $method= new $this->method($this->config);
689 $id= $method->uattrib;
690 if ($method->connect($this->gosaMailServer)){
692 /* Remove account from IMAP server */
693 $method->deleteMailbox($this->folder_prefix.$this->$id);
694 $method->disconnect();
695 }
696 }
698 /* Update shared folder membership, ACL may need to be updated */
699 $this->updateSharedFolder();
701 /* Optionally execute a command after we're done */
702 $this->handle_post_events("remove",array("uid" => $this->uid));
703 }
706 /* check if we have some delegations configured, those delegations must be removed first */
707 function accountDelegationsConfigured()
708 {
709 /* We are in administrational edit mode.
710 Check tab configurations directly */
711 if(isset($this->attrs)){
712 $checkArray = array("kolabInvitationPolicy","unrestrictedMailSize", "calFBURL","kolabDelegate","kolabFreeBusyFuture");
713 foreach($checkArray as $index){
714 if(isset($this->attrs[$index])){
715 return(true);
716 }
717 }
718 }
719 return(false);
720 }
723 /* Save data to object */
724 function save_object()
725 {
726 if (isset($_POST['mailTab'])){
728 /* Save ldap attributes */
729 plugin::save_object();
732 if(isset($_POST['own_script'])){
734 if(!preg_match("/C/",$this->gosaMailDeliveryMode)){
735 $str= preg_replace("/[\[\]]/","",$this->gosaMailDeliveryMode);
736 $this->gosaMailDeliveryMode = "[".$str."C]";
737 }
739 }else{
741 /* Assemble mail delivery mode
742 The mode field in ldap consists of values between braces, this must
743 be called when 'mail' is set, because checkboxes may not be set when
744 we're in some other dialog.
746 Example for gosaMailDeliveryMode [LR ]
747 L: Local delivery
748 R: Reject when exceeding mailsize limit
749 S: Use spam filter
750 V: Use vacation message
751 C: Use custm sieve script
752 I: Only insider delivery */
754 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
757 /* Handle delivery flags */
758 if($this->acl_is_writeable("gosaMailDeliveryModeL")){
759 if(!preg_match("/L/",$tmp) && !isset($_POST['only_local'])){
760 $tmp.="L";
761 }elseif(preg_match("/L/",$tmp) && isset($_POST['only_local'])){
762 $tmp = preg_replace("/L/","",$tmp);
763 }
764 }
766 $opts = array(
767 "R" => "use_mailsize_limit",
768 "S" => "use_spam_filter",
769 "V" => "use_vacation",
770 "C" => "own_script",
771 "I" => "drop_own_mails");
773 foreach($opts as $flag => $post){
774 if($this->acl_is_writeable("gosaMailDeliveryMode".$flag)){
775 if(!preg_match("/".$flag."/",$tmp) && isset($_POST[$post])){
776 $tmp.= $flag;
777 }elseif(preg_match("/".$flag."/",$tmp) && !isset($_POST[$post])){
778 $tmp = preg_replace("/".$flag."/","",$tmp);
779 }
780 }
781 }
783 $tmp= "[$tmp]";
784 if ($this->gosaMailDeliveryMode != $tmp){
785 $this->is_modified= TRUE;
786 }
787 $this->gosaMailDeliveryMode= $tmp;
790 if($this->acl_is_writeable("gosaVacationMessage") && preg_match("/V/",$this->gosaMailDeliveryMode)){
791 if(isset($_POST['gosaVacationStart'])){
792 $this->gosaVacationStart = $_POST['gosaVacationStart'];
793 }
794 if(isset($_POST['gosaVacationStop'])){
795 $this->gosaVacationStop = $_POST['gosaVacationStop'];
796 }
797 }
798 }
799 }
800 }
803 /* Save data to LDAP, depending on is_account we save or delete */
804 function save()
805 {
806 $ldap= $this->config->get_ldap_link();
808 /* Call parents save to prepare $this->attrs */
809 plugin::save();
811 /* Save arrays */
812 $this->attrs['gosaMailAlternateAddress']= $this->gosaMailAlternateAddress;
813 $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
815 /* Adapt attributes if needed */
816 $method= new $this->method($this->config);
817 $id= $method->uattrib;
819 $method->fixAttributesOnStore($this);
821 /* Remove Mailquota if = "" or "0" */
822 if((isset($this->attrs['gosaMailQuota']))&&(!$this->attrs['gosaMailQuota'])) {
823 $this->attrs['gosaMailQuota']=0;
824 }
826 if(empty($this->attrs['gosaSpamMailbox'])){
827 unset($this->attrs['gosaSpamMailbox']);
828 }
830 $this->attrs['mail'] = strtolower($this->attrs['mail']);
832 /* Remove attributes - if not needed */
833 if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
834 unset($this->attrs['gosaVacationStart']);
835 unset($this->attrs['gosaVacationStop']);
836 }
839 /* Remove attributes - if not needed */
840 if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
841 unset($this->attrs['gosaVacationStart']);
842 unset($this->attrs['gosaVacationStop']);
843 }
845 /* Save data to LDAP */
846 $ldap->cd($this->dn);
847 $this->cleanup();
848 $ldap->modify ($this->attrs);
850 show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/mail account with dn '%s' failed."),$this->dn));
852 /* Log last action */
853 if($this->initially_was_account){
854 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
855 }else{
856 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
857 }
859 /* Only do IMAP actions if we are not a template */
860 if (!$this->is_template){
862 if ($method->connect($this->gosaMailServer)){
863 $method->updateMailbox($this->folder_prefix.$this->$id);
865 $method->setQuota($this->folder_prefix.$this->$id, $this->gosaMailQuota);
866 $method->disconnect();
868 /* Ensure that this is an existing account */
869 if(1==1 || $this->initially_was_account){
871 /* Write sieve information only if not in C mode */
872 if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){
873 $method->configureFilter($this->$id,
874 $this->gosaMailDeliveryMode,
875 $this->mail,
876 $this->gosaMailAlternateAddress,
877 $this->gosaMailMaxSize,
878 $this->gosaSpamMailbox,
879 $this->gosaSpamSortLevel,
880 $this->gosaVacationMessage);
881 $this->is_modified = TRUE;
882 }else{
883 $this->sieve_management->save();
884 }
885 }
886 }
887 }
889 /* Optionally execute a command after we're done */
890 if ($this->initially_was_account == $this->is_account){
891 if ($this->is_modified){
892 $this->handle_post_events("modify", array("uid" => $this->uid));
893 }
894 } else {
895 $this->handle_post_events("add", array("uid" => $this->uid));
896 }
898 $this->updateSharedFolder();
899 }
902 /* Check formular input */
903 function check()
904 {
905 if(!$this->is_account) return(array());
907 $ldap= $this->config->get_ldap_link();
909 /* Call common method to give check the hook */
910 $message= plugin::check();
912 if(empty($this->gosaMailServer)){
913 $message[]= _("There is no valid mailserver specified, please add one in the system setup.");
914 }
916 /* must: mail */
917 if ($this->mail == ""){
918 $message[]= _("The required field 'Primary address' is not set.");
919 }
920 if ($this->is_template){
921 if (!tests::is_email($this->mail, TRUE)){
922 $message[]= _("Please enter a valid email address in 'Primary address' field.");
923 }
924 } else {
925 if (!tests::is_email($this->mail)){
926 $message[]= _("Please enter a valid email address in 'Primary address' field.");
927 }
928 }
929 $ldap->cd($this->config->current['BASE']);
930 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=".$this->mail.")(gosaMailAlternateAddress=".$this->mail."))(!(uid=".$this->uid."))(!(cn=".$this->uid.")))", array("uid"));
931 if ($ldap->count() != 0){
932 $message[]= _("The primary address you've entered is already in use.");
933 }
935 /* Check quota */
936 if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
937 if (!is_numeric($this->gosaMailQuota)) {
938 $message[]= _("Value in 'Quota size' is not valid.");
939 } else {
940 $this->gosaMailQuota= (int) $this->gosaMailQuota;
941 }
942 }
944 /* Check rejectsize for integer */
945 if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
946 if (!is_numeric($this->gosaMailMaxSize)){
947 $message[]= _("Please specify a vaild mail size for mails to be rejected.");
948 } else {
949 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
950 }
951 }
953 /* Need gosaMailMaxSize if use_mailsize_limit is checked */
954 if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) &&
955 $this->gosaMailMaxSize == ""){
957 $message[]= _("You need to set the maximum mail size in order to reject anything.");
958 }
960 if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
961 $message[]= _("You specified Spam settings, but there is no Folder specified.");
962 }
964 if (preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart > $this->gosaVacationStop){
965 $message[]= _("Time interval to show vacation message is not valid.");
966 }
968 return ($message);
969 }
972 /* Adapt from template, using 'dn' */
973 function adapt_from_template($dn)
974 {
975 plugin::adapt_from_template($dn);
977 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
978 $this->$val= array();
979 if (isset($this->attrs["$val"]["count"])){
980 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
981 $value= $this->attrs["$val"][$i];
982 foreach (array("sn", "givenName", "uid") as $repl){
983 if (preg_match("/%$repl/i", $value)){
984 $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
985 }
986 }
987 array_push($this->$val, strtolower(rewrite($value)));
988 }
989 }
990 }
991 $this->mail= strtolower(rewrite($this->mail));
992 }
995 /* Add entry to forwarder list */
996 function addForwarder($address)
997 {
998 if($this->acl_is_writeable("gosaMailForwardingAddress")){
999 $this->gosaMailForwardingAddress[]= $address;
1000 $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
1001 sort ($this->gosaMailForwardingAddress);
1002 reset ($this->gosaMailForwardingAddress);
1003 $this->is_modified= TRUE;
1004 }else{
1005 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses."), ERROR_DIALOG);
1006 }
1007 }
1010 /* Remove list of addresses from forwarder list */
1011 function delForwarder($addresses)
1012 {
1013 if($this->acl_is_writeable("gosaMailForwardingAddress")){
1014 $this->gosaMailForwardingAddress= array_remove_entries ($addresses, $this->gosaMailForwardingAddress);
1015 $this->is_modified= TRUE;
1016 }else{
1017 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses."), ERROR_DIALOG);
1018 }
1019 }
1022 /* Add given mail address to the list of alternate adresses ,
1023 check if this mal address is used, skip adding in this case */
1024 function addAlternate($address)
1025 {
1026 if($this->acl_is_writeable("gosaMailAlternateAddress")){
1027 $ldap= $this->config->get_ldap_link();
1028 $address= strtolower($address);
1030 /* Is this address already assigned in LDAP? */
1031 $ldap->cd ($this->config->current['BASE']);
1032 $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
1033 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
1035 if ($ldap->count() > 0){
1036 $attrs= $ldap->fetch ();
1037 return ($attrs["uid"][0]);
1038 }
1040 /* Add to list of alternates */
1041 if (!in_array($address, $this->gosaMailAlternateAddress)){
1042 $this->gosaMailAlternateAddress[]= $address;
1043 $this->is_modified= TRUE;
1044 }
1046 sort ($this->gosaMailAlternateAddress);
1047 reset ($this->gosaMailAlternateAddress);
1048 return ("");
1049 }else{
1050 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses."), ERROR_DIALOG);
1051 }
1052 }
1055 function delAlternate($addresses)
1056 {
1057 if($this->acl_is_writeable("gosaMailAlternateAddress")){
1058 $this->gosaMailAlternateAddress= array_remove_entries ($addresses,$this->gosaMailAlternateAddress);
1059 $this->is_modified= TRUE;
1060 }else{
1061 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses."), ERROR_DIALOG);
1062 }
1063 }
1065 function make_name($attrs)
1066 {
1067 $name= "";
1068 if (isset($attrs['sn'][0])){
1069 $name= $attrs['sn'][0];
1070 }
1071 if (isset($attrs['givenName'][0])){
1072 if ($name != ""){
1073 $name.= ", ".$attrs['givenName'][0];
1074 } else {
1075 $name.= $attrs['givenName'][0];
1076 }
1077 }
1078 if ($name != ""){
1079 $name.= " ";
1080 }
1082 return ($name);
1083 }
1086 /* Create the mail part for the copy & paste dialog */
1087 function getCopyDialog()
1088 {
1089 if(!$this->is_account) return("");
1090 $smarty = get_smarty();
1091 $smarty->assign("mail",$this->mail);
1092 $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
1093 $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
1094 $str = $smarty->fetch(get_template_path("copypaste.tpl",TRUE, dirname(__FILE__)));
1096 $ret = array();
1097 $ret['status'] = "";
1098 $ret['string'] = $str;
1099 return($ret);
1100 }
1102 function saveCopyDialog()
1103 {
1104 if(!$this->is_account) return;
1106 /* Execute to save mailAlternateAddress && gosaMailForwardingAddress */
1107 $this->execute();
1109 if(isset($_POST['mail'])){
1110 $this->mail = $_POST['mail'];
1111 }
1113 }
1115 function allow_remove()
1116 {
1117 if (isset($this->config->current['MAILMETHOD'])){
1118 $method= $this->config->current['MAILMETHOD'];
1119 if(preg_match("/olab/i",$method)){
1120 $ldap = $this->config->get_ldap_link();
1121 $ldap->cd($this->config->current['BASE']);
1122 $ldap->cat($this->dn);
1123 if($ldap->count()){
1124 $attrs = $ldap->fetch();
1125 if(isset($attrs['kolabDeleteFlag'])){
1126 return(_("Waiting for kolab to remove mail properties."));
1127 }elseif(in_array("gosaMailAccount",$attrs['objectClass'])){
1128 return(_("Please remove the mail account first, to allow kolab to call its remove methods."));
1129 }
1130 }
1131 }
1132 }
1133 }
1136 function PrepareForCopyPaste($source)
1137 {
1138 plugin::PrepareForCopyPaste($source);
1140 /* Reset alternate mail addresses */
1141 $this->gosaMailAlternateAddress = array();
1142 }
1145 static function plInfo()
1146 {
1147 return (array(
1148 "plShortName" => _("Mail"),
1149 "plDescription" => _("Mail settings"),
1150 "plSelfModify" => TRUE,
1151 "plDepends" => array("user"), // This plugin depends on
1152 "plPriority" => 4, // Position in tabs
1153 "plSection" => array("personal" => _("My account")),
1154 "plCategory" => array("users"),
1155 "plOptions" => array(),
1157 "plProvidedAcls" => array(
1158 "mail" => _("Mail address"),
1159 "gosaMailServer" => _("Mail server"),
1160 "gosaMailQuota" => _("Quota size"),
1162 "gosaMailDeliveryModeV" => _("Add vacation information"), // This is flag of gosaMailDeliveryMode
1163 "gosaVacationMessage" => _("Vacation message"),
1165 "gosaMailDeliveryModeS" => _("Use spam filter"), // This is flag of gosaMailDeliveryMode
1166 "gosaSpamSortLevel" => _("Spam level"),
1167 "gosaSpamMailbox" => _("Spam mail box"),
1169 "sieveManagement" => _("Sieve management"),
1171 "gosaMailDeliveryModeR" => _("Reject due to mailsize"), // This is flag of gosaMailDeliveryMode
1172 "gosaMailMaxSize" => _("Mail max size"),
1174 "gosaMailForwardingAddress" => _("Forwarding address"),
1175 "gosaMailDeliveryModeL" => _("Local delivery"), // This is flag of gosaMailDeliveryMode
1176 "gosaMailDeliveryModeI" => _("No delivery to own mailbox "), // This is flag of gosaMailDeliveryMode
1177 "gosaMailAlternateAddress" => _("Mail alternative addresses"),
1179 "gosaMailForwardingAddress" => _("Forwarding address"),
1180 "gosaMailDeliveryModeC" => _("Use custom sieve script")) // This is flag of gosaMailDeliveryMode
1181 ));
1182 }
1185 /*! \brief Prepare importet vacation string. \
1186 Replace placeholder like %givenName a.s.o.
1187 @param string Vacation string
1188 @return string Completed vacation string
1189 */
1190 private function prepare_vacation_template($contents)
1191 {
1192 /* Replace attributes */
1193 $attrs = array();
1194 $obj = NULL;
1195 if(isset($this->parent->by_object['user'])){
1196 $attrs = $this->parent->by_object['user']->attributes;
1197 $obj = $this->parent->by_object['user'];
1198 }else{
1199 $obj = new user($this->config,$this->dn);
1200 $attrs = $obj->attributes;
1201 }
1203 if($obj){
1204 foreach ($attrs as $val){
1205 if(preg_match("/dateOfBirth/",$val)){
1206 if($obj->use_dob){
1207 $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
1208 }
1209 }else {
1210 $contents= preg_replace("/%$val/",
1211 $obj->$val, $contents);
1212 }
1214 /* Replace vacation start and end time */
1215 if(preg_match("/%start/",$contents)){
1216 $contents = preg_replace("/%start/",date("d.m.Y",$this->gosaVacationStart),$contents);
1217 }
1218 if(preg_match("/%end/",$contents)){
1219 $contents = preg_replace("/%end/",date("d.m.Y",$this->gosaVacationStop),$contents);
1220 }
1221 }
1222 }
1223 return($contents);
1224 }
1228 /* Upated shared folder ACLs
1229 */
1230 function updateSharedFolder()
1231 {
1232 $ldap = $this->config->get_ldap_link();
1233 $ldap->cd($this->config->current['BASE']);
1234 $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$this->uid."))",array('dn','cn'));
1235 if(class_exists("grouptabs")){
1236 while($attrs = $ldap->fetch()){
1237 $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
1238 if(isset($tmp->by_object['mailgroup'])){
1239 $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
1240 if(!$this->is_account){
1241 $tmp->by_object['mailgroup']->removeUserAcl($this->uid);
1242 $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
1243 }
1244 $tmp->by_object['mailgroup']->save();
1245 }
1246 }
1247 }
1248 }
1250 /* Initialize plugin with given atribute arrays
1251 */
1252 function init_multiple_support($attrs,$all)
1253 {
1254 plugin::init_multiple_support($attrs,$all);
1256 if(isset($this->multi_attrs['gosaMailQuota'])){
1257 $this->gosaMailQuota = $this->multi_attrs['gosaMailQuota'];
1258 }
1259 }
1261 function get_multi_init_values()
1262 {
1263 $attrs = plugin::get_multi_init_values();
1264 $attrs['gosaMailQuota'] = $this->gosaMailQuota;
1265 return($attrs);
1266 }
1268 function multiple_execute()
1269 {
1270 return($this->execute());
1271 }
1273 function multiple_save_object()
1274 {
1275 plugin::multiple_save_object();
1277 $this->save_object();
1278 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
1279 if(isset($_POST["use_".$attr])){
1280 $this->multi_boxes[] = $attr;
1281 }
1282 }
1283 }
1285 function get_multi_edit_values()
1286 {
1287 $ret = plugin::get_multi_edit_values();
1289 if(in_array("gosaMailQuota",$this->multi_boxes)){
1290 $ret['gosaMailQuota'] = $this->gosaMailQuota;
1291 }
1293 $flag_add = $flag_remove = array();
1294 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1295 $opts = array(
1296 "R" => "use_mailsize_limit",
1297 "S" => "use_spam_filter",
1298 "L" => "only_local",
1299 "V" => "use_vacation",
1300 "C" => "own_script",
1301 "I" => "drop_own_mails");
1303 foreach($opts as $flag => $post){
1304 if(in_array($post, $this->multi_boxes)){
1305 if(preg_match("/".$flag."/",$tmp)){
1306 $flag_add[] = $flag;
1307 }else{
1308 $flag_remove[] = $flag;
1309 }
1310 }
1311 }
1313 $ret['flag_add'] = $flag_add;
1314 $ret['flag_remove'] = $flag_remove;
1315 return($ret);
1316 }
1319 function multiple_check()
1320 {
1321 $message = plugin::multiple_check();
1323 if(empty($this->gosaMailServer) && in_array("gosaMailServer",$this->multi_boxes)){
1324 $message[]= _("There is no valid mailserver specified, please add one in the system setup.");
1325 }
1327 /* Check quota */
1328 if ($this->gosaMailQuota != '' && in_array("gosaMailQuota",$this->multi_boxes)){
1329 if (!is_numeric($this->gosaMailQuota)) {
1330 $message[]= _("Value in 'Quota size' is not valid.");
1331 } else {
1332 $this->gosaMailQuota= (int) $this->gosaMailQuota;
1333 }
1334 }
1336 /* Check rejectsize for integer */
1337 if ($this->gosaMailMaxSize != '' && in_array("gosaMailMaxSize",$this->multi_boxes)){
1338 if (!is_numeric($this->gosaMailMaxSize)){
1339 $message[]= _("Please specify a vaild mail size for mails to be rejected.");
1340 } else {
1341 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
1342 }
1343 }
1345 if(empty($this->gosaSpamMailbox) && in_array("gosaSpamMailbox",$this->multi_boxes)){
1346 $message[]= _("You specified Spam settings, but there is no Folder specified.");
1347 }
1349 if ( in_array("use_vacation",$this->multi_boxes) &&
1350 preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart > $this->gosaVacationStop){
1351 $message[]= _("Time interval to show vacation message is not valid.");
1352 }
1353 return($message);
1354 }
1357 function set_multi_edit_values($values)
1358 {
1359 plugin::set_multi_edit_values($values);
1360 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1361 if(isset($values['flag_add'])){
1362 foreach($values['flag_add'] as $flag){
1363 if(!preg_match("/".$flag."/",$tmp)){
1364 $tmp .= $flag;
1365 }
1366 }
1367 }
1368 if(isset($values['flag_remove'])){
1369 foreach($values['flag_remove'] as $flag){
1370 if(preg_match("/".$flag."/",$tmp)){
1371 $tmp = preg_replace("/".$flag."/","",$tmp);
1372 }
1373 }
1374 }
1375 $this->gosaMailDeliveryMode = "[".$tmp."]";
1377 /* Set vacation message and replace placeholder like %givenName
1378 */
1379 if(isset($values['gosaVacationMessage'])){
1380 $this->gosaVacationMessage = $this->prepare_vacation_template($values['gosaVacationMessage']);
1381 }
1382 }
1383 }
1385 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1386 ?>