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(_("Mail method '%s' is unknown!"), $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 msgPool::noValidExtension(_("Mail"))."</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(msgPool::removeFeaturesButton(_("Mail")),
300 _("Mail settings cannot be removed while there are delegations configured!"),TRUE,TRUE);
301 }else{
302 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),
303 msgPool::featuresEnabled(_("Mail")));
304 }
305 } else {
306 $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Mail")),
307 msgPool::featuresDisabled(_("Mail")));
308 return ($display);
309 }
310 }
311 }
313 /* Forwarder subdialog */
315 /* Trigger forward add dialog? */
316 if (isset($_POST['add_local_forwarder'])){
317 $this->forward_dialog= TRUE;
318 $this->dialog= TRUE;
319 }
321 /* Cancel forward add dialog? */
322 if (isset($_POST['add_locals_cancel'])){
323 $this->forward_dialog= FALSE;
324 $this->dialog= FALSE;
325 }
327 /* Finished adding of locals? */
328 if (isset($_POST['add_locals_finish'])){
330 /* Check if we are able to write gosaMailForwardingAddress */
331 if($this->acl_is_writeable("gosaMailForwardingAddress")){
333 /* Walk through list of forwarders, ignore own addresses */
334 foreach ($_POST['local_list'] as $val){
335 if (!in_array ($val, $this->gosaMailAlternateAddress) &&
336 $val != $this->mail){
338 $this->addForwarder($val);
339 $this->is_modified= TRUE;
340 }
341 }
342 }
343 $this->forward_dialog= FALSE;
344 $this->dialog= FALSE;
345 }
347 /* Add forward email addresses */
348 if (isset($_POST['add_forwarder'])){
349 if ($_POST['forward_address'] != ""){
351 /* Valid email address specified? */
352 $address= $_POST['forward_address'];
353 $valid= FALSE;
354 if (!tests::is_email($address)){
355 if (!tests::is_email($address, TRUE)){
356 if ($this->is_template){
357 $valid= TRUE;
358 } else {
359 msg_dialog::display(_("Error"),
360 msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
361 ERROR_DIALOG);
362 }
363 }
364 } elseif ($address == $this->mail
365 || in_array($address, $this->gosaMailAlternateAddress)) {
366 msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
367 } else {
368 $valid= TRUE;
369 }
371 if ($valid){
373 /* Add it, if we are able to write gosaMailForwardingAddress */
374 if($this->acl_is_writeable("gosaMailForwardingAddress")){
375 $this->addForwarder ($address);
376 $this->is_modified= TRUE;
377 }
378 }
379 }
380 }
382 /* Delete forward email addresses */
383 if (isset($_POST['delete_forwarder'])){
384 $this->delForwarder ($_POST['forwarder_list']);
385 }
388 /* Add alternate email addresses */
389 if (isset($_POST['add_alternate'])){
391 $valid= FALSE;
392 if (!tests::is_email($_POST['alternate_address'])){
393 if ($this->is_template){
394 if (!(tests::is_email($_POST['alternate_address'], TRUE))){
395 msg_dialog::display(_("Error"),
396 msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
397 ERROR_DIALOG);
399 } else {
400 $valid= TRUE;
401 }
402 } else {
403 msg_dialog::display(_("Error"),
404 msgPool::invalid(_("Mail address"),"","","example@your-domain.com"),
405 ERROR_DIALOG);
406 }
408 } else {
409 $valid= TRUE;
410 }
412 if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
413 $ui= get_userinfo();
414 if ($user != $ui->username){
415 msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))." ".
416 sprintf(_("Address is already in use by user '%s'."), $user), ERROR_DIALOG);
417 }
418 }
419 }
421 /* Delete alternate email addresses */
422 if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
423 $this->delAlternate ($_POST['alternates_list']);
424 }
427 /* Vacation message */
429 /* Import vacation message? */
430 if (isset($_POST["import_vacation"]) && isset($this->vacation[$_POST["vacation_template"]])){
433 /* Save message */
434 if($this->multiple_support_active){
435 $contents = file_get_contents($_POST["vacation_template"]);
436 }else{
437 $contents = $this->prepare_vacation_template(file_get_contents($_POST["vacation_template"]));
438 }
439 $this->gosaVacationMessage= htmlspecialchars($contents);
440 }
443 /* Display forward dialog if requested above */
445 /* Show forward add dialog */
446 if ($this->forward_dialog){
447 $ldap= $this->config->get_ldap_link();
449 /* Save data */
450 $mailfilter= session::get("mailfilter");
451 foreach( array("depselect", "muser", "regex") as $type){
452 if (isset($_POST[$type])){
453 $mailfilter[$type]= $_POST[$type];
454 }
455 }
456 if (isset($_GET['search'])){
457 $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
458 if ($s == "**"){
459 $s= "*";
460 }
461 $mailfilter['regex']= $s;
462 }
463 session::set("mailfilter", $mailfilter);
465 /* Get actual list */
466 $mailusers= array ();
467 if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
468 $regex= $mailfilter['regex'];
469 $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
470 } else {
471 $filter= "";
472 }
473 if ($mailfilter['muser'] != ""){
474 $user= $mailfilter['muser'];
475 $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
476 }
478 /* Add already present people to the filter */
479 $exclude= "";
480 foreach ($this->gosaMailForwardingAddress as $mail){
481 $exclude.= "(mail=$mail)";
482 }
483 if ($exclude != ""){
484 $filter.= "(!(|$exclude))";
485 }
487 $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'],
488 array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
489 $ldap->cd($mailfilter['depselect']);
490 $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
491 error_reporting (0);
492 while ($attrs= $ldap->fetch()){
493 if(preg_match('/%/', $attrs['mail'][0])){
494 continue;
495 }
496 $name= $this->make_name($attrs);
497 $mailusers[$attrs['mail'][0]]= $name."<".
498 $attrs['mail'][0].">";
499 }
500 error_reporting (E_ALL | E_STRICT);
501 natcasesort ($mailusers);
502 reset ($mailusers);
504 /* Show dialog */
505 $smarty->assign("search_image", get_template_path('images/search.png'));
506 $smarty->assign("usearch_image", get_template_path('images/search_user.png'));
507 $smarty->assign("tree_image", get_template_path('images/tree.png'));
508 $smarty->assign("infoimage", get_template_path('images/info.png'));
509 $smarty->assign("launchimage", get_template_path('images/small_filter.png'));
510 $smarty->assign("mailusers", $mailusers);
511 if (isset($_POST['depselect'])){
512 $smarty->assign("depselect", $_POST['depselect']);
513 }
514 $smarty->assign("deplist", $this->config->idepartments);
515 $smarty->assign("apply", apply_filter());
516 $smarty->assign("alphabet", generate_alphabet());
517 $smarty->assign("hint", print_sizelimit_warning());
518 foreach( array("depselect", "muser", "regex") as $type){
519 $smarty->assign("$type", $mailfilter[$type]);
520 }
521 $smarty->assign("hint", print_sizelimit_warning());
523 $display.= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
524 return ($display);
525 }
527 /* Display mail account tab */
529 $smarty->assign("mailServers", $mailserver);
530 $SkipWrite = (!isset($this->parent) || !$this->parent) && !session::is_set('edit');
532 $tmp = $this->plInfo();
533 foreach($tmp['plProvidedAcls'] as $name => $transl){
534 $smarty->assign("$name"."ACL", $this->getacl($name,$SkipWrite));
535 }
537 foreach(array("gosaMailServer", "gosaMailQuota", "perms", "mail",
538 "gosaMailAlternateAddress", "gosaMailForwardingAddress",
539 "gosaVacationMessage", "gosaMailDeliveryMode", "gosaVacationStart",
540 "gosaVacationStop", "gosaMailMaxSize", "gosaSpamSortLevel", "gosaSpamMailbox") as $val){
541 $smarty->assign("$val", $this->$val);
542 }
544 if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){
545 $smarty->assign("quotausage", progressbar(round(($this->quotaUsage * 100)/ $this->gosaMailQuota),100,15,true));
546 $smarty->assign("quotadefined", "true");
547 } else {
548 $smarty->assign("quotadefined", "false");
549 }
551 /* Disable mail field if needed */
552 $method= new $this->method($this->config);
553 if ($method->uattrib == "mail" && $this->initially_was_account){
554 $smarty->assign("mailACL", preg_replace("/w/","",$this->getacl("mail",$SkipWrite)));
555 }
557 /* Disable/Enable range select, but do not disable them twice
558 * if they are already diabled by "use own sieve script"
559 */
560 if (preg_match('/V/', $this->gosaMailDeliveryMode) || preg_match("/C/",$this->gosaMailDeliveryMode)){
561 $smarty->assign('rangeEnabled', "");
562 } else {
563 $smarty->assign('rangeEnabled', "disabled");
564 }
566 if (!preg_match("/L/", $this->gosaMailDeliveryMode)) {
567 $smarty->assign("only_local", "checked");
568 } else {
569 $smarty->assign("only_local", "");
570 }
572 $types = array(
573 "V"=>"use_vacation",
574 "S"=>"use_spam_filter",
575 "R"=>"use_mailsize_limit",
576 "I"=>"drop_own_mails",
577 "C"=>"own_script");
579 /* Fill checkboxes */
580 foreach($types as $option => $varname){
581 if (preg_match("/".$option."/", $this->gosaMailDeliveryMode)) {
582 $smarty->assign($varname, "checked");
583 } else {
584 $smarty->assign($varname, "");
585 }
586 }
588 /* Display mail account tab */
589 if($this->gosaVacationStart ==0){
590 $date= getdate(time());
591 }else{
592 $date= getdate($this->gosaVacationStart);
593 }
594 $days= array();
595 for($d= 1; $d<32; $d++){
596 $days[$d]= $d;
597 }
598 $years= array();
599 for($y= $date['year']-10; $y<$date['year']+10; $y++){
600 $years[]= $y;
601 }
602 $months= msgPool::months();
603 $smarty->assign("start_day", $date["mday"]);
604 $smarty->assign("days", $days);
605 $smarty->assign("months", $months);
606 $smarty->assign("start_month", $date["mon"]-1);
607 $smarty->assign("years", $years);
608 $smarty->assign("start_year", $date["year"]);
610 if($this->gosaVacationStop ==0){
611 $date= getdate(time());
612 $date["mday"]++;
613 }else{
614 $date= getdate($this->gosaVacationStop);
615 }
616 $smarty->assign("end_day", $date["mday"]);
617 $smarty->assign("end_month", $date["mon"]-1);
618 $smarty->assign("end_year", $date["year"]);
622 /* Have vacation templates? */
623 $smarty->assign("template", "");
624 if (count($this->vacation)){
625 $smarty->assign("show_templates", "true");
626 $smarty->assign("vacationtemplates", $this->vacation);
627 if (isset($_POST['vacation_template'])){
628 $smarty->assign("template", $_POST['vacation_template']);
629 }
630 } else {
631 $smarty->assign("show_templates", "false");
632 }
634 /* Fill spam selector */
635 $spamlevel= array();
636 for ($i= 0; $i<21; $i++){
637 $spamlevel[]= $i;
638 }
639 $smarty->assign("spamlevel", $spamlevel);
640 $smarty->assign("spambox", $this->mailboxList);
642 foreach($this->attributes as $attr){
643 $u_attr = "use_".$attr;
644 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
645 }
647 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
648 $u_attr = "use_".$attr;
649 $smarty->assign($u_attr,in_array($attr,$this->multi_boxes));
650 }
652 $smarty->assign("multiple_support",$this->multiple_support_active);
653 $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__)));
654 return ($display);
655 }
658 /* remove object from parent */
659 function remove_from_parent()
660 {
661 /* Cancel if there's nothing to do here */
662 if (!$this->initially_was_account){
663 return;
664 }
666 /* include global link_info */
667 $ldap= $this->config->get_ldap_link();
669 /* Remove and write to LDAP */
670 plugin::remove_from_parent();
672 /* Zero arrays */
673 $this->attrs['gosaMailAlternateAddress']= array();
674 $this->attrs['gosaMailForwardingAddress']= array();
676 /* Adapt attributes if needed */
677 $method= new $this->method($this->config);
678 $method->fixAttributesOnRemove($this);
680 @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__,$this->attributes, "Save");
681 $ldap->cd($this->dn);
682 $this->cleanup();
684 $ldap->modify ($this->attrs);
686 /* Add "view" to logging class */
687 new log("remove","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
689 show_ldap_error($ldap->get_error(), sprintf(_("Removing of user/mail account with dn '%s' failed."),$this->dn));
691 /* Connect to IMAP server for account deletion */
692 if ($this->gosaMailServer != ""){
693 $method= new $this->method($this->config);
694 $id= $method->uattrib;
695 if ($method->connect($this->gosaMailServer)){
697 /* Remove account from IMAP server */
698 $method->deleteMailbox($this->folder_prefix.$this->$id);
699 $method->disconnect();
700 }
701 }
703 /* Update shared folder membership, ACL may need to be updated */
704 $this->updateSharedFolder();
706 /* Optionally execute a command after we're done */
707 $this->handle_post_events("remove",array("uid" => $this->uid));
708 }
711 /* check if we have some delegations configured, those delegations must be removed first */
712 function accountDelegationsConfigured()
713 {
714 /* We are in administrational edit mode.
715 Check tab configurations directly */
716 if(isset($this->attrs)){
717 $checkArray = array("kolabInvitationPolicy","unrestrictedMailSize", "calFBURL","kolabDelegate","kolabFreeBusyFuture");
718 foreach($checkArray as $index){
719 if(isset($this->attrs[$index])){
720 return(true);
721 }
722 }
723 }
724 return(false);
725 }
728 /* Save data to object */
729 function save_object()
730 {
731 if (isset($_POST['mailTab'])){
733 /* Save ldap attributes */
734 plugin::save_object();
737 if(isset($_POST['own_script'])){
739 if(!preg_match("/C/",$this->gosaMailDeliveryMode)){
740 $str= preg_replace("/[\[\]]/","",$this->gosaMailDeliveryMode);
741 $this->gosaMailDeliveryMode = "[".$str."C]";
742 }
744 }else{
746 /* Assemble mail delivery mode
747 The mode field in ldap consists of values between braces, this must
748 be called when 'mail' is set, because checkboxes may not be set when
749 we're in some other dialog.
751 Example for gosaMailDeliveryMode [LR ]
752 L: Local delivery
753 R: Reject when exceeding mailsize limit
754 S: Use spam filter
755 V: Use vacation message
756 C: Use custm sieve script
757 I: Only insider delivery */
759 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
762 /* Handle delivery flags */
763 if($this->acl_is_writeable("gosaMailDeliveryModeL")){
764 if(!preg_match("/L/",$tmp) && !isset($_POST['only_local'])){
765 $tmp.="L";
766 }elseif(preg_match("/L/",$tmp) && isset($_POST['only_local'])){
767 $tmp = preg_replace("/L/","",$tmp);
768 }
769 }
771 $opts = array(
772 "R" => "use_mailsize_limit",
773 "S" => "use_spam_filter",
774 "V" => "use_vacation",
775 "C" => "own_script",
776 "I" => "drop_own_mails");
778 foreach($opts as $flag => $post){
779 if($this->acl_is_writeable("gosaMailDeliveryMode".$flag)){
780 if(!preg_match("/".$flag."/",$tmp) && isset($_POST[$post])){
781 $tmp.= $flag;
782 }elseif(preg_match("/".$flag."/",$tmp) && !isset($_POST[$post])){
783 $tmp = preg_replace("/".$flag."/","",$tmp);
784 }
785 }
786 }
788 $tmp= "[$tmp]";
789 if ($this->gosaMailDeliveryMode != $tmp){
790 $this->is_modified= TRUE;
791 }
792 $this->gosaMailDeliveryMode= $tmp;
795 if($this->acl_is_writeable("gosaVacationMessage") && preg_match("/V/",$this->gosaMailDeliveryMode)){
796 if(isset($_POST['gosaVacationStart'])){
797 $this->gosaVacationStart = $_POST['gosaVacationStart'];
798 }
799 if(isset($_POST['gosaVacationStop'])){
800 $this->gosaVacationStop = $_POST['gosaVacationStop'];
801 }
802 }
803 }
804 }
805 }
808 /* Save data to LDAP, depending on is_account we save or delete */
809 function save()
810 {
811 $ldap= $this->config->get_ldap_link();
813 /* Call parents save to prepare $this->attrs */
814 plugin::save();
816 /* Save arrays */
817 $this->attrs['gosaMailAlternateAddress']= $this->gosaMailAlternateAddress;
818 $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
820 /* Adapt attributes if needed */
821 $method= new $this->method($this->config);
822 $id= $method->uattrib;
824 $method->fixAttributesOnStore($this);
826 /* Remove Mailquota if = "" or "0" */
827 if((isset($this->attrs['gosaMailQuota']))&&(!$this->attrs['gosaMailQuota'])) {
828 $this->attrs['gosaMailQuota']=0;
829 }
831 if(empty($this->attrs['gosaSpamMailbox'])){
832 unset($this->attrs['gosaSpamMailbox']);
833 }
835 $this->attrs['mail'] = strtolower($this->attrs['mail']);
837 /* Remove attributes - if not needed */
838 if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
839 unset($this->attrs['gosaVacationStart']);
840 unset($this->attrs['gosaVacationStop']);
841 }
844 /* Remove attributes - if not needed */
845 if (!preg_match('/V/', $this->gosaMailDeliveryMode)){
846 unset($this->attrs['gosaVacationStart']);
847 unset($this->attrs['gosaVacationStop']);
848 }
850 /* Save data to LDAP */
851 $ldap->cd($this->dn);
852 $this->cleanup();
853 $ldap->modify ($this->attrs);
855 show_ldap_error($ldap->get_error(), sprintf(_("Saving of user/mail account with dn '%s' failed."),$this->dn));
857 /* Log last action */
858 if($this->initially_was_account){
859 new log("modify","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
860 }else{
861 new log("create","users/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
862 }
864 /* Only do IMAP actions if we are not a template */
865 if (!$this->is_template){
867 if ($method->connect($this->gosaMailServer)){
868 $method->updateMailbox($this->folder_prefix.$this->$id);
870 $method->setQuota($this->folder_prefix.$this->$id, $this->gosaMailQuota);
871 $method->disconnect();
873 /* Ensure that this is an existing account */
874 if(1==1 || $this->initially_was_account){
876 /* Write sieve information only if not in C mode */
877 if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){
878 $method->configureFilter($this->$id,
879 $this->gosaMailDeliveryMode,
880 $this->mail,
881 $this->gosaMailAlternateAddress,
882 $this->gosaMailMaxSize,
883 $this->gosaSpamMailbox,
884 $this->gosaSpamSortLevel,
885 $this->gosaVacationMessage);
886 $this->is_modified = TRUE;
887 }else{
888 $this->sieve_management->save();
889 }
890 }
891 }
892 }
894 /* Optionally execute a command after we're done */
895 if ($this->initially_was_account == $this->is_account){
896 if ($this->is_modified){
897 $this->handle_post_events("modify", array("uid" => $this->uid));
898 }
899 } else {
900 $this->handle_post_events("add", array("uid" => $this->uid));
901 }
903 $this->updateSharedFolder();
904 }
907 /* Check formular input */
908 function check()
909 {
910 if(!$this->is_account) return(array());
912 $ldap= $this->config->get_ldap_link();
914 /* Call common method to give check the hook */
915 $message= plugin::check();
917 if(empty($this->gosaMailServer)){
918 $message[]= msgPool::noserver(_("Mail"));
919 }
921 /* must: mail */
922 if ($this->mail == ""){
923 $message[]= msgPool::required(_("Primary address"));
924 }
925 if ($this->is_template){
926 if (!tests::is_email($this->mail, TRUE)){
927 $message[]= msgPool::invalid(_("Mail address"),"","","%givenName.%sn@your-domain.com");
928 }
929 } else {
930 if (!tests::is_email($this->mail)){
931 $message[]= msgPool::invalid(_("Mail address"),"","","example@your-domain.com");
932 }
933 }
934 $ldap->cd($this->config->current['BASE']);
935 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=".$this->mail.")(gosaMailAlternateAddress=".$this->mail."))(!(uid=".$this->uid."))(!(cn=".$this->uid.")))", array("uid"));
936 if ($ldap->count() != 0){
937 $message[]= msgPool::duplicated(_("Mail address"));
938 }
940 /* Check quota */
941 if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
942 if (!is_numeric($this->gosaMailQuota)) {
943 $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
944 } else {
945 $this->gosaMailQuota= (int) $this->gosaMailQuota;
946 }
947 }
949 /* Check rejectsize for integer */
950 if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
951 if (!is_numeric($this->gosaMailMaxSize)){
952 $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
953 } else {
954 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
955 }
956 }
958 /* Need gosaMailMaxSize if use_mailsize_limit is checked */
959 if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){
960 $message[]= msgPool::required(_("Mail reject size"));
961 }
963 if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
964 $message[]= msgPool::required(_("Spam folder"));
965 }
967 if (preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart >= $this->gosaVacationStop){
968 $message[]= msgPool::invalid(_("Vacation interval"));
969 }
971 return ($message);
972 }
975 /* Adapt from template, using 'dn' */
976 function adapt_from_template($dn)
977 {
978 plugin::adapt_from_template($dn);
980 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
981 $this->$val= array();
982 if (isset($this->attrs["$val"]["count"])){
983 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
984 $value= $this->attrs["$val"][$i];
985 foreach (array("sn", "givenName", "uid") as $repl){
986 if (preg_match("/%$repl/i", $value)){
987 $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
988 }
989 }
990 array_push($this->$val, strtolower(rewrite($value)));
991 }
992 }
993 }
994 $this->mail= strtolower(rewrite($this->mail));
995 }
998 /* Add entry to forwarder list */
999 function addForwarder($address)
1000 {
1001 if($this->acl_is_writeable("gosaMailForwardingAddress")){
1002 $this->gosaMailForwardingAddress[]= $address;
1003 $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
1004 sort ($this->gosaMailForwardingAddress);
1005 reset ($this->gosaMailForwardingAddress);
1006 $this->is_modified= TRUE;
1007 }else{
1008 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
1009 }
1010 }
1013 /* Remove list of addresses from forwarder list */
1014 function delForwarder($addresses)
1015 {
1016 if($this->acl_is_writeable("gosaMailForwardingAddress")){
1017 $this->gosaMailForwardingAddress= array_remove_entries ($addresses, $this->gosaMailForwardingAddress);
1018 $this->is_modified= TRUE;
1019 }else{
1020 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
1021 }
1022 }
1025 /* Add given mail address to the list of alternate adresses ,
1026 check if this mal address is used, skip adding in this case */
1027 function addAlternate($address)
1028 {
1029 if($this->acl_is_writeable("gosaMailAlternateAddress")){
1030 $ldap= $this->config->get_ldap_link();
1031 $address= strtolower($address);
1033 /* Is this address already assigned in LDAP? */
1034 $ldap->cd ($this->config->current['BASE']);
1035 $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
1036 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)"."(gosaMailAlternateAddress=$address)))", array("uid"));
1038 if ($ldap->count() > 0){
1039 $attrs= $ldap->fetch ();
1040 return ($attrs["uid"][0]);
1041 }
1043 /* Add to list of alternates */
1044 if (!in_array($address, $this->gosaMailAlternateAddress)){
1045 $this->gosaMailAlternateAddress[]= $address;
1046 $this->is_modified= TRUE;
1047 }
1049 sort ($this->gosaMailAlternateAddress);
1050 reset ($this->gosaMailAlternateAddress);
1051 return ("");
1052 }else{
1053 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
1054 }
1055 }
1058 function delAlternate($addresses)
1059 {
1060 if($this->acl_is_writeable("gosaMailAlternateAddress")){
1061 $this->gosaMailAlternateAddress= array_remove_entries ($addresses,$this->gosaMailAlternateAddress);
1062 $this->is_modified= TRUE;
1063 }else{
1064 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
1065 }
1066 }
1068 function make_name($attrs)
1069 {
1070 $name= "";
1071 if (isset($attrs['sn'][0])){
1072 $name= $attrs['sn'][0];
1073 }
1074 if (isset($attrs['givenName'][0])){
1075 if ($name != ""){
1076 $name.= ", ".$attrs['givenName'][0];
1077 } else {
1078 $name.= $attrs['givenName'][0];
1079 }
1080 }
1081 if ($name != ""){
1082 $name.= " ";
1083 }
1085 return ($name);
1086 }
1089 /* Create the mail part for the copy & paste dialog */
1090 function getCopyDialog()
1091 {
1092 if(!$this->is_account) return("");
1093 $smarty = get_smarty();
1094 $smarty->assign("mail",$this->mail);
1095 $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
1096 $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
1097 $str = $smarty->fetch(get_template_path("copypaste.tpl",TRUE, dirname(__FILE__)));
1099 $ret = array();
1100 $ret['status'] = "";
1101 $ret['string'] = $str;
1102 return($ret);
1103 }
1105 function saveCopyDialog()
1106 {
1107 if(!$this->is_account) return;
1109 /* Execute to save mailAlternateAddress && gosaMailForwardingAddress */
1110 $this->execute();
1112 if(isset($_POST['mail'])){
1113 $this->mail = $_POST['mail'];
1114 }
1116 }
1118 function allow_remove()
1119 {
1120 if (isset($this->config->current['MAILMETHOD'])){
1121 $method= $this->config->current['MAILMETHOD'];
1122 if(preg_match("/olab/i",$method)){
1123 $ldap = $this->config->get_ldap_link();
1124 $ldap->cd($this->config->current['BASE']);
1125 $ldap->cat($this->dn);
1126 if($ldap->count()){
1127 $attrs = $ldap->fetch();
1128 if(isset($attrs['kolabDeleteFlag'])){
1129 return(_("Waiting for kolab to remove mail properties..."));
1130 }elseif(in_array("gosaMailAccount",$attrs['objectClass'])){
1131 return(_("Please remove the mail settings first to allow kolab to call its remove methods!"));
1132 }
1133 }
1134 }
1135 }
1136 }
1139 function PrepareForCopyPaste($source)
1140 {
1141 plugin::PrepareForCopyPaste($source);
1143 /* Reset alternate mail addresses */
1144 $this->gosaMailAlternateAddress = array();
1145 }
1148 static function plInfo()
1149 {
1150 return (array(
1151 "plShortName" => _("Mail"),
1152 "plDescription" => _("Mail settings"),
1153 "plSelfModify" => TRUE,
1154 "plDepends" => array("user"), // This plugin depends on
1155 "plPriority" => 4, // Position in tabs
1156 "plSection" => array("personal" => _("My account")),
1157 "plCategory" => array("users"),
1158 "plOptions" => array(),
1160 "plProvidedAcls" => array(
1161 "mail" => _("Mail address"),
1162 "gosaMailServer" => _("Mail server"),
1163 "gosaMailQuota" => _("Quota size"),
1165 "gosaMailDeliveryModeV" => _("Add vacation information"), // This is flag of gosaMailDeliveryMode
1166 "gosaVacationMessage" => _("Vacation message"),
1168 "gosaMailDeliveryModeS" => _("Use spam filter"), // This is flag of gosaMailDeliveryMode
1169 "gosaSpamSortLevel" => _("Spam level"),
1170 "gosaSpamMailbox" => _("Spam mail box"),
1172 "sieveManagement" => _("Sieve management"),
1174 "gosaMailDeliveryModeR" => _("Reject due to mailsize"), // This is flag of gosaMailDeliveryMode
1175 "gosaMailMaxSize" => _("Mail max size"),
1177 "gosaMailForwardingAddress" => _("Forwarding address"),
1178 "gosaMailDeliveryModeL" => _("Local delivery"), // This is flag of gosaMailDeliveryMode
1179 "gosaMailDeliveryModeI" => _("No delivery to own mailbox "), // This is flag of gosaMailDeliveryMode
1180 "gosaMailAlternateAddress" => _("Mail alternative addresses"),
1182 "gosaMailForwardingAddress" => _("Forwarding address"),
1183 "gosaMailDeliveryModeC" => _("Use custom sieve script")) // This is flag of gosaMailDeliveryMode
1184 ));
1185 }
1188 /*! \brief Prepare importet vacation string. \
1189 Replace placeholder like %givenName a.s.o.
1190 @param string Vacation string
1191 @return string Completed vacation string
1192 */
1193 private function prepare_vacation_template($contents)
1194 {
1195 /* Replace attributes */
1196 $attrs = array();
1197 $obj = NULL;
1198 if(isset($this->parent->by_object['user'])){
1199 $attrs = $this->parent->by_object['user']->attributes;
1200 $obj = $this->parent->by_object['user'];
1201 }else{
1202 $obj = new user($this->config,$this->dn);
1203 $attrs = $obj->attributes;
1204 }
1206 if($obj){
1207 foreach ($attrs as $val){
1208 if(preg_match("/dateOfBirth/",$val)){
1209 if($obj->use_dob){
1210 $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
1211 }
1212 }else {
1213 $contents= preg_replace("/%$val/",
1214 $obj->$val, $contents);
1215 }
1217 /* Replace vacation start and end time */
1218 if(preg_match("/%start/",$contents)){
1219 $contents = preg_replace("/%start/",date("d.m.Y",$this->gosaVacationStart),$contents);
1220 }
1221 if(preg_match("/%end/",$contents)){
1222 $contents = preg_replace("/%end/",date("d.m.Y",$this->gosaVacationStop),$contents);
1223 }
1224 }
1225 }
1226 return($contents);
1227 }
1231 /* Upated shared folder ACLs
1232 */
1233 function updateSharedFolder()
1234 {
1235 $ldap = $this->config->get_ldap_link();
1236 $ldap->cd($this->config->current['BASE']);
1237 $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$this->uid."))",array('dn','cn'));
1238 if(class_exists("grouptabs")){
1239 while($attrs = $ldap->fetch()){
1240 $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
1241 if(isset($tmp->by_object['mailgroup'])){
1242 $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
1243 if(!$this->is_account){
1244 $tmp->by_object['mailgroup']->removeUserAcl($this->uid);
1245 $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
1246 }
1247 $tmp->by_object['mailgroup']->save();
1248 }
1249 }
1250 }
1251 }
1253 /* Initialize plugin with given atribute arrays
1254 */
1255 function init_multiple_support($attrs,$all)
1256 {
1257 plugin::init_multiple_support($attrs,$all);
1259 if(isset($this->multi_attrs['gosaMailQuota'])){
1260 $this->gosaMailQuota = $this->multi_attrs['gosaMailQuota'];
1261 }
1262 }
1264 function get_multi_init_values()
1265 {
1266 $attrs = plugin::get_multi_init_values();
1267 $attrs['gosaMailQuota'] = $this->gosaMailQuota;
1268 return($attrs);
1269 }
1271 function multiple_execute()
1272 {
1273 return($this->execute());
1274 }
1276 function multiple_save_object()
1277 {
1278 plugin::multiple_save_object();
1280 $this->save_object();
1281 foreach(array("only_local","gosaMailForwardingAddress","use_mailsize_limit","drop_own_mails","use_vacation","use_spam_filter") as $attr){
1282 if(isset($_POST["use_".$attr])){
1283 $this->multi_boxes[] = $attr;
1284 }
1285 }
1286 }
1288 function get_multi_edit_values()
1289 {
1290 $ret = plugin::get_multi_edit_values();
1292 if(in_array("gosaMailQuota",$this->multi_boxes)){
1293 $ret['gosaMailQuota'] = $this->gosaMailQuota;
1294 }
1296 $flag_add = $flag_remove = array();
1297 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1298 $opts = array(
1299 "R" => "use_mailsize_limit",
1300 "S" => "use_spam_filter",
1301 "L" => "only_local",
1302 "V" => "use_vacation",
1303 "C" => "own_script",
1304 "I" => "drop_own_mails");
1306 foreach($opts as $flag => $post){
1307 if(in_array($post, $this->multi_boxes)){
1308 if(preg_match("/".$flag."/",$tmp)){
1309 $flag_add[] = $flag;
1310 }else{
1311 $flag_remove[] = $flag;
1312 }
1313 }
1314 }
1316 $ret['flag_add'] = $flag_add;
1317 $ret['flag_remove'] = $flag_remove;
1318 return($ret);
1319 }
1322 function multiple_check()
1323 {
1324 $message = plugin::multiple_check();
1326 if(empty($this->gosaMailServer) && in_array("gosaMailServer",$this->multi_boxes)){
1327 $message[]= msgPool::noserver(_("Mail"));
1328 }
1330 /* Check quota */
1331 if ($this->gosaMailQuota != '' && in_array("gosaMailQuota",$this->multi_boxes)){
1332 if (!is_numeric($this->gosaMailQuota)) {
1333 $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
1334 } else {
1335 $this->gosaMailQuota= (int) $this->gosaMailQuota;
1336 }
1337 }
1339 /* Check rejectsize for integer */
1340 if ($this->gosaMailMaxSize != '' && in_array("gosaMailMaxSize",$this->multi_boxes)){
1341 if (!is_numeric($this->gosaMailMaxSize)){
1342 $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
1343 } else {
1344 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
1345 }
1346 }
1348 if(empty($this->gosaSpamMailbox) && in_array("gosaSpamMailbox",$this->multi_boxes)){
1349 $message[]= msgPool::required(_("Spam folder"));
1350 }
1352 if ( in_array("use_vacation",$this->multi_boxes) &&
1353 preg_match('/V/', $this->gosaMailDeliveryMode) && $this->gosaVacationStart > $this->gosaVacationStop){
1354 $message[]= msgPool::invalid(_("Vacation interval"));
1355 }
1356 return($message);
1357 }
1360 function set_multi_edit_values($values)
1361 {
1362 plugin::set_multi_edit_values($values);
1363 $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
1364 if(isset($values['flag_add'])){
1365 foreach($values['flag_add'] as $flag){
1366 if(!preg_match("/".$flag."/",$tmp)){
1367 $tmp .= $flag;
1368 }
1369 }
1370 }
1371 if(isset($values['flag_remove'])){
1372 foreach($values['flag_remove'] as $flag){
1373 if(preg_match("/".$flag."/",$tmp)){
1374 $tmp = preg_replace("/".$flag."/","",$tmp);
1375 }
1376 }
1377 }
1378 $this->gosaMailDeliveryMode = "[".$tmp."]";
1380 /* Set vacation message and replace placeholder like %givenName
1381 */
1382 if(isset($values['gosaVacationMessage'])){
1383 $this->gosaVacationMessage = $this->prepare_vacation_template($values['gosaVacationMessage']);
1384 }
1385 }
1386 }
1388 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1389 ?>