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 }
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 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 }
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){
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);
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 }
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();
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 }
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."<".
1156 $attrs['mail'][0].">";
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)) return;
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($addresses)) return;
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 }
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 }
1301 }
1303 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1304 ?>