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