1 <?php
3 class groupware extends plugin
4 {
5 var $plHeadline = "Mail";
6 var $plDescription = "GOsa mail extension.";
7 var $view_logged = FALSE;
9 var $attributes = array(
10 "mailAddress",
11 "mailLocation",
12 "quotaUsage",
13 "quotaSize",
14 "alternateAddresses",
15 "forwardingAddresses",
16 "vacationEnabled",
17 "vacationStart",
18 "vacationStop",
19 "vacationMessage",
20 "mailBoxWarnLimitEnabled",
21 "mailBoxWarnLimitValue",
22 "mailBoxSendSizelimitEnabled",
23 "mailBoxSendSizelimitValue",
24 "mailBoxHardSizelimitEnabled",
25 "mailBoxHardSizelimitValue",
26 "mailBoxAutomaticRemovalEnabled",
27 "mailBoxAutomaticRemovalValue",
28 "localDeliveryOnly",
29 "dropOwnMails"
30 );
32 var $enabledFeatures = array(
33 "quotaUsage" => FALSE,
34 "quotaSize" => FALSE,
35 "mailFilter" => FALSE,
36 "alternateAddresses" => FALSE,
37 "forwardingAddresses" => FALSE,
38 "vacationMessage" => FALSE,
39 "mailBoxWarnLimit" => FALSE,
40 "mailBoxSendSizelimit" => FALSE,
41 "alternateAddresses" => FALSE,
42 "mailBoxHardSizelimit" => FALSE,
43 "mailBoxAutomaticRemoval" => FALSE,
44 "localDeliveryOnly" => FALSE,
45 "dropOwnMails" => FALSE);
47 var $flagAttrinutes = array("vacationEnabled","mailBoxWarnLimitEnabled","mailBoxSendSizelimitEnabled",
48 "mailBoxHardSizelimitEnabled","mailBoxAutomaticRemovalEnabled","localDeliveryOnly","dropOwnMails");
50 var $mailAddressSelectDialog = NULL;
51 var $vacationTemplates = array();
53 var $mailAddress = "";
54 var $mailLocation = "";
55 var $quotaUsage = "";
56 var $quotaSize = "";
57 var $alternateAddresses = "";
58 var $forwardingAddresses = "";
59 var $vacationEnabled = FALSE;
60 var $vacationStart = 0;
61 var $vacationStop = 0;
62 var $vacationMessage = "";
63 var $mailBoxWarnLimitEnabled = FALSE;
64 var $mailBoxWarnLimitValue = "";
65 var $mailBoxSendSizelimitEnabled = FALSE;
66 var $mailBoxSendSizelimitValue = "";
67 var $mailBoxHardSizelimitEnabled = FALSE;
68 var $mailBoxHardSizelimitValue = "";
69 var $mailBoxAutomaticRemovalEnabled = FALSE;
70 var $mailBoxAutomaticRemovalValue = "";
71 var $localDeliveryOnly = FALSE;
72 var $dropOwnMails = FALSE;
74 function __construct ($config, $dn= NULL)
75 {
76 plugin::plugin($config,$dn);
78 // Get attributes from parent object
79 foreach(array("uid","cn") as $attr){
80 if(isset($this->parent->by_object['group']) && isset($this->parent->by_object['group']->$attr)){
81 $this->$attr = &$this->parent->by_object['group']->$attr;
82 }elseif(isset($this->attrs[$attr])){
83 $this->$attr = $this->attrs[$attr][0];
84 }
85 }
87 // Set vacation start/stop if not set alreasy
88 $this->vacationStart = time();
89 $this->vacationStop = time() + (14 * 60*60*24);
91 // Prepare vacation start/stop time to be initially valid.
92 $this->vacationStart= date('d.m.Y', $this->vacationStart);
93 $this->vacationStop= date('d.m.Y', $this->vacationStop);
94 }
97 function execute()
98 {
99 $this->enabledFeatures = array(
100 "quotaUsage" => TRUE,
101 "quotaSize" => TRUE,
102 "mailFilter" => TRUE,
103 "alternateAddresses" => TRUE,
104 "forwardingAddresses" => TRUE,
105 "vacationMessage" => TRUE,
106 "mailBoxWarnLimit" => TRUE,
107 "mailBoxSendSizelimit" => TRUE,
108 "mailBoxHardSizelimit" => TRUE,
109 "mailBoxAutomaticRemoval" => TRUE,
110 "localDeliveryOnly" => TRUE,
111 "dropOwnMails" => TRUE);
113 // Register plugin execution
114 $display = plugin::execute();
116 // Log plugin execution.
117 if($this->is_account && !$this->view_logged){
118 $this->view_logged = TRUE;
119 new log("view","users/".get_class($this),$this->dn);
120 }
123 /****************
124 Account status
125 ****************/
127 if(isset($_POST['modify_state'])){
128 if($this->is_account && $this->acl_is_removeable() && $this->mailMethod->accountRemoveAble()){
129 $this->is_account= FALSE;
130 }elseif(!$this->is_account && $this->acl_is_createable() && $this->mailMethod->accountCreateable()){
131 $this->is_account= TRUE;
132 }
133 }
134 if(!$this->multiple_support_active){
135 if (!$this->is_account && $this->parent === NULL){
136 $display= "<img alt=\"\" src=\"images/small-error.png\" align=\"middle\"> <b>".
137 msgPool::noValidExtension(_("Mail"))."</b>";
138 $display.= back_to_main();
139 return ($display);
140 }
141 if ($this->parent !== NULL){
142 if ($this->is_account){
143 $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),msgPool::featuresEnabled(_("Mail")));
144 } else {
145 $display= $this->show_enable_header(msgPool::addFeaturesButton(_("Mail")),msgPool::featuresDisabled(_("Mail")));
146 return ($display);
147 }
148 }
149 }
151 /****************
152 Forward addresses
153 ****************/
155 // Display dialog to select a local fowarder
156 if (isset($_POST['addLocalForwardingAddress'])){
157 $this->mailAddressSelectDialog= new mailAddressSelect($this->config, get_userinfo());
158 $this->dialog= TRUE;
159 }
161 // Close dialogs, action was canceled
162 if (isset($_POST['mailAddressSelect_cancel'])){
163 $this->mailAddressSelectDialog= FALSE;
164 $this->dialog= FALSE;
165 }
167 // Append selected forwarding addresses now.
168 if (isset($_POST['mailAddressSelect_save']) && $this->mailAddressSelectDialog instanceOf mailAddressSelect){
169 if($this->acl_is_writeable("gosaMailForwardingAddress")){
170 $list = $this->mailAddressSelectDialog->save();
171 foreach ($list as $entry){
172 $val = $entry['mail'][0];
173 if (!in_array ($val, $this->gosaMailAlternateAddress) && $val != $this->mail){
174 $this->addForwarder($val);
175 $this->is_modified= TRUE;
176 }
177 }
178 $this->mailAddressSelectDialog= FALSE;
179 $this->dialog= FALSE;
180 } else {
181 msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
182 }
183 }
185 // Display the address selection dialog.
186 if($this->mailAddressSelectDialog instanceOf mailAddressSelect){
187 $used = array();
188 $used['mail'] = array_values($this->gosaMailAlternateAddress);
189 $used['mail'] = array_merge($used['mail'], array_values($this->gosaMailForwardingAddress));
190 $used['mail'][] = $this->mail;
192 // Build up blocklist
193 session::set('filterBlacklist', $used);
194 return($this->mailAddressSelectDialog->execute());
195 }
197 // Add manually inserted forwarding address.
198 if (isset($_POST['addForwardingAddress'])){
199 if ($_POST['forwardingAddressInput'] != ""){
200 $address= get_post('forwardingAddressInput');
201 $valid= FALSE;
202 if (!tests::is_email($address)){
203 if (!tests::is_email($address, TRUE)){
204 if ($this->is_template){
205 $valid= TRUE;
206 } else {
207 msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
208 "","","your-address@your-domain.com"),ERROR_DIALOG);
209 }
210 }
211 } elseif ($address == $this->mail
212 || in_array($address, $this->gosaMailAlternateAddress)) {
213 msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
214 } else {
215 $valid= TRUE;
216 }
217 if ($valid){
218 if($this->acl_is_writeable("gosaMailForwardingAddress")){
219 $this->addForwarder ($address);
220 $this->is_modified= TRUE;
221 }
222 }
223 }
224 }
225 if (isset($_POST['deleteForwardingAddress'])){
226 $this->delForwarder ($_POST['forwardingAddressList']);
227 }
230 /****************
231 Alternate addresses
232 ****************/
234 // Add manually inserted alternate mail address.
235 if (isset($_POST['addAlternateAddress'])){
236 $valid= FALSE;
237 if (!tests::is_email($_POST['alternateAddressInput'])){
238 if ($this->is_template){
239 if (!(tests::is_email($_POST['alternateAddressInput'], TRUE))){
240 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
241 "","","your-domain@your-domain.com"),ERROR_DIALOG);
242 } else {
243 $valid= TRUE;
244 }
245 } else {
246 msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
247 "","","your-domain@your-domain.com"),ERROR_DIALOG);
248 }
249 } else {
250 $valid= TRUE;
251 }
252 if ($valid && ($user= $this->addAlternate (get_post('alternateAddressInput'))) != ""){
253 $ui= get_userinfo();
254 $addon= "";
255 if ($user[0] == "!") {
256 $addon= sprintf(_("Address is already in use by group '%s'."), mb_substr($user, 1));
257 } else {
258 $addon= sprintf(_("Address is already in use by user '%s'."), $user);
259 }
260 msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."<br><br><i>".
261 "$addon</i>", ERROR_DIALOG);
262 }
263 }
265 // Remove alternate mail address.
266 if (isset($_POST['deleteAlternateAddress']) && isset($_POST['alternateAddressList'])){
267 $this->delAlternate ($_POST['alternateAddressList']);
268 }
271 /****************
272 SMARTY- Assign smarty variables
273 ****************/
275 $smarty = get_smarty();
276 foreach($this->attributes as $attr){
277 $smarty->assign($attr, $this->$attr);
278 }
280 $plInfo = $this->plInfo();
281 foreach($plInfo['plProvidedAcls'] as $acl => $name){
282 $smarty->assign($acl."ACL", $this->getacl($acl));
283 }
284 foreach($this->enabledFeatures as $feature => $state){
285 $smarty->assign($feature."_isActive", $state);
286 }
288 $smarty->assign("mailLocations", array("tester"));
289 if (count($this->vacationTemplates)){
290 $smarty->assign("displayTemplateSelector", "true");
291 $smarty->assign("vacationTemplate", set_post($this->vacationTemplate));
292 $smarty->assign("vacationTemplates", set_post($this->vacationTemplates));
293 $smarty->assign("template", set_post(get_post('vacation_template')));
294 } else {
295 $smarty->assign("displayTemplateSelector", "false");
296 }
298 return($display.$smarty->fetch(get_template_path("generic.tpl",TRUE,dirname(__FILE__))));
299 }
303 /* Save data to object */
304 function save_object()
305 {
306 if(isset($_POST['groupwarePluginPosted'])){
307 foreach($this->attributes as $attr){
308 if(isset($_POST[$attr])){
309 $this->$attr = get_post($attr);
310 }
311 }
313 foreach($this->flagAttrinutes as $attr){
314 $this->$attr = isset($_POST[$attr]);
315 }
316 }
317 }
320 /*! \brief Parse vacation templates and build up an array
321 containing 'filename' => 'description'.
322 Used to fill vacation dropdown box.
323 @return Array All useable vacation templates.
324 */
325 function get_vacation_templates()
326 {
327 $vct = array();
328 if ($this->config->get_cfg_value("core","vacationTemplateDirectory") != ""){
329 $dir= $this->config->get_cfg_value("core","vacationTemplateDirectory");
330 if (is_dir($dir) && is_readable($dir)){
331 $dh = opendir($dir);
332 while($file = readdir($dh)){
333 $description= "";
334 if (is_file($dir."/".$file)){
335 $fh = fopen($dir."/".$file, "r");
336 $line= fgets($fh, 256);
337 if (!preg_match('/^DESC:/', $line)){
338 msg_dialog::display(_("Configuration error"), sprintf(_("No DESC tag in vacation template '%s'!"), $file), ERROR_DIALOG);
339 }else{
340 $description= trim(preg_replace('/^DESC:\s*/', '', $line));
341 }
342 fclose ($fh);
343 }
344 if ($description != ""){
345 $vct["$dir/$file"]= $description;
346 }
347 }
348 closedir($dh);
349 }
350 }
351 return($vct);
352 }
355 /*! \brief Adds the given mail address to the list of mail forwarders
356 */
357 function addForwarder($address)
358 {
359 if(empty($address)) return;
360 if($this->acl_is_writeable("gosaMailForwardingAddress")){
361 $this->gosaMailForwardingAddress[]= $address;
362 $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress);
363 sort ($this->gosaMailForwardingAddress);
364 reset ($this->gosaMailForwardingAddress);
365 $this->is_modified= TRUE;
366 }else{
367 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
368 }
369 }
372 /*! \brief Removes the given mail address from the list of mail forwarders
373 */
374 function delForwarder($addresses)
375 {
376 if($this->acl_is_writeable("gosaMailForwardingAddress")){
377 $this->gosaMailForwardingAddress= array_remove_entries ($addresses, $this->gosaMailForwardingAddress);
378 $this->is_modified= TRUE;
379 }else{
380 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
381 }
382 }
385 /*! \brief Add given mail address to the list of alternate adresses ,
386 . check if this mal address is used, skip adding in this case
387 */
388 function addAlternate($address)
389 {
390 if(empty($address)) return;
391 if($this->acl_is_writeable("gosaMailAlternateAddress")){
392 $ldap= $this->config->get_ldap_link();
393 $address= strtolower($address);
395 /* Is this address already assigned in LDAP? */
396 $ldap->cd ($this->config->current['BASE']);
397 $ldap->search ("(&(!(objectClass=gosaUserTemplate))(objectClass=gosaMailAccount)(|(mail=$address)".
398 "(alias=$address)(gosaMailAlternateAddress=$address)))", array("uid", "cn"));
399 if ($ldap->count() > 0){
400 $attrs= $ldap->fetch ();
401 if (!isset($attrs["uid"])) {
402 return ("!".$attrs["cn"][0]);
403 }
404 return ($attrs["uid"][0]);
405 }
406 if (!in_array($address, $this->gosaMailAlternateAddress)){
407 $this->gosaMailAlternateAddress[]= $address;
408 $this->is_modified= TRUE;
409 }
410 sort ($this->gosaMailAlternateAddress);
411 reset ($this->gosaMailAlternateAddress);
412 return ("");
413 }else{
414 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
415 }
416 }
419 /*! \brief Removes the given mail address from the alternate addresses list
420 */
421 function delAlternate($addresses)
422 {
423 if($this->acl_is_writeable("gosaMailAlternateAddress")){
424 $this->gosaMailAlternateAddress= array_remove_entries ($addresses,$this->gosaMailAlternateAddress);
425 $this->is_modified= TRUE;
426 }else{
427 msg_dialog::display(_("Permission error"), _("You have no permission to modify these addresses!"), ERROR_DIALOG);
428 }
429 }
432 /*! \brief Prepare importet vacation string. \
433 . Replace placeholder like %givenName a.s.o.
434 @param string Vacation string
435 @return string Completed vacation string
436 */
437 private function prepare_vacation_template($contents)
438 {
439 /* Replace attributes */
440 $attrs = array();
441 $obj = NULL;
442 if(isset($this->parent->by_object['user'])){
443 $attrs = $this->parent->by_object['user']->attributes;
444 $obj = $this->parent->by_object['user'];
445 }else{
446 $obj = new user($this->config,$this->dn);
447 $attrs = $obj->attributes;
448 }
449 if($obj){
451 /* Replace vacation start and end time */
452 if($this->mailMethod->vacationRangeEnabled()){
453 if(preg_match("/%start/",$contents)){
454 $contents = preg_replace("/%start/",$this->vacationStart,$contents);
455 }
456 if(preg_match("/%end/",$contents)){
457 $contents = preg_replace("/%end/",$this->vacationStop,$contents);
458 }
459 }else{
460 if(preg_match("/%start/",$contents)){
461 $contents = preg_replace("/%start/", _("unknown"),$contents);
462 }
463 if(preg_match("/%end/",$contents)){
464 $contents = preg_replace("/%end/", _("unknown"), $contents);
465 }
466 }
468 foreach ($attrs as $val){
470 // We can only replace strings here
471 if(!is_string($obj->$val)) continue;
473 if(preg_match("/dateOfBirth/",$val)){
474 if($obj->use_dob){
475 $contents= preg_replace("/%$val/",date("Y-d-m",$obj->dateOfBirth),$contents);
476 }
477 }else {
478 $contents= preg_replace("/%$val/",
479 $obj->$val, $contents);
480 }
482 }
483 }
484 $contents = ltrim(preg_replace("/^DESC:.*$/m","",$contents),"\n ");
485 return($contents);
486 }
489 function remove_from_parent()
490 {
491 /* Cancel if there's nothing to do here */
492 if (!$this->initially_was_account){
493 return;
494 }
496 }
499 function save()
500 {
501 }
504 /*! \brief Check given values
505 */
506 function check()
507 {
508 if(!$this->is_account){
509 return(array());
510 }
512 $ldap= $this->config->get_ldap_link();
514 /* Call common method to give check the hook */
515 $message= plugin::check();
517 if(empty($this->gosaMailServer)){
518 $message[]= msgPool::noserver(_("Mail"));
519 }
521 /* Mail address checks */
522 $mail = $this->mail;
523 if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
525 if($this->mailMethod->domainSelectionEnabled()){
526 $mail.= "@".$this->mailDomainPart;
527 }
529 if (empty($mail)){
530 $message[]= msgPool::required(_("Primary address"));
531 }
532 if ($this->is_template){
533 if (!tests::is_email($mail, TRUE)){
534 $message[]= msgPool::invalid(_("Mail address"),"","","%givenName.%sn@your-domain.com");
535 }
536 } else {
537 if (!tests::is_email($mail)){
538 $message[]= msgPool::invalid(_("Mail address"),"","","your-address@your-domain.com");
539 }
540 }
542 /* Check if this mail address is already in use */
543 $ldap->cd($this->config->current['BASE']);
544 $filter = "(&(!(objectClass=gosaUserTemplate))(!(uid=".$this->uid."))".
545 "(objectClass=gosaMailAccount)".
546 "(|(mail=".$mail.")(alias=".$mail.")(gosaMailAlternateAddress=".$mail.")))";
547 $ldap->search($filter,array("uid", "cn"));
548 if ($ldap->count() != 0){
549 $entry= $ldap->fetch();
550 $addon= "";
551 if (!isset($entry['uid'])) {
552 $addon= sprintf(_("Address is already in use by group '%s'."), $entry['cn'][0]);
553 } else {
554 $addon= sprintf(_("Address is already in use by user '%s'."), $entry['uid'][0]);
555 }
556 $message[]= msgPool::duplicated(_("Mail address"))."<br><br><i>$addon</i>";
557 }
558 }
561 /* Check quota */
562 if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
563 if (!is_numeric($this->gosaMailQuota)) {
564 $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/^[0-9]*/");
565 } else {
566 $this->gosaMailQuota= (int) $this->gosaMailQuota;
567 }
568 }
570 /* Check rejectsize for integer */
571 if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailMaxSize")){
572 if (!is_numeric($this->gosaMailMaxSize)){
573 $message[]= msgPool::invalid(_("Mail reject size"),$this->gosaMailMaxSize,"/^[0-9]*/");
574 } else {
575 $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
576 }
577 }
579 /* Need gosaMailMaxSize if use_mailsize_limit is checked */
580 if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){
581 $message[]= msgPool::required(_("Mail reject size"));
582 }
584 if((preg_match("/S/", $this->gosaMailDeliveryMode))&&(empty($this->gosaSpamMailbox))) {
585 $message[]= msgPool::required(_("Spam folder"));
586 }
588 if ($this->mailMethod->vacationRangeEnabled() && preg_match('/V/', $this->gosaMailDeliveryMode)){
590 /* Check date strings */
591 $state= true;
592 if ($this->vacationStart == "" || !tests::is_date($this->vacationStart)) {
593 $message[]= msgPool::invalid(_("from"),$this->vacationStart);
594 $state= false;
595 }
596 if ($this->vacationStart == "" || !tests::is_date($this->vacationStop)) {
597 $message[]= msgPool::invalid(_("to"),$this->vacationStop);
598 $state= false;
599 }
601 #TODO: take care of date format
602 if ($state) {
603 list($day, $month, $year)= explode('.', $this->vacationStart);
604 $start= mktime(0,0,0,$month, $day, $year);
605 list($day, $month, $year)= explode('.', $this->vacationStop);
606 $stop= mktime(0,0,0,$month, $day, $year);
607 if($start > $stop){
608 $message[]= msgPool::invalid(_("Vacation interval"));
609 }
610 }
611 }
612 return($message);
613 }
616 /*! \brief Adapt from template, using 'dn'
617 */
618 function adapt_from_template($dn, $skip= array())
619 {
620 plugin::adapt_from_template($dn, $skip);
622 }
625 /*! \brief ACL settings
626 */
627 static function plInfo()
628 {
629 return (array(
630 "plShortName" => _("Mail"),
631 "plDescription" => _("Mail settings"),
632 "plSelfModify" => TRUE,
633 "plDepends" => array("user"), // This plugin depends on
634 "plPriority" => 4, // Position in tabs
635 "plSection" => array("personal" => _("My account")),
636 "plCategory" => array("users"),
637 "plOptions" => array(),
638 "plProvidedAcls" => array(
639 "mailAddress" => _("Mail address"),
640 "mailLocation" => _("Mail location"),
641 "quotaUsage" => _("Quota usage"),
642 "mailFilter" => _("Mail filter"),
643 "quotaSize" => _("Quota size"),
644 "alternateAddresses" => _("Alternate mail addresses"),
645 "forwardingAddresses" => _("Forwarding mail addresses"),
646 "vacationEnabled" => _("Vaction switch"),
647 "vacationStart" => _("Vacation start time"),
648 "vacationStop" => _("Vacation stop time"),
649 "vacationMessage" => _("Vacation message"),
650 "mailBoxWarnLimit" => _("Warn sizelimit"),
651 "mailBoxSendSizelimit" => _("Send sizelimit"),
652 "mailBoxHardSizelimit" => _("Hard sizelimit"),
653 "mailBoxAutomaticRemoval" => _("Automatic mail removal"),
654 "localDeliveryOnly" => _("Local delivery only"),
655 "dropOwnMails" => _("Drop own mails")
656 )
657 ));
658 }
659 }
661 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
662 ?>