CHANGELOG | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_smtp.php | ●●●●● patch | view | raw | blame | history | |
program/include/rcube_template.php | ●●●●● patch | view | raw | blame | history | |
program/js/app.js | ●●●●● patch | view | raw | blame | history | |
program/js/list.js | ●●●●● patch | view | raw | blame | history | |
program/lib/Net/SMTP.php | ●●●●● patch | view | raw | blame | history | |
program/localization/de_CH/messages.inc | ●●●●● patch | view | raw | blame | history | |
program/localization/de_DE/messages.inc | ●●●●● patch | view | raw | blame | history | |
program/localization/index.inc | ●●●●● patch | view | raw | blame | history |
CHANGELOG
@@ -1,6 +1,8 @@ CHANGELOG Roundcube Webmail =========================== - PEAR::Net_SMTP 1.5.2, fixed timeout issue (#1487843) - Fix bug where template name without plugin prefix was used in render_page hook - Support 'abort' and 'result' response in 'preferences_save' hook, add error handling - Fix bug where some content would cause hang on html2text conversion (#1487863) - Improve space-stuffing handling in format=flowed messages (#1487861) @@ -8,7 +10,6 @@ - Added workaround for some IMAP server with broken STATUS response (#1487859) - Fix bug where default_charset was not used for text messages (#1487836) - Stateless request tokens. No keep-alive necessary on login page (#1487829) - PEAR::Net_SMTP 1.5.1 - Force names of unique constraints in PostgreSQL DDL - Add code for prevention from IMAP connection hangs when server closes socket unexpectedly - Remove redundant DELETE query (for old session deletion) on login @@ -16,7 +17,7 @@ - Fix some emails are not shown using Cyrus IMAP (#1487820) - Fix handling of mime-encoded words with non-integral number of octets in a word (#1487801) - Fix parsing links with non-printable characters inside (#1487805) - Fixed de_CH Localization bugs (#1487773) - Fixed de_CH/de_DE localization bugs (#1487773) - Add variable for 'Today' label in date_today option (#1486120) - Applied plugin changes since 0.5-stable release - Fix SQL query in rcube_user::query() so it uses index on MySQL again program/include/rcube_smtp.php
@@ -116,6 +116,13 @@ $this->error = array('label' => 'smtpconnerror', 'vars' => array('code' => $this->conn->_code)); $this->conn = null; return false; } // workaround for timeout bug in Net_SMTP 1.5.[0-1] (#1487843) if (method_exists($this->conn, 'setTimeout') && ($timeout = ini_get('default_socket_timeout')) ) { $this->conn->setTimeout($timeout); } $smtp_user = str_replace('%u', $_SESSION['username'], $CONFIG['smtp_user']); program/include/rcube_template.php
@@ -374,15 +374,18 @@ { $skin_path = $this->config['skin_path']; $plugin = false; $realname = $name; $temp = explode('.', $name, 2); $this->plugin_skin_path = null; $temp = explode(".", $name, 2); if (count($temp) > 1) { $plugin = $temp[0]; $name = $temp[1]; $skin_dir = $plugin . '/skins/' . $this->config['skin']; $skin_path = $this->plugin_skin_path = $this->app->plugins->dir . $skin_dir; if (!is_dir($skin_path)) { // fallback to default skin // fallback to default skin if (!is_dir($skin_path)) { $skin_dir = $plugin . '/skins/default'; $skin_path = $this->plugin_skin_path = $this->app->plugins->dir . $skin_dir; } @@ -390,12 +393,13 @@ $path = "$skin_path/templates/$name.html"; if (!is_readable($path) && $this->deprecated_templates[$name]) { $path = "$skin_path/templates/".$this->deprecated_templates[$name].".html"; if (!is_readable($path) && $this->deprecated_templates[$realname]) { $path = "$skin_path/templates/".$this->deprecated_templates[$realname].".html"; if (is_readable($path)) raise_error(array('code' => 502, 'type' => 'php', 'file' => __FILE__, 'line' => __LINE__, 'message' => "Using deprecated template '".$this->deprecated_templates[$name]."' in ".$this->config['skin_path']."/templates. Please rename to '".$name."'"), 'message' => "Using deprecated template '".$this->deprecated_templates[$realname] ."' in ".$this->config['skin_path']."/templates. Please rename to '".$realname."'"), true, false); } @@ -406,7 +410,7 @@ 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__, 'message' => 'Error loading template for '.$name 'message' => 'Error loading template for '.$realname ), true, true); return false; } @@ -422,7 +426,7 @@ $output = $this->parse_xml($output); // trigger generic hook where plugins can put additional content to the page $hook = $this->app->plugins->exec_hook("render_page", array('template' => $name, 'content' => $output)); $hook = $this->app->plugins->exec_hook("render_page", array('template' => $realname, 'content' => $output)); // add debug console if ($this->config['debug_level'] & 8) { program/js/app.js
@@ -4650,17 +4650,18 @@ // and for setting some message list global variables this.set_message_coltypes = function(coltypes, repl) { this.env.coltypes = coltypes; var list = this.message_list, thead = list ? list.list.tHead : null, cell, col, n, len, th, tr; // set correct list titles var thead = this.gui_objects.messagelist ? this.gui_objects.messagelist.tHead : null, cell, col, n, len; this.env.coltypes = coltypes; // replace old column headers if (thead) { if (repl) { var th = document.createElement('thead'), th = document.createElement('thead'); tr = document.createElement('tr'); for (c=0, len=repl.length; c < len; c++) { cell = document.createElement('td'); cell.innerHTML = repl[c].html; @@ -4694,15 +4695,16 @@ if ((n = $.inArray('subject', this.env.coltypes)) >= 0) { this.set_env('subject_col', n); if (this.message_list) this.message_list.subject_col = n; if (list) list.subject_col = n; } if ((n = $.inArray('flag', this.env.coltypes)) >= 0) this.set_env('flagged_col', n); if ((n = $.inArray('status', this.env.coltypes)) >= 0) this.set_env('status_col', n); this.message_list.init_header(); if (list) list.init_header(); }; // replace content of row count display program/js/list.js
@@ -102,8 +102,8 @@ { // make references in internal array and set event handlers if (row && String(row.id).match(/rcmrow([a-z0-9\-_=\+\/]+)/i)) { var self = this; var uid = RegExp.$1; var self = this, uid = RegExp.$1; row.uid = uid; this.rows[uid] = {uid:uid, id:row.id, obj:row}; @@ -170,6 +170,10 @@ if (sel) this.clear_selection(); // reset scroll position (in Opera) if (this.frame) this.frame.scrollTop = 0; }, @@ -212,10 +216,10 @@ */ focus: function(e) { var id; var n, id; this.focused = true; for (var n in this.selection) { for (n in this.selection) { id = this.selection[n]; if (this.rows[id] && this.rows[id].obj) { $(this.rows[id].obj).addClass('selected').removeClass('unfocused'); @@ -236,9 +240,9 @@ */ blur: function() { var id; var n, id; this.focused = false; for (var n in this.selection) { for (n in this.selection) { id = this.selection[n]; if (this.rows[id] && this.rows[id].obj) { $(this.rows[id].obj).removeClass('selected').addClass('unfocused'); @@ -430,8 +434,7 @@ expand: function(row) { var depth, new_row; var last_expanded_parent_depth; var r, p, depth, new_row, last_expanded_parent_depth; if (row) { row.expanded = true; @@ -449,13 +452,13 @@ while (new_row) { if (new_row.nodeType == 1) { var r = this.rows[new_row.uid]; r = this.rows[new_row.uid]; if (r) { if (row && (!r.depth || r.depth <= depth)) break; if (r.parent_uid) { var p = this.rows[r.parent_uid]; p = this.rows[r.parent_uid]; if (p && p.expanded) { if ((row && p == row) || last_expanded_parent_depth >= p.depth - 1) { last_expanded_parent_depth = p.depth; @@ -696,9 +699,10 @@ */ select_next: function() { var next_row = this.get_next_row(); var prev_row = this.get_prev_row(); var new_row = (next_row) ? next_row : prev_row; var next_row = this.get_next_row(), prev_row = this.get_prev_row(), new_row = (next_row) ? next_row : prev_row; if (new_row) this.select_row(new_row.uid, false, false); }, @@ -710,13 +714,16 @@ select_first: function(mod_key) { var row = this.get_first_row(); if (row && mod_key) { if (row) { if (mod_key) { this.shift_select(row, mod_key); this.triggerEvent('select'); this.scrollto(row); } else if (row) else { this.select(row); } } }, @@ -726,13 +733,16 @@ select_last: function(mod_key) { var row = this.get_last_row(); if (row && mod_key) { if (row) { if (mod_key) { this.shift_select(row, mod_key); this.triggerEvent('select'); this.scrollto(row); } else if (row) else { this.select(row); } } }, @@ -744,8 +754,9 @@ if (!this.rows[uid] || !this.rows[uid].has_children) return; var depth = this.rows[uid].depth; var row = this.rows[uid].obj.nextSibling; var depth = this.rows[uid].depth, row = this.rows[uid].obj.nextSibling; while (row) { if (row.nodeType == 1) { if ((r = this.rows[row.uid])) { @@ -768,13 +779,13 @@ if (!this.rows[this.shift_start] || !this.selection.length) this.shift_start = id; var from_rowIndex = this.rows[this.shift_start].obj.rowIndex, var n, from_rowIndex = this.rows[this.shift_start].obj.rowIndex, to_rowIndex = this.rows[id].obj.rowIndex, i = ((from_rowIndex < to_rowIndex)? from_rowIndex : to_rowIndex), j = ((from_rowIndex > to_rowIndex)? from_rowIndex : to_rowIndex); // iterate through the entire message list for (var n in this.rows) { for (n in this.rows) { if (this.rows[n].obj.rowIndex >= i && this.rows[n].obj.rowIndex <= j) { if (!this.in_selection(n)) { this.highlight_row(n, true); @@ -811,10 +822,10 @@ return false; // reset but remember selection first var select_before = this.selection.join(','); var n, select_before = this.selection.join(','); this.selection = []; for (var n in this.rows) { for (n in this.rows) { if (!filter || this.rows[n][filter] == true) { this.last_selected = n; this.highlight_row(n, true); @@ -843,9 +854,9 @@ return false; // remember old selection var select_before = this.selection.join(','); var n, select_before = this.selection.join(','); for (var n in this.rows) for (n in this.rows) this.highlight_row(n, true); // trigger event if selection changed @@ -863,11 +874,11 @@ */ clear_selection: function(id) { var num_select = this.selection.length; var n, num_select = this.selection.length; // one row if (id) { for (var n in this.selection) for (n in this.selection) if (this.selection[n] == id) { this.selection.splice(n,1); break; @@ -875,7 +886,7 @@ } // all rows else { for (var n in this.selection) for (n in this.selection) if (this.rows[this.selection[n]]) { $(this.rows[this.selection[n]].obj).removeClass('selected').removeClass('unfocused'); } @@ -927,9 +938,10 @@ $(this.rows[id].obj).addClass('selected'); } else { // unselect row var p = $.inArray(id, this.selection); var a_pre = this.selection.slice(0, p); var a_post = this.selection.slice(p+1, this.selection.length); var p = $.inArray(id, this.selection), a_pre = this.selection.slice(0, p), a_post = this.selection.slice(p+1, this.selection.length); this.selection = a_pre.concat(a_post); $(this.rows[id].obj).removeClass('selected').removeClass('unfocused'); } @@ -945,8 +957,8 @@ if (this.focused != true) return true; var keyCode = rcube_event.get_keycode(e); var mod_key = rcube_event.get_modifier(e); var keyCode = rcube_event.get_keycode(e), mod_key = rcube_event.get_modifier(e); switch (keyCode) { case 40: @@ -1371,7 +1383,7 @@ */ column_replace: function(from, to) { var cells = this.list.tHead.rows[0].cells, var len, cells = this.list.tHead.rows[0].cells, elem = cells[from], before = cells[to], td = document.createElement('td'); @@ -1384,7 +1396,7 @@ cells[0].parentNode.replaceChild(elem, td); // replace list cells for (r=0; r<this.list.tBodies[0].rows.length; r++) { for (r=0, len=this.list.tBodies[0].rows.length; r<len; r++) { row = this.list.tBodies[0].rows[r]; elem = row.cells[from]; program/lib/Net/SMTP.php
@@ -106,6 +106,14 @@ var $_socket = null; /** * Array of socket options that will be passed to Net_Socket::connect(). * @see stream_context_create() * @var array * @access private */ var $_socket_options = null; /** * The socket I/O timeout value in seconds. * @var int * @access private @@ -156,12 +164,13 @@ * @param string $localhost The value to give when sending EHLO or HELO. * @param boolean $pipeling Use SMTP command pipelining * @param integer $timeout Socket I/O timeout in seconds. * @param array $socket_options Socket stream_context_create() options. * * @access public * @since 1.0 */ function Net_SMTP($host = null, $port = null, $localhost = null, $pipelining = false, $timeout = 0) $pipelining = false, $timeout = 0, $socket_options = null) { if (isset($host)) { $this->host = $host; @@ -175,6 +184,7 @@ $this->pipelining = $pipelining; $this->_socket = new Net_Socket(); $this->_socket_options = $socket_options; $this->_timeout = $timeout; /* Include the Auth_SASL package. If the package is not @@ -405,7 +415,8 @@ { $this->_greeting = null; $result = $this->_socket->connect($this->host, $this->port, $persistent, $timeout); $persistent, $timeout, $this->_socket_options); if (PEAR::isError($result)) { return PEAR::raiseError('Failed to connect socket: ' . $result->getMessage()); @@ -417,9 +428,11 @@ * timeout values for the initial connection (our $timeout parameter) * and all other socket operations. */ if ($this->_timeout > 0) { if (PEAR::isError($error = $this->setTimeout($this->_timeout))) { return $error; } } if (PEAR::isError($error = $this->_parseResponse(220))) { return $error; program/localization/de_CH/messages.inc
@@ -135,7 +135,7 @@ $messages['nametoolong'] = 'Der Name ist zu lang'; $messages['folderupdated'] = 'Der Ordner wurde erfolgreich aktualisiert'; $messages['foldercreated'] = 'Der Ordner wurde erfolgreich erstellt'; $messages['errorreadonly'] = 'Die Aktion nicht ausgeführt werden. Der Ordner ist schreibgeschützt.'; $messages['errornoperm'] = 'Die Aktion nicht ausgeführt werden. Zugriff verweigert.'; $messages['errorreadonly'] = 'Die Aktion kann nicht ausgeführt werden. Der Ordner ist schreibgeschützt.'; $messages['errornoperm'] = 'Die Aktion kann nicht ausgeführt werden. Zugriff verweigert.'; ?> program/localization/de_DE/messages.inc
@@ -24,8 +24,8 @@ $messages['imaperror'] = 'Keine Verbindung zum IMAP-Server'; $messages['servererror'] = 'Serverfehler!'; $messages['servererrormsg'] = 'Serverfehler: $msg'; $messages['errorreadonly'] = 'Die Aktion nicht ausgeführt werden. Der Ordner ist schreibgeschützt.'; $messages['errornoperm'] = 'Die Aktion nicht ausgeführt werden. Zugriff verweigert.'; $messages['errorreadonly'] = 'Die Aktion kann nicht ausgeführt werden. Der Ordner ist schreibgeschützt.'; $messages['errornoperm'] = 'Die Aktion kann nicht ausgeführt werden. Zugriff verweigert.'; $messages['invalidrequest'] = 'Ungültige Anfrage! Es wurden keine Daten gespeichert.'; $messages['nomessagesfound'] = 'Keine Nachrichten in diesem Ordner'; $messages['loggedout'] = 'Sie haben Ihre Session erfolgreich beendet. Auf Wiedersehen!'; @@ -117,7 +117,7 @@ $messages['smtpfromerror'] = 'SMTP Fehler ($code): Der Absender "$from" konnte nicht gesetzt werden ($msg)'; $messages['smtptoerror'] = 'SMTP Fehler ($code): Der Empfänger "$to" konnte nicht gesetzt werden ($msg)'; $messages['smtprecipientserror'] = 'SMTP Fehler: Die Empfängerliste konnte nicht verarbeitet werden'; $messages['smtpdsnerror'] = 'SMTP-Fehler: Empfangsbestätigung werden nicht unterstützt'; $messages['smtpdsnerror'] = 'SMTP-Fehler: Empfangsbestätigungen werden nicht unterstützt'; $messages['smtperror'] = 'SMTP Fehler: $msg'; $messages['emailformaterror'] = 'Ungültige E-Mail-Adresse: $email'; $messages['toomanyrecipients'] = 'Zuviele Empfänger. Reduzieren Sie die Anzahl Empfängeradressen auf $max.'; program/localization/index.inc
@@ -32,7 +32,7 @@ 'az_AZ' => 'Azerbaijani (Azərbaycanca)', 'eu_ES' => 'Basque (Euskara)', 'bn_BD' => 'Bengali (বাংলা)', 'bs_BA' => 'Bosnian (Bošnjački)', 'bs_BA' => 'Bosnian (Bosanski)', 'br' => 'Breton (Brezhoneg)', 'bg_BG' => 'Bulgarian (Български)', 'ca_ES' => 'Catalan (Català)',