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 /* gosaSharedFolderTarget settings,
43 * E.g.
44 * For an accountID like: 'share/herberts.folder@gonicus.de' the value 'dummy+'
45 * will result in gosaSharedFolderTarget: dummy+share/herberts.folder@gonicus.de
46 */
47 protected $gosaSharedPrefix = '';
49 /* The atribute mapping for this class Source --> Destination */
50 protected $attributes = array();
51 protected $userObjectClasses = array();
52 protected $shareObjectClasses = array();
54 /* Enabled mail domain selection. If enabled getMailDomains() have to return an array
55 * with the domain parts.
56 */
57 protected $enableDomainSelection= FALSE;
58 protected $enableQuota = TRUE;
59 protected $enableSieveManager = FALSE;
60 protected $enableVacationRange = TRUE;
61 protected $enableFolderTypes = FALSE;
63 /* Default values */
64 protected $quotaValue = 0;
65 protected $quotaUsage = 0;
67 /* Method internal */
68 protected $type = "user";
69 protected $account_id = "";
70 protected $initial_account_id = "";
71 protected $connected = FALSE;
72 protected $error = "";
73 protected $parent = NULL;
74 protected $MailServer = "";
76 protected $default_acls = array("__anyone__" => "p", "__member__" => "lrswp");
78 protected $acl_map = array(
79 "lrsw" => "read",
80 "lrswp" => "post",
81 "p" => "external post",
82 "lrswip" => "append",
83 "lrswipcd" => "write",
84 "lrswipcda"=> "admin",
85 " " => "none");
87 protected $acl_mapping = array();
90 /*! \brief Constructs the mail class
91 @param Object Config The GOsa configuration object
92 @param Object Plugin The initator
93 @param String Open "user" or "group" account.
94 */
95 function __construct(&$config, &$parent, $type = "user")
96 {
97 $this->parent = $parent;
98 $this->config = $config;
100 /* Create a refernce to the mail selected server
101 */
102 if(isset($this->parent->gosaMailServer)){
103 $this->MailServer = &$this->parent->gosaMailServer;
104 }else{
105 trigger_error("mailMethod with invalid parent object initialized.");
106 }
108 if(!in_array($this->type,array("user","group"))){
109 trigger_error("Unknown mail class type used '".$type."'.");
110 }else{
111 $this->type = $type;
112 }
114 }
117 /*! \brief Intialize attributes and config settings.
118 */
119 protected function init()
120 {
121 /* Get config value for cyrusUseSlashes
122 */
123 if ($this->config->get_cfg_value("cyrusUseSlashes") == "true"){
124 $this->cyrusUseSlashes = TRUE;
125 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Enabled</b>");
126 }else{
127 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL:</b> cyrusUseSlashes: <b>Disabled</b>");
128 }
130 /* Check if the mail account identification attribute
131 is overridden in the configuration file
132 */
133 if($this->config->get_cfg_value("mailAttribute","mail") != ""){
134 $new_uattrib= strtolower($this->config->get_cfg_value("mailAttribute"));
135 if(in_array($new_uattrib,array("mail","uid"))){
136 $this->uattrib = $new_uattrib;
137 }else{
138 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$new_uattrib."</b>",
139 "<b>MAIL:</b> Unsupported 'mailAttribute' in gosa configuration specified");
140 msg_dialog::display(_("Configuration error"),
141 sprintf(_("The configured mail attribute '%s' is unsupported!"), $new_uattrib), ERROR_DIALOG);
142 }
143 }
145 /* Create ACL map */
146 foreach($this->acl_map as $acl => $name){
147 $this->acl_mapping[$acl] = _($name);
148 }
150 /* Check if we have an individual user/folder creation syntax
151 */
152 $tmp = $this->config->get_cfg_value("mailUserCreation");
153 if(!empty($tmp)){
154 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<i>".$tmp."</i>",
155 "<b>MAIL:</b> User creation set to");
156 $this->user_id = $tmp;
157 }
158 $tmp = $this->config->get_cfg_value("mailFolderCreation");
159 if(!empty($tmp)){
160 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<i>".$tmp."</i>",
161 "<b>MAIL:</b> Shared folder creation set to");
162 $this->share_id = $tmp;
163 }
165 $this->build_account_id();
166 $this->initial_account_id = $this->account_id;
167 }
170 public function fixAttributesOnLoad()
171 {
172 foreach($this->attributes as $source => $dest){
173 if(isset($this->parent->attrs[$source])){
174 $this->parent->attrs[$dest] = $this->parent->attrs[$source];
175 }
176 if(isset($this->parent->$source)){
177 $this->parent->$dest = $this->parent->$source;
178 }
179 if(isset($this->parent->attrs[$source][0])){
180 $this->parent->saved_attributes[$source] = $this->parent->attrs[$source][0];
181 }
182 }
183 }
186 public function mailEqualsCN()
187 {
188 return($this->mailEqualsCN);
189 }
192 public function fixAttributesOnRemove()
193 {
194 /* Remove objectClasses
195 */
196 if($this->type == "user"){
197 $this->parent->attrs['objectClass'] =
198 array_remove_entries_ics($this->userObjectClasses, $this->parent->attrs['objectClass']);
199 }else{
200 $this->parent->attrs['objectClass'] =
201 array_remove_entries_ics($this->shareObjectClasses, $this->parent->attrs['objectClass']);
202 }
203 foreach($this->attributes as $source => $dest){
204 $this->attrs[$dest] = array();
205 $this->attrs[$source] = array();
206 }
207 }
209 public function fixAttributesOnStore()
210 {
211 foreach($this->attributes as $source => $dest){
212 if(isset($this->parent->attrs[$dest])){
213 $this->parent->attrs[$source] = $this->parent->attrs[$dest ];
214 }
215 if(isset($this->parent->$dest)){
216 $this->parent->$source = $this->parent->$dest;
217 }
218 }
220 if($this->type == "user"){
221 $ocs = $this->userObjectClasses;
222 }else{
223 $ocs = $this->shareObjectClasses;
224 }
225 foreach($ocs as $oc){
226 if(!in_array($oc, $this->parent->attrs['objectClass'])){
227 $this->parent->attrs['objectClass'][] = $oc;
228 }
229 }
231 // Add gosaSharedFolderTarget for groups.
232 $this->build_account_id();
233 if($this->type == "group"){
234 $this->parent->attrs['gosaSharedFolderTarget'] =
235 $this->gosaSharedPrefix.$this->account_id;
236 }
237 }
240 /*! \brief Connect services like imap.
241 Not necessary for the base class.
242 @return Boolean True if this method is connected else false.
243 */
244 public function connect()
245 {
246 $this->reset_error();
247 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Connect method</b>: ".get_class($this));
248 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Current server</b>: ".$this->MailServer);
250 $this->connected = TRUE;
251 return(TRUE);
252 }
255 /*! \brief Returns the connection status of this method.
256 @return Boolean True if this method is connected else false.
257 */
258 public function is_connected()
259 {
260 return($this->connected);
261 }
264 /*! \brief Disconnect this method. Close services like imap connection.
265 Not necessary for the base class.
266 */
267 public function disconnect()
268 {
269 $this->reset_error();
270 if($this->is_connected()){
271 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>MAIL: Disconnect method</b>: ".get_class($this));
272 $this->connected =FALSE;
273 }
274 }
277 /*! \brief Returns true the current object represents a valid account
278 (Some methods may check imap accounts here.)
279 @return Boolean TRUE if this is a valid account else FALSE
280 */
281 public function account_exists()
282 {
283 $this->reset_error();
284 return(TRUE);
285 }
288 /*! \brief Returns the last error occurred
289 @return String The last error message.
290 */
291 public function get_error(){
292 return($this->error);
293 }
296 public function isModifyableMail()
297 {
298 return($this->modifyableMail);
299 }
302 public function isModifyableServer()
303 {
304 return($this->modifyableServer);
305 }
308 /*! \brief Returns TRUE if the action caused an error.
309 @return Boolean TRUE on error else FALSE
310 */
311 public function is_error(){
312 return($this->error != "");
313 }
316 /*! \brief Resets the error message.
317 */
318 public function reset_error(){
319 $this->error = "";
320 }
323 public function get_account_id()
324 {
325 $this->build_account_id();
326 return($this->account_id);
327 }
329 /*! \brief Create a new account id, like 'user/name@domain.com'.
330 */
331 protected function build_account_id()
332 {
333 /* Build account identicator */
334 if($this->type == "user"){
335 $prefix = $this->user_prefix;
336 $acc_string = $this->user_id;
337 }else{
338 $prefix = $this->share_prefix;
339 $acc_string = $this->share_id;
340 }
342 /* Create account prefix and respect "cyrusUseSlashes"
343 Do not replace escaped dots for cyrusUseSlashes.
344 */
345 $uattrib = $this->uattrib;
346 if($this->cyrusUseSlashes){
347 $prefix = preg_replace('/([^\\\\])\./',"\\1/",$prefix);
348 $acc_string = preg_replace('/([^\\\\])\./',"\\1/",$acc_string);
349 }
350 $prefix = preg_replace("/\\\\([\.\/])/","\\1",$prefix);
351 $acc_string = preg_replace("/\\\\([\.\/])/","\\1",$acc_string);
353 $domain = $mailpart = "";
354 $mail = $this->parent->mail;
355 if(preg_match("/\@/",$mail)){
356 list($mailpart,$domain) = split("\@",$mail);
357 }
359 /* Create account_id
360 */
361 $from = array("/%cn%/i","/%uid%/i","/%prefix%/i","/%uattrib%/i","/%domain%/i","/%mailpart%/i","/%mail%/i");
362 $to = array($this->parent->cn,$this->parent->uid,$prefix,$this->parent->$uattrib, $domain, $mailpart,$mail);
363 $acc_id = trim(strtolower(preg_replace($from,$to,$acc_string)));
365 /* Check for not replaced pattern.
366 */
367 if(preg_match("/%/",$acc_id)){
368 $notr = preg_replace("/^[^%]*/","",$acc_id);
369 if(!empty($notr)){
370 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Warning</b>",
371 sprintf("<b>MAIL: WARNING unknown pattern in account creation string '%s' near '%s'</b>", $acc_id, $notr));
373 /* Remove incomprehensible patterns */
374 $acc_id = preg_replace("/%[^%]+%/","",$acc_id);
375 }
376 }
379 if($this->account_id != $acc_id){
380 $this->account_id = $acc_id;
381 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> AccountID generated: <b>".$acc_id."</b>");
382 }
383 }
386 /*! \brief Creates a valid folder id for a given folder name.
387 e.g. $folder_id = "INBOX/test" && $this->account_id = "share/mailbox@domain.de"
388 will result in "share/mailbox/test@domain.de"
389 This function is mainly used to read and write folder permissions.
390 @return String A valid folder id
391 */
392 public function create_folder_id($folder, $type = "")
393 {
395 if(!empty($folder)){
396 $folder = trim(preg_replace("/^INBOX[\.\/]*/i","",$folder));
397 }
398 if(!empty($folder)){
399 $folder = "/".$folder;
400 }
402 /* Build account identicator */
403 if($this->type == "user"){
404 $prefix = $this->user_prefix;
405 $acc_string = $this->user_id;
406 }else{
407 $prefix = $this->share_prefix;
408 $acc_string = $this->share_id;
409 }
411 /* Create account prefix and respect "cyrusUseSlashes"
412 Do not replace escaped dots for cyrusUseSlashes.
413 */
414 $uattrib = $this->uattrib;
415 if($this->cyrusUseSlashes){
416 $prefix = preg_replace('/([^\\\\])\./',"\\1/",$prefix);
417 $acc_string = preg_replace('/([^\\\\])\./',"\\1/",$acc_string);
418 }
419 $prefix = preg_replace("/\\\\([\.\/])/","\\1",$prefix);
420 $acc_string = preg_replace("/\\\\([\.\/])/","\\1",$acc_string);
422 $domain = $mailpart = "";
423 $mail = $this->parent->mail;
424 if(preg_match("/\@/",$mail)){
425 list($mailpart,$domain) = split("\@",$mail);
426 }
428 /* Create account_id
429 */
430 $from = array("/%cn%/i","/%uid%/i","/%prefix%/i","/%uattrib%/i","/%domain%/i","/%mailpart%/i","/%mail%/i");
431 $to = array($this->parent->cn,$this->parent->uid,$prefix,$this->parent->$uattrib, $domain, $mailpart,$mail);
432 $acc_id = trim(strtolower(preg_replace($from,$to,$acc_string)));
434 /* Check for not replaced pattern.
435 */
436 if(preg_match("/%/",$acc_id)){
437 $notr = preg_replace("/^[^%]*/","",$acc_id);
438 if(!empty($notr)){
439 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Warning</b>",
440 sprintf("<b>MAIL: WARNING unknown pattern in account creation string '%s' near '%s'</b>", $acc_id, $notr));
442 /* Remove incomprehensible patterns */
443 $acc_id = preg_replace("/%[^%]+%/","",$acc_id);
444 }
445 }
447 if(preg_match("/\@/",$acc_id)){
448 list($mail,$domain) = split("\@",$acc_id);
449 $str = trim($mail . $folder . "@" . $domain);
450 }else{
451 $str = trim($acc_id . $folder);
452 }
453 return($str) ;
454 }
457 /*! \brief Returns the configured mail method for the given parent object,
458 initialized and read for use.
459 @return mailMethod The configured mailMethod.
460 */
461 public function get_method()
462 {
463 $methods = mailMethod::get_methods();
464 if ($this->config->get_cfg_value("mailmethod") != ""){
465 $method= $this->config->get_cfg_value("mailmethod");
466 $cls = get_correct_class_name("mailMethod$method");
467 if(isset($methods[$cls])){
468 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"", "<b>MAIL:</b> Selected mailMethod: <b>".$cls."</b>");
469 $tmp = new $cls($this->config,$this->parent,$this->type);
470 $tmp->init();
471 return($tmp);
472 }else{
473 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "","<b>MAIL: Invalid mailMethod defined: ".$cls.
474 " falling back to ".get_class($this)."</b>");
476 /* Print out configuration errors directly, we can't catch them everywhere.
477 */
478 msg_dialog::display(_("Configuration error"),
479 sprintf(_("Mail method '%s' is unknown!"), $method), ERROR_DIALOG);
480 }
481 }
483 /* If no valued mailMethod could be detected, return the base class.
484 */
485 $this->init();
486 return($this);
487 }
490 /*! \brief Saves sieve settings
491 */
492 public function saveSieveSettings()
493 {
494 $this->reset_error();
495 return(TRUE);
496 }
499 /*! \brief Creates or Updates the mailAccount represented by this class.
500 */
501 public function updateMailbox()
502 {
503 $this->reset_error();
504 return(TRUE);
505 }
508 /*! \brief Update shared folder dependencies
509 */
510 public function updateSharedFolder()
511 {
512 $this->reset_error();
513 return(TRUE);
514 }
517 /*! \brief Removes the mailbox represented by this class,
518 and update shared folder ACLs .
519 */
520 public function deleteMailbox()
521 {
522 $this->reset_error();
524 @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" ,
525 "<b>MAIL: Remove account</b> from server :".$this->MailServer);
527 return(TRUE);
528 }
531 /*! \brief Returns the used mail attribute (mail,uid)
532 @param String One out of 'mail','uid'
533 */
534 public function getUAttrib()
535 {
536 return($this->uattrib);
537 }
540 /*! \brief Returns the used mail attribute (mail,uid)
541 @param String One out of 'mail','uid'
542 */
543 public function getUAttribValue()
544 {
545 $uattrib = $this->getUAttrib();
546 return($this->parent->$uattrib);
547 }
550 /*! \brief Returns whether the quota settings are enabled or not
551 @return Boolean TRUE if enabled else FALSE
552 */
553 public function quotaEnabled()
554 {
555 return($this->enableQuota);
556 }
559 /*! \brief Returns the used quota
560 @return Integer Quota used.
561 */
562 public function getQuotaUsage()
563 {
564 return(-1);
565 }
568 /*! \brief Returns the quota restrictions.
569 @return Integer Quota restrictions.
570 */
571 public function getQuota($quotaValue)
572 {
573 return($quotaValue);
574 }
577 /*! \brief Sets the mail quota
578 */
579 public function setQuota($number)
580 {
581 if(!is_numeric($number)){
582 $number = (int) $number;
583 if(!$number){
584 $number = 0;
585 }
586 }
587 $this->quotaValue = $number;
588 return(TRUE);
589 }
592 /*! \brief Returns true whether the domain is selectable or not
593 */
594 public function domainSelectionEnabled()
595 {
596 return($this->enableDomainSelection);
597 }
600 /*! \brief Returns a list of configured mail domains
601 @return Array A list of mail domains
602 */
603 public function getMailDomains()
604 {
605 return(array("Unconfigured"));
606 }
609 /*! \brief Returns the used Spamlevels for this mailmethod
610 */
611 public function getSpamLevels()
612 {
613 $spamlevel= array();
614 for ($i= 0; $i<21; $i++){
615 $spamlevel[]= $i;
616 }
617 return($spamlevel);
618 }
621 /*! \brief Returns the list of configured mailbox folders
622 @return Array The mailbox folders.
623 */
624 public function getMailboxList()
625 {
626 return(array("INBOX"));
627 }
630 /*! \brief Returns whether the vacation range is selectable or not
631 @return Boolean TRUE, FALSE
632 */
633 public function vacationRangeEnabled()
634 {
635 return($this->enableVacationRange);
636 }
639 /*! \brief Returns true if the sieveManagement is allowed
640 @return Boolean TRUE, FALSE
641 */
642 public function allowSieveManagement()
643 {
644 return($this->enableSieveManager);
645 }
648 /*! \brief Checks dependencies to other GOsa plugins.
649 */
650 public function accountCreateable(&$reason = ""){
651 return(TRUE);
652 }
655 /*! \brief Checks whether this account is removeable or not.
656 There may be some dependencies left, eg. kolab.
657 */
658 public function accountRemoveable(&$reason = ""){
659 return(TRUE);
660 }
663 /*! \brief Returns all mail servers configured in GOsa
664 that are useable with this mailMethod.
665 @return Array All useable mail servers.
666 */
667 public function getMailServers()
668 {
669 $mailserver = array();
670 $ui = get_userinfo();
671 foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){
672 if( $this->MailServer == $key ||
673 preg_match("/r/",$ui->get_permissions($val['server_dn'],"server/goImapServer",""))){
674 $mailserver[]= $key;
675 }
676 }
677 return($mailserver);
678 }
681 /*! \brief Returns the available mailMethods
682 @return Array A list of all avaialable mailMethods_
683 */
684 static protected function get_methods()
685 {
686 global $class_mapping;
687 $available = array();
688 foreach($class_mapping as $class => $path){
689 if($class == "mailMethod") continue;
690 if(preg_match("/^mailMethod/",$class)){
691 $available[$class] = $class;
692 }
693 }
694 return($available);
695 }
698 /* \brief Some method require special folder types, "kolab" for example.
699 !! Those values are dummy values, the base class doesn't use folder types;
700 @return Array Return folder types.
701 */
702 public function getAvailableFolderTypes()
703 {
704 $ret = array();
705 $ret['CAT'][''] = _("None");
706 $ret['SUB_CAT'][''][''] = _("None");
707 return($ret);
708 }
711 /* \brief Returns the selected folder type.
712 !! Those values are dummy values, the base class doesn't use folder types;
713 @return Array The folde type.
714 */
715 public function getFolderType($default)
716 {
717 return($default);
718 }
721 /* \brief Returns the selected folder type.
722 !! Those values are dummy values, the base class doesn't use folder types;
723 @return Array The folde type.
724 */
725 public function setFolderType($type)
726 {
727 return(TRUE) ;
728 }
731 /*! \brief Returns configured acls
732 */
733 public function getFolderACLs($folder_acls)
734 {
735 /* Merge given ACL with acl mapping
736 This ensures that no ACL will accidentally overwritten by gosa.
737 */
738 foreach($folder_acls as $user => $acl){
739 if(!isset($this->acl_mapping[$acl])){
740 $this->acl_mapping[$acl] = $acl;
741 }
742 }
744 return($folder_acls);
745 }
748 /*! \brief Write ACLs back to imap or what ever
749 */
750 public function setFolderACLs($array)
751 {
752 return(TRUE);
753 }
756 /*! \brief Returns a list of all possible acls.
757 @return Array ACLs.
758 */
759 public function getAclTypes()
760 {
761 return( $this->acl_mapping);
762 }
764 public function folderTypesEnabled()
765 {
766 return($this->enableFolderTypes);
767 }
769 public function allow_remove(&$reason)
770 {
771 return(TRUE);
772 }
775 /*! \brief Returns the configured mailMethod
776 @return String the configured mail method or ""
777 */
778 static public function get_current_method($config)
779 {
780 global $class_mapping;
781 $method= $config->get_cfg_value("mailmethod");
782 $cls = get_correct_class_name("mailMethod$method");
783 foreach($class_mapping as $class => $path){
784 if($class == $cls){
785 return($class);
786 }
787 }
788 return("");
789 }
792 static function quota_to_image($use,$quota)
793 {
794 if($use == -1){
795 return(" "._("Unknown"));
796 }elseif(empty($quota)){
797 return(" "._("Unlimited"));
798 }else{
799 $usage =round(($use/$quota) * 100);
800 return("<img src='progress.php?x=100&y=17&p=$usage'>");
801 }
802 }
805 /*! \brief Returns the default sharedFolder ACLs for this method.
806 @return Array Returns an array containg acls for __member__ and __anyone__
807 */
808 public function getDefaultACLs()
809 {
810 $tmp = $this->default_acls;
811 if(!isset($tmp['__member__'])) $tmp['__member__'] = " ";
812 if(!isset($tmp['__anyone__'])) $tmp['__anyone__'] = " ";
813 return($tmp);
814 }
815 }
818 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
819 ?>