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