1 <?php
4 class mailMethod{
6 /* Allow modification of account_ids for existing mail accounts */
7 protected $modifyableMail = TRUE;
9 /* Allow modification of the mail server attribute existing mail accounts */
10 protected $modifyableServer = TRUE;
12 /* Enforces same value for 'mail' as used for 'cn' */
13 protected $mailEqualsCN = FALSE;
15 /* the attribute used to create accounts */
16 protected $uattrib = "mail"; // Naming attribute for accounts, e.g. imap.
18 /* The account prefixes, keep the '.' here! See FAQ cyrusUseSlashes */
19 protected $user_prefix = "user.";
20 protected $share_prefix = "share.";
22 /* Account ID creation
24 !!Depends on the attributes 'user_prefix'/'share_prefix' and the option 'cyrusUseSlashes'
26 Examples - based on defaults :
27 __PREFIX__ => "user." or "user/" (Depending on cyrusUseSlashes=FALSE/TRUE)
28 __CN__ => "technik" (The groups cn)
29 __UID__ => "herbert" (The users uid)
30 __MAIL__ => "herbert@domain.de"(The mail address)
31 __DOMAIN__ => "domain.de" (The domain part of the specified mail)
32 __MAILPART__ => "herbert" (The mail address without domain)
33 __UATTRIB__ => "herbert"/"herbert@domains.de"
34 (Configured in gosa.conf mailAttribute="mail"/"uid")
35 */
36 protected $user_id = "__PREFIX____UATTRIB__";
37 protected $share_id = "__PREFIX____UATTRIB__";
39 /* Create accounts in cyrus style with '/' instead of '.' */
40 protected $cyrusUseSlashes= FALSE;
42 /* The atribute mapping for this class Source --> Destination */
43 protected $attributes = array();
44 protected $userObjectClasses = array();
45 protected $shareObjectClasses = array();
47 /* Enabled mail domain selection. If enabled getMailDomains must the domain parts */
48 protected $enableDomainSelection= FALSE;
49 protected $enableQuota = TRUE;
50 protected $enableSieveManager = FALSE;
51 protected $enableVacationRange = TRUE;
52 protected $enableFolderTypes = FALSE;
54 /* Default values */
55 protected $quotaValue = 0;
56 protected $quotaUsage = 0;
58 /* Method internal */
59 protected $type = "user";
60 protected $account_id = "";
61 protected $initial_account_id = "";
62 protected $connected = FALSE;
63 protected $error = "";
64 protected $parent = NULL;
65 protected $MailServer = "";
67 protected $default_acls = array("__anyone__" => "p", "__member__" => "lrswp");
69 protected $acl_map = array(
70 "lrsw" => "read",
71 "lrswp" => "post",
72 "p" => "external post",
73 "lrswip" => "append",
74 "lrswipcd" => "write",
75 "lrswipcda"=> "admin",
76 " " => "none");
78 protected $acl_mapping = array();
81 /*! \brief Constructs the mail class
82 @param Object Config The GOsa configuration object
83 @param Object Plugin The initator
84 @param String Open "user" or "group" account.
85 */
86 function __construct(&$config, &$parent, $type = "user")
87 {
88 $this->parent = $parent;
89 $this->config = $config;
91 /* Create a refernce to the mail selected server
92 */
93 if(isset($this->parent->gosaMailServer)){
94 $this->MailServer = &$this->parent->gosaMailServer;
95 }else{
96 trigger_error("mailMethod with invalid parent object initialized.");
97 }
99 if(!in_array($this->type,array("user","group"))){
100 trigger_error("Unknown mail class type used '".$type."'.");
101 }else{
102 $this->type = $type;
103 }
104 }
107 /*! \brief Intialize attributes and config settings.
108 */
109 protected function init()
110 {
111 /* Get config value for cyrusUseSlashes
112 */
113 if ($this->config->get_cfg_value("cyrusUseSlashes") == "true"){
114 $this->cyrusUseSlashes = TRUE;
115 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Enabled</b>");
116 }else{
117 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Disabled</b>");
118 }
120 /* Check if the mail account identification attribute
121 is overridden in the configuration file
122 */
123 if($this->config->get_cfg_value("mailAttribute","mail") != ""){
124 $new_uattrib= strtolower($this->config->get_cfg_value("mailAttribute"));
125 if(in_array($new_uattrib,array("mail","uid"))){
126 $this->uattrib = $new_uattrib;
127 }else{
128 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$new_uattrib."</b>",
129 "<b>MAIL:</b> Unsupported 'mailAttribute' in gosa configuration specified");
130 msg_dialog::display(_("Configuration error"),
131 sprintf(_("The configured mail attribute '%s' is unsupported!"), $new_uattrib), ERROR_DIALOG);
132 }
133 }
135 /* Create ACL map */
136 foreach($this->acl_map as $acl => $name){
137 $this->acl_mapping[$acl] = _($name);
138 }
140 $this->build_account_id();
141 $this->initial_account_id = $this->account_id;
142 }
145 public function fixAttributesOnLoad()
146 {
147 foreach($this->attributes as $source => $dest){
148 if(isset($this->parent->attrs[$source])){
149 $this->parent->attrs[$dest] = $this->parent->attrs[$source];
150 }
151 if(isset($this->parent->$source)){
152 $this->parent->$dest = $this->parent->$source;
153 }
154 if(isset($this->parent->attrs[$source][0])){
155 $this->parent->saved_attributes[$source] = $this->parent->attrs[$source][0];
156 }
157 }
158 }
161 public function mailEqualsCN()
162 {
163 return($this->mailEqualsCN);
164 }
167 public function fixAttributesOnRemove()
168 {
169 /* Remove objectClasses
170 */
171 if($this->type == "user"){
172 $this->parent->attrs['objectClass'] =
173 array_remove_entries_ics($this->userObjectClasses, $this->parent->attrs['objectClass']);
174 }else{
175 $this->parent->attrs['objectClass'] =
176 array_remove_entries_ics($this->shareObjectClasses, $this->parent->attrs['objectClass']);
177 }
178 foreach($this->attributes as $source => $dest){
179 $this->attrs[$dest] = array();
180 $this->attrs[$source] = array();
181 }
182 }
184 public function fixAttributesOnStore()
185 {
186 foreach($this->attributes as $source => $dest){
187 if(isset($this->parent->attrs[$dest])){
188 $this->parent->attrs[$source] = $this->parent->attrs[$dest ];
189 }
190 if(isset($this->parent->$dest)){
191 $this->parent->$source = $this->parent->$dest;
192 }
193 }
195 if($this->type == "user"){
196 $ocs = $this->userObjectClasses;
197 }else{
198 $ocs = $this->shareObjectClasses;
199 }
200 foreach($ocs as $oc){
201 if(!in_array($oc, $this->parent->attrs['objectClass'])){
202 $this->parent->attrs['objectClass'][] = $oc;
203 }
204 }
205 }
208 /*! \brief Connect services like imap.
209 Not necessary for the base class.
210 @return Boolean True if this method is connected else false.
211 */
212 public function connect()
213 {
214 $this->reset_error();
215 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Connect method</b>: ".get_class($this));
216 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Current server</b>: ".$this->MailServer);
218 $this->connected = TRUE;
219 return(TRUE);
220 }
223 /*! \brief Returns the connection status of this method.
224 @return Boolean True if this method is connected else false.
225 */
226 public function is_connected()
227 {
228 return($this->connected);
229 }
232 /*! \brief Disconnect this method. Close services like imap connection.
233 Not necessary for the base class.
234 */
235 public function disconnect()
236 {
237 $this->reset_error();
238 if($this->is_connected()){
239 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Disconnect method</b>: ".get_class($this));
240 $this->connected =FALSE;
241 }
242 }
245 /*! \brief Returns true the current object represents a valid account
246 (Some methods may check imap accounts here.)
247 @return Boolean TRUE if this is a valid account else FALSE
248 */
249 public function account_exists()
250 {
251 $this->reset_error();
252 return(TRUE);
253 }
256 /*! \brief Returns the last error occurred
257 @return String The last error message.
258 */
259 public function get_error(){
260 return($this->error);
261 }
264 public function isModifyableMail()
265 {
266 return($this->modifyableMail);
267 }
270 public function isModifyableServer()
271 {
272 return($this->modifyableServer);
273 }
276 /*! \brief Returns TRUE if the action caused an error.
277 @return Boolean TRUE on error else FALSE
278 */
279 public function is_error(){
280 return($this->error != "");
281 }
284 /*! \brief Resets the error message.
285 */
286 public function reset_error(){
287 $this->error = "";
288 }
291 public function get_account_id()
292 {
293 $this->build_account_id();
294 return($this->account_id);
295 }
297 /*! \brief Create a new account id, like 'user/name@domain.com'.
298 */
299 protected function build_account_id()
300 {
301 /* Build account identicator */
302 if($this->type == "user"){
303 $prefix = $this->user_prefix;
304 $acc_string = $this->user_id;
305 }else{
306 $prefix = $this->share_prefix;
307 $acc_string = $this->share_id;
308 }
310 /* Create account prefix and respect "cyrusUseSlashes"
311 Do not replace escaped dots for cyrusUseSlashes.
312 */
313 $uattrib = $this->uattrib;
314 if($this->cyrusUseSlashes){
315 $prefix = preg_replace('/([^\\\\])\./',"\\1/",$prefix);
316 }
317 $prefix = preg_replace("/\\\\([\.\/])/","\\1",$prefix);
319 $domain = $mailpart = "";
320 $mail = $this->parent->mail;
321 if(preg_match("/\@/",$mail)){
322 list($mailpart,$domain) = split("\@",$mail);
323 }
325 /* Create account_id
326 */
327 $from = array("/__CN__/","/__UID__/","/__PREFIX__/","/__UATTRIB__/","/__DOMAIN__/","/__MAILPART__/","/__MAIL__/");
328 $to = array($this->parent->cn,$this->parent->uid,$prefix,$this->parent->$uattrib, $domain, $mailpart,$mail);
330 $acc_id = trim(strtolower(preg_replace($from,$to,$acc_string)));
332 if($this->account_id != $acc_id){
333 $this->account_id = $acc_id;
334 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> AccountID generated: <b>".$acc_id."</b>");
335 }
336 }
339 /*! \brief Creates a valid folder id for a given folder name.
340 e.g. $folder_id = "INBOX/test" && $this->account_id = "share/mailbox@domain.de"
341 will result in "share/mailbox/test@domain.de"
342 This function is mainly used to read and write folder permissions.
343 @return String A valid folder id
344 */
345 public function create_folder_id($folder, $type = "")
346 {
348 if(!empty($folder)){
349 $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
350 }
351 if(!empty($folder)){
352 $folder = "/".$folder;
353 }
355 /* Build account identicator */
356 if($this->type == "user"){
357 $prefix = $this->user_prefix;
358 $acc_string = $this->user_id;
359 }else{
360 $prefix = $this->share_prefix;
361 $acc_string = $this->share_id;
362 }
364 /* Create account prefix and respect "cyrusUseSlashes"
365 Do not replace escaped dots for cyrusUseSlashes.
366 */
367 $uattrib = $this->uattrib;
368 if($this->cyrusUseSlashes){
369 $prefix = preg_replace('/([^\\\\])\./',"\\1/",$prefix);
370 }
371 $prefix = preg_replace("/\\\\([\.\/])/","\\1",$prefix);
373 $domain = $mailpart = "";
374 $mail = $this->parent->mail;
375 if(preg_match("/\@/",$mail)){
376 list($mailpart,$domain) = split("\@",$mail);
377 }
379 /* Create account_id
380 */
381 $from = array("/__CN__/","/__UID__/","/__PREFIX__/","/__UATTRIB__/","/__DOMAIN__/","/__MAILPART__/","/__MAIL__/");
382 $to = array($this->parent->cn,$this->parent->uid,$prefix,$this->parent->$uattrib, $domain, $mailpart,$mail);
384 $acc_id = trim(strtolower(preg_replace($from,$to,$acc_string)));
386 if(preg_match("/\@/",$acc_id)){
387 list($mail,$domain) = split("\@",$acc_id);
388 $str = trim($mail . $folder . "@" . $domain);
389 }else{
390 $str = trim($acc_id . $folder);
391 }
392 return($str) ;
393 }
396 /*! \brief Returns the configured mail method for the given parent object,
397 initialized and read for use.
398 @return mailMethod The configured mailMethod.
399 */
400 public function get_method()
401 {
402 $methods = mailMethod::get_methods();
403 if ($this->config->get_cfg_value("mailmethod") != ""){
404 $method= $this->config->get_cfg_value("mailmethod");
405 $cls = get_correct_class_name("mailMethod$method");
406 if(isset($methods[$cls])){
407 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> Selected mailMethod: <b>".$cls."</b>");
408 $tmp = new $cls($this->config,$this->parent,$this->type);
409 $tmp->init();
410 return($tmp);
411 }else{
412 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL: Invalid mailMethod defined: <b>".$cls.
413 "</b> falling back to <b>".get_class($this)."</b>");
415 /* Print out configuration errors directly, we can't catch them everywhere.
416 */
417 msg_dialog::display(_("Configuration error"),
418 sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
419 }
420 }
422 /* If no valued mailMethod could be detected, return the base class.
423 */
424 $this->init();
425 return($this);
426 }
429 /*! \brief Saves sieve settings
430 */
431 public function saveSieveSettings()
432 {
433 $this->reset_error();
434 return(TRUE);
435 }
438 /*! \brief Creates or Updates the mailAccount represented by this class.
439 */
440 public function updateMailbox()
441 {
442 $this->reset_error();
443 return(TRUE);
444 }
447 /*! \brief Update shared folder dependencies
448 */
449 public function updateSharedFolder()
450 {
451 $this->reset_error();
452 return(TRUE);
453 }
456 /*! \brief Removes the mailbox represented by this class,
457 and update shared folder ACLs .
458 */
459 public function deleteMailbox()
460 {
461 $this->reset_error();
463 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
464 "<b>MAIL: Remove account</b> from server :".$this->MailServer);
466 return(TRUE);
467 }
470 /*! \brief Returns the used mail attribute (mail,uid)
471 @param String One out of 'mail','uid'
472 */
473 public function getUAttrib()
474 {
475 return($this->uattrib);
476 }
479 /*! \brief Returns the used mail attribute (mail,uid)
480 @param String One out of 'mail','uid'
481 */
482 public function getUAttribValue()
483 {
484 $uattrib = $this->getUAttrib();
485 return($this->parent->$uattrib);
486 }
489 /*! \brief Returns whether the quota settings are enabled or not
490 @return Boolean TRUE if enabled else FALSE
491 */
492 public function quotaEnabled()
493 {
494 return($this->enableQuota);
495 }
498 /*! \brief Returns the used quota
499 @return Integer Quota used.
500 */
501 public function getQuotaUsage()
502 {
503 return(-1);
504 }
507 /*! \brief Returns the quota restrictions.
508 @return Integer Quota restrictions.
509 */
510 public function getQuota($quotaValue)
511 {
512 return($quotaValue);
513 }
516 /*! \brief Sets the mail quota
517 */
518 public function setQuota($number)
519 {
520 if(!is_numeric($number)){
521 $number = (int) $number;
522 if(!$number){
523 $number = 0;
524 }
525 }
526 $this->quotaValue = $number;
527 return(TRUE);
528 }
531 /*! \brief Returns true whether the domain is selectable or not
532 */
533 public function domainSelectionEnabled()
534 {
535 return($this->enableDomainSelection);
536 }
539 /*! \brief Returns a list of configured mail domains
540 @return Array A list of mail domains
541 */
542 public function getMailDomains()
543 {
544 return(array("Unconfigured"));
545 }
548 /*! \brief Returns the used Spamlevels for this mailmethod
549 */
550 public function getSpamLevels()
551 {
552 $spamlevel= array();
553 for ($i= 0; $i<21; $i++){
554 $spamlevel[]= $i;
555 }
556 return($spamlevel);
557 }
560 /*! \brief Returns the list of configured mailbox folders
561 @return Array The mailbox folders.
562 */
563 public function getMailboxList()
564 {
565 return(array("INBOX"));
566 }
569 /*! \brief Returns whether the vacation range is selectable or not
570 @return Boolean TRUE, FALSE
571 */
572 public function vacationRangeEnabled()
573 {
574 return($this->enableVacationRange);
575 }
578 /*! \brief Returns true if the sieveManagement is allowed
579 @return Boolean TRUE, FALSE
580 */
581 public function allowSieveManagement()
582 {
583 return($this->enableSieveManager);
584 }
587 /*! \brief Checks dependencies to other GOsa plugins.
588 */
589 public function accountCreateable(&$reason = ""){
590 return(TRUE);
591 }
594 /*! \brief Checks whether this account is removeable or not.
595 There may be some dependencies left, eg. kolab.
596 */
597 public function accountRemoveable(&$reason = ""){
598 return(TRUE);
599 }
602 /*! \brief Returns all mail servers configured in GOsa
603 that are useable with this mailMethod.
604 @return Array All useable mail servers.
605 */
606 public function getMailServers()
607 {
608 $mailserver = array();
609 $ui = get_userinfo();
610 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
611 if( $this->MailServer == $key ||
612 preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
613 $mailserver[]= $key;
614 }
615 }
616 return($mailserver);
617 }
620 /*! \brief Returns the available mailMethods
621 @return Array A list of all avaialable mailMethods_
622 */
623 static protected function get_methods()
624 {
625 global $class_mapping;
626 $available = array();
627 foreach($class_mapping as $class => $path){
628 if($class == "mailMethod") continue;
629 if(preg_match("/^mailMethod/",$class)){
630 $available[$class] = $class;
631 }
632 }
633 return($available);
634 }
637 /* \brief Some method require special folder types, "kolab" for example.
638 !! Those values are dummy values, the base class doesn't use folder types;
639 @return Array Return folder types.
640 */
641 public function getAvailableFolderTypes()
642 {
643 $ret = array();
644 $ret['CAT'][''] = _("None");
645 $ret['SUB_CAT'][''][''] = _("None");
646 return($ret);
647 }
650 /* \brief Returns the selected folder type.
651 !! Those values are dummy values, the base class doesn't use folder types;
652 @return Array The folde type.
653 */
654 public function getFolderType($default)
655 {
656 return($default);
657 }
660 /* \brief Returns the selected folder type.
661 !! Those values are dummy values, the base class doesn't use folder types;
662 @return Array The folde type.
663 */
664 public function setFolderType($type)
665 {
666 return(TRUE) ;
667 }
670 /*! \brief Returns configured acls
671 */
672 public function getFolderACLs($folder_acls)
673 {
674 /* Merge given ACL with acl mapping
675 This ensures that no ACL will accidentally overwritten by gosa.
676 */
677 foreach($folder_acls as $user => $acl){
678 if(!isset($this->acl_mapping[$acl])){
679 $this->acl_mapping[$acl] = $acl;
680 }
681 }
683 return($folder_acls);
684 }
687 /*! \brief Write ACLs back to imap or what ever
688 */
689 public function setFolderACLs($array)
690 {
691 return(TRUE);
692 }
695 /*! \brief Returns a list of all possible acls.
696 @return Array ACLs.
697 */
698 public function getAclTypes()
699 {
700 return( $this->acl_mapping);
701 }
703 public function folderTypesEnabled()
704 {
705 return($this->enableFolderTypes);
706 }
708 public function allow_remove(&$reason)
709 {
710 return(TRUE);
711 }
714 /*! \brief Returns the configured mailMethod
715 @return String the configured mail method or ""
716 */
717 static public function get_current_method($config)
718 {
719 global $class_mapping;
720 $method= $config->get_cfg_value("mailmethod");
721 $cls = get_correct_class_name("mailMethod$method");
722 foreach($class_mapping as $class => $path){
723 if($class == $cls){
724 return($class);
725 }
726 }
727 return("");
728 }
731 static function quota_to_image($use,$quota)
732 {
733 if($use == -1){
734 return(" "._("Unknown"));
735 }elseif(empty($quota)){
736 return(" "._("Unlimited"));
737 }else{
738 $usage =(int) ($use/$quota) * 100;
739 return("<img src='progress.php?x=100&y=17&p=$usage'>");
740 }
741 }
744 /*! \brief Returns the default sharedFolder ACLs for this method.
745 @return Array Returns an array containg acls for __member__ and __anyone__
746 */
747 public function getDefaultACLs()
748 {
749 $tmp = $this->default_acls;
750 if(!isset($tmp['__member__'])) $tmp['__member__'] = " ";
751 if(!isset($tmp['__anyone__'])) $tmp['__anyone__'] = " ";
752 return($tmp);
753 }
754 }
757 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
758 ?>