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