From 8ffd08a7398d044dc7e9f5deecc76a29c6aa270e Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Sun, 17 Apr 2011 05:34:02 -0400
Subject: [PATCH] - Aplied fixes from trunk

---
 program/include/rcube_smtp.php          |    9 ++
 program/js/list.js                      |  102 ++++++++++++++-----------
 program/localization/de_DE/messages.inc |    6 
 CHANGELOG                               |    5 
 program/localization/de_CH/messages.inc |    4 
 program/lib/Net/SMTP.php                |   21 ++++-
 program/include/rcube_template.php      |   26 +++--
 program/js/app.js                       |   20 ++--
 program/localization/index.inc          |    2 
 9 files changed, 117 insertions(+), 78 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index e9437a1..6958e8e 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 @@
 - 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
diff --git a/program/include/rcube_smtp.php b/program/include/rcube_smtp.php
index 81f212d..6216838 100644
--- a/program/include/rcube_smtp.php
+++ b/program/include/rcube_smtp.php
@@ -105,7 +105,7 @@
 
     $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 @@
       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 5806d51..5c69290 100755
--- a/program/include/rcube_template.php
+++ b/program/include/rcube_template.php
@@ -373,16 +373,19 @@
     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 @@
 
         $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) {
diff --git a/program/js/app.js b/program/js/app.js
index d752a76..8cdddcc 100644
--- a/program/js/app.js
+++ b/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'),
-          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 @@
 
     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 ae4890f..8da3181 100644
--- a/program/js/list.js
+++ b/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) {
-    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_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 @@
   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 @@
   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 @@
  */
 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 @@
     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];
diff --git a/program/lib/Net/SMTP.php b/program/lib/Net/SMTP.php
index fef8076..0463758 100644
--- a/program/lib/Net/SMTP.php
+++ b/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,8 +428,10 @@
          * 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 98623c2..f272cb3 100644
--- a/program/localization/de_CH/messages.inc
+++ b/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.';
 
 ?>
diff --git a/program/localization/de_DE/messages.inc b/program/localization/de_DE/messages.inc
index 1d63591..73b60ef 100644
--- a/program/localization/de_DE/messages.inc
+++ b/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.';
diff --git a/program/localization/index.inc b/program/localization/index.inc
index 9925a87..a251048 100644
--- a/program/localization/index.inc
+++ b/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à)',

--
Gitblit v1.9.1