From 40a1860174c612c4d60754b328fa572a7879f1e3 Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Mon, 23 May 2011 07:03:52 -0400
Subject: [PATCH] - Store user preferences in session when write-master is not available and session is stored in memcache, write them later

---
 CHANGELOG                      |    1 
 program/include/rcmail.php     |    5 ++
 program/include/rcube_user.php |   56 +++++++++++++++++++++++-----
 program/steps/mail/show.inc    |    2 
 4 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index bab451d..ebb51cc 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Store user preferences in session when write-master is not available and session is stored in memcache, write them later
 - Improve performence of folder manager operations
 - Fix default_port option handling in Installer when config.inc.php file exists (#1487925)
 - Removed option focus_on_new_message, added newmail_notifier plugin
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index acd661d..8198c3e 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -1125,6 +1125,11 @@
     if ($config['logout_expunge']) {
       $this->imap->expunge('INBOX');
     }
+
+    // Try to save unsaved user preferences
+    if (!empty($_SESSION['preferences'])) {
+      $this->user->save_prefs(unserialize($_SESSION['preferences']));
+    }
   }
 
 
diff --git a/program/include/rcube_user.php b/program/include/rcube_user.php
index e6ec461..b4a7c88 100644
--- a/program/include/rcube_user.php
+++ b/program/include/rcube_user.php
@@ -29,16 +29,23 @@
  */
 class rcube_user
 {
-    public $ID = null;
-    public $data = null;
-    public $language = null;
+    public $ID;
+    public $data;
+    public $language;
 
     /**
      * Holds database connection.
      *
      * @var rcube_mdb2
      */
-    private $db = null;
+    private $db;
+
+    /**
+     * rcmail object.
+     *
+     * @var rcmail
+     */
+    private $rc;
 
 
     /**
@@ -49,7 +56,8 @@
      */
     function __construct($id = null, $sql_arr = null)
     {
-        $this->db = rcmail::get_instance()->get_dbh();
+        $this->rc = rcmail::get_instance();
+        $this->db = $this->rc->get_dbh();
 
         if ($id && !$sql_arr) {
             $sql_result = $this->db->query(
@@ -82,8 +90,7 @@
             }
             // if no domain was provided...
             if (empty($domain)) {
-                $rcmail = rcmail::get_instance();
-                $domain = $rcmail->config->mail_domain($this->data['mail_host']);
+                $domain = $this->rc->config->mail_domain($this->data['mail_host']);
             }
 
             if ($part == 'domain') {
@@ -110,8 +117,22 @@
         if (!empty($this->language))
             $prefs = array('language' => $this->language);
 
-        if ($this->ID && $this->data['preferences'])
-            $prefs += (array)unserialize($this->data['preferences']);
+        if ($this->ID) {
+            // Preferences from session (write-master is unavailable)
+            if (!empty($_SESSION['preferences'])) {
+                // Check last write attempt time, try to write again (every 5 minutes)
+                if ($_SESSION['preferences_time'] < time() - 5 * 60) {
+                    $this->save_prefs(unserialize($_SESSION['preferences']));
+                }
+                else {
+                    $this->data['preferences'] = $_SESSION['preferences'];
+                }
+            }
+
+            if ($this->data['preferences']) {
+                $prefs += (array)unserialize($this->data['preferences']);
+            }
+        }
 
         return $prefs;
     }
@@ -128,7 +149,7 @@
         if (!$this->ID)
             return false;
 
-        $config = rcmail::get_instance()->config;
+        $config    = $this->rc->config;
         $old_prefs = (array)$this->get_prefs();
 
         // merge (partial) prefs array with existing settings
@@ -154,11 +175,26 @@
 
         $this->language = $_SESSION['language'];
 
+        // Update success
         if ($this->db->affected_rows() !== false) {
             $config->set_user_prefs($a_user_prefs);
             $this->data['preferences'] = $save_prefs;
+
+            if (isset($_SESSION['preferences'])) {
+                $this->rc->session->remove('preferences');
+                $this->rc->session->remove('preferences_time');
+            }
             return true;
         }
+        // Update error, but we are using replication (we have read-only DB connection)
+        // and we are storing session not in the SQL database
+        // we can store preferences in session and try to write later (see get_prefs())
+        else if ($this->db->is_replicated() && $config->get('session_storage', 'db') != 'db') {
+            $_SESSION['preferences'] = $save_prefs;
+            $_SESSION['preferences_time'] = time();
+            $config->set_user_prefs($a_user_prefs);
+            $this->data['preferences'] = $save_prefs;
+        }
 
         return false;
     }
diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc
index 8c063e8..3c2fa23 100644
--- a/program/steps/mail/show.inc
+++ b/program/steps/mail/show.inc
@@ -64,7 +64,7 @@
     $OUTPUT->set_env('display_next', true);
   if ($MESSAGE->headers->others['list-post'])
     $OUTPUT->set_env('list_post', true);
-  if ($CONFIG['forward_attachment'])                                                                                                      
+  if ($CONFIG['forward_attachment'])
     $OUTPUT->set_env('forward_attachment', true);
 
   if (!$OUTPUT->ajax_call)

--
Gitblit v1.9.1