Code

Updated group mail and kolab 22
[gosa.git] / gosa-plugins / mail / admin / groups / mail / class_groupMail.inc
1 <?php
3 class mailgroup extends plugin
4 {
5   /* Multiple edit */
6   var $gosaMailForwardingAddress_Some  = array();  // Used in multiple edit 
8   /* Default values */
9   var $mail                       = "";           // Default mail address 
10   var $gosaMailAlternateAddress   = array();  // Set default Alternate Mail Adresses to empty array
11   var $gosaMailForwardingAddress  = array();  // Forwarding also empty
12   var $gosaMailServer             = "";       // Selected mailserver 
13   var $gosaMailQuota              = "";       // Defined Quota 
14   var $gosaVacationMessage        = "";       // Vocation message 
15   var $gosaSpamSortLevel          = "";     
16   var $gosaSpamMailbox            = "";
17   var $gosaSharedFolderTarget     ;
18   var $gosaMailDeliveryMode       = "[L        ]";   // 
19   var $gosaMailMaxSize            = "";       // 
20   var $FolderType                 = array("CAT" => '', "SUB_CAT" => '');
22   var $quotaUsage                 = -1;        // -1 Means undefined
24   /* Internal */
25   var $AclTypes                   = array();
26   var $members                    = array();  // Group members
27   var $mailusers                  = array();  // Group member with mail account
28   var $folder_acls                = array();
29   var $MailMethod = NULL; 
30   var $forward_dialog             = FALSE;    
31   var $remove_folder_from_imap    = true;
32   var $view_logged                = FALSE;
33   var $mailDomainPart             = "";
35   /* attribute list for save action */
36   var $attributes= array( "mail",   "gosaMailServer", "gosaMailQuota", "gosaMailMaxSize",
37       "gosaMailAlternateAddress", "gosaMailForwardingAddress",
38       "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox",
39       "acl","gosaSharedFolderTarget", "gosaVacationMessage");
41   var $objectclasses= array("gosaMailAccount");
42   var $multiple_support = FALSE; // Not tested yet
44   var $uid = "";
45   var $cn ="";
46   var $orig_cn = "";
48   function __construct (&$config, $dn= NULL, $ui= NULL)
49   {
50     plugin::plugin($config, $dn);
52     /* Get attributes from parent object
53      */
54     foreach(array("uid","cn") as $attr){
55       if(isset($this->parent->by_object['group']) && isset($this->parent->by_object['group']->$attr)){
56         $this->$attr = &$this->parent->by_object['group']->$attr;
57       }elseif(isset($this->attrs[$attr])){
58         $this->$attr = $this->attrs[$attr][0];
59       }
60     }
61     $this->orig_cn = $this->cn;
63     /* Intialize the used mailMethod
64      */
65     $tmp = new mailMethod($config,$this,"group");
66     $this->mailMethod           = $tmp->get_method();
67     $this->mailMethod->fixAttributesOnLoad();
68     $this->mailDomainParts      = $this->mailMethod->getMailDomains();
69     $this->AvailableFolderTypes = $this->mailMethod->getAvailableFolderTypes();
70     $this->MailBoxes = array();
72     /* Remember account status
73      */
74     $this->initially_was_account = $this->is_account;
76     /* Load folder_acls with defaults.
77       anyone -- The default acl, will be written to ldap.
78       member -- The ACL used for the members.
79      */ 
80     $this->folder_acls = $this->mailMethod->getDefaultACLs();
82     /* Load acls
83        The most used acl will be used as member acl, this
84         shortens the listed acls.        
85        This may be merged/overwritten by the mail methods.
86      */
87     $ldap = $this->config->get_ldap_link();
88     if(isset($this->attrs['acl'])){
89       for($i = 0; $i < $this->attrs['acl']['count'] ; $i++){
90         $str = trim($this->attrs['acl'][$i]);
92         /* Be carefull here, since kolab22 uses spaces in the acls (herbert read anon/post)
93          */
94         $name = trim(preg_replace("/^([^\s]*).*$/","\\1",$str));
95         $acl  = trim(preg_replace("/^[^\s]*+\s/","",$str));
96         if($name == "anyone") $name = "__anyone__";
97         $this->folder_acls[$name] = $acl;
98       }
99     }
101     /* Initialize configured values
102      */
103     if($this->is_account){
104       if($this->mailMethod->connect() && $this->mailMethod->account_exists()){
106         /* Read quota */
107         $this->gosaMailQuota = $this->mailMethod->getQuota($this->gosaMailQuota);
108         $this->quotaUsage = $this->mailMethod->getQuotaUsage($this->quotaUsage);
109         if($this->mailMethod->is_error()){
110           msg_dialog::display(_("Mail error"), sprintf(_("Cannot read quota settings: %s"),
111                 $this->mailMethod->get_error()), ERROR_DIALOG);
112         }
114         /* Read mailboxes */
115         $this->MailBoxes = $this->mailMethod->getMailboxList($this->MailBoxes);
116         if($this->mailMethod->is_error()){
117           msg_dialog::display(_("Mail error"), sprintf(_("Cannot get list of mailboxes: %s"),
118                 $this->mailMethod->get_error()), ERROR_DIALOG);
119         }
121         /* Receive folder types */
122         $this->FolderType = $this->mailMethod->getFolderType($this->FolderType);
123         if($this->mailMethod->is_error()){
124           msg_dialog::display(_("Mail error"), sprintf(_("Cannot receive folder types: %s"),
125                 $this->mailMethod->get_error()), ERROR_DIALOG);
126         }
128         /* Receive permissions */  
129         $this->folder_acls = $this->mailMethod->getFolderACLs($this->folder_acls);
130         if($this->mailMethod->is_error()){
131           msg_dialog::display(_("Mail error"), sprintf(_("Cannot receive folder permissions: %s"),
132                 $this->mailMethod->get_error()), ERROR_DIALOG);
133         }
135       }elseif(!$this->mailMethod->is_connected()){
136         msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
137               $this->mailMethod->get_error()), ERROR_DIALOG);
138       }elseif(!$this->mailMethod->account_exists()){
139         msg_dialog::display(_("Mail error"), sprintf(_("Mailbox '%s' doesn't exists on mail server: %s"),
140               $this->mailMethod->get_account_id(),$this->gosaMailServer), ERROR_DIALOG);
141       }
143       /* If the doamin part is selectable, we have to split the mail address
144        */
145       if(!(!$this->mailMethod->isModifyableMail() && $this->is_account)){
146         if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
147           $this->mailDomainPart = preg_replace("/^[^@]*+@/","",$this->mail);
148           $this->mail = preg_replace("/@.*$/","\\1",$this->mail);
149           if(!in_array($this->mailDomainPart,$this->mailDomainParts)){
150             $this->mailDomainParts[] = $this->mailDomainPart;
151           }
152         }
153       }
155       /* Load attributes containing arrays */
156       foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
157         $this->$val= array();
158         if (isset($this->attrs["$val"]["count"])){
159           for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
160             array_push($this->$val, $this->attrs["$val"][$i]);
161           }
162         }
163       }
164     }
166     /* Disconnect mailMethod. Connect on demand later.
167      */
168     $this->mailMethod->disconnect();
169     $this->AclTypes = $this->mailMethod->getAclTypes();
171     /* Summarize most used ACLs as member acl 
172      */
173     if(count($this->folder_acls) > 2){
174       $acl_usage = array();
175       $most_acl = $this->folder_acls['__member__'];
176       $most_cnt = 0;
177       $member = $this->get_member();
178       foreach($this->folder_acls as $user => $acl){
179         if(preg_match("/^__/",$user)) continue;
180         if(!in_array($user,$member['mail'])) continue; 
181         if(!isset($acl_usage[$acl])) $acl_usage[$acl]=0;
182         $acl_usage[$acl] ++;
183         if($acl_usage[$acl] > $most_cnt){
184           $most_cnt = $acl_usage[$acl];
185           $most_acl = $acl;
186         }
187       }
188       $this->folder_acls['__member__'] = $most_acl;  
189       foreach($this->folder_acls as $name => $acl){
190         if(preg_match("/^__/",$name)) continue;
191         if($acl == $most_acl && in_array($name,$member['mail'])){
192           unset($this->folder_acls[$name]);
193         }
194       }
195     }
197     /* Get global filter config */
198     if (!session::is_set("gmailfilter")){
199       $ui= get_userinfo();
200       $base= get_base_from_people($ui->dn);
201       $gmailfilter= array( "depselect"       => $base,
202           "muser"            => "",
203           "regex"           => "*");
204       session::set("gmailfilter", $gmailfilter);
205     }
206   }
208  
209   /*! \brief  Returns all group members once with 'dn' and once with 'mail'.
210               This function is used to summarize ACLs by member acls.
211       @return Array   Containing all members, with mail and dn
212    */ 
213   function get_member()
214   {
215     $member = array('all' => array(), 'mail' => array());
216     $ldap = $this->config->get_ldap_link();
217     $ldap->cd($this->config->current['BASE']);
218     if(isset($this->parent->by_object['group'])){
219       foreach($this->parent->by_object['group']->memberUid as $uid){
220         $dn = $this->parent->by_object['group']->dnMapping[$uid];
221         $member['all'][$uid] = $uid;
222         if($ldap->object_match_filter($dn,"(&(objectClass=gosaMailAccount)(".$this->mailMethod->getUAttrib()."=*))")){
223           $ldap->cat($dn);
224           $attrs = $ldap->fetch();
225           $member['mail'][$uid] = $attrs[$this->mailMethod->getUAttrib()][0]; 
226         }
227       }
228     }else{
229       if(!isset($this->attrs['memberUid'])) return($member);
230       $uattrib = $this->mailMethod->getUAttrib();
231       $users = get_list("(&(objectClass=person)(objectClass=gosaAccount)(uid=*))",
232               "users",$this->config->current['BASE'],
233               array("uid","objectClass",$uattrib),GL_SUBSEARCH | GL_NO_ACL_CHECK);
234       foreach($users as $user){
235         $member['all'][$user['uid'][0]] = $user['dn'];
236         if(isset($user[$uattrib]) 
237             && in_array("gosaMailAccount",$user['objectClass']) 
238             && (in_array($user['uid'][0], $this->attrs['memberUid']))){
239           $member['mail'][$user['uid'][0]] = $user[$uattrib][0];
240         }
241       }
242     }
243     return($member);
244   }
247   function execute()
248   {
249     /* Call parent execute */
250     plugin::execute();
252     /* Log view */
253     if($this->is_account && !$this->view_logged){
254       $this->view_logged = TRUE;
255       new log("view","groups/".get_class($this),$this->dn);
256     }
258     $this->get_member();
259  
260     /****************
261       Account status
262      ****************/
264     if(!$this->multiple_support_active){
266       if(isset($_POST['modify_state'])){
267         if($this->is_account && $this->acl_is_removeable() && $this->mailMethod->accountRemoveAble()){
268           $this->is_account= FALSE;
269         }elseif(!$this->is_account && $this->acl_is_createable() && $this->mailMethod->accountCreateable()){
270           $this->is_account= TRUE;
271         }
272       }
274       if ($this->is_account){
275         $reason = "";
276         if(!$this->mailMethod->accountRemoveable($reason)){
277           $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
278         }else{
279           $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),msgPool::
280               featuresEnabled(_("Mail")));
281         }
282       } else {
283         $reason = "";
284         if(!$this->mailMethod->accountCreateable($reason)){
285           $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
286         }else{
287           $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),msgPool::
288               featuresDisabled(_("Mail")));
290           /* Show checkbox that allows us to remove imap entry too*/
291           if($this->initially_was_account){
292             $c = "";
293             if($this->remove_folder_from_imap){
294               $c= " checked ";
295             }
296             $display .= "<h2>Shared folder delete options</h2>
297               <input class='center' type='checkbox' name='remove_folder_from_imap' value='1' ".$c."
298               title='"._("Remove shared folder from mail server database when entry gets removed in LDAP")."'>";
299             $display .= _("Remove the shared folder and all its contents after saving this account");
300           }
301         }
302         return ($display);
303       }
304     }
306     
307     /****************
308       Preset mail attribute
309      ****************/
310     if(empty($this->mail) && $this->mailMethod->mailEqualsCN() && !$this->initially_was_account){
311       if($this->mailMethod->domainSelectionEnabled()){
312         $this->mail = &$this->parent->by_object['group']->cn;
313       }
314     }
317     /****************
318       Forward addresses
319      ****************/
320     if (isset($_POST['add_local_forwarder'])){
321       $this->forward_dialog= TRUE;
322       $this->dialog= TRUE;
323     }
324     if (isset($_POST['add_locals_cancel'])){
325       $this->forward_dialog= FALSE;
326       $this->dialog= FALSE;
327     }
328     if (isset($_POST['add_locals_finish'])){
329       if (isset($_POST['local_list'])){
330         if($this->acl_is_writeable("gosaMailForwardingAddress")){
331           foreach ($_POST['local_list'] as $val){
332             if (!in_array ($val, $this->gosaMailAlternateAddress) &&
333                 $val != $this->mail){
334               $this->addForwarder($val);
335               $this->is_modified= TRUE;
336             }
337           }
338         }
339         $this->forward_dialog= FALSE;
340         $this->dialog= FALSE;
341       } else {
342         msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
343       }
344     }
346     if (isset($_POST['add_forwarder'])){
347       if ($_POST['forward_address'] != ""){
348         $address= $_POST['forward_address'];
349         $valid= FALSE;
350         if (!tests::is_email($address)){
351           if (!tests::is_email($address, TRUE)){
352             if ($this->is_template){
353               $valid= TRUE;
354             } else {
355               msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
356                     "","","your-address@your-domain.com"),ERROR_DIALOG);
357             }
358           }
359         } elseif ($address == $this->mail
360             || in_array($address, $this->gosaMailAlternateAddress)) {
361           msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
362         } else {
363           $valid= TRUE;
364         }
365         if ($valid){
366           if($this->acl_is_writeable("gosaMailForwardingAddress")){
367             $this->addForwarder ($address);
368             $this->is_modified= TRUE;
369           }
370         }
371       }
372     }
373     if (isset($_POST['delete_forwarder'])){
374       $this->delForwarder ($_POST['forwarder_list']);
375     }
376     if ($this->forward_dialog){
377       return($this->display_forward_dialog());
378     } 
380  
381     /****************
382       Alternate addresses
383      ****************/
385     if (isset($_POST['add_alternate'])){
386       $valid= FALSE;
387       if (!tests::is_email($_POST['alternate_address'])){
388         if ($this->is_template){
389           if (!(tests::is_email($_POST['alternate_address'], TRUE))){
390             msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
391                   "","","your-domain@your-domain.com"),     ERROR_DIALOG);
392           } else {
393             $valid= TRUE;
394           }
395         } else {
396           msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
397                 "","","your-domain@your-domain.com"),       ERROR_DIALOG);
398         }
399       } else {
400         $valid= TRUE;
401       }
402       if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
403         $ui= get_userinfo();
404         if ($user != $ui->username){
405           msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."&nbsp;".
406               sprintf(_("Address is already in use by user '%s'."), $user), ERROR_DIALOG);
407         }
408       }
409     }
410     if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
411       $this->delAlternate ($_POST['alternates_list']);
412     }
415     /****************
416       SMARTY- Assign smarty variables
417      ****************/
419     /* Load templating engine */
420     $smarty= get_smarty();
421     $smarty->assign("initially_was_account", $this->initially_was_account);
422     $smarty->assign("isModifyableMail", $this->mailMethod->isModifyableMail());
423     $smarty->assign("isModifyableServer", $this->mailMethod->isModifyableServer());
424     $smarty->assign("mailEqualsCN", $this->mailMethod->mailEqualsCN());
425     $smarty->assign("folder_acls" , $this->postable_acls());
426     $smarty->assign("AclTypes" ,    $this->AclTypes);
427   
428     $smarty->assign("quotaEnabled", $this->mailMethod->quotaEnabled());
429     if($this->mailMethod->quotaEnabled()){
430       $smarty->assign("gosaMailQuota",$this->gosaMailQuota);
431       $smarty->assign("quotaUsage",   mailMethod::quota_to_image($this->quotaUsage,$this->gosaMailQuota)); 
432     }
434     $smarty->assign("MailDomains", $this->mailDomainParts);
435     $smarty->assign("MailDomain" , $this->mailDomainPart);
436     $smarty->assign("MailServers", $this->mailMethod->getMailServers());
437     $smarty->assign("allowSieveManagement", $this->mailMethod->allowSieveManagement());
439     $smarty->assign("domainSelectionEnabled", $this->mailMethod->domainSelectionEnabled());
440     $smarty->assign("folderTypesEnabled",$this->mailMethod->folderTypesEnabled());
441     $smarty->assign("AvailableFolderTypes", $this->AvailableFolderTypes);
442     $smarty->assign("FolderType", $this->FolderType);
443  
444     if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){
445       if($this->acl_is_readable("gosaMailQuota")){
446         $smarty->assign("quotausage", progressbar(round(($this->quotaUsage * 100)/ $this->gosaMailQuota),100,15,true));
447         $smarty->assign("quotadefined", "true");
448       }else{
449         $smarty->assign("quotadefined", "true");
450         $smarty->assign("quotausage", "-");
451       }
452     } else {
453       $smarty->assign("quotadefined", "false");
454     }
456     /* Assign acls */
457     $tmp = $this->plInfo();
458     foreach($tmp['plProvidedAcls'] as $name => $translation) {
459       $smarty->assign($name."ACL",$this->getacl($name));
460     }
461     foreach($this->attributes as $name){
462       $smarty->assign($name,$this->$name);
463     }
467     $smarty->assign("mailServers", $this->mailMethod->getMailServers());
468     if (preg_match("/I/", $this->gosaMailDeliveryMode)) {
469       $smarty->assign("only_local", "checked");
470     }else{
471       $smarty->assign("only_local", "");
472     }
475     /******
476       Multi edit support 
477      ******/
478     foreach($this->attributes as $attr){
479       if(in_array($attr,$this->multi_boxes)){
480         $smarty->assign("use_".$attr,TRUE);
481       }else{
482         $smarty->assign("use_".$attr,FALSE);
483       }
484     }
486     /* Multiple support handling */
487     foreach(array("kolabFolderType") as $attr){
488       if(in_array($attr,$this->multi_boxes)){
489         $smarty->assign("use_".$attr,TRUE);
490       }else{
491         $smarty->assign("use_".$attr,FALSE);
492       }
493     }
495     $smarty->assign("Forward_all",$this->gosaMailForwardingAddress);
496     $smarty->assign("Forward_some",$this->gosaMailForwardingAddress_Some);
497     $smarty->assign("multiple_support",$this->multiple_support_active);
499     $display.= $smarty->fetch (get_template_path('mail.tpl', TRUE, dirname(__FILE__)));
500     return ($display);
501   }
504   /* remove object from parent */
505   function remove_from_parent()
506   {
507     if(!$this->initially_was_account){
508       return;
509     }
510  
511     /* If domain part was selectable, contruct mail address */
512     if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
513       $this->mail = $this->mail."@".$this->mailDomainPart;
514     }
516     /* Remove GOsa attributes */
517     plugin::remove_from_parent();
519     /* Zero arrays */
520     $this->attrs['gosaMailAlternateAddress'] = array();
521     $this->attrs['gosaMailForwardingAddress']= array();
522     $this->attrs['gosaSharedFolderTarget']= array();
524     $this->mailMethod->fixAttributesOnRemove();
525     $this->cleanup();
526     $ldap = $this->config->get_ldap_link();
527     $ldap->cd($this->dn);
528     $ldap->modify ($this->attrs); 
529     if (!$ldap->success()){
530       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
531     }
533     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
536     /* Let the mailMethod remove this mailbox, e.g. from imap and
537        update shared folder membership, ACL may need to be updated.
538      */
539     if (!$this->is_template && $this->remove_folder_from_imap){
541       if(!$this->mailMethod->connect()){
542         msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
543               $this->mailMethod->get_error()), ERROR_DIALOG);
544       }else{
545         if(!$this->mailMethod->deleteMailbox()){
546           msg_dialog::display(_("Mail error"), sprintf(_("Cannot remove mailbox: %s"),
547                 $this->mailMethod->get_error()), ERROR_DIALOG);
548         }
549         if(!$this->mailMethod->updateSharedFolder()){
550           msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions: %s"),
551                 $this->mailMethod->get_error()), ERROR_DIALOG);
552         }
553       }
554     }
555     $this->mailMethod->disconnect();
558     /* Optionally execute a command after we're done */
559     $this->handle_post_events("remove");
560   }
563   /* Save data to object */
564   function save_object()
565   {
566     /* Check if user wants to remove the shared folder from imap too 
567      */
568     if($this->initially_was_account && !$this->is_account){
569       if(isset($_POST['remove_folder_from_imap'])){
570         $this->remove_folder_from_imap = true;
571       }else{
572         $this->remove_folder_from_imap = false;
573       }
574     }
575     if (isset($_POST['mailedit'])){
577       $mail = $this->mail;
578       $server = $this->gosaMailServer;
579       plugin::save_object();
581       if(!$this->mailMethod->isModifyableServer() && $this->initially_was_account){
582         $this->gosaMailServer = $server;
583       }
584       if(!$this->mailMethod->isModifyableMail() && $this->initially_was_account){
585         $this->mail = $mail;
586       }else{
588         if($this->mailMethod->mailEqualsCN()){
589           $this->mail = &$this->parent->by_object['group']->cn;
590           if(isset($_POST['MailDomain'])){
591             $this->mailDomainPart = get_post('MailDomain');
592           }
593         }
595       /* Get posted mail domain part, if necessary
596        */
597       if($this->mailMethod->domainSelectionEnabled() && isset($_POST['MailDomain'])){
598         if(in_array(get_post('MailDomain'), $this->mailDomainParts)){
599           $this->mailDomainPart = get_post('MailDomain');
600         }
601       }
602     }
604       /* Get folder type 
605        */
606       if($this->mailMethod->folderTypesEnabled()){
607         if(isset($_POST['FolderTypeCAT'])){
608         $this->FolderType['CAT']     = get_post('FolderTypeCAT');
609         }
610         if(isset($_POST['FolderTypeSUB_CAT'])){
611           $this->FolderType['SUB_CAT'] = get_post('FolderTypeSUB_CAT');
612         }
613       }
615       /* Handle posted ACL changes. 
616          Add/del member acls.
617        */
618       if(isset($_POST['mail_acls_posted'])){
619         $new_acls = array();
620         foreach(array("__anyone__","__member__") as $attr){
621           $pname = base64_encode($attr);
622           if(get_post('acl_value_'.$pname)){ 
623             $new_acls[$attr] = get_post('acl_value_'.$pname);
624           }else{
625             $new_acls[$attr] = $this->folder_acls[$attr];
626           }
627         }
629         foreach($this->folder_acls as $user => $acl){
630           $pname = base64_encode($user);
631           if($user == "__member__" || $user == "__anyone__") continue;
632           if(isset($_POST['remove_acl_user_'.$pname])){
633           }elseif(isset($_POST['acl_user_'.$pname])){
634             if($user != get_post('acl_user_'.$pname)){
635               $new_acls[get_post('acl_user_'.$pname)] = get_post('acl_value_'.$pname);
636             }else{
637               $new_acls[$user] = get_post('acl_value_'.$pname);
638             }
639           }else{
640             $new_acls[$user] = $acl;
641           }
642         }
643         if(isset($_POST['add_acl_user'])){
644           $new_acls[_('New')] = $this->folder_acls['__anyone__'];
645         }
646         $this->folder_acls = $new_acls;
647       }
649       /* Handle GOsa mail delivery flags.
650        */
652     /* Assemble mail delivery mode
653        The mode field in ldap consists of values between braces, this must
654        be called when 'mail' is set, because checkboxes may not be set when
655        we're in some other dialog.
657        Example for gosaMailDeliveryMode [LR        ]
658        L - Local delivery
659        R - Reject when exceeding mailsize limit
660        S - Use spam filter
661        V - Use vacation message
662        C - Use custom sieve script
663        I - Only insider delivery */
664       $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
665       if($this->acl_is_writeable("gosaMailDeliveryModeL")){
666         if(!preg_match("/L/",$tmp) && !isset($_POST['drop_own_mails'])){
667           $tmp.="L";
668         }elseif(preg_match("/L/",$tmp) && isset($_POST['drop_own_mails'])){
669           $tmp = preg_replace("/L/","",$tmp);
670         }
671       }
673       $opts = array(
674           "R"   => "use_mailsize_limit",
675           "S"   => "use_spam_filter",
676           "V"   => "use_vacation",
677           "C"   => "own_script",
678           "I"   => "only_local");
680       foreach($opts as $flag => $post){
681         if($this->acl_is_writeable("gosaMailDeliveryMode".$flag)){
682           if(!preg_match("/".$flag."/",$tmp) && isset($_POST[$post])){
683             $tmp.= $flag;
684           }elseif(preg_match("/".$flag."/",$tmp) && !isset($_POST[$post])){
685             $tmp = preg_replace("/".$flag."/","",$tmp);
686           }
687         }
688       }
690       $tmp= "[$tmp]";
691       if ($this->gosaMailDeliveryMode != $tmp){
692         $this->is_modified= TRUE;
693       }
694       $this->gosaMailDeliveryMode= $tmp;
695     }
696   }
699   /* Save data to LDAP, depending on is_account we save or delete */
700   function save()
701   {
702     $ldap= $this->config->get_ldap_link();
704     /* If domain part was selectable, contruct mail address */
705     if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
707       if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
708         $this->mail = $this->mail."@".$this->mailDomainPart;
709       }
710     }
712     /* Enforce lowercase mail address and trim whitespaces
713      */
714     $this->mail = trim(strtolower($this->mail));
715     
717     /* Create acls 
718      */
719     $this->acl = array("anyone ".$this->folder_acls['__anyone__']);
720     $member = $this->get_member();
721     $new_folder_acls = array("anyone" => $this->folder_acls['__anyone__']);
722     foreach($member['mail'] as $uid => $mail){
723       $this->acl[] = $mail." ".$this->folder_acls['__member__'];
724       $new_folder_acls[$mail]=$this->folder_acls['__member__'];
725     }
726     foreach($this->folder_acls as $user => $acls){
727       if(preg_match("/^__/",$user)) continue;
728       $this->acl[] = $user." ".$acls;
729       $new_folder_acls[$user]=$acls;
730     }
731     $this->folder_acls = $new_folder_acls;
732     $this->acl = array_unique($this->acl);
733       
734     /* Call parents save to prepare $this->attrs */
735     plugin::save();
737     /* Save arrays */
738     $this->attrs['gosaMailAlternateAddress'] = $this->gosaMailAlternateAddress;
739     $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
741     /* Map method attributes */
742     $this->mailMethod->fixAttributesOnStore();
744     /* Save data to LDAP */
745     $ldap->cd($this->dn);
746     $this->cleanup();
747     $ldap->modify ($this->attrs); 
748     if (!$ldap->success()){
749       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
750     }
751     
752     if($this->initially_was_account){
753       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
754     }else{
755       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());  
756     }
757     
758     /* Do imap/sieve actions,
759      */
760     $this->mailMethod->connect();
761     if(!$this->mailMethod->is_connected()){
762       msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
763             $this->mailMethod->get_error()), ERROR_DIALOG);
764     }else{
765       if(!$this->mailMethod->updateMailbox()){
766         msg_dialog::display(_("Mail error"), sprintf(_("Cannot update mailbox: %s"),
767               $this->mailMethod->get_error()), ERROR_DIALOG);
768       }
769       if(!$this->mailMethod->setQuota($this->gosaMailQuota)){
770         msg_dialog::display(_("Mail error"), sprintf(_("Cannot write quota settings: %s"),
771               $this->mailMethod->get_error()), ERROR_DIALOG);
772       }
773       /* Save Folder Types, if available 
774        */
775       if($this->mailMethod->folderTypesEnabled()){
776         $this->mailMethod->setFolderType($this->FolderType);
777       }
778       if(!$this->mailMethod->setFolderACLs($this->folder_acls)){
779         msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions: %s"),
780               $this->mailMethod->get_error()), ERROR_DIALOG);
781       }
782     }
783     $this->mailMethod->disconnect();
785     /* Optionally execute a command after we're done */
786     if ($this->initially_was_account == $this->is_account){
787       if ($this->is_modified){
788         $this->handle_post_events("modify");
789       }
790     } else {
791       $this->handle_post_events("add");
792     }
793   }
797   /* Check formular input */
798   function check()
799   {
800     if(!$this->is_account) return array();
801     $ldap= $this->config->get_ldap_link();
804     /* Call common method to give check the hook */
805     $message= plugin::check();
807     /* Ensure that this group isn't renamed if the mailMethod enforces cn mailAttributes 
808      */
809     if($this->mailMethod->mailEqualsCN() && $this->initially_was_account){
810       if($this->cn != $this->orig_cn){
811         $message[] = sprintf(_("The groups 'cn' has changed!  The cn attribute can't be changed due to the fact that this mail method '%s' relies on it.")
812             ,get_class($this->mailMethod));
813       }
814     }
816     if(empty($this->gosaMailServer)){
817       $message[]= msgPool::noserver(_("Mail"));
818     }
820     /* Mail address checks */
821     if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
822       $mail = $this->mail;
823       if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
824         $mail.= "@".$this->mailDomainPart;
825       }
826       if (empty($mail)){
827         $message[]= msgPool::required(_("Primary address"));
828       }elseif (!tests::is_email($mail)){
829         $message[]= msgPool::invalid(_("Mail address"),"","","your-address@your-domain.com");
830       }
831     }
832     
833     /* Check quota */
834     if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
835       if (!is_numeric($this->gosaMailQuota)) {
836         $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/[0-9]/");
837       } else {
838         $this->gosaMailQuota= (int) $this->gosaMailQuota;
839       }
840     }
842     /* Check rejectsize for integer */
843     if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailQuota")){
844       if (!is_numeric($this->gosaMailMaxSize)){
845         $message[]= msgPool::invalid(_("Mail max size"));
846       } else {
847         $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
848       }
849     }
851     /* Need gosaMailMaxSize if use_mailsize_limit is checked */
852     if (is_integer(strpos($this->gosaMailDeliveryMode, "reject")) && $this->gosaMailMaxSize == ""){
853       $message[]= _("You need to set the maximum mail size in order to reject anything.");
854     }
856     if(empty($this->gosaMailServer)){
857       $message[] = msgPool::required(_("Mail server"));
858     }
860     return ($message);
861   }
863   /* Adapt from template, using 'dn' */
864   function adapt_from_template($dn, $skip= array())
865   {
866     plugin::adapt_from_template($dn, $skip);
868     foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
869  
870       if (in_array($val, $skip)){
871         continue;
872       }
874       $this->$val= array();
875       if (isset($this->attrs["$val"]["count"])){
876         for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
877           $value= $this->attrs["$val"][$i];
878           foreach (array("sn", "givenName", "uid") as $repl){
879             if (preg_match("/%$repl/i", $value)){
880               $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
881             }
882           }
883           array_push($this->$val, $value);
884         }
885       }
886     }
887   }
891   function make_name($attrs)
892   {
893     $name= "";
894     if (isset($attrs['sn'][0])){
895       $name= $attrs['sn'][0];
896     }
897     if (isset($attrs['givenName'][0])){
898       if ($name != ""){
899         $name.= ", ".$attrs['givenName'][0];
900       } else {
901         $name.= $attrs['givenName'][0];
902       }
903     }
904     if ($name != ""){
905       $name.= " ";
906     }
908     return ($name);
909   }
911   function getCopyDialog()
912   {
913     if(!$this->is_account) return("");
915     $smarty = get_smarty();
916     $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
917     $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
918     $smarty->assign("mail",$this->mail);
919     $display= $smarty->fetch (get_template_path('paste_mail.tpl', TRUE, dirname(__FILE__)));
920     $ret = array();
921     $ret['string'] = $display;
922     $ret['status'] = "";
923     return($ret);
924   }
926   function saveCopyDialog()
927   {
928     if(!$this->is_account) return;
930     /* Perform ADD / REMOVE ... for mail alternate / mail forwarding addresses 
931     */
932     $this->execute();
933     if(isset($_POST['mail'])){
934       $this->mail = $_POST['mail'];
935     }
936   }
939   function PrepareForCopyPaste($source)
940   {
941     plugin::PrepareForCopyPaste($source);
942  
943     /* Reset alternate mail addresses */
944     $this->gosaMailAlternateAddress = array();
945   }
948   /* Return plugin informations for acl handling  */
949   static function plInfo()
950   {
951     return (array(
952           "plShortName"   => _("Mail"),
953           "plDescription" => _("Group mail"),
954           "plSelfModify"  => FALSE,
955           "plDepends"     => array(),
956           "plPriority"    => 10,
957           "plSection"     => array("administration"),
958           "plCategory"    => array("groups"), 
959           "plProvidedAcls"=> array(
960             "mail"                      => _("Mail address"),
961             "gosaMailQuota"             => _("Quota size"),
962             "gosaMailServer"            => _("Mail server"),
963             "kolabFolderType"           => _("Folder type")." ("._("Kolab").")",
964             "gosaMailAlternateAddress"  => _("Alternate addresses"),
965             "gosaMailForwardingAddress" => _("Forwarding addresses"),
966             "gosaMailDeliveryModeI"     => _("Only local"),
967             "acl"                       => _("Permissions"))
968           ));
969   }
971   
972   /* Remove given ACL for given member (uid,mail) ..
973    */
974   function removeUserAcl($index )
975   {
976     if(isset($this->imapacl[$index])){
977       unset($this->imapacl[$index]);
978     }
979   }
981   function multiple_execute()
982   {
983     return($this->execute());
984   }
987   function init_multiple_support($attrs,$all)
988   {
989     plugin::init_multiple_support($attrs,$all);
991     $this->gosaMailForwardingAddress = array();
992     if(isset($attrs['gosaMailForwardingAddress'])){
993       for($i = 0 ; $i < $attrs['gosaMailForwardingAddress']['count'] ; $i++){
994         $this->gosaMailForwardingAddress[] = $attrs['gosaMailForwardingAddress'][$i];
995       }
996     }
998     $this->gosaMailForwardingAddress_Some = array();
999     if(isset($all['gosaMailForwardingAddress'])){
1000       for($i = 0 ; $i < $all['gosaMailForwardingAddress']['count'] ; $i++){
1001         if(!in_array($all['gosaMailForwardingAddress'][$i],$this->gosaMailForwardingAddress)){
1002           $this->gosaMailForwardingAddress_Some[] = $all['gosaMailForwardingAddress'][$i];
1003         }
1004       }
1005     }
1006   }
1008   function multiple_save_object()
1009   {
1010     if(isset($_POST['multiple_mail_group_posted'])){
1011       plugin::multiple_save_object();
1012       
1013       foreach(array("kolabFolderType") as $attr){
1014         if(isset($_POST['use_'.$attr])){
1015           $this->multi_boxes[] = $attr;
1016         }
1017       }
1019       /* Add special kolab attributes */
1020       if(preg_match("/olab/i",$this->config->get_cfg_value("mailmethod"))){
1021         if(isset($_POST['kolabFolderTypeType']) && $this->acl_is_writeable("kolabFolderType")){
1022           $this->kolabFolderTypeType = get_post("kolabFolderTypeType");
1023           $this->kolabFolderTypeSubType = get_post("kolabFolderTypeSubType");
1024         }
1025       }
1027       /* Collect data and re-assign it to the imapacl array */
1028       if ($this->acl_is_writeable("acl")){
1029         $this->imapacl= array();
1030         $this->imapacl['%members%']= $_POST['member_permissions'];
1031         $this->imapacl['anyone']= $_POST['default_permissions'];
1032         foreach ($this->indexed_user as $nr => $user){
1033           if (!isset($_POST["user_$nr"])){
1034             continue;
1035           }
1036           if ($_POST["user_$nr"] != $user ||
1037               $_POST["perm_$nr"] != $this->indexed_acl[$nr]){
1038             $this->is_modified= TRUE;
1039           }
1040           $this->imapacl[$_POST["user_$nr"]]= $_POST["perm_$nr"];
1041         }
1042       }
1043     }
1044   }
1045   
1046   
1047   /* Return selected values for multiple edit */
1048   function get_multi_edit_values()
1049   {
1050     $ret = plugin::get_multi_edit_values();
1051     $ret['Forward_some'] = $this->gosaMailForwardingAddress_Some;    
1052     $ret['Forward_all'] = $this->gosaMailForwardingAddress;    
1053     if(in_array('kolabFolderType',$this->multi_boxes)){
1054       $ret['kolabFolderTypeType'] = $this->kolabFolderTypeType;
1055       $ret['kolabFolderTypeSubType'] = $this->kolabFolderTypeSubType;
1056     }
1057     if(in_array("acl",$this->multi_boxes)){
1058       $ret['imapacl'] = $this->imapacl;
1059     }
1060     return($ret);
1061   }
1063   function set_multi_edit_values($attrs)
1064   {
1065     $forward = array();
1066     foreach($attrs['Forward_some'] as $addr){
1067       if(in_array($addr,$this->gosaMailForwardingAddress)){
1068         $forward[] = $addr;
1069       }
1070     }
1071     foreach($attrs['Forward_all'] as $addr){
1072       $forward[] = $addr;
1073     }
1074     plugin::set_multi_edit_values($attrs);
1075     $this->gosaMailForwardingAddress = $forward;
1076   }
1079   /*! \brief  Displays a dialog that allows mail address selection.
1080    */
1081   function display_forward_dialog()
1082   {
1083     restore_error_handler();
1085     $smarty = get_smarty();
1086     $ldap= $this->config->get_ldap_link();
1088     /* Save data */
1089     $mailfilter= session::get("mailfilter");
1090     foreach( array("depselect", "muser", "regex") as $type){
1091       if (isset($_POST[$type])){
1092         $mailfilter[$type]= $_POST[$type];
1093       }
1094     }
1095     if (isset($_GET['search'])){
1096       $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
1097       if ($s == "**"){
1098         $s= "*";
1099       }
1100       $mailfilter['regex']= $s;
1101     }
1102     session::set("mailfilter", $mailfilter);
1104     /* Get actual list */
1105     $mailusers= array ();
1106     if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
1107       $regex= $mailfilter['regex'];
1108       $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
1109     } else {
1110       $filter= "";
1111     }
1112     if ($mailfilter['muser'] != ""){
1113       $user= $mailfilter['muser'];
1114       $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
1115     }
1117     /* Add already present people to the filter */
1118     $exclude= "";
1119     foreach ($this->gosaMailForwardingAddress as $mail){
1120       $exclude.= "(mail=$mail)";
1121     }
1122     if ($exclude != ""){
1123       $filter.= "(!(|$exclude))";
1124     }
1125     $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'],
1126         array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
1127     $ldap->cd($mailfilter['depselect']);
1128     $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
1129     while ($attrs= $ldap->fetch()){
1130       if(preg_match('/%/', $attrs['mail'][0])){
1131         continue;
1132       }
1133       $name= $this->make_name($attrs);
1134       $mailusers[$attrs['mail'][0]]= $name."&lt;".
1135         $attrs['mail'][0]."&gt;";
1136     }
1137     natcasesort ($mailusers);
1138     reset ($mailusers);
1140     /* Show dialog */
1141     $smarty->assign("search_image", get_template_path('images/lists/search.png'));
1142     $smarty->assign("usearch_image", get_template_path('images/lists/search-user.png'));
1143     $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
1144     $smarty->assign("infoimage", get_template_path('images/info.png'));
1145     $smarty->assign("launchimage", get_template_path('images/lists/action.png'));
1146     $smarty->assign("mailusers", $mailusers);
1147     if (isset($_POST['depselect'])){
1148       $smarty->assign("depselect", $_POST['depselect']);
1149     }
1150     $smarty->assign("deplist", $this->config->idepartments);
1151     $smarty->assign("apply", apply_filter());
1152     $smarty->assign("alphabet", generate_alphabet());
1153     $smarty->assign("hint", print_sizelimit_warning());
1154     foreach( array("depselect", "muser", "regex") as $type){
1155       $smarty->assign("$type", $mailfilter[$type]);
1156     }
1157     $smarty->assign("hint", print_sizelimit_warning());
1158     $display= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
1159     return ($display);
1160   }
1163   /*! \brief  Add given mail address to the list of forwarders.
1164    */
1165   function addForwarder($address)
1166   {
1167     if(empty($address)) continue;
1168     $this->gosaMailForwardingAddress[]= $address;
1169     $this->gosaMailForwardingAddress= array_unique($this->gosaMailForwardingAddress);
1171     /* Update multiple edit values too */
1172     if($this->multiple_support_active){
1173       $this->gosaMailForwardingAddress_Some= 
1174         array_remove_entries (array($address),$this->gosaMailForwardingAddress_Some);
1175     }
1177     sort ($this->gosaMailForwardingAddress);
1178     reset ($this->gosaMailForwardingAddress);
1179     $this->is_modified= TRUE;
1180   }
1183   /*! \brief  Removes the given mail address from the forwarders 
1184    */
1185   function delForwarder($addresses)
1186   {
1187     if(empty($address)) continue;
1188     $this->gosaMailForwardingAddress= array_remove_entries ($addresses,
1189         $this->gosaMailForwardingAddress);
1191     /* Update multiple edit values too */
1192     if($this->multiple_support_active){
1193       $this->gosaMailForwardingAddress_Some = array_remove_entries ($addresses,
1194           $this->gosaMailForwardingAddress_Some);
1195     }
1196     $this->is_modified= TRUE;
1197   }
1200   /*! \brief  Add given mail address to the list of alternate adresses ,
1201     .          check if this mal address is used, skip adding in this case
1202    */
1203   function addAlternate($address)
1204   {
1205     if(empty($address)) continue;
1206     $ldap= $this->config->get_ldap_link();
1208     $address= strtolower($address);
1210     /* Is this address already assigned in LDAP? */
1211     $ldap->cd ($this->config->current['BASE']);
1212     $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)".
1213         "(gosaMailAlternateAddress=$address)))");
1215     if ($ldap->count() > 0){
1216       $attrs= $ldap->fetch ();
1217       return ($attrs["uid"][0]);
1218     }
1220     /* Add to list of alternates */
1221     if (!in_array($address, $this->gosaMailAlternateAddress)){
1222       $this->gosaMailAlternateAddress[]= $address;
1223     }
1225     sort ($this->gosaMailAlternateAddress);
1226     reset ($this->gosaMailAlternateAddress);
1227     $this->is_modified= TRUE;
1229     return ("");
1230   }
1233   /*! \brief  Removes the given mail address from the alternate addresses  
1234    */
1235   function delAlternate($addresses)
1236   {
1237     if(empty($address)) continue;
1238     $this->gosaMailAlternateAddress= array_remove_entries ($addresses,
1239         $this->gosaMailAlternateAddress);
1240     $this->is_modified= TRUE;
1241   }
1244   function postable_acls()
1245   {
1246     $ret = array();
1247     foreach($this->folder_acls as $name => $acl){
1248       $ret[$name] = array("name" => $name,"acl" => $acl,"post_name" => base64_encode($name));
1249     }
1250     return($ret);
1251   }
1253   
1254   function allow_remove()
1255   {
1256     $resason = "";
1257     if(!$this->mailMethod->allow_remove($reason)){
1258       return($reason);
1259     }
1260     return("");
1261   }
1264   // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1265 ?>