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 $uattrib = $this->uattrib;
261 if($this->cyrusUseSlashes){
262 $str = preg_replace("/[^\\\\]\./","/",$str);
263 }
264 $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
265 $str = trim(strtolower($str . $this->parent->$uattrib));
266 if($this->account_id != $str){
267 $this->account_id = $str;
268 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "accountID generated: <b>".$str."</b>","");
269 }
270 }
273 /*! \brief Creates a valid folder id for a given folder name.
274 e.g. $folder_id = "INBOX/test" && $this->account_id = "share/mailbox@domain.de"
275 will result in "share/mailbox/test@domain.de"
276 This function is mainly used to read and write folder permissions.
277 @return String A valid folder id
278 */
279 public function create_folder_id($folder, $type = "")
280 {
282 if(!empty($folder)){
283 $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
284 }
285 if(!empty($folder)){
286 $folder = "/".$folder;
287 }
289 /* Build account identicator */
290 if($type == ""){
291 $type = $this->type;
292 }
293 if($type == "user"){
294 $str = $this->user_prefix;
295 }else{
296 $str = $this->share_prefix;
297 }
299 $uattrib = $this->uattrib;
300 if($this->cyrusUseSlashes){
301 $str = preg_replace("/\./","/",$str);
302 }
303 if(preg_match("/\@/",$this->parent->$uattrib)){
304 list($mail,$domain) = split("\@",$this->parent->$uattrib);
305 $str = trim(strtolower($str . $mail . $folder . "@" . $domain));
306 }else{
307 $str = trim(strtolower($str . $this->parent->$uattrib));
308 }
309 return($str) ;
310 }
313 /*! \brief Returns the configured mail method for the given parent object,
314 initialized and read for use.
315 @return mailMethod The configured mailMethod.
316 */
317 public function get_method()
318 {
319 $methods = mailMethod::get_methods();
320 if ($this->config->get_cfg_value("mailmethod") != ""){
321 $method= $this->config->get_cfg_value("mailmethod");
322 $cls = get_correct_class_name("mailMethod$method");
323 if(isset($methods[$cls])){
324 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Selected mailMethod: <b>".$cls."</b>","");
325 $tmp = new $cls($this->config,$this->parent,$this->type);
326 $tmp->init();
327 return($tmp);
328 }else{
329 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Invalid mailMethod defined <b>".$cls.
330 "</b> falling back to <b>".get_class($this)."</b>","");
332 /* Print out configuration errors directly, we can't catch them everywhere.
333 */
334 msg_dialog::display(_("Configuration error"),
335 sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
336 }
337 }
339 /* If no valued mailMethod could be detected, return the base class.
340 */
341 $this->init();
342 return($this);
343 }
346 /*! \brief Saves sieve settings
347 */
348 public function saveSieveSettings()
349 {
350 $this->reset_error();
351 return(TRUE);
352 }
355 /*! \brief Creates or Updates the mailAccount represented by this class.
356 */
357 public function updateMailbox()
358 {
359 $this->reset_error();
360 return(TRUE);
361 }
364 /*! \brief Update shared folder dependencies
365 */
366 public function updateSharedFolder()
367 {
368 $this->reset_error();
369 return(TRUE);
370 }
373 /*! \brief Removes the mailbox represented by this class,
374 and update shared folder ACLs .
375 */
376 public function deleteMailbox()
377 {
378 $this->reset_error();
380 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
381 "<b>Remove account</b> from server :".$this->MailServer);
383 return(TRUE);
385 /* No imap actions here, just updated shared folder membership
386 */
387 $ldap = $this->config->get_ldap_link();
388 $ldap->cd($this->config->current['BASE']);
389 $ldap->search("(&(objectClass=posixGroup)(objectClass=gosaMailAccount)(memberUid=".$account."))",array('dn','cn'));
390 if(class_exists("grouptabs")){
391 while($attrs = $ldap->fetch()){
392 $tmp = new grouptabs($this->config, $this->config->data['TABS']['GROUPTABS'], $attrs['dn']);
393 if(isset($tmp->by_object['mailgroup'])){
394 $tmp->by_object['mailgroup']->members= $tmp->by_object['group']->memberUid;
395 if(!$this->is_account){
396 $tmp->by_object['mailgroup']->removeUserAcl($account);
397 $tmp->by_object['mailgroup']->removeUserAcl($this->mail);
398 }
399 $tmp->by_object['mailgroup']->save();
400 }
401 }
402 }
403 return(TRUE);
404 }
407 /*! \brief Returns the used mail attribute (mail,uid)
408 @param String One out of 'mail','uid'
409 */
410 public function getUAttrib()
411 {
412 return($this->uattrib);
413 }
416 /*! \brief Returns the used mail attribute (mail,uid)
417 @param String One out of 'mail','uid'
418 */
419 public function getUAttribValue()
420 {
421 $uattrib = $this->getUAttrib();
422 return($this->parent->$uattrib);
423 }
426 /*! \brief Returns whether the quota settings are enabled or not
427 @return Boolean TRUE if enabled else FALSE
428 */
429 public function quotaEnabled()
430 {
431 return($this->enableQuota);
432 }
435 /*! \brief Returns the used quota
436 @return Integer Quota used.
437 */
438 public function getQuotaUsage()
439 {
440 return(-1);
441 }
444 /*! \brief Returns the quota restrictions.
445 @return Integer Quota restrictions.
446 */
447 public function getQuota($quotaValue)
448 {
449 return($quotaValue);
450 }
453 /*! \brief Sets the mail quota
454 */
455 public function setQuota($number)
456 {
457 if(!is_numeric($number)){
458 $number = (int) $number;
459 if(!$number){
460 $number = 0;
461 }
462 }
463 $this->quotaValue = $number;
464 return(TRUE);
465 }
468 /*! \brief Returns true whether the domain is selectable or not
469 */
470 public function domainSelectionEnabled()
471 {
472 return($this->enableDomainSelection);
473 }
476 /*! \brief Returns a list of configured mail domains
477 @return Array A list of mail domains
478 */
479 public function getMailDomains()
480 {
481 return(array("gonicus.de","test.intranet.de"));
482 }
485 /*! \brief Returns the used Spamlevels for this mailmethod
486 */
487 public function getSpamLevels()
488 {
489 $spamlevel= array();
490 for ($i= 0; $i<21; $i++){
491 $spamlevel[]= $i;
492 }
493 return($spamlevel);
494 }
497 /*! \brief Returns the list of configured mailbox folders
498 @return Array The mailbox folders.
499 */
500 public function getMailboxList()
501 {
502 return(array("INBOX"));
503 }
506 /*! \brief Returns whether the vacation range is selectable or not
507 @return Boolean TRUE, FALSE
508 */
509 public function vacationRangeEnabled()
510 {
511 return($this->enableVacationRange);
512 }
515 /*! \brief Returns true if the sieveManagement is allowed
516 @return Boolean TRUE, FALSE
517 */
518 public function allowSieveManagement()
519 {
520 return($this->enableSieveManager);
521 }
524 /*! \brief Checks dependencies to other GOsa plugins.
525 */
526 public function accountCreateable(&$reason = ""){
527 return(TRUE);
528 }
531 /*! \brief Checks whether this account is removeable or not.
532 There may be some dependencies left, eg. kolab.
533 */
534 public function accountRemoveable(&$reason = ""){
535 return(TRUE);
537 /* We are in administrational edit mode.
538 Check tab configurations directly * /
540 $
541 if(isset($this->attrs)){
542 $checkArray = array("kolabInvitationPolicy","unrestrictedMailSize", "calFBURL","kolabDelegate","kolabFreeBusyFuture");
543 foreach($checkArray as $index){
544 if(isset($this->attrs[$index])){
545 return(true);
546 }
547 }
548 }
549 return(false);
551 */
552 }
555 /*! \brief Returns all mail servers configured in GOsa
556 that are useable with this mailMethod.
557 @return Array All useable mail servers.
558 */
559 public function getMailServers()
560 {
561 $mailserver = array();
562 $ui = get_userinfo();
563 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
564 if( $this->MailServer == $key ||
565 preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
566 $mailserver[]= $key;
567 }
568 }
569 return($mailserver);
570 }
573 /*! \brief Returns the available mailMethods
574 @return Array A list of all avaialable mailMethods_
575 */
576 static protected function get_methods()
577 {
578 global $class_mapping;
579 $available = array();
580 foreach($class_mapping as $class => $path){
581 if($class == "mailMethod") continue;
582 if(preg_match("/^mailMethod/",$class)){
583 $available[$class] = $class;
584 }
585 }
586 return($available);
587 }
590 /* \brief Some method require special folder types, "kolab" for example.
591 !! Those values are dummy values, the base class doesn't use folder types;
592 @return Array Return folder types.
593 */
594 public function getAvailableFolderTypes()
595 {
596 $ret = array();
597 $ret['CAT']['mail'] = _("Mail");
598 $ret['CAT']['peter']= _("User");
599 $ret['SUB_CAT']['mail']['a'] = "a";
600 $ret['SUB_CAT']['mail']['b'] = "b";
601 $ret['SUB_CAT']['peter']['tt'] = "tt";
602 $ret['SUB_CAT']['peter']['dd'] = "dd";
603 $ret['SUB_CAT']['peter']['did'] = "did";
604 return($ret);
605 }
608 /* \brief Returns the selected folder type.
609 !! Those values are dummy values, the base class doesn't use folder types;
610 @return Array The folde type.
611 */
612 public function getFolderType($default)
613 {
614 if($this->enableFolderTypes && $this->parent->attrs['kolabFolderType'][0]){
615 list($cat,$sub) = split("\.",$this->parent->attrs['kolabFolderType'][0]);
616 return(array("CAT" => $cat, "SUB_CAT" => $sub));
617 }else{
618 return($default);
619 }
620 }
623 /* \brief Returns the selected folder type.
624 !! Those values are dummy values, the base class doesn't use folder types;
625 @return Array The folde type.
626 */
627 public function setFolderType($type)
628 {
629 $ldap = $this->config->get_ldap_link();
630 $ldap->cd ($this->parent->dn);
631 $ldap->modify(array("kolabFolderType" => $type['CAT'].".".$type['SUB_CAT']));
632 echo "Move me to KOLAB";
633 }
636 /*! \brief Returns configured acls
637 */
638 public function getFolderACLs($folder_acls)
639 {
640 return($folder_acls);
641 }
644 /*! \brief Write ACLs back to imap or what ever
645 */
646 public function setFolderACLs($array)
647 {
648 return(TRUE);
649 }
652 /*! \brief Returns a list of all possible acls.
653 @return Array ACLs.
654 */
655 public function getAclTypes()
656 {
657 $acls["lrsw"] = _("read");
658 $acls["lrswp"] = _("post");
659 $acls["p"] = _("external post");
660 $acls["lrswip"] = _("append");
661 $acls["lrswipcd"] = _("write");
662 $acls["lrswipcda"]= _("admin");
663 $acls[" "]= _("none");
664 return($acls);
665 }
667 public function folderTypesEnabled()
668 {
669 return($this->enableFolderTypes);
670 }
672 }
675 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
676 ?>