summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralecpl <alec@alec.pl>2011-04-17 09:34:02 +0000
committeralecpl <alec@alec.pl>2011-04-17 09:34:02 +0000
commit8ffd08a7398d044dc7e9f5deecc76a29c6aa270e (patch)
treea4fb7dedbd3c8e7cb51c9db80d7f8c1c2480e867
parentd3105370870a8c51aaeb6a18f561311202da3356 (diff)
- Aplied fixes from trunk
-rw-r--r--CHANGELOG5
-rw-r--r--program/include/rcube_smtp.php9
-rwxr-xr-xprogram/include/rcube_template.php26
-rw-r--r--program/js/app.js20
-rw-r--r--program/js/list.js102
-rw-r--r--program/lib/Net/SMTP.php21
-rw-r--r--program/localization/de_CH/messages.inc4
-rw-r--r--program/localization/de_DE/messages.inc6
-rw-r--r--program/localization/index.inc2
9 files changed, 117 insertions, 78 deletions
diff --git a/CHANGELOG b/CHANGELOG
index e9437a17e..6958e8e10 100644
--- a/CHANGELOG
+++ b/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 @@ CHANGELOG Roundcube Webmail
- 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 @@ CHANGELOG Roundcube Webmail
- 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
diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php
index 81f212dcf..62168389c 100644
--- a/program/include/rcube_smtp.php
+++ b/program/include/rcube_smtp.php
@@ -105,7 +105,7 @@ class rcube_smtp
$this->conn = new Net_SMTP($smtp_host, $smtp_port, $helo_host);
- if($RCMAIL->config->get('smtp_debug'))
+ if ($RCMAIL->config->get('smtp_debug'))
$this->conn->setDebug(true, array($this, 'debug_handler'));
// try to connect to server and exit on failure
@@ -118,6 +118,13 @@ class rcube_smtp
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']);
$smtp_pass = str_replace('%p', $RCMAIL->decrypt($_SESSION['password']), $CONFIG['smtp_pass']);
$smtp_auth_type = empty($CONFIG['smtp_auth_type']) ? NULL : $CONFIG['smtp_auth_type'];
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
index 5806d5185..5c69290c5 100755
--- a/program/include/rcube_template.php
+++ b/program/include/rcube_template.php
@@ -373,16 +373,19 @@ class rcube_template extends rcube_html_page
private function parse($name = 'main', $exit = true)
{
$skin_path = $this->config['skin_path'];
- $plugin = false;
+ $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'];
+ $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 @@ class rcube_template extends rcube_html_page
$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 @@ class rcube_template extends rcube_html_page
'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 @@ class rcube_template extends rcube_html_page
$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) {
diff --git a/program/js/app.js b/program/js/app.js
index d752a768b..8cdddccca 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -4650,17 +4650,18 @@ function rcube_webmail()
// 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'),
- tr = document.createElement('tr');
+ 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 @@ function rcube_webmail()
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
diff --git a/program/js/list.js b/program/js/list.js
index ae4890f60..8da318174 100644
--- a/program/js/list.js
+++ b/program/js/list.js
@@ -102,8 +102,8 @@ init_row: function(row)
{
// 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 @@ clear: function(sel)
if (sel)
this.clear_selection();
+
+ // reset scroll position (in Opera)
+ if (this.frame)
+ this.frame.scrollTop = 0;
},
@@ -212,10 +216,10 @@ insert_row: function(row, attop)
*/
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 @@ focus: function(e)
*/
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 @@ collapse: function(row)
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 @@ expand: function(row)
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: function(id)
*/
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_next: function()
select_first: function(mod_key)
{
var row = this.get_first_row();
- if (row && mod_key) {
- this.shift_select(row, mod_key);
- this.triggerEvent('select');
- this.scrollto(row);
+ if (row) {
+ if (mod_key) {
+ this.shift_select(row, mod_key);
+ this.triggerEvent('select');
+ this.scrollto(row);
+ }
+ else {
+ this.select(row);
+ }
}
- else if (row)
- this.select(row);
},
@@ -726,13 +733,16 @@ select_first: function(mod_key)
select_last: function(mod_key)
{
var row = this.get_last_row();
- if (row && mod_key) {
- this.shift_select(row, mod_key);
- this.triggerEvent('select');
- this.scrollto(row);
+ if (row) {
+ if (mod_key) {
+ this.shift_select(row, mod_key);
+ this.triggerEvent('select');
+ this.scrollto(row);
+ }
+ else {
+ this.select(row);
+ }
}
- else if (row)
- this.select(row);
},
@@ -744,8 +754,9 @@ select_childs: function(uid)
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,20 +779,20 @@ shift_select: function(id, control)
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);
}
}
else {
- if (this.in_selection(n) && !control) {
+ if (this.in_selection(n) && !control) {
this.highlight_row(n, true);
}
}
@@ -794,7 +805,7 @@ shift_select: function(id, control)
*/
in_selection: function(id)
{
- for(var n in this.selection)
+ for (var n in this.selection)
if (this.selection[n]==id)
return true;
@@ -811,10 +822,10 @@ select_all: function(filter)
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 @@ invert_selection: function()
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 @@ invert_selection: function()
*/
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 @@ clear_selection: function(id)
}
// 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 @@ highlight_row: function(id, multiple)
$(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 @@ key_press: function(e)
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 @@ del_dragfix: function()
*/
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 @@ column_replace: function(from, to)
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];
diff --git a/program/lib/Net/SMTP.php b/program/lib/Net/SMTP.php
index fef8076ce..0463758b3 100644
--- a/program/lib/Net/SMTP.php
+++ b/program/lib/Net/SMTP.php
@@ -106,6 +106,14 @@ class Net_SMTP
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 @@ class Net_SMTP
* @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 @@ class Net_SMTP
$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 @@ class Net_SMTP
{
$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,8 +428,10 @@ class Net_SMTP
* timeout values for the initial connection (our $timeout parameter)
* and all other socket operations.
*/
- if (PEAR::isError($error = $this->setTimeout($this->_timeout))) {
- return $error;
+ if ($this->_timeout > 0) {
+ if (PEAR::isError($error = $this->setTimeout($this->_timeout))) {
+ return $error;
+ }
}
if (PEAR::isError($error = $this->_parseResponse(220))) {
diff --git a/program/localization/de_CH/messages.inc b/program/localization/de_CH/messages.inc
index 98623c29d..f272cb3a6 100644
--- a/program/localization/de_CH/messages.inc
+++ b/program/localization/de_CH/messages.inc
@@ -135,7 +135,7 @@ $messages['namecannotbeempty'] = 'Der Name darf nicht leer sein';
$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.';
?>
diff --git a/program/localization/de_DE/messages.inc b/program/localization/de_DE/messages.inc
index 1d63591c3..73b60ef0d 100644
--- a/program/localization/de_DE/messages.inc
+++ b/program/localization/de_DE/messages.inc
@@ -24,8 +24,8 @@ $messages['sessionerror'] = 'Ihre Session ist ungültig oder abgelaufen';
$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['smtpautherror'] = 'SMTP Fehler ($code): Die Authentisierung ist fehlg
$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.';
diff --git a/program/localization/index.inc b/program/localization/index.inc
index 9925a87a5..a25104820 100644
--- a/program/localization/index.inc
+++ b/program/localization/index.inc
@@ -32,7 +32,7 @@ $rcube_languages = array(
'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à)',