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->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 }
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 }
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 }
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 }
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"))." ".
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);
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);
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 }
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));
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);
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 }
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 }
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 groups 'cn' has changed! The cn attribute can't be changed due to the fact that this 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 }
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 rejectsize for integer */
854 if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailQuota")){
855 if (!is_numeric($this->gosaMailMaxSize)){
856 $message[]= msgPool::invalid(_("Mail max size"));
857 } else {
858 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
859 }
860 }
862 /* Need gosaMailMaxSize if use_mailsize_limit is checked */
863 if (is_integer(strpos($this->gosaMailDeliveryMode, "reject")) && $this->gosaMailMaxSize == ""){
864 $message[]= _("You need to set the maximum mail size in order to reject anything.");
865 }
867 if(empty($this->gosaMailServer)){
868 $message[] = msgPool::required(_("Mail server"));
869 }
871 return ($message);
872 }
874 /* Adapt from template, using 'dn' */
875 function adapt_from_template($dn, $skip= array())
876 {
877 plugin::adapt_from_template($dn, $skip);
879 foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
881 if (in_array($val, $skip)){
882 continue;
883 }
885 $this->$val= array();
886 if (isset($this->attrs["$val"]["count"])){
887 for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
888 $value= $this->attrs["$val"][$i];
889 foreach (array("sn", "givenName", "uid") as $repl){
890 if (preg_match("/%$repl/i", $value)){
891 $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
892 }
893 }
894 array_push($this->$val, $value);
895 }
896 }
897 }
898 }
902 function make_name($attrs)
903 {
904 $name= "";
905 if (isset($attrs['sn'][0])){
906 $name= $attrs['sn'][0];
907 }
908 if (isset($attrs['givenName'][0])){
909 if ($name != ""){
910 $name.= ", ".$attrs['givenName'][0];
911 } else {
912 $name.= $attrs['givenName'][0];
913 }
914 }
915 if ($name != ""){
916 $name.= " ";
917 }
919 return ($name);
920 }
922 function getCopyDialog()
923 {
924 if(!$this->is_account) return("");
926 $smarty = get_smarty();
927 $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
928 $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
929 $smarty->assign("mail",$this->mail);
930 $display= $smarty->fetch (get_template_path('paste_mail.tpl', TRUE, dirname(__FILE__)));
931 $ret = array();
932 $ret['string'] = $display;
933 $ret['status'] = "";
934 return($ret);
935 }
937 function saveCopyDialog()
938 {
939 if(!$this->is_account) return;
941 /* Perform ADD / REMOVE ... for mail alternate / mail forwarding addresses
942 */
943 $this->execute();
944 if(isset($_POST['mail'])){
945 $this->mail = $_POST['mail'];
946 }
947 }
950 function PrepareForCopyPaste($source)
951 {
952 plugin::PrepareForCopyPaste($source);
954 /* Reset alternate mail addresses */
955 $this->gosaMailAlternateAddress = array();
956 }
959 /* Return plugin informations for acl handling */
960 static function plInfo()
961 {
962 return (array(
963 "plShortName" => _("Mail"),
964 "plDescription" => _("Group mail"),
965 "plSelfModify" => FALSE,
966 "plDepends" => array(),
967 "plPriority" => 10,
968 "plSection" => array("administration"),
969 "plCategory" => array("groups"),
970 "plProvidedAcls"=> array(
971 "mail" => _("Mail address"),
972 "gosaMailQuota" => _("Quota size"),
973 "gosaMailServer" => _("Mail server"),
974 "kolabFolderType" => _("Folder type")." ("._("Kolab").")",
975 "gosaMailAlternateAddress" => _("Alternate addresses"),
976 "gosaMailForwardingAddress" => _("Forwarding addresses"),
977 "gosaMailDeliveryModeI" => _("Only local"),
978 "acl" => _("Permissions"))
979 ));
980 }
983 /* Remove given ACL for given member (uid,mail) ..
984 */
985 function removeUserAcl($index )
986 {
987 if(isset($this->imapacl[$index])){
988 unset($this->imapacl[$index]);
989 }
990 }
992 function multiple_execute()
993 {
994 return($this->execute());
995 }
998 function init_multiple_support($attrs,$all)
999 {
1000 plugin::init_multiple_support($attrs,$all);
1002 $this->gosaMailForwardingAddress = array();
1003 if(isset($attrs['gosaMailForwardingAddress'])){
1004 for($i = 0 ; $i < $attrs['gosaMailForwardingAddress']['count'] ; $i++){
1005 $this->gosaMailForwardingAddress[] = $attrs['gosaMailForwardingAddress'][$i];
1006 }
1007 }
1009 $this->gosaMailForwardingAddress_Some = array();
1010 if(isset($all['gosaMailForwardingAddress'])){
1011 for($i = 0 ; $i < $all['gosaMailForwardingAddress']['count'] ; $i++){
1012 if(!in_array($all['gosaMailForwardingAddress'][$i],$this->gosaMailForwardingAddress)){
1013 $this->gosaMailForwardingAddress_Some[] = $all['gosaMailForwardingAddress'][$i];
1014 }
1015 }
1016 }
1017 }
1019 function multiple_save_object()
1020 {
1021 if(isset($_POST['multiple_mail_group_posted'])){
1022 plugin::multiple_save_object();
1024 foreach(array("kolabFolderType") as $attr){
1025 if(isset($_POST['use_'.$attr])){
1026 $this->multi_boxes[] = $attr;
1027 }
1028 }
1030 /* Add special kolab attributes */
1031 if(preg_match("/olab/i",$this->config->get_cfg_value("mailmethod"))){
1032 if(isset($_POST['kolabFolderTypeType']) && $this->acl_is_writeable("kolabFolderType")){
1033 $this->kolabFolderTypeType = get_post("kolabFolderTypeType");
1034 $this->kolabFolderTypeSubType = get_post("kolabFolderTypeSubType");
1035 }
1036 }
1038 /* Collect data and re-assign it to the imapacl array */
1039 if ($this->acl_is_writeable("acl")){
1040 $this->imapacl= array();
1041 $this->imapacl['%members%']= $_POST['member_permissions'];
1042 $this->imapacl['anyone']= $_POST['default_permissions'];
1043 foreach ($this->indexed_user as $nr => $user){
1044 if (!isset($_POST["user_$nr"])){
1045 continue;
1046 }
1047 if ($_POST["user_$nr"] != $user ||
1048 $_POST["perm_$nr"] != $this->indexed_acl[$nr]){
1049 $this->is_modified= TRUE;
1050 }
1051 $this->imapacl[$_POST["user_$nr"]]= $_POST["perm_$nr"];
1052 }
1053 }
1054 }
1055 }
1058 /* Return selected values for multiple edit */
1059 function get_multi_edit_values()
1060 {
1061 $ret = plugin::get_multi_edit_values();
1062 $ret['Forward_some'] = $this->gosaMailForwardingAddress_Some;
1063 $ret['Forward_all'] = $this->gosaMailForwardingAddress;
1064 if(in_array('kolabFolderType',$this->multi_boxes)){
1065 $ret['kolabFolderTypeType'] = $this->kolabFolderTypeType;
1066 $ret['kolabFolderTypeSubType'] = $this->kolabFolderTypeSubType;
1067 }
1068 if(in_array("acl",$this->multi_boxes)){
1069 $ret['imapacl'] = $this->imapacl;
1070 }
1071 return($ret);
1072 }
1074 function set_multi_edit_values($attrs)
1075 {
1076 $forward = array();
1077 foreach($attrs['Forward_some'] as $addr){
1078 if(in_array($addr,$this->gosaMailForwardingAddress)){
1079 $forward[] = $addr;
1080 }
1081 }
1082 foreach($attrs['Forward_all'] as $addr){
1083 $forward[] = $addr;
1084 }
1085 plugin::set_multi_edit_values($attrs);
1086 $this->gosaMailForwardingAddress = $forward;
1087 }
1090 /*! \brief Displays a dialog that allows mail address selection.
1091 */
1092 function display_forward_dialog()
1093 {
1094 restore_error_handler();
1096 $smarty = get_smarty();
1097 $ldap= $this->config->get_ldap_link();
1099 /* Save data */
1100 $mailfilter= session::get("mailfilter");
1101 foreach( array("depselect", "muser", "regex") as $type){
1102 if (isset($_POST[$type])){
1103 $mailfilter[$type]= $_POST[$type];
1104 }
1105 }
1106 if (isset($_GET['search'])){
1107 $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*";
1108 if ($s == "**"){
1109 $s= "*";
1110 }
1111 $mailfilter['regex']= $s;
1112 }
1113 session::set("mailfilter", $mailfilter);
1115 /* Get actual list */
1116 $mailusers= array ();
1117 if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){
1118 $regex= $mailfilter['regex'];
1119 $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))";
1120 } else {
1121 $filter= "";
1122 }
1123 if ($mailfilter['muser'] != ""){
1124 $user= $mailfilter['muser'];
1125 $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))";
1126 }
1128 /* Add already present people to the filter */
1129 $exclude= "";
1130 foreach ($this->gosaMailForwardingAddress as $mail){
1131 $exclude.= "(mail=$mail)";
1132 }
1133 if ($exclude != ""){
1134 $filter.= "(!(|$exclude))";
1135 }
1136 $res= get_list("(&(objectClass=gosaMailAccount)$filter)", "users", $mailfilter['depselect'],
1137 array("sn", "mail", "givenName"), GL_SIZELIMIT | GL_SUBSEARCH);
1138 $ldap->cd($mailfilter['depselect']);
1139 $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName"));
1140 while ($attrs= $ldap->fetch()){
1141 if(preg_match('/%/', $attrs['mail'][0])){
1142 continue;
1143 }
1144 $name= $this->make_name($attrs);
1145 $mailusers[$attrs['mail'][0]]= $name."<".
1146 $attrs['mail'][0].">";
1147 }
1148 natcasesort ($mailusers);
1149 reset ($mailusers);
1151 /* Show dialog */
1152 $smarty->assign("search_image", get_template_path('images/lists/search.png'));
1153 $smarty->assign("usearch_image", get_template_path('images/lists/search-user.png'));
1154 $smarty->assign("tree_image", get_template_path('images/lists/search-subtree.png'));
1155 $smarty->assign("infoimage", get_template_path('images/info.png'));
1156 $smarty->assign("launchimage", get_template_path('images/lists/action.png'));
1157 $smarty->assign("mailusers", $mailusers);
1158 if (isset($_POST['depselect'])){
1159 $smarty->assign("depselect", $_POST['depselect']);
1160 }
1161 $smarty->assign("deplist", $this->config->idepartments);
1162 $smarty->assign("apply", apply_filter());
1163 $smarty->assign("alphabet", generate_alphabet());
1164 $smarty->assign("hint", print_sizelimit_warning());
1165 foreach( array("depselect", "muser", "regex") as $type){
1166 $smarty->assign("$type", $mailfilter[$type]);
1167 }
1168 $smarty->assign("hint", print_sizelimit_warning());
1169 $display= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__)));
1170 return ($display);
1171 }
1174 /*! \brief Add given mail address to the list of forwarders.
1175 */
1176 function addForwarder($address)
1177 {
1178 if(empty($address)) continue;
1179 $this->gosaMailForwardingAddress[]= $address;
1180 $this->gosaMailForwardingAddress= array_unique($this->gosaMailForwardingAddress);
1182 /* Update multiple edit values too */
1183 if($this->multiple_support_active){
1184 $this->gosaMailForwardingAddress_Some=
1185 array_remove_entries (array($address),$this->gosaMailForwardingAddress_Some);
1186 }
1188 sort ($this->gosaMailForwardingAddress);
1189 reset ($this->gosaMailForwardingAddress);
1190 $this->is_modified= TRUE;
1191 }
1194 /*! \brief Removes the given mail address from the forwarders
1195 */
1196 function delForwarder($addresses)
1197 {
1198 if(empty($address)) continue;
1199 $this->gosaMailForwardingAddress= array_remove_entries ($addresses,
1200 $this->gosaMailForwardingAddress);
1202 /* Update multiple edit values too */
1203 if($this->multiple_support_active){
1204 $this->gosaMailForwardingAddress_Some = array_remove_entries ($addresses,
1205 $this->gosaMailForwardingAddress_Some);
1206 }
1207 $this->is_modified= TRUE;
1208 }
1211 /*! \brief Add given mail address to the list of alternate adresses ,
1212 . check if this mal address is used, skip adding in this case
1213 */
1214 function addAlternate($address)
1215 {
1216 if(empty($address)) continue;
1217 $ldap= $this->config->get_ldap_link();
1219 $address= strtolower($address);
1221 /* Is this address already assigned in LDAP? */
1222 $ldap->cd ($this->config->current['BASE']);
1223 $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)".
1224 "(gosaMailAlternateAddress=$address)))");
1226 if ($ldap->count() > 0){
1227 $attrs= $ldap->fetch ();
1228 return ($attrs["uid"][0]);
1229 }
1231 /* Add to list of alternates */
1232 if (!in_array($address, $this->gosaMailAlternateAddress)){
1233 $this->gosaMailAlternateAddress[]= $address;
1234 }
1236 sort ($this->gosaMailAlternateAddress);
1237 reset ($this->gosaMailAlternateAddress);
1238 $this->is_modified= TRUE;
1240 return ("");
1241 }
1244 /*! \brief Removes the given mail address from the alternate addresses
1245 */
1246 function delAlternate($addresses)
1247 {
1248 if(empty($address)) continue;
1249 $this->gosaMailAlternateAddress= array_remove_entries ($addresses,
1250 $this->gosaMailAlternateAddress);
1251 $this->is_modified= TRUE;
1252 }
1255 function postable_acls()
1256 {
1257 $ret = array();
1258 foreach($this->folder_acls as $name => $acl){
1259 $ret[$name] = array("name" => $name,"acl" => $acl,"post_name" => base64_encode($name));
1260 }
1261 return($ret);
1262 }
1265 function get_effective_member_acls()
1266 {
1267 $tmp = array();
1268 $member = $this->get_member();
1269 foreach($member['mail'] as $uid => $mail){
1271 /* Do not save overridden acls */
1272 if(isset($this->folder_acls[$mail])){
1273 continue;
1274 }
1277 $tmp[$mail] = $this->folder_acls['__member__'];
1278 }
1279 return($tmp);
1280 }
1283 function allow_remove()
1284 {
1285 $resason = "";
1286 if(!$this->mailMethod->allow_remove($reason)){
1287 return($reason);
1288 }
1289 return("");
1290 }
1291 }
1293 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1294 ?>