summaryrefslogtreecommitdiff
path: root/program/include
diff options
context:
space:
mode:
Diffstat (limited to 'program/include')
-rw-r--r--program/include/bugs.inc4
-rw-r--r--program/include/html.php642
-rwxr-xr-xprogram/include/iniset.php98
-rw-r--r--program/include/main.inc89
-rw-r--r--program/include/rcmail_template.inc948
-rw-r--r--program/include/rcube_browser.php75
-rw-r--r--program/include/rcube_contacts.php (renamed from program/include/rcube_contacts.inc)57
-rw-r--r--program/include/rcube_db.php (renamed from program/include/rcube_db.inc)11
-rw-r--r--program/include/rcube_html.inc667
-rw-r--r--program/include/rcube_html_page.php256
-rw-r--r--program/include/rcube_imap.php (renamed from program/include/rcube_imap.inc)5
-rw-r--r--program/include/rcube_json_output.php237
-rw-r--r--program/include/rcube_ldap.php (renamed from program/include/rcube_ldap.inc)6
-rw-r--r--program/include/rcube_mail_mime.php206
-rw-r--r--program/include/rcube_mdb2.php (renamed from program/include/rcube_mdb2.inc)11
-rw-r--r--program/include/rcube_result_set.php74
-rw-r--r--program/include/rcube_shared.inc12
-rwxr-xr-xprogram/include/rcube_template.php1004
-rw-r--r--program/include/rcube_user.php (renamed from program/include/rcube_user.inc)0
19 files changed, 2648 insertions, 1754 deletions
diff --git a/program/include/bugs.inc b/program/include/bugs.inc
index 9d98ef45b..78808c321 100644
--- a/program/include/bugs.inc
+++ b/program/include/bugs.inc
@@ -66,7 +66,7 @@ function raise_error($arg=array(), $log=false, $terminate=false)
*/
function log_bug($arg_arr)
{
- global $CONFIG, $INSTALL_PATH;
+ global $CONFIG;
$program = $arg_arr['type']=='xpath' ? 'XPath' : strtoupper($arg_arr['type']);
// write error to local log file
@@ -81,7 +81,7 @@ function log_bug($arg_arr)
$arg_arr['line']);
if (empty($CONFIG['log_dir']))
- $CONFIG['log_dir'] = $INSTALL_PATH.'logs';
+ $CONFIG['log_dir'] = INSTALL_PATH.'logs';
// try to open specific log file for writing
if ($fp = @fopen($CONFIG['log_dir'].'/errors', 'a'))
diff --git a/program/include/html.php b/program/include/html.php
new file mode 100644
index 000000000..8af1b1f9d
--- /dev/null
+++ b/program/include/html.php
@@ -0,0 +1,642 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/html.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2005-2008, RoundCube Dev, - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Helper class to create valid XHTML code |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: $
+
+ */
+
+
+/**
+ * Class for HTML code creation
+ *
+ * @package HTML
+ */
+class html
+{
+ protected $tagname;
+ protected $attrib = array();
+ protected $allowed;
+ protected $content;
+
+ protected static $common_attrib = array('id','class','style','title','align');
+ public static $containers = array('div','span','p','h1','h2','h3','form','textarea');
+ public static $lc_tags = true;
+
+ /**
+ * Constructor
+ *
+ * @param array Hash array with tag attributes
+ */
+ public function __construct($attrib = array())
+ {
+ if (is_array($attrib)) {
+ $this->attrib = $attrib;
+ }
+ }
+
+ /**
+ * Return the tag code
+ *
+ * @return string The finally composed HTML tag
+ */
+ public function show()
+ {
+ return self::tag($this->tagname, $this->attrib, $this->content, $this->allowed);
+ }
+
+ /****** STATIC METHODS *******/
+
+ /**
+ * Generic method to create a HTML tag
+ *
+ * @param string Tag name
+ * @param array Tag attributes as key/value pairs
+ * @param string Optinal Tag content (creates a container tag)
+ * @param array List with allowed attributes, omit to allow all
+ * @return string The XHTML tag
+ */
+ public static function tag($tagname, $attrib = array(), $content = null, $allowed_attrib = null)
+ {
+ $inline_tags = array('a','span','img');
+ $suffix = $attrib['nl'] || ($content && $attrib['nl'] !== false && !in_array($tagname, $inline_tags)) ? "\n" : '';
+
+ $tagname = self::$lc_tags ? strtolower($tagname) : $tagname;
+ if ($content || in_array($tagname, self::$containers)) {
+ $templ = $attrib['noclose'] ? "<%s%s>%s" : "<%s%s>%s</%s>%s";
+ unset($attrib['noclose']);
+ return sprintf($templ, $tagname, self::attrib_string($attrib, $allowed_attrib), $content, $tagname, $suffix);
+ }
+ else {
+ return sprintf("<%s%s />%s", $tagname, self::attrib_string($attrib, $allowed_attrib), $suffix);
+ }
+ }
+
+ /**
+ * Derrived method for <div> containers
+ *
+ * @param mixed Hash array with tag attributes or string with class name
+ * @param string Div content
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function div($attr = null, $cont = null)
+ {
+ if (is_string($attr)) {
+ $attr = array('class' => $attr);
+ }
+ return self::tag('div', $attr, $cont, self::$common_attrib);
+ }
+
+ /**
+ * Derrived method for <p> blocks
+ *
+ * @param mixed Hash array with tag attributes or string with class name
+ * @param string Paragraph content
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function p($attr = null, $cont = null)
+ {
+ if (is_string($attr)) {
+ $attr = array('class' => $attr);
+ }
+ return self::tag('p', $attr, $cont, self::$common_attrib);
+ }
+
+ /**
+ * Derrived method to create <img />
+ *
+ * @param mixed Hash array with tag attributes or string with image source (src)
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function img($attr = null)
+ {
+ if (is_string($attr)) {
+ $attr = array('src' => $attr);
+ }
+ return self::tag('img', $attr + array('alt' => ''), null, array_merge(self::$common_attrib, array('src','alt','width','height','border','usemap')));
+ }
+
+ /**
+ * Derrived method for link tags
+ *
+ * @param mixed Hash array with tag attributes or string with link location (href)
+ * @param string Link content
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function a($attr, $cont)
+ {
+ if (is_string($attr)) {
+ $attr = array('href' => $attr);
+ }
+ return self::tag('a', $attr, $cont, array_merge(self::$common_attrib, array('href','target','name','onclick','onmouseover','onmouseout')));
+ }
+
+ /**
+ * Derrived method for inline span tags
+ *
+ * @param mixed Hash array with tag attributes or string with class name
+ * @param string Tag content
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function span($attr, $cont)
+ {
+ if (is_string($attr)) {
+ $attr = array('class' => $attr);
+ }
+ return self::tag('span', $attr, $cont, self::$common_attrib);
+ }
+
+ /**
+ * Derrived method for form element labels
+ *
+ * @param mixed Hash array with tag attributes or string with 'for' attrib
+ * @param string Tag content
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function label($attr, $cont)
+ {
+ if (is_string($attr)) {
+ $attr = array('for' => $attr);
+ }
+ return self::tag('label', $attr, $cont, array_merge(self::$common_attrib, array('for')));
+ }
+
+ /**
+ * Derrived method for line breaks
+ *
+ * @return string HTML code
+ * @see html::tag()
+ */
+ public static function br()
+ {
+ return self::tag('br');
+ }
+
+ /**
+ * Create string with attributes
+ *
+ * @param array Associative arry with tag attributes
+ * @param array List of allowed attributes
+ * @return string Valid attribute string
+ */
+ public static function attrib_string($attrib = array(), $allowed = null)
+ {
+ if (empty($attrib)) {
+ return '';
+ }
+
+ $allowed_f = array_flip((array)$allowed);
+ $attrib_arr = array();
+ foreach ($attrib as $key => $value) {
+ // skip size if not numeric
+ if (($key=='size' && !is_numeric($value))) {
+ continue;
+ }
+
+ // ignore "internal" or not allowed attributes
+ if ($key == 'nl' || ($allowed && !isset($allowed_f[$key])) || $value === null) {
+ continue;
+ }
+
+ // skip empty eventhandlers
+ if (preg_match('/^on[a-z]+/', $key) && !$value) {
+ continue;
+ }
+
+ // attributes with no value
+ if (in_array($key, array('checked', 'multiple', 'disabled', 'selected'))) {
+ if ($value) {
+ $attrib_arr[] = sprintf('%s="%s"', $key, $key);
+ }
+ }
+ else if ($key=='value') {
+ $attrib_arr[] = sprintf('%s="%s"', $key, Q($value, 'strict', false));
+ }
+ else {
+ $attrib_arr[] = sprintf('%s="%s"', $key, Q($value));
+ }
+ }
+ return count($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
+ }
+}
+
+/**
+ * Class to create an HTML input field
+ *
+ * @package HTML
+ */
+class html_inputfield extends html
+{
+ protected $tagname = 'input';
+ protected $type = 'text';
+
+ public function __construct($attrib = array())
+ {
+ if (is_array($attrib)) {
+ $this->attrib = $attrib;
+ }
+
+ if ($attrib['type']) {
+ $this->type = $attrib['type'];
+ }
+
+ if ($attrib['newline']) {
+ $this->newline = true;
+ }
+ }
+
+ /**
+ * Compose input tag
+ *
+ * @param string Field value
+ * @param array Additional attributes to override
+ * @return string HTML output
+ */
+ public function show($value = null, $attrib = null)
+ {
+ // overwrite object attributes
+ if (is_array($attrib)) {
+ $this->attrib = array_merge($this->attrib, $attrib);
+ }
+
+ // set value attribute
+ if ($value !== null) {
+ $this->attrib['value'] = $value;
+ }
+ // set type
+ $this->attrib['type'] = $this->type;
+ return parent::show();
+ }
+}
+
+/**
+ * Class to create an HTML password field
+ *
+ * @package HTML
+ */
+class html_passwordfield extends html_inputfield
+{
+ protected $type = 'password';
+}
+
+/**
+ * Class to create an hidden HTML input field
+ *
+ * @package HTML
+ */
+
+class html_hiddenfield extends html_inputfield
+{
+ protected $type = 'hidden';
+ protected $fields_arr = array();
+ protected $newline = true;
+
+ /**
+ * Constructor
+ *
+ * @param array Named tag attributes
+ */
+ public function __construct($attrib = null)
+ {
+ if (is_array($attrib)) {
+ $this->add($attrib);
+ }
+ }
+
+ /**
+ * Add a hidden field to this instance
+ *
+ * @param array Named tag attributes
+ */
+ public function add($attrib)
+ {
+ $this->fields_arr[] = $attrib;
+ }
+
+ /**
+ * Create HTML code for the hidden fields
+ *
+ * @return string Final HTML code
+ */
+ public function show()
+ {
+ $out = '';
+ foreach ($this->fields_arr as $attrib) {
+ $out .= self::tag($this->tagname, array('type' => $this->type) + $attrib);
+ }
+ return $out;
+ }
+}
+
+/**
+ * Class to create HTML radio buttons
+ *
+ * @package HTML
+ */
+class html_radiobutton extends html_inputfield
+{
+ protected $type = 'radio';
+
+ /**
+ * Get HTML code for this object
+ *
+ * @param string Value of the checked field
+ * @param array Additional attributes to override
+ * @return string HTML output
+ */
+ public function show($value = '', $attrib = null)
+ {
+ // overwrite object attributes
+ if (is_array($attrib)) {
+ $this->attrib = array_merge($this->attrib, $attrib);
+ }
+
+ // set value attribute
+ $this->attrib['checked'] = ($value && (string)$value == (string)$this->attrib['value']);
+
+ return parent::show();
+ }
+}
+
+/**
+ * Class to create HTML checkboxes
+ *
+ * @package HTML
+ */
+class html_checkbox extends html_inputfield
+{
+ protected $type = 'checkbox';
+
+ /**
+ * Get HTML code for this object
+ *
+ * @param string Value of the checked field
+ * @param array Additional attributes to override
+ * @return string HTML output
+ */
+ public function show($value = '', $attrib = null)
+ {
+ // overwrite object attributes
+ if (is_array($attrib)) {
+ $this->attrib = array_merge($this->attrib, $attrib);
+ }
+
+ // set value attribute
+ $this->attrib['checked'] = ($value && (string)$value == (string)$this->attrib['value']);
+
+ return parent::show();
+ }
+}
+
+/**
+ * Class to create an HTML textarea
+ *
+ * @package HTML
+ */
+class html_textarea extends html
+{
+ protected $tagname = 'textarea';
+ protected $allowed_attrib = array('name','rows','cols','wrap');
+
+ /**
+ * Get HTML code for this object
+ *
+ * @param string Textbox value
+ * @param array Additional attributes to override
+ * @return string HTML output
+ */
+ public function show($value = '', $attrib = null)
+ {
+ // overwrite object attributes
+ if (is_array($attrib)) {
+ $this->attrib = array_merge($this->attrib, $attrib);
+ }
+
+ // take value attribute as content
+ if ($value == '') {
+ $value = $this->attrib['value'];
+ }
+
+ // make shure we don't print the value attribute
+ if (isset($this->attrib['value'])) {
+ unset($this->attrib['value']);
+ }
+
+ if (!empty($value) && !isset($this->attrib['mce_editable'])) {
+ $value = Q($value, 'strict', FALSE);
+ }
+ return self::tag($this->tagname, $this->attrib, Q($value), array_merge(self::$common_attrib, $this->allowed_attrib));
+ }
+}
+
+/**
+ * Builder for HTML drop-down menus
+ * Syntax:<pre>
+ * // create instance. arguments are used to set attributes of select-tag
+ * $select = new html_select(array('name' => 'fieldname'));
+ *
+ * // add one option
+ * $select->add('Switzerland', 'CH');
+ *
+ * // add multiple options
+ * $select->add(array('Switzerland','Germany'), array('CH','DE'));
+ *
+ * // generate pulldown with selection 'Switzerland' and return html-code
+ * // as second argument the same attributes available to instanciate can be used
+ * print $select->show('CH');
+ * </pre>
+ *
+ * @package HTML
+ */
+class html_select extends html
+{
+ protected $tagname = 'select';
+ protected $options = array();
+
+ /**
+ * Add a new option to this drop-down
+ *
+ * @param mixed Option name or array with option names
+ * @param mixed Option value or array with option values
+ */
+ public function add($names, $values = null)
+ {
+ if (is_array($names)) {
+ foreach ($names as $i => $text) {
+ $this->options[] = array('text' => $text, 'value' => $values[$i]);
+ }
+ }
+ else {
+ $this->options[] = array('text' => $names, 'value' => $values);
+ }
+ }
+
+
+ /**
+ * Get HTML code for this object
+ *
+ * @param string Value of the selection option
+ * @param array Additional attributes to override
+ * @return string HTML output
+ */
+ public function show($select = array(), $attrib = null)
+ {
+ // overwrite object attributes
+ if (is_array($attrib)) {
+ $this->attrib = array_merge($this->attrib, $attrib);
+ }
+
+ $this->content = "\n";
+ $select = (array)$select;
+ foreach ($this->options as $option) {
+ $attr = array(
+ 'value' => $option['value'],
+ 'selected' => ((!empty($option['value']) && in_array($option['value'], $select, true)) ||
+ (in_array($option['text'], $select, TRUE))) ? 1 : null);
+
+ $this->content .= self::tag('option', $attr, Q($option['text']));
+ }
+ return parent::show();
+ }
+}
+
+
+/**
+ * Class to build an HTML table
+ *
+ * @package HTML
+ */
+class html_table extends html
+{
+ protected $tagname = 'table';
+ protected $allowed = array('id','class','style','width','summary','cellpadding','cellspacing','border');
+ private $header = array();
+ private $rows = array();
+ private $rowindex = 0;
+ private $colindex = 0;
+
+
+ public function __construct($attrib = array())
+ {
+ $this->attrib = array_merge($attrib, array('summary' => '', 'border' => 0));
+ }
+
+ /**
+ * Add a table cell
+ *
+ * @param array Cell attributes
+ * @param string Cell content
+ */
+ public function add($attr, $cont)
+ {
+ if (is_string($attr)) {
+ $attr = array('class' => $attr);
+ }
+
+ $cell = new stdClass;
+ $cell->attrib = $attr;
+ $cell->content = $cont;
+
+ $this->rows[$this->rowindex]->cells[$this->colindex] = $cell;
+ $this->colindex++;
+
+ if ($this->attrib['cols'] && $this->colindex == $this->attrib['cols']) {
+ $this->add_row();
+ }
+ }
+
+ /**
+ * Add a table header cell
+ *
+ * @param array Cell attributes
+ * @param string Cell content
+ */
+ private function add_header($attr, $cont)
+ {
+ if (is_string($attr))
+ $attr = array('class' => $attr);
+
+ $cell = new stdClass;
+ $cell->attrib = $attr;
+ $cell->content = $cont;
+ $this->header[] = $cell;
+ }
+
+ /**
+ * Jump to next row
+ *
+ * @param array Row attributes
+ */
+ private function add_row($attr = array())
+ {
+ $this->rowindex++;
+ $this->colindex = 0;
+ $this->rows[$this->rowindex] = new stdClass;
+ $this->rows[$this->rowindex]->attrib = $attr;
+ $this->rows[$this->rowindex]->cells = array();
+ }
+
+
+ /**
+ * Build HTML output of the table data
+ *
+ * @param array Table attributes
+ * @return string The final table HTML code
+ */
+ public function show($attr = array())
+ {
+ $this->attrib = array_merge($this->attrib, $attr);
+ $thead = $tbody = "";
+
+ // include <thead>
+ if (!empty($this->header)) {
+ $rowcontent = '';
+ foreach ($this->header as $c => $col) {
+ $rowcontent .= self::tag('th', $col->attrib, $col->content);
+ }
+ $thead = self::tag('thead', null, self::tag('tr', null, $rowcontent));
+ }
+
+ foreach ($this->rows as $r => $row) {
+ $rowcontent = '';
+ foreach ($row->cells as $c => $col) {
+ $rowcontent .= self::tag('td', $col->attrib, $col->content);
+ }
+
+ if ($r < $this->rowindex || count($row->cells)) {
+ $tbody .= self::tag('tr', $rows->attrib, $rowcontent);
+ }
+ }
+
+ if ($this->attrib['rowsonly']) {
+ return $tbody;
+ }
+
+ // add <tbody>
+ $this->content = $thead . self::tag('tbody', null, $tbody);
+
+ unset($this->attrib['cols'], $this->attrib['rowsonly']);
+ return parent::show();
+ }
+}
+
+?> \ No newline at end of file
diff --git a/program/include/iniset.php b/program/include/iniset.php
new file mode 100755
index 000000000..926b2826f
--- /dev/null
+++ b/program/include/iniset.php
@@ -0,0 +1,98 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/iniset.inc |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2008, RoundCube Dev, - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Setup the application envoronment required to process |
+ | any request. |
+ +-----------------------------------------------------------------------+
+ | Author: Till Klampaeckel <till@php.net> |
+ | Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: cache.inc 88 2005-12-03 16:54:12Z roundcube $
+
+*/
+
+
+// application constants
+define('RCMAIL_VERSION', '0.1-trunk');
+define('RCMAIL_CHARSET', 'UTF-8');
+define('JS_OBJECT_NAME', 'rcmail');
+
+if (!defined('INSTALL_PATH')) {
+ define('INSTALL_PATH', dirname($_SERVER['SCRIPT_FILENAME']).'/');
+}
+
+// make sure path_separator is defined
+if (!defined('PATH_SEPARATOR')) {
+ define('PATH_SEPARATOR', (eregi('win', PHP_OS) ? ';' : ':'));
+}
+
+// RC include folders MUST be included FIRST to avoid other
+// possible not compatible libraries (i.e PEAR) to be included
+// instead the ones provided by RC
+$include_path = INSTALL_PATH . PATH_SEPARATOR;
+$include_path.= INSTALL_PATH . 'program' . PATH_SEPARATOR;
+$include_path.= INSTALL_PATH . 'program/lib' . PATH_SEPARATOR;
+$include_path.= INSTALL_PATH . 'program/include' . PATH_SEPARATOR;
+$include_path.= ini_get('include_path');
+
+if (set_include_path($include_path) === false) {
+ die('Fatal error: ini_set/set_include_path does not work.');
+}
+
+ini_set('session.name', 'roundcube_sessid');
+ini_set('session.use_cookies', 1);
+ini_set('session.gc_maxlifetime', 21600);
+ini_set('session.gc_divisor', 500);
+ini_set('error_reporting', E_ALL&~E_NOTICE);
+set_magic_quotes_runtime(0);
+
+// increase maximum execution time for php scripts
+// (does not work in safe mode)
+if (!ini_get('safe_mode')) {
+ set_time_limit(120);
+}
+
+/**
+ * Use PHP5 autoload for dynamic class loading
+ *
+ * @todo Make Zend, PEAR etc play with this
+ */
+function __autoload($classname)
+{
+ $filename = preg_replace(
+ array('/MDB2_(.+)/', '/Mail_(.+)/', '/^html_.+/', '/^utf8$/'),
+ array('MDB2/\\1', 'Mail/\\1', 'html', 'utf8.class'),
+ $classname
+ );
+ include_once $filename. '.php';
+}
+
+/**
+ * Local callback function for PEAR errors
+ */
+function rcube_pear_error($err)
+{
+ error_log(sprintf("%s (%s): %s",
+ $err->getMessage(),
+ $err->getCode(),
+ $err->getUserinfo()), 0);
+}
+
+// include global functions
+require_once 'include/bugs.inc';
+require_once 'include/main.inc';
+require_once 'include/rcube_shared.inc';
+
+
+// set PEAR error handling (will also load the PEAR main class)
+PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'rcube_pear_error');
+
diff --git a/program/include/main.inc b/program/include/main.inc
index 649dd25e9..6d548d8e5 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -27,9 +27,7 @@
*/
require_once('lib/utf7.inc');
-require_once('include/rcube_user.inc');
require_once('include/rcube_shared.inc');
-require_once('include/rcmail_template.inc');
// fallback if not PHP modules are available
@include_once('lib/des.inc');
@@ -50,15 +48,12 @@ define('RCUBE_INPUT_GPC', 0x0103);
function rcmail_startup($task='mail')
{
global $sess_id, $sess_user_lang;
- global $CONFIG, $INSTALL_PATH, $BROWSER, $OUTPUT, $_SESSION, $IMAP, $DB, $USER;
+ global $CONFIG, $OUTPUT, $IMAP, $DB, $USER;
// start output buffering, we don't need any output yet,
// it'll be cleared after reading of config files, etc.
ob_start();
- // check client
- $BROWSER = rcube_browser();
-
// load configuration
$CONFIG = rcmail_load_config();
@@ -74,10 +69,9 @@ function rcmail_startup($task='mail')
// prepare DB connection
$dbwrapper = empty($CONFIG['db_backend']) ? 'db' : $CONFIG['db_backend'];
$dbclass = "rcube_" . $dbwrapper;
- require_once("include/$dbclass.inc");
$DB = new $dbclass($CONFIG['db_dsnw'], $CONFIG['db_dsnr'], $CONFIG['db_persistent']);
- $DB->sqlite_initials = $INSTALL_PATH.'SQL/sqlite.initial.sql';
+ $DB->sqlite_initials = INSTALL_PATH.'SQL/sqlite.initial.sql';
$DB->set_debug((bool)$CONFIG['sql_debug']);
$DB->db_connect('w');
@@ -136,8 +130,6 @@ function rcmail_startup($task='mail')
*/
function rcmail_load_config()
{
- global $INSTALL_PATH;
-
// load config file
include_once('config/main.inc.php');
$conf = is_array($rcmail_config) ? $rcmail_config : array();
@@ -152,7 +144,7 @@ function rcmail_load_config()
$conf = array_merge($conf, $rcmail_config);
if (empty($conf['log_dir']))
- $conf['log_dir'] = $INSTALL_PATH.'logs';
+ $conf['log_dir'] = INSTALL_PATH.'logs';
else
$conf['log_dir'] = unslashify($conf['log_dir']);
@@ -427,11 +419,10 @@ function get_sequence_name($sequence)
*/
function rcube_language_prop($lang, $prop='lang')
{
- global $INSTALL_PATH;
static $rcube_languages, $rcube_language_aliases, $rcube_charsets;
if (empty($rcube_languages))
- @include($INSTALL_PATH.'program/localization/index.inc');
+ @include(INSTALL_PATH.'program/localization/index.inc');
// check if we have an alias for that language
if (!isset($rcube_languages[$lang]) && isset($rcube_language_aliases[$lang]))
@@ -451,7 +442,7 @@ function rcube_language_prop($lang, $prop='lang')
if (isset($rcube_charsets[$lang]))
$charset = $rcube_charsets[$lang];
else
- $charset = 'UTF-8';
+ $charset = 'UTF-8';
if ($prop=='charset')
@@ -467,18 +458,15 @@ function rcube_language_prop($lang, $prop='lang')
* environment vars according to the current session and configuration
*/
function rcmail_load_gui()
- {
+{
global $CONFIG, $OUTPUT, $sess_user_lang;
// init output page
- $OUTPUT = new rcmail_template($CONFIG, $GLOBALS['_task']);
+ $OUTPUT = new rcube_template($CONFIG, $GLOBALS['_task']);
$OUTPUT->set_env('comm_path', $GLOBALS['COMM_PATH']);
- if (is_array($CONFIG['javascript_config']))
- {
- foreach ($CONFIG['javascript_config'] as $js_config_var)
- $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]);
- }
+ foreach (array('read_when_deleted', 'flag_for_deletion') as $js_config_var)
+ $OUTPUT->set_env($js_config_var, $CONFIG[$js_config_var]);
if (!empty($GLOBALS['_framed']))
$OUTPUT->set_env('framed', true);
@@ -490,19 +478,23 @@ function rcmail_load_gui()
if (!empty($CONFIG['charset']))
$OUTPUT->set_charset($CONFIG['charset']);
- // register common UI objects
- $OUTPUT->add_handlers(array(
- 'loginform' => 'rcmail_login_form',
- 'username' => 'rcmail_current_username',
- 'message' => 'rcmail_message_container',
- 'charsetselector' => 'rcmail_charset_selector',
- ));
-
// add some basic label to client
- if (!$OUTPUT->ajax_call)
- rcube_add_label('loading', 'movingmessage');
- }
+ $OUTPUT->add_label('loading', 'movingmessage');
+}
+/**
+ * Create an output object for JSON responses
+ */
+function rcmail_init_json()
+{
+ global $CONFIG, $OUTPUT;
+
+ // init output object
+ $OUTPUT = new rcube_json_output($CONFIG, $GLOBALS['_task']);
+
+ // set locale setting
+ rcmail_set_locale($sess_user_lang);
+}
/**
* Set localization charset based on the given language.
@@ -878,18 +870,18 @@ function get_des_key()
*/
function rcube_list_languages()
{
- global $CONFIG, $INSTALL_PATH;
+ global $CONFIG;
static $sa_languages = array();
if (!sizeof($sa_languages))
{
- @include($INSTALL_PATH.'program/localization/index.inc');
+ @include(INSTALL_PATH.'program/localization/index.inc');
- if ($dh = @opendir($INSTALL_PATH.'program/localization'))
+ if ($dh = @opendir(INSTALL_PATH.'program/localization'))
{
while (($name = readdir($dh)) !== false)
{
- if ($name{0}=='.' || !is_dir($INSTALL_PATH.'program/localization/'.$name))
+ if ($name{0}=='.' || !is_dir(INSTALL_PATH.'program/localization/'.$name))
continue;
if ($label = $rcube_languages[$name])
@@ -904,6 +896,7 @@ function rcube_list_languages()
/**
* Add a localized label to the client environment
+ * @deprecated
*/
function rcube_add_label()
{
@@ -911,7 +904,7 @@ function rcube_add_label()
$arg_list = func_get_args();
foreach ($arg_list as $i => $name)
- $OUTPUT->command('add_label', $name, rcube_label($name));
+ $OUTPUT->add_label($name);
}
@@ -1135,7 +1128,7 @@ function rep_specialchars_output($str, $enctype='', $mode='', $newlines=TRUE)
if ($OUTPUT->get_charset()!='UTF-8')
$str = rcube_charset_convert($str, RCMAIL_CHARSET, $OUTPUT->get_charset());
- return preg_replace(array("/\r?\n/", "/\r/"), array('\n', '\n'), addslashes(strtr($str, $js_rep_table)));
+ return preg_replace(array("/\r?\n/", "/\r/", '/<\\//'), array('\n', '\n', '<\\/'), addslashes(strtr($str, $js_rep_table)));
}
// no encoding given -> return original string
@@ -1261,16 +1254,6 @@ function template_exists($name)
/**
- * Wrapper for rcmail_template::parse()
- * @deprecated
- */
-function parse_template($name='main', $exit=true)
- {
- $GLOBALS['OUTPUT']->parse($name, $exit);
- }
-
-
-/**
* Create a HTML table based on the given data
*
* @param array Named table attributes
@@ -1360,15 +1343,15 @@ function rcmail_get_edit_field($col, $value, $attrib, $type='text')
if ($type=='checkbox')
{
$attrib['value'] = '1';
- $input = new checkbox($attrib);
+ $input = new html_checkbox($attrib);
}
else if ($type=='textarea')
{
$attrib['cols'] = $attrib['size'];
- $input = new textarea($attrib);
+ $input = new html_textarea($attrib);
}
else
- $input = new textfield($attrib);
+ $input = new html_inputfield($attrib);
// use value from post
if (!empty($_POST[$fname]))
@@ -1645,7 +1628,7 @@ function console($msg)
*/
function write_log($name, $line)
{
- global $CONFIG, $INSTALL_PATH;
+ global $CONFIG;
if (!is_string($line))
$line = var_export($line, true);
@@ -1655,7 +1638,7 @@ function write_log($name, $line)
$line);
if (empty($CONFIG['log_dir']))
- $CONFIG['log_dir'] = $INSTALL_PATH.'logs';
+ $CONFIG['log_dir'] = INSTALL_PATH.'logs';
// try to open specific log file for writing
if ($fp = @fopen($CONFIG['log_dir'].'/'.$name, 'a'))
diff --git a/program/include/rcmail_template.inc b/program/include/rcmail_template.inc
deleted file mode 100644
index 301b3f20d..000000000
--- a/program/include/rcmail_template.inc
+++ /dev/null
@@ -1,948 +0,0 @@
-<?php
-
-/*
- +-----------------------------------------------------------------------+
- | program/include/rcmail_template.inc |
- | |
- | This file is part of the RoundCube Webmail client |
- | Copyright (C) 2007, RoundCube Dev. - Switzerland |
- | Licensed under the GNU GPL |
- | |
- | PURPOSE: |
- | Class to handle HTML page output using a skin template. |
- | Extends rcube_html_page class from rcube_html.inc |
- | |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com> |
- +-----------------------------------------------------------------------+
-
- $Id: $
-
-*/
-
-
-/**
- * Classes and functions for HTML output
- *
- * @package View
- */
-
-require_once('include/rcube_html.inc');
-
-
-/**
- * Class to create HTML page output using a skin template
- */
-class rcmail_template extends rcube_html_page
-{
- var $config;
- var $task = '';
- var $framed = false;
- var $ajax_call = false;
- var $pagetitle = '';
- var $env = array();
- var $js_env = array();
- var $js_commands = array();
- var $object_handlers = array();
-
-
- /**
- * Constructor
- *
- * @param array Configuration array
- * @param string Current task
- */
- function __construct(&$config, $task)
- {
- $this->task = $task;
- $this->config = $config;
- $this->ajax_call = !empty($_GET['_remote']) || !empty($_POST['_remote']);
-
- // add common javascripts
- if (!$this->ajax_call)
- {
- $javascript = "var ".JS_OBJECT_NAME." = new rcube_webmail();";
-
- // don't wait for page onload. Call init at the bottom of the page (delayed)
- $javascript_foot = "if (window.call_init)\n call_init('".JS_OBJECT_NAME."');";
-
- $this->add_script($javascript, 'head_top');
- $this->add_script($javascript_foot, 'foot');
- $this->scripts_path = 'program/js/';
- $this->include_script('common.js');
- $this->include_script('app.js');
- }
- }
-
- /**
- * PHP 4 compatibility
- * @see rcmail_template::__construct()
- */
- function rcmail_template(&$config, $task)
- {
- $this->__construct($config, $task);
- }
-
-
- /**
- * Set environment variable
- *
- * @param string Property name
- * @param mixed Property value
- * @param boolean True if this property should be added to client environment
- */
- function set_env($name, $value, $addtojs=true)
- {
- $this->env[$name] = $value;
- if ($addtojs || isset($this->js_env[$name]))
- $this->js_env[$name] = $value;
- }
-
-
- /**
- * Set page title variable
- */
- function set_pagetitle($title)
- {
- $this->pagetitle = $title;
- }
-
-
- /**
- * Register a template object handler
- *
- * @param string Object name
- * @param string Function name to call
- */
- function add_handler($obj, $func)
- {
- $this->object_handlers[$obj] = $func;
- }
-
- /**
- * Register a list of template object handlers
- *
- * @param array Hash array with object=>handler pairs
- */
- function add_handlers($arr)
- {
- $this->object_handlers = array_merge($this->object_handlers, $arr);
- }
-
- /**
- * Register a GUI object to the client script
- *
- * @param string Object name
- * @param string Object ID
- */
- function add_gui_object($obj, $id)
- {
- $this->add_script(JS_OBJECT_NAME.".gui_object('$obj', '$id');");
- }
-
-
- /**
- * Call a client method
- *
- * @param string Method to call
- * @param ... Additional arguments
- */
- function command()
- {
- $this->js_commands[] = func_get_args();
- }
-
-
- /**
- * Invoke display_message command
- *
- * @param string Message to display
- * @param string Message type [notice|confirm|error]
- * @param array Key-value pairs to be replaced in localized text
- */
- function show_message($message, $type='notice', $vars=NULL)
- {
- $this->command(
- 'display_message',
- rcube_label(array('name' => $message, 'vars' => $vars)),
- $type);
- }
-
-
- /**
- * Delete all stored env variables and commands
- */
- function reset()
- {
- $this->env = array();
- $this->js_env = array();
- $this->js_commands = array();
- $this->object_handlers = array();
- parent::reset();
- }
-
- /**
- * Send the request output to the client.
- * This will either parse a skin tempalte or send an AJAX response
- *
- * @param string Template name
- * @param boolean True if script should terminate (default)
- */
- function send($templ=null, $exit=true)
- {
- if ($this->ajax_call)
- $this->remote_response('', !$exit);
- else if ($templ != 'iframe')
- $this->parse($templ, false);
- else
- {
- $this->framed = $templ == 'iframe' ? true : $this->framed;
- $this->write();
- }
-
- if ($exit)
- exit;
- }
-
-
- /**
- * Send an AJAX response with executable JS code
- *
- * @param string Additional JS code
- * @param boolean True if output buffer should be flushed
- */
- function remote_response($add='', $flush=false)
- {
- static $s_header_sent = FALSE;
-
- if (!$s_header_sent)
- {
- $s_header_sent = TRUE;
- send_nocacheing_headers();
- header('Content-Type: application/x-javascript; charset='.RCMAIL_CHARSET);
- print '/** ajax response ['.date('d/M/Y h:i:s O')."] **/\n";
- }
-
- // unset default env vars
- unset($this->js_env['task'], $this->js_env['action'], $this->js_env['comm_path']);
-
- // send response code
- print rcube_charset_convert($this->get_js_commands() . $add, RCMAIL_CHARSET, $this->get_charset());
-
- if ($flush) // flush the output buffer
- flush();
- }
-
-
- /**
- * Process template and write to stdOut
- *
- * @param string HTML template
- * @see rcube_html_page::write()
- */
- function write($template='')
- {
- // unlock interface after iframe load
- if ($this->framed)
- array_unshift($this->js_commands, array('set_busy', false));
-
- // write all env variables to client
- $js = $this->framed ? "if(window.parent) {\n" : '';
- $js .= $this->get_js_commands() . ($this->framed ? ' }' : '');
- $this->add_script($js, 'head_top');
-
- // call super method
- parent::write($template, $this->config['skin_path']);
- }
-
-
- /**
- * Parse a specific skin template and deliver to stdout
- *
- * @param string Template name
- * @param boolean Exit script
- */
- function parse($name='main', $exit=true)
- {
- $skin_path = $this->config['skin_path'];
-
- // read template file
- $templ = '';
- $path = "$skin_path/templates/$name.html";
-
- if($fp = @fopen($path, 'r'))
- {
- $templ = fread($fp, filesize($path));
- fclose($fp);
- }
- else
- {
- raise_error(array(
- 'code' => 501,
- 'type' => 'php',
- 'line' => __LINE__,
- 'file' => __FILE__,
- 'message' => "Error loading template for '$name'"), TRUE, TRUE);
- return FALSE;
- }
-
- // parse for specialtags
- $output = $this->parse_xml($this->parse_conditions($templ));
-
- // add debug console
- if ($this->config['debug_level'] & 8)
- $this->add_footer('<div style="position:absolute;top:5px;left:5px;width:400px;padding:0.2em;background:white;opacity:0.8;z-index:9000">
- <a href="#toggle" onclick="con=document.getElementById(\'dbgconsole\');con.style.display=(con.style.display==\'none\'?\'block\':\'none\');return false">console</a>
- <form action="/" name="debugform"><textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:x-small"></textarea></form></div>');
-
- $this->write(trim($this->parse_with_globals($output)), $skin_path);
-
- if ($exit)
- exit;
- }
-
-
- /**
- * Return executable javascript code for all registered commands
- * @access private
- */
- function get_js_commands()
- {
- $out = '';
- if (!$this->framed && !empty($this->js_env))
- $out .= ($this->ajax_call ? 'this' : JS_OBJECT_NAME) . '.set_env('.json_serialize($this->js_env).");\n";
-
- // add command to set page title
- if ($this->ajax_call && !empty($this->pagetitle))
- $out .= sprintf(
- "this.set_pagetitle('%s');\n",
- JQ((!empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '') . $this->pagetitle)
- );
-
- foreach ($this->js_commands as $i => $args)
- {
- $method = array_shift($args);
- foreach ($args as $i => $arg)
- $args[$i] = json_serialize($arg);
-
- $parent = $this->framed || preg_match('/^parent\./', $method);
- $out .= sprintf(
- "%s.%s(%s);\n",
- $this->ajax_call ? 'this' : ($parent ? 'parent.' : '') . JS_OBJECT_NAME,
- preg_replace('/^parent\./', '', $method),
- join(',', $args));
- }
-
-
-
- return $out;
- }
-
- /**
- * Make URLs starting with a slash point to skin directory
- * @access private
- */
- function abs_url($str)
- {
- return preg_replace('/^\//', $this->config['skin_path'].'/', $str);
- }
-
-
-
- /***** Template parsing methods *****/
-
- /**
- * Replace all strings ($varname)
- * with the content of the according global variable.
- * @access private
- */
- function parse_with_globals($input)
- {
- $GLOBALS['__comm_path'] = Q($GLOBALS['COMM_PATH']);
- return preg_replace('/\$(__[a-z0-9_\-]+)/e', '$GLOBALS["\\1"]', $input);
- }
-
-
- /**
- * Parse for conditional tags
- * @access private
- */
- function parse_conditions($input)
- {
- if (($matches = preg_split('/<roundcube:(if|elseif|else|endif)\s+([^>]+)>/is', $input, 2, PREG_SPLIT_DELIM_CAPTURE)) && count($matches)==4)
- {
- if (preg_match('/^(else|endif)$/i', $matches[1]))
- return $matches[0] . $this->parse_conditions($matches[3]);
- else
- {
- $attrib = parse_attrib_string($matches[2]);
- if (isset($attrib['condition']))
- {
- $condmet = $this->check_condition($attrib['condition']);
- $submatches = preg_split('/<roundcube:(elseif|else|endif)\s+([^>]+)>/is', $matches[3], 2, PREG_SPLIT_DELIM_CAPTURE);
-
- if ($condmet)
- $result = $submatches[0] . ($submatches[1] != 'endif' ? preg_replace('/.*<roundcube:endif\s+[^>]+>/Uis', '', $submatches[3], 1) : $submatches[3]);
- else
- $result = "<roundcube:$submatches[1] $submatches[2]>" . $submatches[3];
-
- return $matches[0] . $this->parse_conditions($result);
- }
- else
- {
- raise_error(array('code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
- 'message' => "Unable to parse conditional tag " . $matches[2]), TRUE, FALSE);
- }
- }
- }
-
- return $input;
- }
-
-
- /**
- * Determines if a given condition is met
- *
- * @return True if condition is valid, False is not
- * @access private
- */
- function check_condition($condition)
- {
- $condition = preg_replace(
- array('/session:([a-z0-9_]+)/i', '/config:([a-z0-9_]+)/i', '/env:([a-z0-9_]+)/i', '/request:([a-z0-9_]+)/ie'),
- array("\$_SESSION['\\1']", "\$this->config['\\1']", "\$this->env['\\1']", "get_input_value('\\1', RCUBE_INPUT_GPC)"),
- $condition);
-
- return @eval("return (".$condition.");");
- }
-
-
- /**
- * Search for special tags in input and replace them
- * with the appropriate content
- *
- * @param string Input string to parse
- * @return Altered input string
- * @access private
- */
- function parse_xml($input)
- {
- return preg_replace('/<roundcube:([-_a-z]+)\s+([^>]+)>/Uie', "\$this->xml_command('\\1', '\\2')", $input);
- }
-
-
- /**
- * Convert a xml command tag into real content
- *
- * @param string Tag command: object,button,label, etc.
- * @param string Attribute string
- * @return Tag/Object content string
- * @access private
- */
- function xml_command($command, $str_attrib, $add_attrib=array())
- {
- $command = strtolower($command);
- $attrib = parse_attrib_string($str_attrib) + $add_attrib;
-
- // empty output if required condition is not met
- if (!empty($attrib['condition']) && !$this->check_condition($attrib['condition']))
- return '';
-
- // execute command
- switch ($command)
- {
- // return a button
- case 'button':
- return $this->button($attrib);
- break;
-
- // show a label
- case 'label':
- if ($attrib['name'] || $attrib['command'])
- return Q(rcube_label($attrib + array('vars' => array('product' => $this->config['product_name']))));
- break;
-
- // include a file
- case 'include':
- $path = realpath($this->config['skin_path'].$attrib['file']);
- if (filesize($path))
- {
- if ($this->config['skin_include_php'])
- $incl = $this->include_php($path);
- else if ($fp = @fopen($path, 'r'))
- {
- $incl = fread($fp, filesize($path));
- fclose($fp);
- }
- return $this->parse_xml($incl);
- }
- break;
-
- // return code for a specific application object
- case 'object':
- $object = strtolower($attrib['name']);
-
- // execute object handler function
- if ($this->object_handlers[$object] && function_exists($this->object_handlers[$object]))
- return call_user_func($this->object_handlers[$object], $attrib);
-
- else if ($object=='productname')
- {
- $name = !empty($this->config['product_name']) ? $this->config['product_name'] : 'RoundCube Webmail';
- return Q($name);
- }
- else if ($object=='version')
- {
- return (string)RCMAIL_VERSION;
- }
- else if ($object=='pagetitle')
- {
- $task = $this->task;
- $title = !empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '';
-
- if (!empty($this->pagetitle))
- $title .= $this->pagetitle;
- else if ($task == 'login')
- $title = rcube_label(array('name' => 'welcome', 'vars' => array('product' => $this->config['product_name'])));
- else
- $title .= ucfirst($task);
-
- return Q($title);
- }
-
- break;
-
- // return variable
- case 'var':
- $var = explode(':', $attrib['name']);
- $name = $var[1];
- $value = '';
-
- switch ($var[0])
- {
- case 'env':
- $value = $this->env[$name];
- break;
- case 'config':
- $value = $this->config[$name];
- if (is_array($value) && $value[$_SESSION['imap_host']])
- $value = $value[$_SESSION['imap_host']];
- break;
- case 'request':
- $value = get_input_value($name, RCUBE_INPUT_GPC);
- break;
- case 'session':
- $value = $_SESSION[$name];
- break;
- }
-
- if (is_array($value))
- $value = join(", ", $value);
-
- return Q($value);
- }
-
- return '';
- }
-
-
- /**
- * Include a specific file and return it's contents
- *
- * @param string File path
- * @return string Contents of the processed file
- */
- function include_php($file)
- {
- ob_start();
- @include($file);
- $out = ob_get_contents();
- ob_end_clean();
-
- return $out;
- }
-
-
- /**
- * Create and register a button
- *
- * @param array Button attributes
- * @return HTML button
- * @access private
- */
- function button($attrib)
- {
- global $CONFIG, $OUTPUT, $BROWSER, $MAIN_TASKS;
- static $sa_buttons = array();
- static $s_button_count = 100;
-
- // these commands can be called directly via url
- $a_static_commands = array('compose', 'list');
-
- $skin_path = $this->config['skin_path'];
-
- if (!($attrib['command'] || $attrib['name'] || $attrib['onclick']))
- return '';
-
- // try to find out the button type
- if ($attrib['type'])
- $attrib['type'] = strtolower($attrib['type']);
- else
- $attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $attrib['imageact']) ? 'image' : 'link';
-
- $command = $attrib['command'];
-
- // take the button from the stack
- if($attrib['name'] && $sa_buttons[$attrib['name']])
- $attrib = $sa_buttons[$attrib['name']];
-
- // add button to button stack
- else if($attrib['image'] || $attrib['imageact'] || $attrib['imagepas'] || $attrib['class'])
- {
- if (!$attrib['name'])
- $attrib['name'] = $command;
-
- if (!$attrib['image'])
- $attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact'];
-
- $sa_buttons[$attrib['name']] = $attrib;
- }
-
- // get saved button for this command/name
- else if ($command && $sa_buttons[$command])
- $attrib = $sa_buttons[$command];
-
- //else
- // return '';
-
-
- // set border to 0 because of the link arround the button
- if ($attrib['type']=='image' && !isset($attrib['border']))
- $attrib['border'] = 0;
-
- if (!$attrib['id'])
- $attrib['id'] = sprintf('rcmbtn%d', $s_button_count++);
-
- // get localized text for labels and titles
- if ($attrib['title'])
- $attrib['title'] = Q(rcube_label($attrib['title']));
- if ($attrib['label'])
- $attrib['label'] = Q(rcube_label($attrib['label']));
-
- if ($attrib['alt'])
- $attrib['alt'] = Q(rcube_label($attrib['alt']));
-
- // set title to alt attribute for IE browsers
- if ($BROWSER['ie'] && $attrib['title'] && !$attrib['alt'])
- {
- $attrib['alt'] = $attrib['title'];
- unset($attrib['title']);
- }
-
- // add empty alt attribute for XHTML compatibility
- if (!isset($attrib['alt']))
- $attrib['alt'] = '';
-
-
- // register button in the system
- if ($attrib['command'])
- {
- $this->add_script(sprintf(
- "%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
- JS_OBJECT_NAME,
- $command,
- $attrib['id'],
- $attrib['type'],
- $attrib['imageact'] ? $skin_path.$attrib['imageact'] : $attrib['classact'],
- $attrib['imagesel'] ? $skin_path.$attrib['imagesel'] : $attrib['classsel'],
- $attrib['imageover'] ? $skin_path.$attrib['imageover'] : '')
- );
-
- // make valid href to specific buttons
- if (in_array($attrib['command'], $MAIN_TASKS))
- $attrib['href'] = Q(rcmail_url(null, null, $attrib['command']));
- else if (in_array($attrib['command'], $a_static_commands))
- $attrib['href'] = Q(rcmail_url($attrib['command']));
- }
-
- // overwrite attributes
- if (!$attrib['href'])
- $attrib['href'] = '#';
-
- if ($command)
- $attrib['onclick'] = sprintf("return %s.command('%s','%s',this)", JS_OBJECT_NAME, $command, $attrib['prop']);
-
- if ($command && $attrib['imageover'])
- {
- $attrib['onmouseover'] = sprintf("return %s.button_over('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
- $attrib['onmouseout'] = sprintf("return %s.button_out('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
- }
-
- if ($command && $attrib['imagesel'])
- {
- $attrib['onmousedown'] = sprintf("return %s.button_sel('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
- $attrib['onmouseup'] = sprintf("return %s.button_out('%s','%s')", JS_OBJECT_NAME, $command, $attrib['id']);
- }
-
- $out = '';
-
- // generate image tag
- if ($attrib['type']=='image')
- {
- $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id', 'width', 'height', 'border', 'hspace', 'vspace', 'align', 'alt'));
- $img_tag = sprintf('<img src="%%s"%s />', $attrib_str);
- $btn_content = sprintf($img_tag, $skin_path.$attrib['image']);
- if ($attrib['label'])
- $btn_content .= ' '.$attrib['label'];
-
- $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'title');
- }
- else if ($attrib['type']=='link')
- {
- $btn_content = $attrib['label'] ? $attrib['label'] : $attrib['command'];
- $link_attrib = array('href', 'onclick', 'title', 'id', 'class', 'style');
- }
- else if ($attrib['type']=='input')
- {
- $attrib['type'] = 'button';
-
- if ($attrib['label'])
- $attrib['value'] = $attrib['label'];
-
- $attrib_str = create_attrib_string($attrib, array('type', 'value', 'onclick', 'id', 'class', 'style'));
- $out = sprintf('<input%s disabled="disabled" />', $attrib_str);
- }
-
- // generate html code for button
- if ($btn_content)
- {
- $attrib_str = create_attrib_string($attrib, $link_attrib);
- $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
- }
-
- return $out;
- }
-
-} // end class rcmail_template
-
-
-
-// ************** common functions delivering gui objects **************
-
-
-/**
- * Builder for GUI object 'message'
- *
- * @param array Named tag parameters
- * @return string HTML code for the gui object
- */
-function rcmail_message_container($attrib)
- {
- global $OUTPUT;
-
- if (!$attrib['id'])
- $attrib['id'] = 'rcmMessageContainer';
-
- // allow the following attributes to be added to the <table> tag
- $attrib_str = create_attrib_string($attrib, array('style', 'class', 'id'));
- $out = '<div' . $attrib_str . "></div>";
-
- $OUTPUT->add_gui_object('message', $attrib['id']);
-
- return $out;
- }
-
-
-/**
- * GUI object 'username'
- * Showing IMAP username of the current session
- *
- * @param array Named tag parameters (currently not used)
- * @return string HTML code for the gui object
- */
-function rcmail_current_username($attrib)
- {
- global $USER;
- static $s_username;
-
- // alread fetched
- if (!empty($s_username))
- return $s_username;
-
- if ($sql_arr = $USER->get_identity())
- $s_username = $sql_arr['email'];
- else if (strstr($_SESSION['username'], '@'))
- $s_username = $_SESSION['username'];
- else
- $s_username = $_SESSION['username'].'@'.$_SESSION['imap_host'];
-
- return $s_username;
- }
-
-
-/**
- * GUI object 'loginform'
- * Returns code for the webmail login form
- *
- * @param array Named parameters
- * @return string HTML code for the gui object
- */
-function rcmail_login_form($attrib)
- {
- global $CONFIG, $OUTPUT, $SESS_HIDDEN_FIELD;
-
- $labels = array();
- $labels['user'] = rcube_label('username');
- $labels['pass'] = rcube_label('password');
- $labels['host'] = rcube_label('server');
-
- $input_user = new textfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30) + $attrib);
- $input_pass = new passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30) + $attrib);
- $input_action = new hiddenfield(array('name' => '_action', 'value' => 'login'));
-
- $fields = array();
- $fields['user'] = $input_user->show(get_input_value('_user', RCUBE_INPUT_POST));
- $fields['pass'] = $input_pass->show();
- $fields['action'] = $input_action->show();
-
- if (is_array($CONFIG['default_host']))
- {
- $select_host = new select(array('name' => '_host', 'id' => 'rcmloginhost'));
-
- foreach ($CONFIG['default_host'] as $key => $value)
- {
- if (!is_array($value))
- $select_host->add($value, (is_numeric($key) ? $value : $key));
- else
- {
- unset($select_host);
- break;
- }
- }
-
- $fields['host'] = isset($select_host) ? $select_host->show(get_input_value('_host', RCUBE_INPUT_POST)) : null;
- }
- else if (!strlen($CONFIG['default_host']))
- {
- $input_host = new textfield(array('name' => '_host', 'id' => 'rcmloginhost', 'size' => 30));
- $fields['host'] = $input_host->show(get_input_value('_host', RCUBE_INPUT_POST));
- }
-
- $form_name = strlen($attrib['form']) ? $attrib['form'] : 'form';
- $form_start = !strlen($attrib['form']) ? '<form name="form" action="./" method="post">' : '';
- $form_end = !strlen($attrib['form']) ? '</form>' : '';
-
- if ($fields['host'])
- $form_host = <<<EOF
-
-</tr><tr>
-
-<td class="title"><label for="rcmloginhost">$labels[host]</label></td>
-<td>$fields[host]</td>
-
-EOF;
-
- $OUTPUT->add_gui_object('loginform', $form_name);
-
- $out = <<<EOF
-$form_start
-$SESS_HIDDEN_FIELD
-$fields[action]
-<table><tr>
-
-<td class="title"><label for="rcmloginuser">$labels[user]</label></td>
-<td>$fields[user]</td>
-
-</tr><tr>
-
-<td class="title"><label for="rcmloginpwd">$labels[pass]</label></td>
-<td>$fields[pass]</td>
-$form_host
-</tr></table>
-$form_end
-EOF;
-
- return $out;
- }
-
-
-/**
- * GUI object 'charsetselector'
- *
- * @param array Named parameters for the select tag
- * @return string HTML code for the gui object
- */
-function rcmail_charset_selector($attrib)
- {
- global $OUTPUT;
-
- // pass the following attributes to the form class
- $field_attrib = array('name' => '_charset');
- foreach ($attrib as $attr => $value)
- if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex')))
- $field_attrib[$attr] = $value;
-
- $charsets = array(
- 'US-ASCII' => 'ASCII (English)',
- 'EUC-JP' => 'EUC-JP (Japanese)',
- 'EUC-KR' => 'EUC-KR (Korean)',
- 'BIG5' => 'BIG5 (Chinese)',
- 'GB2312' => 'GB2312 (Chinese)',
- 'ISO-2022-JP' => 'ISO-2022-JP (Japanese)',
- 'ISO-8859-1' => 'ISO-8859-1 (Latin-1)',
- 'ISO-8859-2' => 'ISO-8895-2 (Central European)',
- 'ISO-8859-7' => 'ISO-8859-7 (Greek)',
- 'ISO-8859-9' => 'ISO-8859-9 (Turkish)',
- 'Windows-1251' => 'Windows-1251 (Cyrillic)',
- 'Windows-1252' => 'Windows-1252 (Western)',
- 'Windows-1255' => 'Windows-1255 (Hebrew)',
- 'Windows-1256' => 'Windows-1256 (Arabic)',
- 'Windows-1257' => 'Windows-1257 (Baltic)',
- 'UTF-8' => 'UTF-8'
- );
-
- $select = new select($field_attrib);
- $select->add(array_values($charsets), array_keys($charsets));
-
- $set = $_POST['_charset'] ? $_POST['_charset'] : $OUTPUT->get_charset();
- return $select->show($set);
- }
-
-
-/**
- * GUI object 'searchform'
- * Returns code for search function
- *
- * @param array Named parameters
- * @return string HTML code for the gui object
- */
-function rcmail_search_form($attrib)
- {
- global $OUTPUT;
-
- // add some labels to client
- rcube_add_label('searching');
-
- $attrib['name'] = '_q';
-
- if (empty($attrib['id']))
- $attrib['id'] = 'rcmqsearchbox';
-
- $input_q = new textfield($attrib);
- $out = $input_q->show();
-
- $OUTPUT->add_gui_object('qsearchbox', $attrib['id']);
-
- // add form tag around text field
- if (empty($attrib['form']))
- $out = sprintf(
- '<form name="rcmqsearchform" action="./" '.
- 'onsubmit="%s.command(\'search\');return false" style="display:inline;">%s</form>',
- JS_OBJECT_NAME,
- $out);
-
- return $out;
- }
-
-
-?>
diff --git a/program/include/rcube_browser.php b/program/include/rcube_browser.php
new file mode 100644
index 000000000..af393d63e
--- /dev/null
+++ b/program/include/rcube_browser.php
@@ -0,0 +1,75 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_browser.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Class representing the client browser's properties |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: rcube_browser.php 328 2006-08-30 17:41:21Z thomasb $
+
+*/
+
+/**
+ * rcube_browser
+ *
+ * Provide details about the client's browser based on the User-Agent header
+ *
+ * @package Core
+ */
+class rcube_browser
+{
+ function __construct()
+ {
+ $HTTP_USER_AGENT = $_SERVER['HTTP_USER_AGENT'];
+
+ $this->ver = 0;
+ $this->win = stristr($HTTP_USER_AGENT, 'win');
+ $this->mac = stristr($HTTP_USER_AGENT, 'mac');
+ $this->linux = stristr($HTTP_USER_AGENT, 'linux');
+ $this->unix = stristr($HTTP_USER_AGENT, 'unix');
+
+ $this->ns4 = stristr($HTTP_USER_AGENT, 'mozilla/4') && !stristr($HTTP_USER_AGENT, 'msie');
+ $this->ns = ($this->ns4 || stristr($HTTP_USER_AGENT, 'netscape'));
+ $this->ie = stristr($HTTP_USER_AGENT, 'msie');
+ $this->mz = stristr($HTTP_USER_AGENT, 'mozilla/5');
+ $this->opera = stristr($HTTP_USER_AGENT, 'opera');
+ $this->safari = stristr($HTTP_USER_AGENT, 'safari');
+
+ if ($this->ns) {
+ $test = eregi("mozilla\/([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+ $this->ver = $test ? (float)$regs[1] : 0;
+ }
+ if ($this->mz) {
+ $test = ereg("rv:([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+ $this->ver = $test ? (float)$regs[1] : 0;
+ }
+ if($this->ie) {
+ $test = eregi("msie ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+ $this->ver = $test ? (float)$regs[1] : 0;
+ }
+ if ($this->opera) {
+ $test = eregi("opera ([0-9\.]+)", $HTTP_USER_AGENT, $regs);
+ $this->ver = $test ? (float)$regs[1] : 0;
+ }
+
+ if (eregi(" ([a-z]{2})-([a-z]{2})", $HTTP_USER_AGENT, $regs))
+ $this->lang = $regs[1];
+ else
+ $this->lang = 'en';
+
+ $this->dom = ($this->mz || $this->safari || ($this->ie && $this->ver>=5) || ($this->opera && $this->ver>=7));
+ $this->pngalpha = $this->mz || $this->safari || ($this->ie && $this->ver>=5.5) ||
+ ($this->ie && $this->ver>=5 && $this->mac) || ($this->opera && $this->ver>=7) ? true : false;
+ }
+ }
+
diff --git a/program/include/rcube_contacts.inc b/program/include/rcube_contacts.php
index 6a4865662..a9d16149e 100644
--- a/program/include/rcube_contacts.inc
+++ b/program/include/rcube_contacts.php
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_contacts.inc |
+ | program/include/rcube_contacts.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2006-2007, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -403,56 +403,3 @@ class rcube_contacts
}
-/**
- * RoundCube result set class.
- * Representing an address directory result set.
- */
-class rcube_result_set
-{
- var $count = 0;
- var $first = 0;
- var $current = 0;
- var $records = array();
-
- function __construct($c=0, $f=0)
- {
- $this->count = (int)$c;
- $this->first = (int)$f;
- }
-
- function rcube_result_set($c=0, $f=0)
- {
- $this->__construct($c, $f);
- }
-
- function add($rec)
- {
- $this->records[] = $rec;
- }
-
- function iterate()
- {
- return $this->records[$this->current++];
- }
-
- function first()
- {
- $this->current = 0;
- return $this->records[$this->current++];
- }
-
- // alias
- function next()
- {
- return $this->iterate();
- }
-
- function seek($i)
- {
- $this->current = $i;
- }
-
-}
-
-
-?> \ No newline at end of file
diff --git a/program/include/rcube_db.inc b/program/include/rcube_db.php
index 63c6759b9..8fa34e6a5 100644
--- a/program/include/rcube_db.inc
+++ b/program/include/rcube_db.php
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_db.inc |
+ | program/include/rcube_db.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -23,11 +23,6 @@
/**
- * Obtain the PEAR::DB class that is used for abstraction
- */
-require_once 'DB.php';
-
-/**
* Database independent query interface
*
* This is a wrapper for the PEAR::DB class
@@ -605,4 +600,4 @@ class rcube_db
} // end class rcube_db
-?>
+
diff --git a/program/include/rcube_html.inc b/program/include/rcube_html.inc
deleted file mode 100644
index d23760ade..000000000
--- a/program/include/rcube_html.inc
+++ /dev/null
@@ -1,667 +0,0 @@
-<?php
-
-/*
- +-----------------------------------------------------------------------+
- | rcube_html.inc |
- | |
- | This file is part of the RoundCube PHP suite |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
- | Licensed under the GNU GPL |
- | |
- | CONTENTS: |
- | Common Classes to create HTML output |
- | |
- +-----------------------------------------------------------------------+
- | Author: Thomas Bruederli <roundcube@gmail.com> |
- +-----------------------------------------------------------------------+
-
- $Id: $
-
-*/
-
-
-/**
- * HTML page builder class
- *
- * @package HTML
- */
-class rcube_html_page
-{
- var $scripts_path = '';
- var $script_files = array();
- var $scripts = array();
- var $charset = 'UTF-8';
-
- var $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
- var $script_tag = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
- var $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
-
- var $title = 'RoundCube Mail';
- var $header = '';
- var $footer = '';
- var $body = '';
- var $body_attrib = array();
- var $meta_tags = array();
-
-
- /**
- * Link an external script file
- *
- * @param string File URL
- * @param string Target position [head|foot]
- */
- function include_script($file, $position='head')
- {
- static $sa_files = array();
-
- if (in_array($file, $sa_files))
- return;
-
- if (!is_array($this->script_files[$position]))
- $this->script_files[$position] = array();
-
- $this->script_files[$position][] = $file;
- }
-
- /**
- * Add inline javascript code
- *
- * @param string JS code snippet
- * @param string Target position [head|head_top|foot]
- */
- function add_script($script, $position='head')
- {
- if (!isset($this->scripts[$position]))
- $this->scripts[$position] = "\n".rtrim($script);
- else
- $this->scripts[$position] .= "\n".rtrim($script);
- }
-
- /**
- * Add HTML code to the page header
- */
- function add_header($str)
- {
- $this->header .= "\n".$str;
- }
-
- /**
- * Add HTML code to the page footer
- * To be added right befor </body>
- */
- function add_footer($str)
- {
- $this->footer .= "\n".$str;
- }
-
- /**
- * Setter for page title
- */
- function set_title($t)
- {
- $this->title = $t;
- }
-
-
- /**
- * Setter for output charset.
- * To be specified in a meta tag and sent as http-header
- */
- function set_charset($charset)
- {
- global $MBSTRING;
-
- $this->charset = $charset;
-
- if ($MBSTRING && function_exists("mb_internal_encoding"))
- {
- if(!@mb_internal_encoding($charset))
- $MBSTRING = FALSE;
- }
- }
-
- /**
- * Getter for output charset
- */
- function get_charset()
- {
- return $this->charset;
- }
-
-
- /**
- * Reset all saved properties
- */
- function reset()
- {
- $this->script_files = array();
- $this->scripts = array();
- $this->title = '';
- $this->header = '';
- $this->footer = '';
- }
-
-
- /**
- * Process template and write to stdOut
- *
- * @param string HTML template
- * @param string Base for absolute paths
- */
- function write($templ='', $base_path='')
- {
- $output = empty($templ) ? $this->default_template : trim($templ);
-
- // replace specialchars in content
- $__page_title = Q($this->title, 'show', FALSE);
- $__page_header = $__page_body = $__page_footer = '';
-
-
- // include meta tag with charset
- if (!empty($this->charset))
- {
- header('Content-Type: text/html; charset='.$this->charset, true);
- $__page_header = '<meta http-equiv="content-type" content="text/html; charset='.$this->charset.'" />'."\n";
- }
-
-
- // definition of the code to be placed in the document header and footer
- if (is_array($this->script_files['head']))
- foreach ($this->script_files['head'] as $file)
- $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
-
- $head_script = $this->scripts['head_top'] . $this->scripts['head'];
- if (!empty($head_script))
- $__page_header .= sprintf($this->script_tag, $head_script);
-
- if (!empty($this->header))
- $__page_header .= $this->header;
-
- if (is_array($this->script_files['foot']))
- foreach ($this->script_files['foot'] as $file)
- $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
-
- if (!empty($this->scripts['foot']))
- $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
-
- if (!empty($this->footer))
- $__page_footer .= $this->footer;
-
- // find page header
- if ($hpos = strpos(strtolower($output), '</head>'))
- $__page_header .= "\n";
- else
- {
- if (!is_numeric($hpos))
- $hpos = strpos(strtolower($output), '<body');
- if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html')))
- {
- while($output[$hpos]!='>')
- $hpos++;
- $hpos++;
- }
-
- $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n";
- }
-
- // add page hader
- if ($hpos)
- $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output));
- else
- $output = $__page_header . $output;
-
-
- // find page body
- if($bpos = strpos(strtolower($output), '<body'))
- {
- while($output[$bpos]!='>') $bpos++;
- $bpos++;
- }
- else
- $bpos = strpos(strtolower($output), '</head>')+7;
-
- // add page body
- if($bpos && $__page_body)
- $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output));
-
-
- // find and add page footer
- $output_lc = strtolower($output);
- if(($fpos = strrstr($output_lc, '</body>')) ||
- ($fpos = strrstr($output_lc, '</html>')))
- $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos);
- else
- $output .= "\n$__page_footer";
-
-
- // reset those global vars
- $__page_header = $__page_footer = '';
-
-
- // correct absolute paths in images and other tags
- $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
- $output = str_replace('$__skin_path', $base_path, $output);
-
- print rcube_charset_convert($output, 'UTF-8', $this->charset);
- }
-
-} // end class rcube_html_page
-
-
-
-/**
- * Base class to build a HTML for element
- *
- * @package HTML
- */
-class rcube_form_element
- {
- var $uppertags = FALSE;
- var $upperattribs = FALSE;
- var $upperprops = FALSE;
- var $newline = FALSE;
-
- var $attrib = array();
-
-
- /**
- * Create string with saved attributes
- *
- * @return string HTML formatted tag attributes
- */
- function create_attrib_string()
- {
- if (!sizeof($this->attrib))
- return '';
-
- if ($this->name!='')
- $this->attrib['name'] = $this->name;
-
- $attrib_arr = array();
- foreach ($this->attrib as $key => $value)
- {
- // don't output some internally used attributes
- if (in_array($key, array('form', 'quicksearch')))
- continue;
-
- // skip if size if not numeric
- if (($key=='size' && !is_numeric($value)))
- continue;
-
- // skip empty eventhandlers
- if ((strpos($key,'on')===0 && $value==''))
- continue;
-
- // attributes with no value
- if (in_array($key, array('checked', 'multiple', 'disabled', 'selected', 'nowrap')))
- {
- if ($value)
- $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $key);
- }
- // don't convert size of value attribute
- else if ($key=='value')
- $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), Q($value, 'strict', false));
-
- // regular tag attributes
- else
- $attrib_arr[] = sprintf('%s="%s"', $this->_conv_case($key, 'attrib'), $this->_conv_case(Q($value), 'value'));
- }
-
- return sizeof($attrib_arr) ? ' '.implode(' ', $attrib_arr) : '';
- }
-
-
- /**
- * Convert tags and attributes to upper-/lowercase
- *
- * @param string Input string
- * @param string Value type (can either be "tag" or "attrib")
- * @return string Converted output string
- * @access private
- */
- function _conv_case($str, $type='attrib')
- {
- if ($type == 'tag')
- return $this->uppertags ? strtoupper($str) : strtolower($str);
- else if ($type == 'attrib')
- return $this->upperattribs ? strtoupper($str) : strtolower($str);
- else if ($type == 'value')
- return $this->upperprops ? strtoupper($str) : strtolower($str);
- }
- }
-
-
-/**
- * Builder for an <input> field
- *
- * @package HTML
- */
-class input_field extends rcube_form_element
-{
- var $type = 'text';
-
- /**
- * Constructor
- * @param array Named tag attributes
- */
- function input_field($attrib=array())
- {
- if (is_array($attrib))
- $this->attrib = $attrib;
-
- if ($attrib['type'])
- $this->type = $attrib['type'];
-
- if ($attrib['newline'])
- $this->newline = TRUE;
- }
-
- /**
- * Compose input tag
- *
- * @param string Field value
- * @param array Additional tag attributes
- * @return string Final HTML code
- */
- function show($value=NULL, $attrib=NULL)
- {
- // overwrite object attributes
- if (is_array($attrib))
- $this->attrib = array_merge($this->attrib, $attrib);
-
- // set value attribute
- if ($value!==NULL)
- $this->attrib['value'] = $value;
-
- $this->attrib['type'] = $this->type;
-
- // return final tag
- return sprintf(
- '<%s%s />%s',
- $this->_conv_case('input', 'tag'),
- $this->create_attrib_string(),
- ($this->newline ? "\n" : ""));
- }
-}
-
-
-/**
- * Builder for a <input type="text"> field
- *
- * @package HTML
- */
-class textfield extends input_field
-{
- var $type = 'text';
-}
-
-/**
- * Builder for a <input type="password"> field
- *
- * @package HTML
- */
-class passwordfield extends input_field
-{
- var $type = 'password';
-}
-
-/**
- * Builder for <input type="radio"> fields
- *
- * @package HTML
- */
-class radiobutton extends input_field
-{
- var $type = 'radio';
-}
-
-/**
- * Builder for <input type="checkbox"> fields
- *
- * @package HTML
- */
-class checkbox extends input_field
-{
- var $type = 'checkbox';
-
-
- /**
- * Compose input tag
- *
- * @param string Field value
- * @param array Additional tag attributes
- * @return string Final HTML code
- */
- function show($value='', $attrib=NULL)
- {
- // overwrite object attributes
- if (is_array($attrib))
- $this->attrib = array_merge($this->attrib, $attrib);
-
- $this->attrib['type'] = $this->type;
-
- if ($value && (string)$value==(string)$this->attrib['value'])
- $this->attrib['checked'] = TRUE;
- else
- $this->attrib['checked'] = FALSE;
-
- // return final tag
- return sprintf(
- '<%s%s />%s',
- $this->_conv_case('input', 'tag'),
- $this->create_attrib_string(),
- ($this->newline ? "\n" : ""));
- }
-}
-
-
-/**
- * Builder for a <textarea> field
- *
- * @package HTML
- */
-class textarea extends rcube_form_element
- {
-
- /**
- * Constructor
- * @param array Named tag attributes
- */
- function textarea($attrib=array())
- {
- $this->attrib = $attrib;
-
- if ($attrib['newline'])
- $this->newline = TRUE;
- }
-
- /**
- * Create HTML representation for this field
- *
- * @param string Field value
- * @param array Additional tag attributes
- * @return string Final HTML code
- */
- function show($value='', $attrib=NULL)
- {
- // overwrite object attributes
- if (is_array($attrib))
- $this->attrib = array_merge($this->attrib, $attrib);
-
- // take value attribute as content
- if ($value=='')
- $value = $this->attrib['value'];
-
- // make shure we don't print the value attribute
- if (isset($this->attrib['value']))
- unset($this->attrib['value']);
-
- if (!empty($value) && !isset($this->attrib['mce_editable']))
- $value = Q($value, 'strict', FALSE);
-
- // return final tag
- return sprintf(
- '<%s%s>%s</%s>%s',
- $this->_conv_case('textarea', 'tag'),
- $this->create_attrib_string(),
- $value,
- $this->_conv_case('textarea', 'tag'),
- ($this->newline ? "\n" : ""));
- }
-}
-
-
-/**
- * Builder for group of hidden form fields
- *
- * @package HTML
- */
-class hiddenfield extends rcube_form_element
-{
- var $fields_arr = array();
- var $newline = TRUE;
-
- /**
- * Constructor
- *
- * @param array Named tag attributes
- */
- function hiddenfield($attrib=NULL)
- {
- if (is_array($attrib))
- $this->add($attrib);
- }
-
- /**
- * Add a hidden field to this instance
- * @param array Named tag attributes
- */
- function add($attrib)
- {
- $this->fields_arr[] = $attrib;
- }
-
-
- /**
- * Create HTML code for the hidden fields
- *
- * @return string Final HTML code
- */
- function show()
- {
- $out = '';
- foreach ($this->fields_arr as $attrib)
- {
- $this->attrib = $attrib;
- $this->attrib['type'] = 'hidden';
-
- $out .= sprintf(
- '<%s%s />%s',
- $this->_conv_case('input', 'tag'),
- $this->create_attrib_string(),
- ($this->newline ? "\n" : ""));
- }
-
- return $out;
- }
-}
-
-
-/**
- * Builder for HTML drop-down menus
- * Syntax:<pre>
- * // create instance. arguments are used to set attributes of select-tag
- * $select = new select(array('name' => 'fieldname'));
- *
- * // add one option
- * $select->add('Switzerland', 'CH');
- *
- * // add multiple options
- * $select->add(array('Switzerland','Germany'), array('CH','DE'));
- *
- * // generate pulldown with selection 'Switzerland' and return html-code
- * // as second argument the same attributes available to instanciate can be used
- * print $select->show('CH');
- * </pre>
- *
- * @package HTML
- */
-class select extends rcube_form_element
-{
- var $options = array();
-
- /**
- * Constructor
- *
- * @param array Named tag attributes
- */
- function select($attrib=NULL)
- {
- if (is_array($attrib))
- $this->attrib = $attrib;
-
- if ($attrib['newline'])
- $this->newline = TRUE;
- }
-
-
- /**
- * Add one ore more menu options
- *
- * @param mixed Array with names or single option name
- * @param mixed Array with values or single option value
- */
- function add($names, $values=NULL)
- {
- if (is_array($names))
- {
- foreach ($names as $i => $text)
- $this->options[] = array('text' => $text, 'value' => $values[$i]);
- }
- else
- $this->options[] = array('text' => $names, 'value' => $values);
- }
-
-
- /**
- * Generate HTML code for this drop-down menu
- *
- * @param string Value of the selected option
- * @param array Additional tag attributes
- * @return string Final HTML code
- */
- function show($select=array(), $attrib=NULL)
- {
- $options_str = "\n";
- $value_str = $this->_conv_case(' value="%s"', 'attrib');
-
- if (!is_array($select))
- $select = array($select);
-
- foreach ($this->options as $option)
- {
- $selected = ((isset($option['value']) &&
- in_array($option['value'], $select, TRUE)) ||
- (in_array($option['text'], $select, TRUE))) ?
- $this->_conv_case(' selected="selected"', 'attrib') : '';
-
- $options_str .= sprintf("<%s%s%s>%s</%s>\n",
- $this->_conv_case('option', 'tag'),
- isset($option['value']) ? sprintf($value_str, Q($option['value'])) : '',
- $selected,
- Q($option['text'], 'strict', FALSE),
- $this->_conv_case('option', 'tag'));
- }
-
- // return final tag
- return sprintf('<%s%s>%s</%s>%s',
- $this->_conv_case('select', 'tag'),
- $this->create_attrib_string(),
- $options_str,
- $this->_conv_case('select', 'tag'),
- ($this->newline ? "\n" : ""));
- }
-}
-
-
-?>
diff --git a/program/include/rcube_html_page.php b/program/include/rcube_html_page.php
new file mode 100644
index 000000000..42036f63c
--- /dev/null
+++ b/program/include/rcube_html_page.php
@@ -0,0 +1,256 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_html_page.php |
+ | |
+ | This file is part of the RoundCube PHP suite |
+ | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | CONTENTS: |
+ | Class to build XHTML page output |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: $
+
+*/
+
+/**
+ * Class for HTML page creation
+ *
+ * @package HTML
+ */
+class rcube_html_page
+{
+ protected $scripts_path = '';
+ protected $script_files = array();
+ protected $external_scripts = array();
+ protected $scripts = array();
+ protected $charset = 'UTF-8';
+
+ protected $script_tag_file = "<script type=\"text/javascript\" src=\"%s%s\"></script>\n";
+ protected $script_tag = "<script type=\"text/javascript\">\n<!--\n%s\n\n//-->\n</script>\n";
+ protected $default_template = "<html>\n<head><title></title></head>\n<body></body>\n</html>";
+ protected $tag_format_external_script = "<script type=\"text/javascript\" src=\"%s\"></script>\n";
+
+ protected $title = '';
+ protected $header = '';
+ protected $footer = '';
+ protected $body = '';
+
+
+ /** Constructor */
+ public function __construct() {}
+
+ /**
+ * Link an external script file
+ *
+ * @param string File URL
+ * @param string Target position [head|foot]
+ */
+ public function include_script($file, $position='head')
+ {
+ static $sa_files = array();
+
+ if (in_array($file, $sa_files)) {
+ return;
+ }
+ if (!is_array($this->script_files[$position])) {
+ $this->script_files[$position] = array();
+ }
+ $this->script_files[$position][] = $file;
+ }
+
+ /**
+ * Add inline javascript code
+ *
+ * @param string JS code snippet
+ * @param string Target position [head|head_top|foot]
+ */
+ public function add_script($script, $position='head')
+ {
+ if (!isset($this->scripts[$position])) {
+ $this->scripts[$position] = "\n".rtrim($script);
+ } else {
+ $this->scripts[$position] .= "\n".rtrim($script);
+ }
+ }
+
+ /**
+ * Add HTML code to the page header
+ */
+ public function add_header($str)
+ {
+ $this->header .= "\n".$str;
+ }
+
+ /**
+ * Add HTML code to the page footer
+ * To be added right befor </body>
+ */
+ public function add_footer($str)
+ {
+ $this->footer .= "\n".$str;
+ }
+
+ /**
+ * Setter for page title
+ */
+ public function set_title($t)
+ {
+ $this->title = $t;
+ }
+
+ /**
+ * Setter for output charset.
+ * To be specified in a meta tag and sent as http-header
+ */
+ public function set_charset($charset)
+ {
+ $this->charset = $charset;
+ }
+
+ /**
+ * Getter for output charset
+ */
+ public function get_charset()
+ {
+ return $this->charset;
+ }
+
+ /**
+ * Reset all saved properties
+ */
+ public function reset()
+ {
+ $this->script_files = array();
+ $this->scripts = array();
+ $this->title = '';
+ $this->header = '';
+ $this->footer = '';
+ }
+
+ /**
+ * Process template and write to stdOut
+ *
+ * @param string HTML template
+ * @param string Base for absolute paths
+ */
+ public function write($templ='', $base_path='')
+ {
+ $output = empty($templ) ? $this->default_template : trim($templ);
+
+ // set default page title
+ if (empty($this->title)) {
+ $this->title = 'RoundCube Mail';
+ }
+
+ // replace specialchars in content
+ $__page_title = Q($this->title, 'show', FALSE);
+ $__page_header = $__page_body = $__page_footer = '';
+
+ // include meta tag with charset
+ if (!empty($this->charset)) {
+ if (!headers_sent()) {
+ header('Content-Type: text/html; charset=' . $this->charset);
+ }
+ $__page_header = '<meta http-equiv="content-type"';
+ $__page_header.= ' content="text/html; charset=';
+ $__page_header.= $this->charset . '" />'."\n";
+ }
+
+ // definition of the code to be placed in the document header and footer
+ if (is_array($this->script_files['head'])) {
+ foreach ($this->script_files['head'] as $file) {
+ $__page_header .= sprintf($this->script_tag_file, $this->scripts_path, $file);
+ }
+ }
+
+ $head_script = $this->scripts['head_top'] . $this->scripts['head'];
+ if (!empty($head_script)) {
+ $__page_header .= sprintf($this->script_tag, $head_script);
+ }
+
+ if (!empty($this->header)) {
+ $__page_header .= $this->header;
+ }
+
+ if (is_array($this->script_files['foot'])) {
+ foreach ($this->script_files['foot'] as $file) {
+ $__page_footer .= sprintf($this->script_tag_file, $this->scripts_path, $file);
+ }
+ }
+
+ if (!empty($this->scripts['foot'])) {
+ $__page_footer .= sprintf($this->script_tag, $this->scripts['foot']);
+ }
+
+ if (!empty($this->footer)) {
+ $__page_footer .= $this->footer;
+ }
+
+ // find page header
+ if ($hpos = strpos(strtolower($output), '</head>')) {
+ $__page_header .= "\n";
+ }
+ else {
+ if (!is_numeric($hpos)) {
+ $hpos = strpos(strtolower($output), '<body');
+ }
+ if (!is_numeric($hpos) && ($hpos = strpos(strtolower($output), '<html'))) {
+ while ($output[$hpos] != '>') {
+ $hpos++;
+ }
+ $hpos++;
+ }
+ $__page_header = "<head>\n<title>$__page_title</title>\n$__page_header\n</head>\n";
+ }
+
+ // add page hader
+ if ($hpos) {
+ $output = substr($output,0,$hpos) . $__page_header . substr($output,$hpos,strlen($output));
+ }
+ else {
+ $output = $__page_header . $output;
+ }
+
+ // find page body
+ if ($bpos = strpos(strtolower($output), '<body')) {
+ while ($output[$bpos] != '>') {
+ $bpos++;
+ }
+ $bpos++;
+ }
+ else {
+ $bpos = strpos(strtolower($output), '</head>')+7;
+ }
+
+ // add page body
+ if ($bpos && $__page_body) {
+ $output = substr($output,0,$bpos) . "\n$__page_body\n" . substr($output,$bpos,strlen($output));
+ }
+
+ // find and add page footer
+ $output_lc = strtolower($output);
+ if (($fpos = strrpos($output_lc, '</body>')) || ($fpos = strrpos($output_lc, '</html>'))) {
+ $output = substr($output, 0, $fpos) . "$__page_footer\n" . substr($output, $fpos);
+ }
+ else {
+ $output .= "\n".$__page_footer;
+ }
+
+ // reset those global vars
+ $__page_header = $__page_footer = '';
+
+ // correct absolute paths in images and other tags
+ $output = preg_replace('/(src|href|background)=(["\']?)(\/[a-z0-9_\-]+)/Ui', "\\1=\\2$base_path\\3", $output);
+ $output = str_replace('$__skin_path', $base_path, $output);
+
+ print rcube_charset_convert($output, 'UTF-8', $this->charset);
+ }
+}
+
diff --git a/program/include/rcube_imap.inc b/program/include/rcube_imap.php
index 9a594854c..04bb7bfc3 100644
--- a/program/include/rcube_imap.inc
+++ b/program/include/rcube_imap.php
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_imap.inc |
+ | program/include/rcube_imap.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -2929,4 +2929,3 @@ function quoted_printable_encode($input, $line_max=76, $space_conv=false)
}
-?>
diff --git a/program/include/rcube_json_output.php b/program/include/rcube_json_output.php
new file mode 100644
index 000000000..6bf4f8a2a
--- /dev/null
+++ b/program/include/rcube_json_output.php
@@ -0,0 +1,237 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_json_output.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Class to handle HTML page output using a skin template. |
+ | Extends rcube_html_page class from rcube_shared.inc |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: $
+
+*/
+
+
+/**
+ * View class to produce JSON responses
+ *
+ * @package View
+ */
+class rcube_json_output
+{
+ private $config;
+ private $charset = 'UTF-8';
+ private $env = array();
+ private $texts = array();
+ private $commands = array();
+
+ public $task = '';
+ public $ajax_call = true;
+
+
+ /**
+ * Constructor
+ */
+ public function __construct(&$config, $task)
+ {
+ $this->task = $task;
+ $this->config = $config;
+ }
+
+
+ /**
+ * Set environment variable
+ *
+ * @param string Property name
+ * @param mixed Property value
+ */
+ public function set_env($name, $value)
+ {
+ $this->env[$name] = $value;
+ }
+
+ /**
+ * @ignore
+ */
+ public function set_pagetitle($title)
+ {
+ // ignore
+ }
+
+ /**
+ * @ignore
+ */
+ function set_charset($charset)
+ {
+ // ignore: $this->charset = $charset;
+ }
+
+
+ /**
+ * Get charset for output
+ *
+ * @return string Output charset
+ */
+ function get_charset()
+ {
+ return $this->charset;
+ }
+
+
+ /**
+ * Register a template object handler
+ *
+ * @param string Object name
+ * @param string Function name to call
+ * @return void
+ */
+ public function add_handler($obj, $func)
+ {
+ // ignore
+ }
+
+ /**
+ * Register a list of template object handlers
+ *
+ * @param array Hash array with object=>handler pairs
+ * @return void
+ */
+ public function add_handlers($arr)
+ {
+ // ignore
+ }
+
+
+ /**
+ * Call a client method
+ *
+ * @param string Method to call
+ * @param ... Additional arguments
+ */
+ public function command()
+ {
+ $this->commands[] = func_get_args();
+ }
+
+
+ /**
+ * Add a localized label to the client environment
+ */
+ public function add_label()
+ {
+ $arg_list = func_get_args();
+ foreach ($arg_list as $i => $name) {
+ $this->texts[$name] = rcube::gettext($name);
+ }
+ }
+
+
+ /**
+ * Invoke display_message command
+ *
+ * @param string Message to display
+ * @param string Message type [notice|confirm|error]
+ * @param array Key-value pairs to be replaced in localized text
+ * @uses self::command()
+ */
+ public function show_message($message, $type='notice', $vars=null)
+ {
+ $this->command(
+ 'display_message',
+ rcube::gettext(array('name' => $message, 'vars' => $vars)),
+ $type
+ );
+ }
+
+ /**
+ * Delete all stored env variables and commands
+ */
+ public public function reset()
+ {
+ $this->env = array();
+ $this->texts = array();
+ $this->commands = array();
+ }
+
+
+ /**
+ * Send an AJAX response to the client.
+ */
+ public function send()
+ {
+ $this->remote_response();
+ exit;
+ }
+
+
+ /**
+ * Send an AJAX response with executable JS code
+ *
+ * @param string Additional JS code
+ * @param boolean True if output buffer should be flushed
+ * @return void
+ * @deprecated
+ */
+ public function remote_response($add='', $flush=false)
+ {
+ static $s_header_sent = false;
+
+ if (!$s_header_sent) {
+ $s_header_sent = true;
+ send_nocacheing_headers();
+ header('Content-Type: application/x-javascript; charset=' . $this->get_charset());
+ print '/** ajax response ['.date('d/M/Y h:i:s O')."] **/\n";
+ }
+
+ // unset default env vars
+ unset($this->env['task'], $this->env['action'], $this->env['comm_path']);
+
+ // send response code
+ echo $this->get_js_commands() . $add;
+
+ // flush the output buffer
+ if ($flush)
+ flush();
+ }
+
+
+ /**
+ * Return executable javascript code for all registered commands
+ *
+ * @return string $out
+ */
+ private function get_js_commands()
+ {
+ $out = 'this.set_env('.json_serialize($this->env).");\n";
+
+ foreach($this->texts as $name => $text) {
+ $out .= sprintf("this.add_label('%s', '%s');\n", $name, JQ($text));
+ }
+
+ foreach ($this->commands as $i => $args) {
+ $method = array_shift($args);
+ foreach ($args as $i => $arg) {
+ $args[$i] = json_serialize($arg);
+ }
+
+ $out .= sprintf(
+ "this.%s(%s);\n",
+ preg_replace('/^parent\./', '', $method),
+ implode(',', $args)
+ );
+ }
+
+ return $out;
+ }
+}
+
+
diff --git a/program/include/rcube_ldap.inc b/program/include/rcube_ldap.php
index 969101b2a..4d0574e67 100644
--- a/program/include/rcube_ldap.inc
+++ b/program/include/rcube_ldap.php
@@ -1,10 +1,10 @@
<?php
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_ldap.inc |
+ | program/include/rcube_ldap.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2006-2007, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -456,4 +456,4 @@ class rcube_ldap
}
-?>
+
diff --git a/program/include/rcube_mail_mime.php b/program/include/rcube_mail_mime.php
new file mode 100644
index 000000000..866786b93
--- /dev/null
+++ b/program/include/rcube_mail_mime.php
@@ -0,0 +1,206 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_mail_mime.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2007-2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Extend PEAR:Mail_mime class and override encodeHeaders method |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: sendmail.inc 506 2007-03-14 00:39:51Z thomasb $
+
+*/
+
+
+/**
+ * Replacement PEAR:Mail_mime with some additional or overloaded methods
+ *
+ * @package Mail
+ */
+class rcube_mail_mime extends Mail_mime
+{
+ /**
+ * Set build parameters
+ */
+ function setParam($param)
+ {
+ if (is_array($param)) {
+ $this->_build_params = array_merge($this->_build_params, $param);
+ }
+ }
+
+ /**
+ * Adds an image to the list of embedded images.
+ *
+ * @param string $file The image file name OR image data itself
+ * @param string $c_type The content type
+ * @param string $name The filename of the image.
+ * Only use if $file is the image data
+ * @param bool $isfilename Whether $file is a filename or not
+ * Defaults to true
+ * @param string $contentid Desired Content-ID of MIME part
+ * Defaults to generated unique ID
+ * @return mixed true on success or PEAR_Error object
+ * @access public
+ */
+ function addHTMLImage($file, $c_type='application/octet-stream', $name = '', $isfilename = true, $contentid = '')
+ {
+ $filedata = ($isfilename === true) ? $this->_file2str($file) : $file;
+ if ($isfilename === true) {
+ $filename = ($name == '' ? $file : $name);
+ }
+ else {
+ $filename = $name;
+ }
+
+ if (PEAR::isError($filedata)) {
+ return $filedata;
+ }
+
+ if ($contentid == '') {
+ $contentid = md5(uniqid(time()));
+ }
+
+ $this->_html_images[] = array(
+ 'body' => $filedata,
+ 'name' => $filename,
+ 'c_type' => $c_type,
+ 'cid' => $contentid
+ );
+
+ return true;
+ }
+
+
+ /**
+ * returns the HTML body portion of the message
+ * @return string HTML body of the message
+ * @access public
+ */
+ function getHTMLBody()
+ {
+ return $this->_htmlbody;
+ }
+
+
+ /**
+ * Creates a new mimePart object, using multipart/mixed as
+ * the initial content-type and returns it during the
+ * build process.
+ *
+ * @return object The multipart/mixed mimePart object
+ * @access private
+ */
+ function &_addMixedPart()
+ {
+ $params['content_type'] = $this->_headers['Content-Type'] ? $this->_headers['Content-Type'] : 'multipart/mixed';
+ $ret = new Mail_mimePart('', $params);
+ return $ret;
+ }
+
+
+ /**
+ * Encodes a header as per RFC2047
+ *
+ * @param array $input The header data to encode
+ * @param array $params Extra build parameters
+ * @return array Encoded data
+ * @access private
+ * @override
+ */
+ function _encodeHeaders($input, $params = array())
+ {
+ $maxlen = 73;
+ $params += $this->_build_params;
+
+ foreach ($input as $hdr_name => $hdr_value)
+ {
+ // if header contains e-mail addresses
+ if (preg_match('/\s<.+@[a-z0-9\-\.]+\.[a-z]+>/U', $hdr_value)) {
+ $chunks = $this->_explode_quoted_string(',', $hdr_value);
+ }
+ else {
+ $chunks = array($hdr_value);
+ }
+
+ $hdr_value = '';
+ $line_len = 0;
+
+ foreach ($chunks as $i => $value) {
+ $value = trim($value);
+
+ //This header contains non ASCII chars and should be encoded.
+ if (preg_match('#[\x80-\xFF]{1}#', $value)) {
+ $suffix = '';
+ // Don't encode e-mail address
+ if (preg_match('/(.+)\s(<.+@[a-z0-9\-\.]+>)$/Ui', $value, $matches)) {
+ $value = $matches[1];
+ $suffix = ' '.$matches[2];
+ }
+
+ switch ($params['head_encoding']) {
+ case 'base64':
+ // Base64 encoding has been selected.
+ $mode = 'B';
+ $encoded = base64_encode($value);
+ break;
+
+ case 'quoted-printable':
+ default:
+ // quoted-printable encoding has been selected
+ $mode = 'Q';
+ $encoded = preg_replace('/([\x2C\x3F\x80-\xFF])/e', "'='.sprintf('%02X', ord('\\1'))", $value);
+ // replace spaces with _
+ $encoded = str_replace(' ', '_', $encoded);
+ }
+
+ $value = '=?' . $params['head_charset'] . '?' . $mode . '?' . $encoded . '?=' . $suffix;
+ }
+
+ // add chunk to output string by regarding the header maxlen
+ $len = strlen($value);
+ if ($i == 0 || $line_len + $len < $maxlen) {
+ $hdr_value .= ($i>0?', ':'') . $value;
+ $line_len += $len + ($i>0?2:0);
+ }
+ else {
+ $hdr_value .= ($i>0?', ':'') . "\n " . $value;
+ $line_len = $len;
+ }
+ }
+
+ $input[$hdr_name] = $hdr_value;
+ }
+
+ return $input;
+ }
+
+
+ function _explode_quoted_string($delimiter, $string)
+ {
+ $result = array();
+ $strlen = strlen($string);
+ for ($q=$p=$i=0; $i < $strlen; $i++) {
+ if ($string{$i} == "\"" && $string{$i-1} != "\\") {
+ $q = $q ? false : true;
+ }
+ else if (!$q && $string{$i} == $delimiter) {
+ $result[] = substr($string, $p, $i - $p);
+ $p = $i + 1;
+ }
+ }
+
+ $result[] = substr($string, $p);
+ return $result;
+ }
+
+}
+
diff --git a/program/include/rcube_mdb2.inc b/program/include/rcube_mdb2.php
index 72d906664..f2845d3ac 100644
--- a/program/include/rcube_mdb2.inc
+++ b/program/include/rcube_mdb2.php
@@ -2,10 +2,10 @@
/*
+-----------------------------------------------------------------------+
- | program/include/rcube_mdb2.inc |
+ | program/include/rcube_mdb2.php |
| |
| This file is part of the RoundCube Webmail client |
- | Copyright (C) 2005-2007, RoundCube Dev. - Switzerland |
+ | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland |
| Licensed under the GNU GPL |
| |
| PURPOSE: |
@@ -22,12 +22,6 @@
/**
- * Obtain the PEAR::DB class that is used for abstraction
- */
-require_once('MDB2.php');
-
-
-/**
* Database independent query interface
*
* This is a wrapper for the PEAR::MDB2 class
@@ -617,4 +611,3 @@ function mdb2_debug_handler(&$db, $scope, $message, $context = array())
}
-?>
diff --git a/program/include/rcube_result_set.php b/program/include/rcube_result_set.php
new file mode 100644
index 000000000..7e968cd2b
--- /dev/null
+++ b/program/include/rcube_result_set.php
@@ -0,0 +1,74 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_result_set.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Class representing an address directory result set |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id: rcube_result_set.php 328 2006-08-30 17:41:21Z thomasb $
+
+*/
+
+
+/**
+ * RoundCube result set class.
+ * Representing an address directory result set.
+ *
+ * @package Addressbook
+ */
+class rcube_result_set
+{
+ var $count = 0;
+ var $first = 0;
+ var $current = 0;
+ var $records = array();
+
+ function __construct($c=0, $f=0)
+ {
+ $this->count = (int)$c;
+ $this->first = (int)$f;
+ }
+
+ function rcube_result_set($c=0, $f=0)
+ {
+ $this->__construct($c, $f);
+ }
+
+ function add($rec)
+ {
+ $this->records[] = $rec;
+ }
+
+ function iterate()
+ {
+ return $this->records[$this->current++];
+ }
+
+ function first()
+ {
+ $this->current = 0;
+ return $this->records[$this->current++];
+ }
+
+ // alias
+ function next()
+ {
+ return $this->iterate();
+ }
+
+ function seek($i)
+ {
+ $this->current = $i;
+ }
+
+} \ No newline at end of file
diff --git a/program/include/rcube_shared.inc b/program/include/rcube_shared.inc
index 815331195..c9cf4fbbf 100644
--- a/program/include/rcube_shared.inc
+++ b/program/include/rcube_shared.inc
@@ -91,7 +91,7 @@ function rcube_browser()
*/
function rcube_label($attrib)
{
- global $sess_user_lang, $INSTALL_PATH, $OUTPUT;
+ global $sess_user_lang, $OUTPUT;
static $sa_text_data, $s_language, $utf8_decode;
// extract attributes
@@ -111,8 +111,8 @@ function rcube_label($attrib)
$sa_text_data = array();
// get english labels (these should be complete)
- @include($INSTALL_PATH.'program/localization/en_US/labels.inc');
- @include($INSTALL_PATH.'program/localization/en_US/messages.inc');
+ @include(INSTALL_PATH.'program/localization/en_US/labels.inc');
+ @include(INSTALL_PATH.'program/localization/en_US/messages.inc');
if (is_array($labels))
$sa_text_data = $labels;
@@ -120,10 +120,10 @@ function rcube_label($attrib)
$sa_text_data = array_merge($sa_text_data, $messages);
// include user language files
- if ($sess_user_lang!='en' && is_dir($INSTALL_PATH.'program/localization/'.$sess_user_lang))
+ if ($sess_user_lang!='en' && is_dir(INSTALL_PATH.'program/localization/'.$sess_user_lang))
{
- include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/labels.inc');
- include_once($INSTALL_PATH.'program/localization/'.$sess_user_lang.'/messages.inc');
+ include_once(INSTALL_PATH.'program/localization/'.$sess_user_lang.'/labels.inc');
+ include_once(INSTALL_PATH.'program/localization/'.$sess_user_lang.'/messages.inc');
if (is_array($labels))
$sa_text_data = array_merge($sa_text_data, $labels);
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
new file mode 100755
index 000000000..2002a62fc
--- /dev/null
+++ b/program/include/rcube_template.php
@@ -0,0 +1,1004 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | program/include/rcube_template.php |
+ | |
+ | This file is part of the RoundCube Webmail client |
+ | Copyright (C) 2006-2008, RoundCube Dev. - Switzerland |
+ | Licensed under the GNU GPL |
+ | |
+ | PURPOSE: |
+ | Class to handle HTML page output using a skin template. |
+ | Extends rcube_html_page class from rcube_shared.inc |
+ | |
+ +-----------------------------------------------------------------------+
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+
+ $Id$
+
+ */
+
+
+/**
+ * Class to create HTML page output using a skin template
+ *
+ * @package View
+ * @todo Documentation
+ * @uses rcube_html_page
+ */
+class rcube_template extends rcube_html_page
+{
+ var $config;
+ var $task = '';
+ var $framed = false;
+ var $pagetitle = '';
+ var $env = array();
+ var $js_env = array();
+ var $js_commands = array();
+ var $object_handlers = array();
+
+ public $ajax_call = false;
+
+ /**
+ * Constructor
+ *
+ * @todo Use jQuery's $(document).ready() here.
+ */
+ public function __construct(&$config, $task)
+ {
+ parent::__construct();
+
+ $this->task = $task;
+ $this->config = $config;
+
+ // add common javascripts
+ $javascript = 'var '.JS_OBJECT_NAME.' = new rcube_webmail();';
+
+ // don't wait for page onload. Call init at the bottom of the page (delayed)
+ $javascript_foot = "if (window.call_init)\n call_init('".JS_OBJECT_NAME."');";
+
+ $this->add_script($javascript, 'head_top');
+ $this->add_script($javascript_foot, 'foot');
+ $this->scripts_path = 'program/js/';
+ $this->include_script('common.js');
+ $this->include_script('app.js');
+
+ // register common UI objects
+ $this->add_handlers(array(
+ 'loginform' => array($this, 'login_form'),
+ 'username' => array($this, 'current_username'),
+ 'message' => array($this, 'message_container'),
+ 'charsetselector' => array($this, 'charset_selector'),
+ ));
+ }
+
+ /**
+ * Set environment variable
+ *
+ * @param string Property name
+ * @param mixed Property value
+ * @param boolean True if this property should be added to client environment
+ */
+ public function set_env($name, $value, $addtojs = true)
+ {
+ $this->env[$name] = $value;
+ if ($addtojs || isset($this->js_env[$name])) {
+ $this->js_env[$name] = $value;
+ }
+ }
+
+
+ /**
+ * Set page title variable
+ */
+ public function set_pagetitle($title)
+ {
+ $this->pagetitle = $title;
+ }
+
+
+ /**
+ * Register a template object handler
+ *
+ * @param string Object name
+ * @param string Function name to call
+ * @return void
+ */
+ public function add_handler($obj, $func)
+ {
+ $this->object_handlers[$obj] = $func;
+ }
+
+ /**
+ * Register a list of template object handlers
+ *
+ * @param array Hash array with object=>handler pairs
+ * @return void
+ */
+ public function add_handlers($arr)
+ {
+ $this->object_handlers = array_merge($this->object_handlers, $arr);
+ }
+
+ /**
+ * Register a GUI object to the client script
+ *
+ * @param string Object name
+ * @param string Object ID
+ * @return void
+ */
+ public function add_gui_object($obj, $id)
+ {
+ $this->add_script(JS_OBJECT_NAME.".gui_object('$obj', '$id');");
+ }
+
+ /**
+ * Call a client method
+ *
+ * @param string Method to call
+ * @param ... Additional arguments
+ */
+ public function command()
+ {
+ $this->js_commands[] = func_get_args();
+ }
+
+
+ /**
+ * Add a localized label to the client environment
+ */
+ public function add_label()
+ {
+ $arg_list = func_get_args();
+ foreach ($arg_list as $i => $name) {
+ $this->command('add_label', $name, rcube_label($name));
+ }
+ }
+
+
+ /**
+ * Invoke display_message command
+ *
+ * @param string Message to display
+ * @param string Message type [notice|confirm|error]
+ * @param array Key-value pairs to be replaced in localized text
+ * @uses self::command()
+ */
+ public function show_message($message, $type='notice', $vars=NULL)
+ {
+ $this->command(
+ 'display_message',
+ rcube_label(array('name' => $message, 'vars' => $vars)),
+ $type);
+ }
+
+
+ /**
+ * Delete all stored env variables and commands
+ *
+ * @return void
+ * @uses rcube_html::reset()
+ * @uses self::$env
+ * @uses self::$js_env
+ * @uses self::$js_commands
+ * @uses self::$object_handlers
+ */
+ public public function reset()
+ {
+ $this->env = array();
+ $this->js_env = array();
+ $this->js_commands = array();
+ $this->object_handlers = array();
+ parent::reset();
+ }
+
+
+ /**
+ * Send the request output to the client.
+ * This will either parse a skin tempalte or send an AJAX response
+ *
+ * @param string Template name
+ * @param boolean True if script should terminate (default)
+ */
+ public function send($templ = null, $exit = true)
+ {
+ if ($templ != 'iframe') {
+ $this->parse($templ, false);
+ }
+ else {
+ $this->framed = $templ == 'iframe' ? true : $this->framed;
+ $this->write();
+ }
+
+ if ($exit) {
+ exit;
+ }
+ }
+
+ /**
+ * Process template and write to stdOut
+ *
+ * @param string HTML template
+ * @see rcube_html_page::write()
+ * @override
+ */
+ public function write($template = '')
+ {
+ // unlock interface after iframe load
+ if ($this->framed) {
+ array_unshift($this->js_commands, array('set_busy', false));
+ }
+ // write all env variables to client
+ $js = $this->framed ? "if(window.parent) {\n" : '';
+ $js .= $this->get_js_commands() . ($this->framed ? ' }' : '');
+ $this->add_script($js, 'head_top');
+
+ // call super method
+ parent::write($template, $this->config['skin_path']);
+ }
+
+ /**
+ * Parse a specific skin template and deliver to stdout
+ *
+ * Either returns nothing, or exists hard (exit();)
+ *
+ * @param string Template name
+ * @param boolean Exit script
+ * @return void
+ * @link http://php.net/manual/en/function.exit.php
+ */
+ private function parse($name = 'main', $exit = true)
+ {
+ $skin_path = $this->config['skin_path'];
+
+ // read template file
+ $templ = '';
+ $path = "$skin_path/templates/$name.html";
+
+ if (($fp = fopen($path, 'r')) === false) {
+ $message = '';
+ ob_start();
+ fopen($path, 'r');
+ $message.= ob_get_contents();
+ ob_end_clean();
+ rcube_error::raise(array(
+ 'code' => 501,
+ 'type' => 'php',
+ 'line' => __LINE__,
+ 'file' => __FILE__,
+ 'message' => 'Error loading template for '.$name.': '.$message
+ ), true, true);
+ return false;
+ }
+ $templ = fread($fp, filesize($path));
+ fclose($fp);
+
+ // parse for specialtags
+ $output = $this->parse_conditions($templ);
+ $output = $this->parse_xml($output);
+
+ // add debug console
+ if ($this->config['debug_level'] & 8) {
+ $this->add_footer('<div style="position:absolute;top:5px;left:5px;width:400px;padding:0.2em;background:white;opacity:0.8;z-index:9000">
+ <a href="#toggle" onclick="con=document.getElementById(\'dbgconsole\');con.style.display=(con.style.display==\'none\'?\'block\':\'none\');return false">console</a>
+ <form action="/" name="debugform"><textarea name="console" id="dbgconsole" rows="20" cols="40" wrap="off" style="display:none;width:400px;border:none;font-size:x-small"></textarea></form></div>'
+ );
+ }
+ $output = $this->parse_with_globals($output);
+ $this->write(trim($output), $skin_path);
+ if ($exit) {
+ exit;
+ }
+ }
+
+
+ /**
+ * Return executable javascript code for all registered commands
+ *
+ * @return string $out
+ */
+ private function get_js_commands()
+ {
+ $out = '';
+ if (!$this->framed && !empty($this->js_env)) {
+ $out .= JS_OBJECT_NAME . '.set_env('.json_serialize($this->js_env).");\n";
+ }
+ foreach ($this->js_commands as $i => $args) {
+ $method = array_shift($args);
+ foreach ($args as $i => $arg) {
+ $args[$i] = json_serialize($arg);
+ }
+ $parent = $this->framed || preg_match('/^parent\./', $method);
+ $out .= sprintf(
+ "%s.%s(%s);\n",
+ ($parent ? 'parent.' : '') . JS_OBJECT_NAME,
+ preg_replace('/^parent\./', '', $method),
+ implode(',', $args)
+ );
+ }
+ // add command to set page title
+ if ($this->ajax_call && !empty($this->pagetitle)) {
+ $out .= sprintf(
+ "this.set_pagetitle('%s');\n",
+ JQ((!empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '') . $this->pagetitle)
+ );
+ }
+ return $out;
+ }
+
+ /**
+ * Make URLs starting with a slash point to skin directory
+ *
+ * @param string Input string
+ * @return string
+ */
+ public function abs_url($str)
+ {
+ return preg_replace('/^\//', $this->config['skin_path'].'/', $str);
+ }
+
+
+ /***** Template parsing methods *****/
+
+ /**
+ * Replace all strings ($varname)
+ * with the content of the according global variable.
+ */
+ private function parse_with_globals($input)
+ {
+ $GLOBALS['__comm_path'] = Q($GLOBALS['COMM_PATH']);
+ return preg_replace('/\$(__[a-z0-9_\-]+)/e', '$GLOBALS["\\1"]', $input);
+ }
+
+ /**
+ * Public wrapper to dipp into template parsing.
+ *
+ * @param string $input
+ * @return string
+ * @uses rcube_template::parse_xml()
+ * @since 0.1-rc1
+ */
+ public function just_parse($input)
+ {
+ return $this->parse_xml($input);
+ }
+
+ /**
+ * Parse for conditional tags
+ *
+ * @param string $input
+ * @return string
+ */
+ private function parse_conditions($input)
+ {
+ $matches = preg_split('/<roundcube:(if|elseif|else|endif)\s+([^>]+)>/is', $input, 2, PREG_SPLIT_DELIM_CAPTURE);
+ if ($matches && count($matches) == 4) {
+ if (preg_match('/^(else|endif)$/i', $matches[1])) {
+ return $matches[0] . $this->parse_conditions($matches[3]);
+ }
+ $attrib = parse_attrib_string($matches[2]);
+ if (isset($attrib['condition'])) {
+ $condmet = $this->check_condition($attrib['condition']);
+ $submatches = preg_split('/<roundcube:(elseif|else|endif)\s+([^>]+)>/is', $matches[3], 2, PREG_SPLIT_DELIM_CAPTURE);
+ if ($condmet) {
+ $result = $submatches[0];
+ $result.= ($submatches[1] != 'endif' ? preg_replace('/.*<roundcube:endif\s+[^>]+>/Uis', '', $submatches[3], 1) : $submatches[3]);
+ }
+ else {
+ $result = "<roundcube:$submatches[1] $submatches[2]>" . $submatches[3];
+ }
+ return $matches[0] . $this->parse_conditions($result);
+ }
+ rcube_error::raise(array(
+ 'code' => 500,
+ 'type' => 'php',
+ 'line' => __LINE__,
+ 'file' => __FILE__,
+ 'message' => "Unable to parse conditional tag " . $matches[2]
+ ), true, false);
+ }
+ return $input;
+ }
+
+
+ /**
+ * Determines if a given condition is met
+ *
+ * @todo Get rid off eval() once I understand what this does.
+ * @todo Extend this to allow real conditions, not just "set"
+ * @param string Condition statement
+ * @return boolean True if condition is met, False is not
+ */
+ private function check_condition($condition)
+ {
+ $condition = preg_replace(
+ array(
+ '/session:([a-z0-9_]+)/i',
+ '/config:([a-z0-9_]+)/i',
+ '/env:([a-z0-9_]+)/i',
+ '/request:([a-z0-9_]+)/ie'
+ ),
+ array(
+ "\$_SESSION['\\1']",
+ "\$this->config['\\1']",
+ "\$this->env['\\1']",
+ "get_input_value('\\1', RCUVE_INPUT_GPC)"
+ ),
+ $condition);
+
+ return eval("return (".$condition.");");
+ }
+
+
+ /**
+ * Search for special tags in input and replace them
+ * with the appropriate content
+ *
+ * @param string Input string to parse
+ * @return string Altered input string
+ * @todo Maybe a cache.
+ */
+ private function parse_xml($input)
+ {
+ return preg_replace('/<roundcube:([-_a-z]+)\s+([^>]+)>/Uie', "\$this->xml_command('\\1', '\\2')", $input);
+ }
+
+
+ /**
+ * Convert a xml command tag into real content
+ *
+ * @param string Tag command: object,button,label, etc.
+ * @param string Attribute string
+ * @return string Tag/Object content
+ */
+ private function xml_command($command, $str_attrib, $add_attrib = array())
+ {
+ $command = strtolower($command);
+ $attrib = parse_attrib_string($str_attrib) + $add_attrib;
+
+ // empty output if required condition is not met
+ if (!empty($attrib['condition']) && !$this->check_condition($attrib['condition'])) {
+ return '';
+ }
+
+ // execute command
+ switch ($command) {
+ // return a button
+ case 'button':
+ if ($attrib['command']) {
+ return $this->button($attrib);
+ }
+ break;
+
+ // show a label
+ case 'label':
+ if ($attrib['name'] || $attrib['command']) {
+ return Q(rcube_label($attrib + array('vars' => array('product' => $this->config['product_name']))));
+ }
+ break;
+
+ // include a file
+ case 'include':
+ $path = realpath($this->config['skin_path'].$attrib['file']);
+ if ($fsize = filesize($path)) {
+ if ($this->config['skin_include_php']) {
+ $incl = $this->include_php($path);
+ }
+ else if ($fp = fopen($path, 'r')) {
+ $incl = fread($fp, $fsize);
+ fclose($fp);
+ }
+ return $this->parse_xml($incl);
+ }
+ break;
+
+ case 'plugin.include':
+ //rcube::tfk_debug(var_export($this->config['skin_path'], true));
+ $path = realpath($this->config['skin_path'].$attrib['file']);
+ if (!$path) {
+ //rcube::tfk_debug("Does not exist:");
+ //rcube::tfk_debug($this->config['skin_path']);
+ //rcube::tfk_debug($attrib['file']);
+ //rcube::tfk_debug($path);
+ }
+ $incl = file_get_contents($path);
+ if ($incl) {
+ return $this->parse_xml($incl);
+ }
+ break;
+
+ // return code for a specific application object
+ case 'object':
+ $object = strtolower($attrib['name']);
+
+ // we are calling a class/method
+ if (($handler = $this->object_handlers[$object]) && is_array($handler)) {
+ if ((is_object($handler[0]) && method_exists($handler[0], $handler[1])) ||
+ (is_string($handler[0]) && class_exists($handler[0])))
+ return call_user_func($handler, $attrib);
+ }
+ else if (function_exists($handler)) {
+ // execute object handler function
+ return call_user_func($handler, $attrib);
+ }
+
+ if ($object=='productname') {
+ $name = !empty($this->config['product_name']) ? $this->config['product_name'] : 'RoundCube Webmail';
+ return Q($name);
+ }
+ if ($object=='version') {
+ return (string)RCMAIL_VERSION;
+ }
+ if ($object=='pagetitle') {
+ $task = $this->task;
+ $title = !empty($this->config['product_name']) ? $this->config['product_name'].' :: ' : '';
+
+ if (!empty($this->pagetitle)) {
+ $title .= $this->pagetitle;
+ }
+ else if ($task == 'login') {
+ $title = rcube_label(array('name' => 'welcome', 'vars' => array('product' => $this->config['product_name'])));
+ }
+ else {
+ $title .= ucfirst($task);
+ }
+
+ return Q($title);
+ }
+ break;
+
+ // return variable
+ case 'var':
+ $var = explode(':', $attrib['name']);
+ $name = $var[1];
+ $value = '';
+
+ switch ($var[0]) {
+ case 'env':
+ $value = $this->env[$name];
+ break;
+ case 'config':
+ $value = $this->config[$name];
+ if (is_array($value) && $value[$_SESSION['imap_host']]) {
+ $value = $value[$_SESSION['imap_host']];
+ }
+ break;
+ case 'request':
+ $value = get_input_value($name, RCUBE_INPUT_GPC);
+ break;
+ case 'session':
+ $value = $_SESSION[$name];
+ break;
+ }
+
+ if (is_array($value)) {
+ $value = implode(', ', $value);
+ }
+
+ return Q($value);
+ break;
+ }
+ return '';
+ }
+
+ /**
+ * Include a specific file and return it's contents
+ *
+ * @param string File path
+ * @return string Contents of the processed file
+ */
+ private function include_php($file)
+ {
+ ob_start();
+ include $file;
+ $out = ob_get_contents();
+ ob_end_clean();
+
+ return $out;
+ }
+
+
+ /**
+ * Create and register a button
+ *
+ * @param array Named button attributes
+ * @return string HTML button
+ * @todo Remove all inline JS calls and use jQuery instead.
+ * @todo Remove all sprintf()'s - they are pretty, but also slow.
+ */
+ private function button($attrib)
+ {
+ global $CONFIG, $OUTPUT, $MAIN_TASKS;
+ static $sa_buttons = array();
+ static $s_button_count = 100;
+
+ // these commands can be called directly via url
+ $a_static_commands = array('compose', 'list');
+
+ $browser = new rcube_browser();
+ $skin_path = $this->config['skin_path'];
+
+ if (!($attrib['command'] || $attrib['name'])) {
+ return '';
+ }
+ // try to find out the button type
+ if ($attrib['type']) {
+ $attrib['type'] = strtolower($attrib['type']);
+ }
+ else {
+ $attrib['type'] = ($attrib['image'] || $attrib['imagepas'] || $attrib['imageact']) ? 'image' : 'link';
+ }
+ $command = $attrib['command'];
+
+ // take the button from the stack
+ if ($attrib['name'] && $sa_buttons[$attrib['name']]) {
+ $attrib = $sa_buttons[$attrib['name']];
+ }
+ else if($attrib['image'] || $attrib['imageact'] || $attrib['imagepas'] || $attrib['class']) {
+ // add button to button stack
+ if (!$attrib['name']) {
+ $attrib['name'] = $command;
+ }
+ if (!$attrib['image']) {
+ $attrib['image'] = $attrib['imagepas'] ? $attrib['imagepas'] : $attrib['imageact'];
+ }
+ $sa_buttons[$attrib['name']] = $attrib;
+ }
+ else if ($command && $sa_buttons[$command]) {
+ // get saved button for this command/name
+ $attrib = $sa_buttons[$command];
+ }
+
+ // set border to 0 because of the link arround the button
+ if ($attrib['type']=='image' && !isset($attrib['border'])) {
+ $attrib['border'] = 0;
+ }
+ if (!$attrib['id']) {
+ $attrib['id'] = sprintf('rcmbtn%d', $s_button_count++);
+ }
+ // get localized text for labels and titles
+ if ($attrib['title']) {
+ $attrib['title'] = Q(rcube_label($attrib['title']));
+ }
+ if ($attrib['label']) {
+ $attrib['label'] = Q(rcube_label($attrib['label']));
+ }
+ if ($attrib['alt']) {
+ $attrib['alt'] = Q(rcube_label($attrib['alt']));
+ }
+ // set title to alt attribute for IE browsers
+ if ($browser->ie && $attrib['title'] && !$attrib['alt']) {
+ $attrib['alt'] = $attrib['title'];
+ unset($attrib['title']);
+ }
+
+ // add empty alt attribute for XHTML compatibility
+ if (!isset($attrib['alt'])) {
+ $attrib['alt'] = '';
+ }
+
+ // register button in the system
+ if ($attrib['command']) {
+ $this->add_script(sprintf(
+ "%s.register_button('%s', '%s', '%s', '%s', '%s', '%s');",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['id'],
+ $attrib['type'],
+ $attrib['imageact'] ? $skin_path.$attrib['imageact'] : $attrib['classact'],
+ $attrib['imagesel'] ? $skin_path.$attrib['imagesel'] : $attrib['classsel'],
+ $attrib['imageover'] ? $skin_path.$attrib['imageover'] : ''
+ ));
+
+ // make valid href to specific buttons
+ if (in_array($attrib['command'], $MAIN_TASKS)) {
+ $attrib['href'] = Q(rcmail_url(null, null, $attrib['command']));
+ }
+ else if (in_array($attrib['command'], $a_static_commands)) {
+ $attrib['href'] = Q(rcmail_url($attrib['command']));
+ }
+ }
+
+ // overwrite attributes
+ if (!$attrib['href']) {
+ $attrib['href'] = '#';
+ }
+ if ($command) {
+ $attrib['onclick'] = sprintf(
+ "return %s.command('%s','%s',this)",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['prop']
+ );
+ }
+ if ($command && $attrib['imageover']) {
+ $attrib['onmouseover'] = sprintf(
+ "return %s.button_over('%s','%s')",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['id']
+ );
+ $attrib['onmouseout'] = sprintf(
+ "return %s.button_out('%s','%s')",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['id']
+ );
+ }
+
+ if ($command && $attrib['imagesel']) {
+ $attrib['onmousedown'] = sprintf(
+ "return %s.button_sel('%s','%s')",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['id']
+ );
+ $attrib['onmouseup'] = sprintf(
+ "return %s.button_out('%s','%s')",
+ JS_OBJECT_NAME,
+ $command,
+ $attrib['id']
+ );
+ }
+
+ $out = '';
+
+ // generate image tag
+ if ($attrib['type']=='image') {
+ $attrib_str = html::attrib_string(
+ $attrib,
+ array(
+ 'style', 'class', 'id', 'width',
+ 'height', 'border', 'hspace',
+ 'vspace', 'align', 'alt',
+ )
+ );
+ $img_tag = sprintf('<img src="%%s"%s />', $attrib_str);
+ $btn_content = sprintf($img_tag, $skin_path.$attrib['image']);
+ if ($attrib['label']) {
+ $btn_content .= ' '.$attrib['label'];
+ }
+ $link_attrib = array('href', 'onclick', 'onmouseover', 'onmouseout', 'onmousedown', 'onmouseup', 'title');
+ }
+ else if ($attrib['type']=='link') {
+ $btn_content = $attrib['label'] ? $attrib['label'] : $attrib['command'];
+ $link_attrib = array('href', 'onclick', 'title', 'id', 'class', 'style');
+ }
+ else if ($attrib['type']=='input') {
+ $attrib['type'] = 'button';
+
+ if ($attrib['label']) {
+ $attrib['value'] = $attrib['label'];
+ }
+
+ $attrib_str = html::attrib_string(
+ $attrib,
+ array(
+ 'type', 'value', 'onclick',
+ 'id', 'class', 'style'
+ )
+ );
+ $out = sprintf('<input%s disabled="disabled" />', $attrib_str);
+ }
+
+ // generate html code for button
+ if ($btn_content) {
+ $attrib_str = html::attrib_string($attrib, $link_attrib);
+ $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);
+ }
+
+ return $out;
+ }
+
+
+ /* ************* common functions delivering gui objects ************** */
+
+
+ /**
+ * GUI object 'username'
+ * Showing IMAP username of the current session
+ *
+ * @param array Named tag parameters (currently not used)
+ * @return string HTML code for the gui object
+ */
+ static function current_username($attrib)
+ {
+ global $USER;
+ static $username;
+
+ // alread fetched
+ if (!empty($username)) {
+ return $username;
+ }
+
+ // get e-mail address form default identity
+ if ($sql_arr = $USER->get_identity()) {
+ $s_username = $sql_arr['email'];
+ }
+ else if (strstr($_SESSION['username'], '@')) {
+ $username = $_SESSION['username'];
+ }
+ else {
+ $username = $_SESSION['username'].'@'.$_SESSION['imap_host'];
+ }
+
+ return $username;
+ }
+
+
+ /**
+ * GUI object 'loginform'
+ * Returns code for the webmail login form
+ *
+ * @param array Named parameters
+ * @return string HTML code for the gui object
+ */
+ private function login_form($attrib)
+ {
+ global $CONFIG, $SESS_HIDDEN_FIELD;
+ $default_host = $CONFIG['default_host'];
+
+ $_SESSION['temp'] = true;
+
+ $input_user = new html_inputfield(array('name' => '_user', 'id' => 'rcmloginuser', 'size' => 30, 'autocomplete' => 'off'));
+ $input_pass = new html_passwordfield(array('name' => '_pass', 'id' => 'rcmloginpwd', 'size' => 30));
+ $input_action = new html_hiddenfield(array('name' => '_action', 'value' => 'login'));
+ $input_host = null;
+
+ if (is_array($default_host)) {
+ $input_host = new html_select(array('name' => '_host', 'id' => 'rcmloginhost'));
+
+ foreach ($default_host as $key => $value) {
+ if (!is_array($value)) {
+ $input_host->add($value, (is_numeric($key) ? $value : $key));
+ }
+ else {
+ $input_host = null;
+ break;
+ }
+ }
+ }
+ else if (!strlen($default_host)) {
+ $input_host = new html_inputfield(array('name' => '_host', 'id' => 'rcmloginhost', 'size' => 30));
+ }
+
+ $form_name = !empty($attrib['form']) ? $attrib['form'] : 'form';
+ $this->add_gui_object('loginform', $form_name);
+
+ // create HTML table with two cols
+ $table = new html_table(array('cols' => 2));
+
+ $table->add('title', html::label('rcmloginuser', Q(rcube_label('username'))));
+ $table->add(null, $input_user->show(get_input_value('_user', RCUVE_INPUT_POST)));
+
+ $table->add('title', html::label('rcmloginpwd', Q(rcube_label('password'))));
+ $table->add(null, $input_pass->show());
+
+ // add host selection row
+ if (is_object($input_host)) {
+ $table->add('title', html::label('rcmloginhost', Q(rcube_label('server'))));
+ $table->add(null, $input_host->show(get_input_value('_host', RCUVE_INPUT_POST)));
+ }
+
+ $out = $SESS_HIDDEN_FIELD;
+ $out .= $input_action->show();
+ $out .= $table->show();
+
+ // surround html output with a form tag
+ if (empty($attrib['form'])) {
+ $out = html::tag(
+ 'form',
+ array(
+ 'name' => $form_name,
+ 'action' => "./",
+ 'method' => "post"
+ ),
+ $out);
+ }
+
+ return $out;
+ }
+
+
+ /**
+ * GUI object 'searchform'
+ * Returns code for search function
+ *
+ * @param array Named parameters
+ * @return string HTML code for the gui object
+ */
+ private function search_form($attrib)
+ {
+ // add some labels to client
+ $this->add_label('searching');
+
+ $attrib['name'] = '_q';
+
+ if (empty($attrib['id'])) {
+ $attrib['id'] = 'rcmqsearchbox';
+ }
+ $input_q = new html_inputfield($attrib);
+ $out = $input_q->show();
+
+ $this->add_gui_object('qsearchbox', $attrib['id']);
+
+ // add form tag around text field
+ if (empty($attrib['form'])) {
+ $out = html::tag(
+ 'form',
+ array(
+ 'name' => "rcmqsearchform",
+ 'action' => "./",
+ 'onsubmit' => JS_OBJECT_NAME . ".command('search');return false;",
+ 'style' => "display:inline",
+ ),
+ $out);
+ }
+
+ return $out;
+ }
+
+
+ /**
+ * Builder for GUI object 'message'
+ *
+ * @param array Named tag parameters
+ * @return string HTML code for the gui object
+ */
+ private function message_container($attrib)
+ {
+ if (isset($attrib['id']) === false) {
+ $attrib['id'] = 'rcmMessageContainer';
+ }
+
+ $this->add_gui_object('message', $attrib['id']);
+ return html::div($attrib, "");
+ }
+
+
+ /**
+ * GUI object 'charsetselector'
+ *
+ * @param array Named parameters for the select tag
+ * @return string HTML code for the gui object
+ */
+ static function charset_selector($attrib)
+ {
+ // pass the following attributes to the form class
+ $field_attrib = array('name' => '_charset');
+ foreach ($attrib as $attr => $value) {
+ if (in_array($attr, array('id', 'class', 'style', 'size', 'tabindex'))) {
+ $field_attrib[$attr] = $value;
+ }
+ }
+ $charsets = array(
+ 'US-ASCII' => 'ASCII (English)',
+ 'EUC-JP' => 'EUC-JP (Japanese)',
+ 'EUC-KR' => 'EUC-KR (Korean)',
+ 'BIG5' => 'BIG5 (Chinese)',
+ 'GB2312' => 'GB2312 (Chinese)',
+ 'ISO-2022-JP' => 'ISO-2022-JP (Japanese)',
+ 'ISO-8859-1' => 'ISO-8859-1 (Latin-1)',
+ 'ISO-8859-2' => 'ISO-8895-2 (Central European)',
+ 'ISO-8859-7' => 'ISO-8859-7 (Greek)',
+ 'ISO-8859-9' => 'ISO-8859-9 (Turkish)',
+ 'Windows-1251' => 'Windows-1251 (Cyrillic)',
+ 'Windows-1252' => 'Windows-1252 (Western)',
+ 'Windows-1255' => 'Windows-1255 (Hebrew)',
+ 'Windows-1256' => 'Windows-1256 (Arabic)',
+ 'Windows-1257' => 'Windows-1257 (Baltic)',
+ 'UTF-8' => 'UTF-8'
+ );
+
+ $select = new html_select($field_attrib);
+ $select->add(array_values($charsets), array_keys($charsets));
+
+ $set = $_POST['_charset'] ? $_POST['_charset'] : $this->get_charset();
+ return $select->show($set);
+ }
+
+} // end class rcube_template
+
+
diff --git a/program/include/rcube_user.inc b/program/include/rcube_user.php
index e748758a9..e748758a9 100644
--- a/program/include/rcube_user.inc
+++ b/program/include/rcube_user.php