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 /* Create accounts in cyrus style with '/' instead of '.' */
23 protected $cyrusUseSlashes= FALSE;
25 /* The atribute mapping for this class Source --> Destination */
26 protected $attributes = array();
27 protected $userObjectClasses = array();
28 protected $shareObjectClasses = array();
30 /* Enabled mail domain selection. If enabled getMailDomains must the domain parts */
31 protected $enableDomainSelection= FALSE;
32 protected $enableQuota = TRUE;
33 protected $enableSieveManager = FALSE;
34 protected $enableVacationRange = TRUE;
35 protected $enableFolderTypes = FALSE;
37 /* Default values */
38 protected $quotaValue = 0;
39 protected $quotaUsage = 0;
41 /* Method internal */
42 protected $type = "user";
43 protected $account_id = "";
44 protected $initial_account_id = "";
45 protected $connected = FALSE;
46 protected $error = "";
47 protected $parent = NULL;
48 protected $MailServer = "";
50 protected $acl_map = array(
51 "lrsw" => "read",
52 "lrswp" => "post",
53 "p" => "external post",
54 "lrswip" => "append",
55 "lrswipcd" => "write",
56 "lrswipcda"=> "admin",
57 " " => "none");
59 protected $acl_mapping = array();
62 /*! \brief Constructs the mail class
63 @param Object Config The GOsa configuration object
64 @param Object Plugin The initator
65 @param String Open "user" or "group" account.
66 */
67 function __construct(&$config, &$parent, $type = "user")
68 {
69 $this->parent = $parent;
70 $this->config = $config;
72 /* Create a refernce to the mail selected server
73 */
74 if(isset($this->parent->gosaMailServer)){
75 $this->MailServer = &$this->parent->gosaMailServer;
76 }else{
77 trigger_error("mailMethod with invalid parent object initialized.");
78 }
80 if(!in_array($this->type,array("user","group"))){
81 trigger_error("Unknown mail class type used '".$type."'.");
82 }else{
83 $this->type = $type;
84 }
85 }
88 /*! \brief Intialize attributes and config settings.
89 */
90 protected function init()
91 {
92 /* Get config value for cyrusUseSlashes
93 */
94 if ($this->config->get_cfg_value("cyrusUseSlashes") == "true"){
95 $this->cyrusUseSlashes = TRUE;
96 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Enabled</b>");
97 }else{
98 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Disabled</b>");
99 }
101 /* Check if the mail account identification attribute
102 is overridden in the configuration file
103 */
104 if($this->config->get_cfg_value("mailAttribute","mail") != ""){
105 $new_uattrib= strtolower($this->config->get_cfg_value("mailAttribute"));
106 if(in_array($new_uattrib,array("mail","uid"))){
107 $this->uattrib = $new_uattrib;
108 }else{
109 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$new_uattrib."</b>",
110 "<b>MAIL:</b> Unsupported 'mailAttribute' in gosa configuration specified");
111 msg_dialog::display(_("Configuration error"),
112 sprintf(_("The configured mail attribute '%s' is unsupported!"), $new_uattrib), ERROR_DIALOG);
113 }
114 }
116 /* Create ACL map */
117 foreach($this->acl_map as $acl => $name){
118 $this->acl_mapping[$acl] = _($name);
119 }
121 $this->build_account_id();
122 $this->initial_account_id = $this->account_id;
123 }
126 public function fixAttributesOnLoad()
127 {
128 foreach($this->attributes as $source => $dest){
129 if(isset($this->parent->attrs[$source])){
130 $this->parent->attrs[$dest] = $this->parent->attrs[$source];
131 }
132 if(isset($this->parent->$source)){
133 $this->parent->$dest = $this->parent->$source;
134 }
135 if(isset($this->parent->attrs[$source][0])){
136 $this->parent->saved_attributes[$source] = $this->parent->attrs[$source][0];
137 }
138 }
139 }
142 public function mailEqualsCN()
143 {
144 return($this->mailEqualsCN);
145 }
148 public function fixAttributesOnRemove()
149 {
150 /* Remove objectClasses
151 */
152 if($this->type == "user"){
153 $this->parent->attrs['objectClass'] =
154 array_remove_entries_ics($this->userObjectClasses, $this->parent->attrs['objectClass']);
155 }else{
156 $this->parent->attrs['objectClass'] =
157 array_remove_entries_ics($this->shareObjectClasses, $this->parent->attrs['objectClass']);
158 }
159 foreach($this->attributes as $source => $dest){
160 $this->attrs[$dest] = array();
161 $this->attrs[$source] = array();
162 }
163 }
165 public function fixAttributesOnStore()
166 {
167 foreach($this->attributes as $source => $dest){
168 if(isset($this->parent->attrs[$dest])){
169 $this->parent->attrs[$source] = $this->parent->attrs[$dest ];
170 }
171 if(isset($this->parent->$dest)){
172 $this->parent->$source = $this->parent->$dest;
173 }
174 }
176 if($this->type == "user"){
177 $ocs = $this->userObjectClasses;
178 }else{
179 $ocs = $this->shareObjectClasses;
180 }
181 foreach($ocs as $oc){
182 if(!in_array($oc, $this->parent->attrs['objectClass'])){
183 $this->parent->attrs['objectClass'][] = $oc;
184 }
185 }
186 }
189 /*! \brief Connect services like imap.
190 Not necessary for the base class.
191 @return Boolean True if this method is connected else false.
192 */
193 public function connect()
194 {
195 $this->reset_error();
196 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Connect method</b>: ".get_class($this));
197 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Current server</b>: ".$this->MailServer);
199 $this->connected = TRUE;
200 return(TRUE);
201 }
204 /*! \brief Returns the connection status of this method.
205 @return Boolean True if this method is connected else false.
206 */
207 public function is_connected()
208 {
209 return($this->connected);
210 }
213 /*! \brief Disconnect this method. Close services like imap connection.
214 Not necessary for the base class.
215 */
216 public function disconnect()
217 {
218 $this->reset_error();
219 if($this->is_connected()){
220 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Disconnect method</b>: ".get_class($this));
221 $this->connected =FALSE;
222 }
223 }
226 /*! \brief Returns true the current object represents a valid account
227 (Some methods may check imap accounts here.)
228 @return Boolean TRUE if this is a valid account else FALSE
229 */
230 public function account_exists()
231 {
232 $this->reset_error();
233 return(TRUE);
234 }
237 /*! \brief Returns the last error occurred
238 @return String The last error message.
239 */
240 public function get_error(){
241 return($this->error);
242 }
245 public function isModifyableMail()
246 {
247 return($this->modifyableMail);
248 }
251 public function isModifyableServer()
252 {
253 return($this->modifyableServer);
254 }
257 /*! \brief Returns TRUE if the action caused an error.
258 @return Boolean TRUE on error else FALSE
259 */
260 public function is_error(){
261 return($this->error != "");
262 }
265 /*! \brief Resets the error message.
266 */
267 public function reset_error(){
268 $this->error = "";
269 }
272 public function get_account_id()
273 {
274 $this->build_account_id();
275 return($this->account_id);
276 }
278 /*! \brief Create a new account id, like 'user/name@domain.com'.
279 */
280 protected function build_account_id()
281 {
282 /* Build account identicator */
283 if($this->type == "user"){
284 $str = $this->user_prefix;
285 }else{
286 $str = $this->share_prefix;
287 }
289 /* Create account prefix and respect "cyrusUseSlashes"
290 Do not replace escaped dots for cyrusUseSlashes.
291 */
292 $uattrib = $this->uattrib;
293 if($this->cyrusUseSlashes){
294 $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
295 }
296 $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
297 $str = trim(strtolower($str . $this->parent->$uattrib));
299 if($this->account_id != $str){
300 $this->account_id = $str;
301 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> AccountID generated: <b>".$str."</b>");
302 }
303 }
306 /*! \brief Creates a valid folder id for a given folder name.
307 e.g. $folder_id = "INBOX/test" && $this->account_id = "share/mailbox@domain.de"
308 will result in "share/mailbox/test@domain.de"
309 This function is mainly used to read and write folder permissions.
310 @return String A valid folder id
311 */
312 public function create_folder_id($folder, $type = "")
313 {
315 if(!empty($folder)){
316 $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
317 }
318 if(!empty($folder)){
319 $folder = "/".$folder;
320 }
322 /* Build account identicator */
323 if($type == ""){
324 $type = $this->type;
325 }
326 if($type == "user"){
327 $str = $this->user_prefix;
328 }else{
329 $str = $this->share_prefix;
330 }
332 /* Create account prefix and respect "cyrusUseSlashes"
333 Do not replace escaped dots for cyrusUseSlashes.
334 */
335 $uattrib = $this->uattrib;
336 if($this->cyrusUseSlashes){
337 $str = preg_replace('/([^\\\\])\./',"\\1/",$str);
338 }
339 $str = preg_replace("/\\\\([\.\/])/","\\1",$str);
340 $str = trim(strtolower($str . $this->parent->$uattrib));
342 if(preg_match("/\@/",$this->parent->$uattrib)){
343 list($mail,$domain) = split("\@",$this->parent->$uattrib);
344 $str = trim(strtolower($str . $mail . $folder . "@" . $domain));
345 }else{
346 $str = trim(strtolower($str . $this->parent->$uattrib));
347 }
348 return($str) ;
349 }
352 /*! \brief Returns the configured mail method for the given parent object,
353 initialized and read for use.
354 @return mailMethod The configured mailMethod.
355 */
356 public function get_method()
357 {
358 $methods = mailMethod::get_methods();
359 if ($this->config->get_cfg_value("mailmethod") != ""){
360 $method= $this->config->get_cfg_value("mailmethod");
361 $cls = get_correct_class_name("mailMethod$method");
362 if(isset($methods[$cls])){
363 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> Selected mailMethod: <b>".$cls."</b>");
364 $tmp = new $cls($this->config,$this->parent,$this->type);
365 $tmp->init();
366 return($tmp);
367 }else{
368 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL: Invalid mailMethod defined: <b>".$cls.
369 "</b> falling back to <b>".get_class($this)."</b>");
371 /* Print out configuration errors directly, we can't catch them everywhere.
372 */
373 msg_dialog::display(_("Configuration error"),
374 sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
375 }
376 }
378 /* If no valued mailMethod could be detected, return the base class.
379 */
380 $this->init();
381 return($this);
382 }
385 /*! \brief Saves sieve settings
386 */
387 public function saveSieveSettings()
388 {
389 $this->reset_error();
390 return(TRUE);
391 }
394 /*! \brief Creates or Updates the mailAccount represented by this class.
395 */
396 public function updateMailbox()
397 {
398 $this->reset_error();
399 return(TRUE);
400 }
403 /*! \brief Update shared folder dependencies
404 */
405 public function updateSharedFolder()
406 {
407 $this->reset_error();
408 return(TRUE);
409 }
412 /*! \brief Removes the mailbox represented by this class,
413 and update shared folder ACLs .
414 */
415 public function deleteMailbox()
416 {
417 $this->reset_error();
419 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
420 "<b>MAIL: Remove account</b> from server :".$this->MailServer);
422 return(TRUE);
423 }
426 /*! \brief Returns the used mail attribute (mail,uid)
427 @param String One out of 'mail','uid'
428 */
429 public function getUAttrib()
430 {
431 return($this->uattrib);
432 }
435 /*! \brief Returns the used mail attribute (mail,uid)
436 @param String One out of 'mail','uid'
437 */
438 public function getUAttribValue()
439 {
440 $uattrib = $this->getUAttrib();
441 return($this->parent->$uattrib);
442 }
445 /*! \brief Returns whether the quota settings are enabled or not
446 @return Boolean TRUE if enabled else FALSE
447 */
448 public function quotaEnabled()
449 {
450 return($this->enableQuota);
451 }
454 /*! \brief Returns the used quota
455 @return Integer Quota used.
456 */
457 public function getQuotaUsage()
458 {
459 return(-1);
460 }
463 /*! \brief Returns the quota restrictions.
464 @return Integer Quota restrictions.
465 */
466 public function getQuota($quotaValue)
467 {
468 return($quotaValue);
469 }
472 /*! \brief Sets the mail quota
473 */
474 public function setQuota($number)
475 {
476 if(!is_numeric($number)){
477 $number = (int) $number;
478 if(!$number){
479 $number = 0;
480 }
481 }
482 $this->quotaValue = $number;
483 return(TRUE);
484 }
487 /*! \brief Returns true whether the domain is selectable or not
488 */
489 public function domainSelectionEnabled()
490 {
491 return($this->enableDomainSelection);
492 }
495 /*! \brief Returns a list of configured mail domains
496 @return Array A list of mail domains
497 */
498 public function getMailDomains()
499 {
500 return(array("Unconfigured"));
501 }
504 /*! \brief Returns the used Spamlevels for this mailmethod
505 */
506 public function getSpamLevels()
507 {
508 $spamlevel= array();
509 for ($i= 0; $i<21; $i++){
510 $spamlevel[]= $i;
511 }
512 return($spamlevel);
513 }
516 /*! \brief Returns the list of configured mailbox folders
517 @return Array The mailbox folders.
518 */
519 public function getMailboxList()
520 {
521 return(array("INBOX"));
522 }
525 /*! \brief Returns whether the vacation range is selectable or not
526 @return Boolean TRUE, FALSE
527 */
528 public function vacationRangeEnabled()
529 {
530 return($this->enableVacationRange);
531 }
534 /*! \brief Returns true if the sieveManagement is allowed
535 @return Boolean TRUE, FALSE
536 */
537 public function allowSieveManagement()
538 {
539 return($this->enableSieveManager);
540 }
543 /*! \brief Checks dependencies to other GOsa plugins.
544 */
545 public function accountCreateable(&$reason = ""){
546 return(TRUE);
547 }
550 /*! \brief Checks whether this account is removeable or not.
551 There may be some dependencies left, eg. kolab.
552 */
553 public function accountRemoveable(&$reason = ""){
554 return(TRUE);
555 }
558 /*! \brief Returns all mail servers configured in GOsa
559 that are useable with this mailMethod.
560 @return Array All useable mail servers.
561 */
562 public function getMailServers()
563 {
564 $mailserver = array();
565 $ui = get_userinfo();
566 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
567 if( $this->MailServer == $key ||
568 preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
569 $mailserver[]= $key;
570 }
571 }
572 return($mailserver);
573 }
576 /*! \brief Returns the available mailMethods
577 @return Array A list of all avaialable mailMethods_
578 */
579 static protected function get_methods()
580 {
581 global $class_mapping;
582 $available = array();
583 foreach($class_mapping as $class => $path){
584 if($class == "mailMethod") continue;
585 if(preg_match("/^mailMethod/",$class)){
586 $available[$class] = $class;
587 }
588 }
589 return($available);
590 }
593 /* \brief Some method require special folder types, "kolab" for example.
594 !! Those values are dummy values, the base class doesn't use folder types;
595 @return Array Return folder types.
596 */
597 public function getAvailableFolderTypes()
598 {
599 $ret = array();
600 $ret['CAT'][''] = _("None");
601 $ret['SUB_CAT'][''][''] = _("None");
602 return($ret);
603 }
606 /* \brief Returns the selected folder type.
607 !! Those values are dummy values, the base class doesn't use folder types;
608 @return Array The folde type.
609 */
610 public function getFolderType($default)
611 {
612 return($default);
613 }
616 /* \brief Returns the selected folder type.
617 !! Those values are dummy values, the base class doesn't use folder types;
618 @return Array The folde type.
619 */
620 public function setFolderType($type)
621 {
622 return(TRUE) ;
623 }
626 /*! \brief Returns configured acls
627 */
628 public function getFolderACLs($folder_acls)
629 {
630 /* Merge given ACL with acl mapping
631 This ensures that no ACL will accidentally overwritten by gosa.
632 */
633 foreach($folder_acls as $user => $acl){
634 if(!isset($this->acl_mapping[$acl])){
635 $this->acl_mapping[$acl] = $acl;
636 }
637 }
639 return($folder_acls);
640 }
643 /*! \brief Write ACLs back to imap or what ever
644 */
645 public function setFolderACLs($array)
646 {
647 return(TRUE);
648 }
651 /*! \brief Returns a list of all possible acls.
652 @return Array ACLs.
653 */
654 public function getAclTypes()
655 {
656 return( $this->acl_mapping);
657 }
659 public function folderTypesEnabled()
660 {
661 return($this->enableFolderTypes);
662 }
664 public function allow_remove(&$reason)
665 {
666 return(TRUE);
667 }
670 /*! \brief Returns the configured mailMethod
671 @return String the configured mail method or ""
672 */
673 static public function get_current_method($config)
674 {
675 global $class_mapping;
676 $method= $config->get_cfg_value("mailmethod");
677 $cls = get_correct_class_name("mailMethod$method");
678 foreach($class_mapping as $class => $path){
679 if($class == $cls){
680 return($class);
681 }
682 }
683 return("");
684 }
686 }
689 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
690 ?>