Code

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