1 <?php
4 class mailMethod{
6 /* Allow modification of account_ids for existing mail accounts */
7 protected $modifyableMail = TRUE;
9 /* Enforces same value for 'mail' as used for 'cn' */
10 protected $mailEqualsCN = FALSE;
12 /* the attribute used to create accounts */
13 protected $uattrib = "mail"; // Naming attribute for accounts, e.g. imap.
15 /* The account prefixes, keep the '.' here! See FAQ cyrusUseSlashes */
16 protected $user_prefix = "user.";
17 protected $share_prefix = "share.";
19 /* Create accounts in cyrus style with '/' instead of '.' */
20 protected $cyrusUseSlashes= FALSE;
22 /* The atribute mapping for this class Source --> Destination */
23 protected $attributes = array();
24 protected $userObjectClasses = array();
25 protected $shareObjectClasses = array();
27 /* Enabled mail domain selection. If enabled getMailDomains must the domain parts */
28 protected $enableDomainSelection= FALSE;
29 protected $enableQuota = TRUE;
30 protected $enableSieveManager = FALSE;
31 protected $enableVacationRange = TRUE;
32 protected $enableFolderTypes = FALSE;
34 /* Default values */
35 protected $quotaValue = 0;
36 protected $quotaUsage = 0;
38 /* Method internal */
39 protected $type = "user";
40 protected $account_id = "";
41 protected $initial_account_id = "";
42 protected $connected = FALSE;
43 protected $error = "";
44 protected $parent = NULL;
45 protected $MailServer = "";
48 /*! \brief Constructs the mail class
49 @param Object Config The GOsa configuration object
50 @param Object Plugin The initator
51 @param String Open "user" or "group" account.
52 */
53 function __construct(&$config, &$parent, $type = "user")
54 {
55 $this->parent = $parent;
56 $this->config = $config;
58 /* Create a refernce to the mail selected server
59 */
60 if(isset($this->parent->gosaMailServer)){
61 $this->MailServer = &$this->parent->gosaMailServer;
62 }else{
63 trigger_error("mailMethod with invalid parent object initialized.");
64 }
66 if(!in_array($this->type,array("user","group"))){
67 trigger_error("Unknown mail class type used '".$type."'.");
68 }else{
69 $this->type = $type;
70 }
71 }
74 /*! \brief Intialize attributes and config settings.
75 */
76 protected function init()
77 {
78 /* Get config value for cyrusUseSlashes
79 */
80 if ($this->config->get_cfg_value("cyrusUseSlashes") == "true"){
81 $this->cyrusUseSlashes = TRUE;
82 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "cyrusUseSlashes: <b>Enabled</b>","");
83 }else{
84 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "cyrusUseSlashes: <b>Disabled</b>","");
85 }
87 /* Check if the mail account identification attribute
88 is overridden in the configuration file
89 */
90 if($this->config->get_cfg_value("mailAttribute","mail") != ""){
91 $new_uattrib= strtolower($this->config->get_cfg_value("mailAttribute"));
92 if(in_array($new_uattrib,array("mail","uid"))){
93 $this->uattrib = $new_uattrib;
94 }else{
95 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$new_uattrib."</b>",
96 "Unsupported 'mailAttribute' in gosa configuration specified");
97 msg_dialog::display(_("Configuration error"),
98 sprintf(_("The configured mail attribute '%s' is unsupported!"), $new_uattrib), ERROR_DIALOG);
99 }
100 }
101 $this->build_account_id();
102 $this->initial_account_id = $this->account_id;
103 }
106 public function fixAttributesOnLoad()
107 {
108 foreach($this->attributes as $source => $dest){
109 if(isset($this->parent->attrs[$source])){
110 $this->parent->attrs[$dest] = $this->parent->attrs[$source];
111 }
112 if(isset($this->parent->$source)){
113 $this->parent->$dest = $this->parent->$source;
114 }
115 }
116 }
119 public function mailEqualsCN()
120 {
121 return($this->mailEqualsCN);
122 }
125 public function fixAttributesOnRemove()
126 {
127 /* Remove objectClasses
128 */
129 if($this->type == "user"){
130 $this->parent->attrs['objectClass'] =
131 array_remove_entries_ics($this->userObjectClasses, $this->parent->attrs['objectClass']);
132 }else{
133 $this->parent->attrs['objectClass'] =
134 array_remove_entries_ics($this->shareObjectClasses, $this->parent->attrs['objectClass']);
135 }
136 foreach($this->attributes as $source => $dest){
137 $this->attrs[$dest] = array();
138 $this->attrs[$source] = array();
139 }
140 }
142 public function fixAttributesOnStore()
143 {
144 foreach($this->attributes as $source => $dest){
145 if(isset($this->parent->attrs[$dest])){
146 $this->parent->attrs[$source] = $this->parent->attrs[$dest ];
147 }
148 if(isset($this->parent->$dest)){
149 $this->parent->$source = $this->parent->$dest;
150 }
151 }
153 if($this->type == "user"){
154 $ocs = $this->userObjectClasses;
155 }else{
156 $ocs = $this->shareObjectClasses;
157 }
158 foreach($ocs as $oc){
159 if(!in_array($oc, $this->parent->attrs['objectClass'])){
160 $this->parent->attrs['objectClass'][] = $oc;
161 }
162 }
163 }
166 /*! \brief Connect services like imap.
167 Not necessary for the base class.
168 @return Boolean True if this method is connected else false.
169 */
170 public function connect()
171 {
172 $this->reset_error();
173 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Connect method</b>: ".get_class($this),"");
174 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Current server</b>: ".$this->MailServer,"");
176 $this->connected = TRUE;
177 return(TRUE);
178 }
181 /*! \brief Returns the connection status of this method.
182 @return Boolean True if this method is connected else false.
183 */
184 public function is_connected()
185 {
186 return($this->connected);
187 }
190 /*! \brief Disconnect this method. Close services like imap connection.
191 Not necessary for the base class.
192 */
193 public function disconnect()
194 {
195 $this->reset_error();
196 if($this->is_connected()){
197 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Disconnect method</b>: ".get_class($this),"");
198 $this->connected =FALSE;
199 }
200 }
203 /*! \brief Returns true the current object represents a valid account
204 (Some methods may check imap accounts here.)
205 @return Boolean TRUE if this is a valid account else FALSE
206 */
207 public function account_exists()
208 {
209 $this->reset_error();
210 return(TRUE);
211 }
214 /*! \brief Returns the last error occurred
215 @return String The last error message.
216 */
217 public function get_error(){
218 return($this->error);
219 }
222 public function isModifyableMail()
223 {
224 return($this->modifyableMail);
225 }
228 /*! \brief Returns TRUE if the action caused an error.
229 @return Boolean TRUE on error else FALSE
230 */
231 public function is_error(){
232 return($this->error != "");
233 }
236 /*! \brief Resets the error message.
237 */
238 public function reset_error(){
239 $this->error = "";
240 }
243 public function get_account_id()
244 {
245 $this->build_account_id();
246 return($this->account_id);
247 }
249 /*! \brief Create a new account id, like 'user/name@domain.com'.
250 */
251 protected function build_account_id()
252 {
253 /* Build account identicator */
254 if($this->type == "user"){
255 $str = $this->user_prefix;
256 }else{
257 $str = $this->share_prefix;
258 }
260 /* Create account prefix and respect "cyrusUseSlashes"
261 Do not replace escaped dots for cyrusUseSlashes.
262 */
263 $uattrib = $this->uattrib;
264 if($this->cyrusUseSlashes){
265 $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
266 }
267 $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
268 $str = trim(strtolower($str . $this->parent->$uattrib));
270 if($this->account_id != $str){
271 $this->account_id = $str;
272 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "accountID generated: <b>".$str."</b>","");
273 }
274 }
277 /*! \brief Creates a valid folder id for a given folder name.
278 e.g. $folder_id = "INBOX/test" && $this->account_id = "share/mailbox@domain.de"
279 will result in "share/mailbox/test@domain.de"
280 This function is mainly used to read and write folder permissions.
281 @return String A valid folder id
282 */
283 public function create_folder_id($folder, $type = "")
284 {
286 if(!empty($folder)){
287 $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
288 }
289 if(!empty($folder)){
290 $folder = "/".$folder;
291 }
293 /* Build account identicator */
294 if($type == ""){
295 $type = $this->type;
296 }
297 if($type == "user"){
298 $str = $this->user_prefix;
299 }else{
300 $str = $this->share_prefix;
301 }
303 /* Create account prefix and respect "cyrusUseSlashes"
304 Do not replace escaped dots for cyrusUseSlashes.
305 */
306 $uattrib = $this->uattrib;
307 if($this->cyrusUseSlashes){
308 $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
309 }
310 $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
311 $str = trim(strtolower($str . $this->parent->$uattrib));
313 if(preg_match("/\@/",$this->parent->$uattrib)){
314 list($mail,$domain) = split("\@",$this->parent->$uattrib);
315 $str = trim(strtolower($str . $mail . $folder . "@" . $domain));
316 }else{
317 $str = trim(strtolower($str . $this->parent->$uattrib));
318 }
319 return($str) ;
320 }
323 /*! \brief Returns the configured mail method for the given parent object,
324 initialized and read for use.
325 @return mailMethod The configured mailMethod.
326 */
327 public function get_method()
328 {
329 $methods = mailMethod::get_methods();
330 if ($this->config->get_cfg_value("mailmethod") != ""){
331 $method= $this->config->get_cfg_value("mailmethod");
332 $cls = get_correct_class_name("mailMethod$method");
333 if(isset($methods[$cls])){
334 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Selected mailMethod: <b>".$cls."</b>","");
335 $tmp = new $cls($this->config,$this->parent,$this->type);
336 $tmp->init();
337 return($tmp);
338 }else{
339 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Invalid mailMethod defined <b>".$cls.
340 "</b> falling back to <b>".get_class($this)."</b>","");
342 /* Print out configuration errors directly, we can't catch them everywhere.
343 */
344 msg_dialog::display(_("Configuration error"),
345 sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
346 }
347 }
349 /* If no valued mailMethod could be detected, return the base class.
350 */
351 $this->init();
352 return($this);
353 }
356 /*! \brief Saves sieve settings
357 */
358 public function saveSieveSettings()
359 {
360 $this->reset_error();
361 return(TRUE);
362 }
365 /*! \brief Creates or Updates the mailAccount represented by this class.
366 */
367 public function updateMailbox()
368 {
369 $this->reset_error();
370 return(TRUE);
371 }
374 /*! \brief Update shared folder dependencies
375 */
376 public function updateSharedFolder()
377 {
378 $this->reset_error();
379 return(TRUE);
380 }
383 /*! \brief Removes the mailbox represented by this class,
384 and update shared folder ACLs .
385 */
386 public function deleteMailbox()
387 {
388 $this->reset_error();
390 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
391 "<b>Remove account</b> from server :".$this->MailServer);
393 return(TRUE);
395 /* No imap actions here, just updated shared folder membership
396 */
397 $ldap = $this->config->get_ldap_link();
398 $ldap->cd($this->config->current['BASE']);
399 $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$account."))",array('dn','cn'));
400 if(class_exists("grouptabs")){
401 while($attrs = $ldap->fetch()){
402 $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
403 if(isset($tmp->by_object['mailgroup'])){
404 $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
405 if(!$this->is_account){
406 $tmp->by_object['mailgroup']->removeUserAcl($account);
407 $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
408 }
409 $tmp->by_object['mailgroup']->save();
410 }
411 }
412 }
413 return(TRUE);
414 }
417 /*! \brief Returns the used mail attribute (mail,uid)
418 @param String One out of 'mail','uid'
419 */
420 public function getUAttrib()
421 {
422 return($this->uattrib);
423 }
426 /*! \brief Returns the used mail attribute (mail,uid)
427 @param String One out of 'mail','uid'
428 */
429 public function getUAttribValue()
430 {
431 $uattrib = $this->getUAttrib();
432 return($this->parent->$uattrib);
433 }
436 /*! \brief Returns whether the quota settings are enabled or not
437 @return Boolean TRUE if enabled else FALSE
438 */
439 public function quotaEnabled()
440 {
441 return($this->enableQuota);
442 }
445 /*! \brief Returns the used quota
446 @return Integer Quota used.
447 */
448 public function getQuotaUsage()
449 {
450 return(-1);
451 }
454 /*! \brief Returns the quota restrictions.
455 @return Integer Quota restrictions.
456 */
457 public function getQuota($quotaValue)
458 {
459 return($quotaValue);
460 }
463 /*! \brief Sets the mail quota
464 */
465 public function setQuota($number)
466 {
467 if(!is_numeric($number)){
468 $number = (int) $number;
469 if(!$number){
470 $number = 0;
471 }
472 }
473 $this->quotaValue = $number;
474 return(TRUE);
475 }
478 /*! \brief Returns true whether the domain is selectable or not
479 */
480 public function domainSelectionEnabled()
481 {
482 return($this->enableDomainSelection);
483 }
486 /*! \brief Returns a list of configured mail domains
487 @return Array A list of mail domains
488 */
489 public function getMailDomains()
490 {
491 return(array("Unconfigured"));
492 }
495 /*! \brief Returns the used Spamlevels for this mailmethod
496 */
497 public function getSpamLevels()
498 {
499 $spamlevel= array();
500 for ($i= 0; $i<21; $i++){
501 $spamlevel[]= $i;
502 }
503 return($spamlevel);
504 }
507 /*! \brief Returns the list of configured mailbox folders
508 @return Array The mailbox folders.
509 */
510 public function getMailboxList()
511 {
512 return(array("INBOX"));
513 }
516 /*! \brief Returns whether the vacation range is selectable or not
517 @return Boolean TRUE, FALSE
518 */
519 public function vacationRangeEnabled()
520 {
521 return($this->enableVacationRange);
522 }
525 /*! \brief Returns true if the sieveManagement is allowed
526 @return Boolean TRUE, FALSE
527 */
528 public function allowSieveManagement()
529 {
530 return($this->enableSieveManager);
531 }
534 /*! \brief Checks dependencies to other GOsa plugins.
535 */
536 public function accountCreateable(&$reason = ""){
537 return(TRUE);
538 }
541 /*! \brief Checks whether this account is removeable or not.
542 There may be some dependencies left, eg. kolab.
543 */
544 public function accountRemoveable(&$reason = ""){
545 return(TRUE);
546 }
549 /*! \brief Returns all mail servers configured in GOsa
550 that are useable with this mailMethod.
551 @return Array All useable mail servers.
552 */
553 public function getMailServers()
554 {
555 $mailserver = array();
556 $ui = get_userinfo();
557 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
558 if( $this->MailServer == $key ||
559 preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
560 $mailserver[]= $key;
561 }
562 }
563 return($mailserver);
564 }
567 /*! \brief Returns the available mailMethods
568 @return Array A list of all avaialable mailMethods_
569 */
570 static protected function get_methods()
571 {
572 global $class_mapping;
573 $available = array();
574 foreach($class_mapping as $class => $path){
575 if($class == "mailMethod") continue;
576 if(preg_match("/^mailMethod/",$class)){
577 $available[$class] = $class;
578 }
579 }
580 return($available);
581 }
584 /* \brief Some method require special folder types, "kolab" for example.
585 !! Those values are dummy values, the base class doesn't use folder types;
586 @return Array Return folder types.
587 */
588 public function getAvailableFolderTypes()
589 {
590 $ret = array();
591 $ret['CAT']['mail'] = _("Mail");
592 $ret['CAT']['peter']= _("User");
593 $ret['SUB_CAT']['mail']['a'] = "a";
594 $ret['SUB_CAT']['mail']['b'] = "b";
595 $ret['SUB_CAT']['peter']['tt'] = "tt";
596 $ret['SUB_CAT']['peter']['dd'] = "dd";
597 $ret['SUB_CAT']['peter']['did'] = "did";
598 return($ret);
599 }
602 /* \brief Returns the selected folder type.
603 !! Those values are dummy values, the base class doesn't use folder types;
604 @return Array The folde type.
605 */
606 public function getFolderType($default)
607 {
608 if($this->enableFolderTypes && $this->parent->attrs['kolabFolderType'][0]){
609 list($cat,$sub) = split("\.",$this->parent->attrs['kolabFolderType'][0]);
610 return(array("CAT" => $cat, "SUB_CAT" => $sub));
611 }else{
612 return($default);
613 }
614 }
617 /* \brief Returns the selected folder type.
618 !! Those values are dummy values, the base class doesn't use folder types;
619 @return Array The folde type.
620 */
621 public function setFolderType($type)
622 {
623 $ldap = $this->config->get_ldap_link();
624 $ldap->cd ($this->parent->dn);
625 $ldap->modify(array("kolabFolderType" => $type['CAT'].".".$type['SUB_CAT']));
626 echo "Move me to KOLAB";
627 }
630 /*! \brief Returns configured acls
631 */
632 public function getFolderACLs($folder_acls)
633 {
634 return($folder_acls);
635 }
638 /*! \brief Write ACLs back to imap or what ever
639 */
640 public function setFolderACLs($array)
641 {
642 return(TRUE);
643 }
646 /*! \brief Returns a list of all possible acls.
647 @return Array ACLs.
648 */
649 public function getAclTypes()
650 {
651 $acls["lrsw"] = _("read");
652 $acls["lrswp"] = _("post");
653 $acls["p"] = _("external post");
654 $acls["lrswip"] = _("append");
655 $acls["lrswipcd"] = _("write");
656 $acls["lrswipcda"]= _("admin");
657 $acls[" "]= _("none");
658 return($acls);
659 }
661 public function folderTypesEnabled()
662 {
663 return($this->enableFolderTypes);
664 }
666 }
669 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
670 ?>