thomascube
2005-11-14 0cbc094164c8a0fa3543e07105e06c129f679805
commit | author | age
4e17e6 1 <?php
T 2
3 /*
4  +-----------------------------------------------------------------------+
5  | program/include/main.inc                                              |
6  |                                                                       |
7  | This file is part of the RoundCube Webmail client                     |
8  | Copyright (C) 2005, RoundCube Dev, - Switzerland                      |
30233b 9  | Licensed under the GNU GPL                                            |
4e17e6 10  |                                                                       |
T 11  | PURPOSE:                                                              |
12  |   Provide basic functions for the webmail package                     |
13  |                                                                       |
14  +-----------------------------------------------------------------------+
15  | Author: Thomas Bruederli <roundcube@gmail.com>                        |
16  +-----------------------------------------------------------------------+
17
18  $Id$
19
20 */
21
22 require_once('lib/des.inc');
23
24
25 // register session and connect to server
26 function rcmail_startup($task='mail')
27   {
28   global $sess_id, $sess_auth, $sess_user_lang;
29   global $CONFIG, $INSTALL_PATH, $BROWSER, $OUTPUT, $_SESSION, $IMAP, $DB, $JS_OBJECT_NAME;
30
31   // check client
32   $BROWSER = rcube_browser();
de2e1e 33
4e17e6 34   // load config file
T 35   include_once('config/main.inc.php');
36   $CONFIG = is_array($rcmail_config) ? $rcmail_config : array();
37   $CONFIG['skin_path'] = $CONFIG['skin_path'] ? preg_replace('/\/$/', '', $CONFIG['skin_path']) : 'skins/default';
38
39   // load db conf
40   include_once('config/db.inc.php');
41   $CONFIG = array_merge($CONFIG, $rcmail_config);
42
fd8c50 43   if (empty($CONFIG['log_dir']))
T 44     $CONFIG['log_dir'] = $INSTALL_PATH.'logs';
45   else
46     $CONFIG['log_dir'] = ereg_replace('\/$', '', $CONFIG['log_dir']);
4e17e6 47
T 48   // set PHP error logging according to config
49   if ($CONFIG['debug_level'] & 1)
50     {
51     ini_set('log_errors', 1);
fd8c50 52     ini_set('error_log', $CONFIG['log_dir'].'/errors');
4e17e6 53     }
T 54   if ($CONFIG['debug_level'] & 4)
55     ini_set('display_errors', 1);
56   else
57     ini_set('display_errors', 0);
7902df 58   
T 59   // set session garbage collecting time according to session_lifetime
60   if (!empty($CONFIG['session_lifetime']))
61     ini_set('session.gc_maxlifetime', ($CONFIG['session_lifetime']+2)*60);
4e17e6 62
T 63
64   // prepare DB connection
f45ec7 65   require_once('include/rcube_'.(empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend']).'.inc');
S 66   
1676e1 67   $DB = new rcube_db($CONFIG['db_dsnw'], $CONFIG['db_dsnr']);
42b113 68   $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql';
4e17e6 69
T 70   // we can use the database for storing session data
36df57 71   // session queries do not work with MDB2
T 72   if ($CONFIG['db_backend']!='mdb2' && is_object($DB) && $DB->db_provider!='sqlite')
4e17e6 73     include_once('include/session.inc');
T 74
75
76   // init session
77   session_start();
78   $sess_id = session_id();
79   
80   // create session and set session vars
81   if (!$_SESSION['client_id'])
82     {
83     $_SESSION['client_id'] = $sess_id;
f3b659 84     $_SESSION['user_lang'] = substr($CONFIG['locale_string'], 0, 2);
4e17e6 85     $_SESSION['auth_time'] = mktime();
T 86     $_SESSION['auth'] = rcmail_auth_hash($sess_id, $_SESSION['auth_time']);
87     unset($GLOBALS['_auth']);
88     }
89
90   // set session vars global
91   $sess_auth = $_SESSION['auth'];
92   $sess_user_lang = $_SESSION['user_lang'];
93
94
95   // overwrite config with user preferences
96   if (is_array($_SESSION['user_prefs']))
97     $CONFIG = array_merge($CONFIG, $_SESSION['user_prefs']);
98
99
100   // reset some session parameters when changing task
101   if ($_SESSION['task'] != $task)
102     unset($_SESSION['page']);
103
104   // set current task to session
105   $_SESSION['task'] = $task;
106
107
108   // create IMAP object
109   if ($task=='mail')
110     rcmail_imap_init();
111
112
113   // set localization
114   if ($CONFIG['locale_string'])
115     setlocale(LC_ALL, $CONFIG['locale_string']);
116   else if ($sess_user_lang)
117     setlocale(LC_ALL, $sess_user_lang);
118
119
120   register_shutdown_function('rcmail_shutdown');
121   }
122   
123
124 // create authorization hash
125 function rcmail_auth_hash($sess_id, $ts)
126   {
127   global $CONFIG;
128   
129   $auth_string = sprintf('rcmail*sess%sR%s*Chk:%s;%s',
130                          $sess_id,
131                          $ts,
132                          $CONFIG['ip_check'] ? $_SERVER['REMOTE_ADDR'] : '***.***.***.***',
133                          $_SERVER['HTTP_USER_AGENT']);
134   
135   if (function_exists('sha1'))
136     return sha1($auth_string);
137   else
138     return md5($auth_string);
139   }
140
141
142
143 // create IMAP object and connect to server
144 function rcmail_imap_init($connect=FALSE)
145   {
146   global $CONFIG, $IMAP;
6dc026 147
4e17e6 148   $IMAP = new rcube_imap();
T 149
7902df 150   // connect with stored session data
T 151   if ($connect)
152     {
153     if (!($conn = $IMAP->connect($_SESSION['imap_host'], $_SESSION['username'], decrypt_passwd($_SESSION['password']), $_SESSION['imap_port'], $_SESSION['imap_ssl'])))
154       show_message('imaperror', 'error');
155       
156     rcmail_set_imap_prop();
157     }
158
6dc026 159   // enable caching of imap data
T 160   if ($CONFIG['enable_caching']===TRUE)
161     $IMAP->set_caching(TRUE);
162
4e17e6 163   if (is_array($CONFIG['default_imap_folders']))
T 164     $IMAP->set_default_mailboxes($CONFIG['default_imap_folders']);
165
166   // set pagesize from config
167   if (isset($CONFIG['pagesize']))
168     $IMAP->set_pagesize($CONFIG['pagesize']);
7902df 169   }
4e17e6 170
T 171
7902df 172 // set root dir and last stored mailbox
T 173 // this must be done AFTER connecting to the server
174 function rcmail_set_imap_prop()
175   {
176   global $CONFIG, $IMAP;
177
178   // set root dir from config
179   if (strlen($CONFIG['imap_root']))
180     $IMAP->set_rootdir($CONFIG['imap_root']);
181
182   if (strlen($_SESSION['mbox']))
183     $IMAP->set_mailbox($_SESSION['mbox']);
184     
185   if (isset($_SESSION['page']))
186     $IMAP->set_page($_SESSION['page']);
4e17e6 187   }
T 188
189
190 // do these things on script shutdown
191 function rcmail_shutdown()
192   {
193   global $IMAP;
194   
195   if (is_object($IMAP))
196     {
197     $IMAP->close();
198     $IMAP->write_cache();
199     }
200   }
201
202
203 // destroy session data and remove cookie
204 function rcmail_kill_session()
205   {
206 /* $sess_name = session_name();
207   if (isset($_COOKIE[$sess_name]))
208    setcookie($sess_name, '', time()-42000, '/');
209 */
210   $_SESSION = array();
211   session_destroy();
212   }
213
214
215 // return correct name for a specific database table
216 function get_table_name($table)
217   {
218   global $CONFIG;
219   
220   // return table name if configured
221   $config_key = 'db_table_'.$table;
222
223   if (strlen($CONFIG[$config_key]))
224     return $CONFIG[$config_key];
225   
226   return $table;
227   }
228
229
230
231 // init output object for GUI and add common scripts
232 function load_gui()
233   {
7cc38e 234   global $CONFIG, $OUTPUT, $COMM_PATH, $JS_OBJECT_NAME, $sess_user_lang;
4e17e6 235
T 236   // init output page
237   $OUTPUT = new rcube_html_page();
238   
239   // add common javascripts
240   $javascript = "var $JS_OBJECT_NAME = new rcube_webmail();\n";
241   $javascript .= "$JS_OBJECT_NAME.set_env('comm_path', '$COMM_PATH');\n";
242
597170 243   if (!empty($GLOBALS['_framed']))
4e17e6 244     $javascript .= "$JS_OBJECT_NAME.set_env('framed', true);\n";
7cc38e 245     
4e17e6 246   $OUTPUT->add_script($javascript);
T 247   $OUTPUT->include_script('program/js/common.js');
7cc38e 248   $OUTPUT->include_script('program/js/app.js');
T 249
250   // set user-selected charset
251   if ($CONFIG['charset'])
252     $OUTPUT->set_charset($CONFIG['charset']);
253   else
254     rcmail_set_locale($sess_user_lang);
10a699 255   
T 256   // add some basic label to client
257   rcube_add_label('loading');
4e17e6 258   }  
7cc38e 259
T 260
261 // set localization charset based on the given language
262 function rcmail_set_locale($lang)
263   {
0cbc09 264   global $OUTPUT, $INSTLL_PATH, $CHARSET;
7cc38e 265   static $rcube_charsets;
T 266
267   if (!$rcube_charsets)
268     @include($INSTLL_PATH.'program/localization/index.inc');
269
270   if (isset($rcube_charsets[$lang]))
0cbc09 271     {
7cc38e 272     $OUTPUT->set_charset($rcube_charsets[$lang]);
0cbc09 273     $CHARSET = $rcube_charsets[$lang];
T 274     }
7cc38e 275   else
0cbc09 276     {
7cc38e 277     $OUTPUT->set_charset('ISO-8859-1');
0cbc09 278     $CHARSET = 'ISO-8859-1';
T 279     }
7cc38e 280   }
4e17e6 281
T 282
283 // perfom login to the IMAP server and to the webmail service
284 function rcmail_login($user, $pass, $host=NULL)
285   {
286   global $CONFIG, $IMAP, $DB, $sess_user_lang;
42b113 287   $user_id = NULL;
4e17e6 288   
T 289   if (!$host)
290     $host = $CONFIG['default_host'];
291
f619de 292   // parse $host URL
T 293   $a_host = parse_url($host);
294   if ($a_host['host'])
295     {
296     $host = $a_host['host'];
297     $imap_ssl = (isset($a_host['scheme']) && in_array($a_host['scheme'], array('ssl','imaps','tls'))) ? TRUE : FALSE;
298     $imap_port = isset($a_host['port']) ? $a_host['port'] : ($imap_ssl ? 993 : $CONFIG['default_port']);
299     }
300
4e17e6 301   // query if user already registered
d7cb77 302   $sql_result = $DB->query("SELECT user_id, username, language, preferences
S 303                             FROM ".get_table_name('users')."
304                             WHERE  mail_host=? AND (username=? OR alias=?)",
305                             $host,
306                             $user,
307                             $user);
4e17e6 308
42b113 309   // user already registered -> overwrite username
4e17e6 310   if ($sql_arr = $DB->fetch_assoc($sql_result))
T 311     {
312     $user_id = $sql_arr['user_id'];
42b113 313     $user = $sql_arr['username'];
T 314     }
315
316   // exit if IMAP login failed
317   if (!($imap_login  = $IMAP->connect($host, $user, $pass, $imap_port, $imap_ssl)))
318     return FALSE;
319
320   // user already registered
321   if ($user_id && !empty($sql_arr))
322     {
4e17e6 323     // get user prefs
T 324     if (strlen($sql_arr['preferences']))
325       {
326       $user_prefs = unserialize($sql_arr['preferences']);
327       $_SESSION['user_prefs'] = $user_prefs;
328       array_merge($CONFIG, $user_prefs);
329       }
330
f3b659 331
4e17e6 332     // set user specific language
T 333     if (strlen($sql_arr['language']))
334       $sess_user_lang = $_SESSION['user_lang'] = $sql_arr['language'];
f3b659 335       
4e17e6 336     // update user's record
d7cb77 337     $DB->query("UPDATE ".get_table_name('users')."
667737 338                 SET    last_login=now()
d7cb77 339                 WHERE  user_id=?",
S 340                 $user_id);
4e17e6 341     }
T 342   // create new system user
343   else if ($CONFIG['auto_create_user'])
344     {
345     $user_id = rcmail_create_user($user, $host);
346     }
347
348   if ($user_id)
349     {
350     $_SESSION['user_id']   = $user_id;
351     $_SESSION['imap_host'] = $host;
7902df 352     $_SESSION['imap_port'] = $imap_port;
T 353     $_SESSION['imap_ssl']  = $imap_ssl;
4e17e6 354     $_SESSION['username']  = $user;
f3b659 355     $_SESSION['user_lang'] = $sess_user_lang;
4e17e6 356     $_SESSION['password']  = encrypt_passwd($pass);
T 357
358     // force reloading complete list of subscribed mailboxes    
359     $IMAP->clear_cache('mailboxes');
360
361     return TRUE;
362     }
363
364   return FALSE;
365   }
366
367
368 // create new entry in users and identities table
369 function rcmail_create_user($user, $host)
370   {
371   global $DB, $CONFIG, $IMAP;
f3b659 372   
d7cb77 373   $DB->query("INSERT INTO ".get_table_name('users')."
S 374               (created, last_login, username, mail_host, language)
667737 375               VALUES (now(), now(), ?, ?, ?)",
d7cb77 376               $user,
S 377               $host,
378               $_SESSION['user_lang']);
4e17e6 379
d7cb77 380   if ($user_id = $DB->insert_id('user_ids'))
4e17e6 381     {
52c1f2 382     $user_email = strstr($user, '@') ? $user : sprintf('%s@%s', $user, $host);
T 383     $user_name = $user!=$user_email ? $user : '';
384     
4e17e6 385     // also create a new identity record
d7cb77 386     $DB->query("INSERT INTO ".get_table_name('identities')."
S 387                 (user_id, `default`, name, email)
388                 VALUES (?, '1', ?, ?)",
389                 $user_id,
390                 $user_name,
391                 $user_email);
4e17e6 392                        
T 393     // get existing mailboxes
394     $a_mailboxes = $IMAP->list_mailboxes();
395     
396     // check if the configured mailbox for sent messages exists
397     if ($CONFIG['sent_mbox'] && !in_array_nocase($CONFIG['sent_mbox'], $a_mailboxes))
398       $IMAP->create_mailbox($CONFIG['sent_mbox'], TRUE);
399
400     // check if the configured mailbox for sent messages exists
401     if ($CONFIG['trash_mbox'] && !in_array_nocase($CONFIG['trash_mbox'], $a_mailboxes))
402       $IMAP->create_mailbox($CONFIG['trash_mbox'], TRUE);
42b113 403     }
T 404   else
405     {
406     raise_error(array('code' => 500,
407                       'type' => 'php',
408                       'line' => __LINE__,
409                       'file' => __FILE__,
410                       'message' => "Failed to create new user"), TRUE, FALSE);
4e17e6 411     }
T 412     
413   return $user_id;
414   }
415
416
10a699 417 // overwrite action variable  
T 418 function rcmail_overwrite_action($action)
419   {
420   global $OUTPUT, $JS_OBJECT_NAME;
421   $GLOBALS['_action'] = $action;
422
423   $OUTPUT->add_script(sprintf("\n%s.set_env('action', '%s');", $JS_OBJECT_NAME, $action));  
424   }
425
426
4e17e6 427 function show_message($message, $type='notice')
T 428   {
429   global $OUTPUT, $JS_OBJECT_NAME, $REMOTE_REQUEST;
430
597170 431   $framed = $GLOBALS['_framed'];
4e17e6 432   $command = sprintf("display_message('%s', '%s');",
T 433                      addslashes(rep_specialchars_output(rcube_label($message))),
434                      $type);
435                      
436   if ($REMOTE_REQUEST)
437     return 'this.'.$command;
438   
439   else
440     $OUTPUT->add_script(sprintf("%s%s.%s",
441                                 $framed ? sprintf('if(parent.%s)parent.', $JS_OBJECT_NAME) : '',
442                                 $JS_OBJECT_NAME,
443                                 $command));
444   
445   // console(rcube_label($message));
446   }
447
448
449 function console($msg, $type=1)
450   {
520c36 451   if ($GLOBALS['REMOTE_REQUEST'])
T 452     print "// $msg\n";
453   else
454     {
455     print $msg;
456     print "\n<hr>\n";
457     }
4e17e6 458   }
T 459
460
461 function encrypt_passwd($pass)
462   {
463   $cypher = des('rcmail?24BitPwDkeyF**ECB', $pass, 1, 0, NULL);
464   return base64_encode($cypher);
465   }
466
467
468 function decrypt_passwd($cypher)
469   {
470   $pass = des('rcmail?24BitPwDkeyF**ECB', base64_decode($cypher), 0, 0, NULL);
471   return trim($pass);
472   }
473
474
475 // send correct response on a remote request
476 function rcube_remote_response($js_code)
477   {
478   send_nocacheing_headers();
479   //header('Content-Type: text/javascript');
480   header('Content-Type: application/x-javascript');
481
482   print '/** remote response ['.date('d/M/Y h:i:s O')."] **/\n";
483   print $js_code;
484   exit;
485   }
486
487
9fee0e 488 // read directory program/localization/ and return a list of available languages
T 489 function rcube_list_languages()
490   {
491   global $CONFIG, $INSTALL_PATH;
492   static $sa_languages = array();
493
494   if (!sizeof($sa_languages))
495     {
7cc38e 496     @include($INSTLL_PATH.'program/localization/index.inc');
9fee0e 497
T 498     if ($dh = @opendir($INSTLL_PATH.'program/localization'))
499       {
500       while (($name = readdir($dh)) !== false)
501         {
502         if ($name{0}=='.' || !is_dir($INSTLL_PATH.'program/localization/'.$name))
503           continue;
504
505         if ($label = $rcube_languages[$name])
506           $sa_languages[$name] = $label ? $label : $name;
507         }
508       closedir($dh);
509       }
510     }
511
512   return $sa_languages;
513   }
514
4e17e6 515
10a699 516 // add a localized label to the client environment
T 517 function rcube_add_label()
518   {
519   global $OUTPUT, $JS_OBJECT_NAME;
520   
521   $arg_list = func_get_args();
522   foreach ($arg_list as $i => $name)
523     $OUTPUT->add_script(sprintf("%s.add_label('%s', '%s');",
524                                 $JS_OBJECT_NAME,
525                                 $name,
526                                 rep_specialchars_output(rcube_label($name), 'js')));  
527   }
528
529
4e17e6 530
T 531 // ************** template parsing and gui functions **************
532
533
534 // return boolean if a specific template exists
535 function template_exists($name)
536   {
537   global $CONFIG, $OUTPUT;
538   $skin_path = $CONFIG['skin_path'];
539
540   // check template file
541   return is_file("$skin_path/templates/$name.html");
542   }
543
544
545 // get page template an replace variable
546 // similar function as used in nexImage
547 function parse_template($name='main', $exit=TRUE)
548   {
549   global $CONFIG, $OUTPUT;
550   $skin_path = $CONFIG['skin_path'];
551
552   // read template file
553   $templ = '';
554   $path = "$skin_path/templates/$name.html";
555
556   if($fp = @fopen($path, 'r'))
557     {
558     $templ = fread($fp, filesize($path));
559     fclose($fp);
560     }
561   else
562     {
563     raise_error(array('code' => 500,
564                       'type' => 'php',
565                       'line' => __LINE__,
566                       'file' => __FILE__,
567                       'message' => "Error loading template for '$name'"), TRUE, TRUE);
568     return FALSE;
569     }
570
571
572   // parse for specialtags
573   $output = parse_rcube_xml($templ);
574   
575   $OUTPUT->write(trim(parse_with_globals($output)), $skin_path);
576
577   if ($exit)
578     exit;
579   }
580
581
582
583 // replace all strings ($varname) with the content of the according global variable
584 function parse_with_globals($input)
585   {
b595c9 586   $GLOBALS['__comm_path'] = $GLOBALS['COMM_PATH'];
4e17e6 587   $output = preg_replace('/\$(__[a-z0-9_\-]+)/e', '$GLOBALS["\\1"]', $input);
T 588   return $output;
589   }
590
591
592
593 function parse_rcube_xml($input)
594   {
595   $output = preg_replace('/<roundcube:([-_a-z]+)\s+([^>]+)>/Uie', "rcube_xml_command('\\1', '\\2')", $input);
596   return $output;
597   }
598
599
600 function rcube_xml_command($command, $str_attrib, $a_attrib=NULL)
601   {
602   global $IMAP, $CONFIG;
603   
604   $attrib = array();
605   $command = strtolower($command);
606
607   preg_match_all('/\s*([-_a-z]+)=["]([^"]+)["]?/i', stripslashes($str_attrib), $regs, PREG_SET_ORDER);
608
609   // convert attributes to an associative array (name => value)
610   if ($regs)
611     foreach ($regs as $attr)
612       $attrib[strtolower($attr[1])] = $attr[2];
613   else if ($a_attrib)
614     $attrib = $a_attrib;
615
616   // execute command
617   switch ($command)
618     {
619     // return a button
620     case 'button':
621       if ($attrib['command'])
622         return rcube_button($attrib);
623       break;
624
625     // show a label
626     case 'label':
627       if ($attrib['name'] || $attrib['command'])
7dd801 628         return rep_specialchars_output(rcube_label($attrib));
4e17e6 629       break;
T 630
631     // create a menu item
632     case 'menu':
633       if ($attrib['command'] && $attrib['group'])
634         rcube_menu($attrib);
635       break;
636
637     // include a file 
638     case 'include':
639       $path = realpath($CONFIG['skin_path'].$attrib['file']);
640       
641       if($fp = @fopen($path, 'r'))
642         {
643         $incl = fread($fp, filesize($path));
644         fclose($fp);        
645         return parse_rcube_xml($incl);
646         }
647       break;
648
649     // return code for a specific application object
650     case 'object':
651       $object = strtolower($attrib['name']);
652
653       if ($object=='loginform')
654         return rcmail_login_form($attrib);
655
656       else if ($object=='message')
657         return rcmail_message_container($attrib);
658
659       // MAIL
660       else if ($object=='mailboxlist' && function_exists('rcmail_mailbox_list'))
661         return rcmail_mailbox_list($attrib);
662         
663       else if ($object=='messages' && function_exists('rcmail_message_list'))
664         return rcmail_message_list($attrib);
665
666       else if ($object=='messagecountdisplay' && function_exists('rcmail_messagecount_display'))
667         return rcmail_messagecount_display($attrib);
668
669       else if ($object=='messageheaders' && function_exists('rcmail_message_headers'))
670         return rcmail_message_headers($attrib);
671
672       else if ($object=='messageattachments' && function_exists('rcmail_message_attachments'))
673         return rcmail_message_attachments($attrib);
674
675       else if ($object=='messagebody' && function_exists('rcmail_message_body'))
676         return rcmail_message_body($attrib);
677         
678       else if ($object=='blockedobjects' && function_exists('rcmail_remote_objects_msg'))
679         return rcmail_remote_objects_msg($attrib);
680
681       else if ($object=='messagecontentframe' && function_exists('rcmail_messagecontent_frame'))
682         return rcmail_messagecontent_frame($attrib);
683
684       else if ($object=='messagepartframe' && function_exists('rcmail_message_part_frame'))
685         return rcmail_message_part_frame($attrib);
686
687       else if ($object=='messagepartcontrols' && function_exists('rcmail_message_part_controls'))
688         return rcmail_message_part_controls($attrib);
689
690       else if ($object=='composeheaders' && function_exists('rcmail_compose_headers'))
691         return rcmail_compose_headers($attrib);
692
693       else if ($object=='composesubject' && function_exists('rcmail_compose_subject'))
694         return rcmail_compose_subject($attrib);
695
696       else if ($object=='composebody' && function_exists('rcmail_compose_body'))
697         return rcmail_compose_body($attrib);
698
699       else if ($object=='composeattachmentlist' && function_exists('rcmail_compose_attachment_list'))
700         return rcmail_compose_attachment_list($attrib);
701
702       else if ($object=='composeattachmentform' && function_exists('rcmail_compose_attachment_form'))
703         return rcmail_compose_attachment_form($attrib);
704
705       else if ($object=='composeattachment' && function_exists('rcmail_compose_attachment_field'))
706         return rcmail_compose_attachment_field($attrib);
707
708       else if ($object=='priorityselector' && function_exists('rcmail_priority_selector'))
709         return rcmail_priority_selector($attrib);
710         
711       else if ($object=='priorityselector' && function_exists('rcmail_priority_selector'))
712         return rcmail_priority_selector($attrib);
713
714
715       // ADDRESS BOOK
716       else if ($object=='addresslist' && function_exists('rcmail_contacts_list'))
717         return rcmail_contacts_list($attrib);
718
719       else if ($object=='addressframe' && function_exists('rcmail_contact_frame'))
720         return rcmail_contact_frame($attrib);
721
722       else if ($object=='recordscountdisplay' && function_exists('rcmail_rowcount_display'))
723         return rcmail_rowcount_display($attrib);
724         
725       else if ($object=='contactdetails' && function_exists('rcmail_contact_details'))
726         return rcmail_contact_details($attrib);
727
728       else if ($object=='contacteditform' && function_exists('rcmail_contact_editform'))
729         return rcmail_contact_editform($attrib);
730
731
732       // USER SETTINGS
733       else if ($object=='userprefs' && function_exists('rcmail_user_prefs_form'))
734         return rcmail_user_prefs_form($attrib);
735
736       else if ($object=='itentitieslist' && function_exists('rcmail_identities_list'))
737         return rcmail_identities_list($attrib);
738
739       else if ($object=='identityframe' && function_exists('rcmail_identity_frame'))
740         return rcmail_identity_frame($attrib);
741
742       else if ($object=='identityform' && function_exists('rcube_identity_form'))
743         return rcube_identity_form($attrib);
744
745       else if ($object=='foldersubscription' && function_exists('rcube_subscription_form'))
746         return rcube_subscription_form($attrib);
747
748       else if ($object=='createfolder' && function_exists('rcube_create_folder_form'))
749         return rcube_create_folder_form($attrib);
750
751
752       else if ($object=='pagetitle')
753         {
754         $task = $GLOBALS['_task'];
755         if ($task=='mail' && isset($GLOBALS['MESSAGE']['subject']))
756           return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['MESSAGE']['subject']);
757         else if (isset($GLOBALS['PAGE_TITLE']))
758           return rep_specialchars_output("RoundCube|Mail :: ".$GLOBALS['PAGE_TITLE']);
759         else if ($task=='mail' && ($mbox_name = $IMAP->get_mailbox_name()))
a95e0e 760           return "RoundCube|Mail :: ".rep_specialchars_output(UTF7DecodeString($mbox_name), 'html', 'all');
4e17e6 761         else
T 762           return "RoundCube|Mail :: $task";
763         }
764
765       else if ($object=='about')
766         return '';
767
768       break;
769     }
770
771   return '';
772   }
773
774
775 // create and register a button
776 function rcube_button($attrib)
777   {
14eafe 778   global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $BROWSER;
4e17e6 779   static $sa_buttons = array();
T 780   static $s_button_count = 100;
781   
782   $skin_path = $CONFIG['skin_path'];
783   
784   if (!($attrib['command'] || $attrib['name']))
785     return '';
786
787   // try to find out the button type
788   if ($attrib['type'])
789     $attrib['type'] = strtolower($attrib['type']);
790   else
791     $attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $arg['imagect']) ? 'image' : 'link';
792   
793   
794   $command = $attrib['command'];
795   
796   // take the button from the stack
797   if($attrib['name'] && $sa_buttons[$attrib['name']])
798     $attrib = $sa_buttons[$attrib['name']];
799
800   // add button to button stack
801   else if($attrib['image'] || $arg['imagect'] || $attrib['imagepas'] || $attrib['class'])
802     {
803     if(!$attrib['name'])
804       $attrib['name'] = $command;
805
806     if (!$attrib['image'])
807       $attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact'];
808
809     $sa_buttons[$attrib['name']] = $attrib;
810     }
811
812   // get saved button for this command/name
813   else if ($command && $sa_buttons[$command])
814     $attrib = $sa_buttons[$command];
815
816   //else
817   //  return '';
818
819
820   // set border to 0 because of the link arround the button
821   if ($attrib['type']=='image' && !isset($attrib['border']))
822     $attrib['border'] = 0;
823     
824   if (!$attrib['id'])
825     $attrib['id'] =  sprintf('rcmbtn%d', $s_button_count++);
826
827   // get localized text for labels and titles
828   if ($attrib['title'])
829     $attrib['title'] = rep_specialchars_output(rcube_label($attrib['title']));
830   if ($attrib['label'])
831     $attrib['label'] = rep_specialchars_output(rcube_label($attrib['label']));
832
833   if ($attrib['alt'])
834     $attrib['alt'] = rep_specialchars_output(rcube_label($attrib['alt']));
14eafe 835
T 836   // set title to alt attribute for IE browsers
837   if ($BROWSER['ie'] && $attrib['title'] && !$attrib['alt'])
838     {
839     $attrib['alt'] = $attrib['title'];
840     unset($attrib['title']);
841     }
842
4e17e6 843   // add empty alt attribute for XHTML compatibility
T 844   if (!isset($attrib['alt']))
845     $attrib['alt'] = '';
846
847
848   // register button in the system
849   if ($attrib['command'])
850     $OUTPUT->add_script(sprintf("%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
851                                 $JS_OBJECT_NAME,
852                                 $command,
853                                 $attrib['id'],
854                                 $attrib['type'],
855                                 $attrib['imageact'] ? $skin_path.$attrib['imageact'] : $attrib['classact'],
856                                 $attirb['imagesel'] ? $skin_path.$attirb['imagesel'] : $attrib['classsel'],
857                                 $attrib['imageover'] ? $skin_path.$attrib['imageover'] : ''));
858
859   // overwrite attributes
860   if (!$attrib['href'])
861     $attrib['href'] = '#';
862
863   if ($command)
864     $attrib['onclick'] = sprintf("return %s.command('%s','%s',this)", $JS_OBJECT_NAME, $command, $attrib['prop']);
865     
866   if ($command && $attrib['imageover'])
867     {
868     $attrib['onmouseover'] = sprintf("return %s.button_over('%s','%s')", $JS_OBJECT_NAME, $command, $attrib['id']);
869     $attrib['onmouseout'] = sprintf("return %s.button_out('%s','%s')", $JS_OBJECT_NAME, $command, $attrib['id']);
870     }
871
872
873   $out = '';
874
875   // generate image tag
876   if ($attrib['type']=='image')
877     {
878     $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'width', 'height', 'border', 'hspace', 'vspace', 'alt'));
879     $img_tag = sprintf('<img src="%%s"%s />', $attrib_str);
880     $btn_content = sprintf($img_tag, $skin_path.$attrib['image']);
881     if ($attrib['label'])
882       $btn_content .= ' '.$attrib['label'];
883     
884     $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'title');
885     }
886   else if ($attrib['type']=='link')
887     {
888     $btn_content = $attrib['label'] ? $attrib['label'] : $attrib['command'];
889     $link_attrib = array('href', 'onclick', 'title', 'id', 'class', 'style');
890     }
891   else if ($attrib['type']=='input')
892     {
893     $attrib['type'] = 'button';
894     
895     if ($attrib['label'])
896       $attrib['value'] = $attrib['label'];
897       
898     $attrib_str = create_attrib_string($attrib, array('type', 'value', 'onclick', 'id', 'class', 'style'));
899     $out = sprintf('<input%s disabled />', $attrib_str);
900     }
901
902   // generate html code for button
903   if ($btn_content)
904     {
905     $attrib_str = create_attrib_string($attrib, $link_attrib);
906     $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
907     }
908
909   return $out;
910   }
911
912
913 function rcube_menu($attrib)
914   {
915   
916   return '';
917   }
918
919
920
921 function rcube_table_output($attrib, $sql_result, $a_show_cols, $id_col)
922   {
923   global $DB;
924   
925   // allow the following attributes to be added to the <table> tag
926   $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'cellpadding', 'cellspacing', 'border', 'summary'));
927   
928   $table = '<table' . $attrib_str . ">\n";
929     
930   // add table title
931   $table .= "<thead><tr>\n";
932
933   foreach ($a_show_cols as $col)
1038d5 934     $table .= '<td class="'.$col.'">' . rep_specialchars_output(rcube_label($col)) . "</td>\n";
4e17e6 935
T 936   $table .= "</tr></thead>\n<tbody>\n";
937   
938   $c = 0;
939   while ($sql_result && ($sql_arr = $DB->fetch_assoc($sql_result)))
940     {
941     $zebra_class = $c%2 ? 'even' : 'odd';
942
943     $table .= sprintf('<tr id="rcmrow%d" class="contact '.$zebra_class.'">'."\n", $sql_arr[$id_col]);
944
945     // format each col
946     foreach ($a_show_cols as $col)
947       {
948       $cont = rep_specialchars_output($sql_arr[$col]);
949       $table .= '<td class="'.$col.'">' . $cont . "</td>\n";
950       }
951
952     $table .= "</tr>\n";
953     $c++;
954     }
955
956   // complete message table
957   $table .= "</tbody></table>\n";
958   
959   return $table;
960   }
961
962
963
964 function rcmail_get_edit_field($col, $value, $attrib, $type='text')
965   {
966   $fname = '_'.$col;
967   $attrib['name'] = $fname;
968   
969   if ($type=='checkbox')
970     {
971     $attrib['value'] = '1';
972     $input = new checkbox($attrib);
973     }
974   else if ($type=='textarea')
975     {
976     $attrib['cols'] = $attrib['size'];
977     $input = new textarea($attrib);
978     }
979   else
980     $input = new textfield($attrib);
981
982   // use value from post
597170 983   if (!empty($_POST[$fname]))
4e17e6 984     $value = $_POST[$fname];
T 985
986   $out = $input->show($value);
987          
988   return $out;
989   }
990
991
992 function create_attrib_string($attrib, $allowed_attribs=array('id', 'class', 'style'))
993   {
994   // allow the following attributes to be added to the <iframe> tag
995   $attrib_str = '';
996   foreach ($allowed_attribs as $a)
997     if (isset($attrib[$a]))
998       $attrib_str .= sprintf(' %s="%s"', $a, $attrib[$a]);
999
1000   return $attrib_str;
1001   }
1002
1003
1004
1005 function format_date($date, $format=NULL)
1006   {
1007   global $CONFIG, $sess_user_lang;
1008   
1009   if (is_numeric($date))
1010     $ts = $date;
b076a4 1011   else if (!empty($date))
4e17e6 1012     $ts = strtotime($date);
b076a4 1013   else
T 1014     return '';
4e17e6 1015
T 1016   // convert time to user's timezone
1017   $timestamp = $ts - date('Z', $ts) + ($CONFIG['timezone'] * 3600);
1018   
1019   // get current timestamp in user's timezone
1020   $now = time();  // local time
1021   $now -= (int)date('Z'); // make GMT time
1022   $now += ($CONFIG['timezone'] * 3600); // user's time
1023
1024   $day_secs = 60*((int)date('H', $now)*60 + (int)date('i', $now));
1025   $week_secs = 60 * 60 * 24 * 7;
1026   $diff = $now - $timestamp;
1027
30233b 1028   // define date format depending on current time  
T 1029   if ($CONFIG['prettydate'] && !$format && $diff < $day_secs)
4e17e6 1030     return sprintf('%s %s', rcube_label('today'), date('H:i', $timestamp));
30233b 1031   else if ($CONFIG['prettydate'] && !$format && $diff < $week_secs)
4e17e6 1032     $format = $CONFIG['date_short'] ? $CONFIG['date_short'] : 'D H:i';
T 1033   else if (!$format)
1034     $format = $CONFIG['date_long'] ? $CONFIG['date_long'] : 'd.m.Y H:i';
1035
1036
1037   // parse format string manually in order to provide localized weekday and month names
1038   // an alternative would be to convert the date() format string to fit with strftime()
1039   $out = '';
1040   for($i=0; $i<strlen($format); $i++)
1041     {
1042     if ($format{$i}=='\\')  // skip escape chars
1043       continue;
1044     
1045     // write char "as-is"
1046     if ($format{$i}==' ' || $format{$i-1}=='\\')
1047       $out .= $format{$i};
1048     // weekday (short)
1049     else if ($format{$i}=='D')
1050       $out .= rcube_label(strtolower(date('D', $timestamp)));
1051     // weekday long
1052     else if ($format{$i}=='l')
1053       $out .= rcube_label(strtolower(date('l', $timestamp)));
1054     // month name (short)
1055     else if ($format{$i}=='M')
1056       $out .= rcube_label(strtolower(date('M', $timestamp)));
1057     // month name (long)
1058     else if ($format{$i}=='F')
1059       $out .= rcube_label(strtolower(date('F', $timestamp)));
1060     else
1061       $out .= date($format{$i}, $timestamp);
1062     }
1063   
1064   return $out;
1065   }
1066
1067
1068 // ************** functions delivering gui objects **************
1069
1070
1071
1072 function rcmail_message_container($attrib)
1073   {
1074   global $OUTPUT, $JS_OBJECT_NAME;
1075
1076   if (!$attrib['id'])
1077     $attrib['id'] = 'rcmMessageContainer';
1078
1079   // allow the following attributes to be added to the <table> tag
1080   $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id'));
1081   $out = '<div' . $attrib_str . "></div>";
1082   
1083   $OUTPUT->add_script("$JS_OBJECT_NAME.gui_object('message', '$attrib[id]');");
1084   
1085   return $out;
1086   }
1087
1088
1089 // return code for the webmail login form
1090 function rcmail_login_form($attrib)
1091   {
1092   global $CONFIG, $OUTPUT, $JS_OBJECT_NAME, $SESS_HIDDEN_FIELD;
1093   
1094   $labels = array();
1095   $labels['user'] = rcube_label('username');
1096   $labels['pass'] = rcube_label('password');
1097   $labels['host'] = rcube_label('server');
1098   
1099   $input_user = new textfield(array('name' => '_user', 'size' => 30));
1100   $input_pass = new passwordfield(array('name' => '_pass', 'size' => 30));
1101   $input_action = new hiddenfield(array('name' => '_action', 'value' => 'login'));
1102     
1103   $fields = array();
1104   $fields['user'] = $input_user->show($_POST['_user']);
1105   $fields['pass'] = $input_pass->show();
1106   $fields['action'] = $input_action->show();
1107   
1108   if (is_array($CONFIG['default_host']))
1109     {
1110     $select_host = new select(array('name' => '_host'));
42b113 1111     
T 1112     foreach ($CONFIG['default_host'] as $key => $value)
1113       $select_host->add($value, (is_numeric($key) ? $value : $key));
1114       
4e17e6 1115     $fields['host'] = $select_host->show($_POST['_host']);
T 1116     }
1117   else if (!strlen($CONFIG['default_host']))
1118     {
1119     $input_host = new textfield(array('name' => '_host', 'size' => 30));
1120     $fields['host'] = $input_host->show($_POST['_host']);
1121     }
1122
1123   $form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
1124   $form_start = !strlen($attrib['form']) ? '<form name="form" action="./" method="post">' : '';
1125   $form_end = !strlen($attrib['form']) ? '</form>' : '';
1126   
1127   if ($fields['host'])
1128     $form_host = <<<EOF
1129     
1130 </tr><tr>
1131
1132 <td class="title">$labels[host]</td>
1133 <td>$fields[host]</td>
1134
1135 EOF;
1136
1137   $OUTPUT->add_script("$JS_OBJECT_NAME.gui_object('loginform', '$form_name');");
1138   
1139   $out = <<<EOF
1140 $form_start
1141 $SESS_HIDDEN_FIELD
1142 $fields[action]
1143 <table><tr>
1144
1145 <td class="title">$labels[user]</td>
1146 <td>$fields[user]</td>
1147
1148 </tr><tr>
1149
1150 <td class="title">$labels[pass]</td>
1151 <td>$fields[pass]</td>
1152 $form_host
1153 </tr></table>
1154 $form_end
1155 EOF;
1156
1157   return $out;
1158   }
1159
1160
1161 ?>