From c719f3c1e06c00fa4723f2f1298b3c94a1bec7e7 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 20 Jun 2008 06:40:01 -0400
Subject: [PATCH] Store compose parameters in session and redirect to a unique URL

---
 CHANGELOG                             |    4 ++
 index.php                             |    7 +--
 program/include/rcube_imap.php        |    1 
 program/steps/mail/compose.inc        |   19 +++++----
 program/include/rcube_json_output.php |   21 +++++++++-
 program/include/rcmail.php            |   22 ++++++++++
 program/include/rcube_template.php    |   16 +++++++
 program/steps/mail/sendmail.inc       |   12 ++++-
 8 files changed, 82 insertions(+), 20 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index e28eacd..77534ae 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,10 @@
 CHANGELOG RoundCube Webmail
 ---------------------------
 
+2008/06/20 (thomasb)
+----------
+- Store compose parameters in session and redirect to a unique URL
+
 2008/06/18 (thomasb)
 ----------
 - Fixed CRAM-MD5 authentication (#1484819)
diff --git a/index.php b/index.php
index 699cf19..839a75f 100644
--- a/index.php
+++ b/index.php
@@ -2,7 +2,7 @@
 /*
  +-------------------------------------------------------------------------+
  | RoundCube Webmail IMAP Client                                           |
- | Version 0.2-20080619                                                    |
+ | Version 0.2-20080620                                                    |
  |                                                                         |
  | Copyright (C) 2005-2008, RoundCube Dev. - Switzerland                   |
  |                                                                         |
@@ -92,8 +92,7 @@
                       $_SERVER['REMOTE_ADDR']));
 
     // send redirect
-    header("Location: {$RCMAIL->comm_path}");
-    exit;
+    $OUTPUT->redirect();
   }
   else {
     $OUTPUT->show_message($IMAP->error_code == -1 ? 'imaperror' : 'loginfailed', 'warning');
@@ -138,7 +137,7 @@
 if (empty($RCMAIL->user->ID)) {
   
   if ($OUTPUT->ajax_call)
-    $OUTPUT->remote_response("setTimeout(\"location.href='\"+this.env.comm_path+\"'\", 2000);");
+    $OUTPUT->redirect(array(), 2000);
   
   // check if installer is still active
   if ($RCMAIL->config->get('enable_installer') && is_readable('./installer/index.php')) {
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 009ad04..7c12ef7 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -139,7 +139,7 @@
       $task = 'mail';
     
     $this->task = $task;
-    $this->comm_path = './?_task=' . $task;
+    $this->comm_path = $this->url(array('task' => $task));
     
     if ($this->output)
       $this->output->set_env('task', $task);
@@ -820,6 +820,26 @@
     return preg_replace('/\x00/', '', $pass);
   }
 
+
+  /**
+   * Build a valid URL to this instance of RoundCube
+   *
+   * @param mixed Either a string with the action or url parameters as key-value pairs
+   * @return string Valid application URL
+   */
+  public function url($p)
+  {
+    if (!is_array($p))
+      $p = array('action' => @func_get_arg(0));
+      
+    $url = $p['task'] ? './?_task=' . $p['task'] : $this->comm_path;
+    unset($p['task']);
+    
+    foreach ($p as $par => $val)
+      $url .= sprintf('&%s=%s', urlencode($par), urlencode($val));
+    
+    return $url;
+  }
 }
 
 
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index fb3870b..858a1e2 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -1487,6 +1487,7 @@
       {
       $this->_expunge($mailbox, FALSE);
       $this->_clear_messagecount($mailbox);
+      unset($this->uid_id_map[$mailbox]);
       }
 
     // remove message ids from search set
diff --git a/program/include/rcube_json_output.php b/program/include/rcube_json_output.php
index 678b194..2f65c19 100644
--- a/program/include/rcube_json_output.php
+++ b/program/include/rcube_json_output.php
@@ -58,12 +58,14 @@
     }
     
     /**
-     * @ignore
+     * Issue command to set page title
+     *
+     * @param string New page title
      */
     public function set_pagetitle($title)
     {
-	$name = $this->config->get('product_name');
-	$this->command('set_pagetitle', JQ(empty($name) ? $title : $name.' :: '.$title));
+        $name = $this->config->get('product_name');
+        $this->command('set_pagetitle', JQ(empty($name) ? $title : $name.' :: '.$title));
     }
 
     /**
@@ -161,6 +163,19 @@
         $this->commands = array();
     }
     
+    /**
+     * Redirect to a certain url
+     *
+     * @param mixed Either a string with the action or url parameters as key-value pairs
+     * @see rcmail::url()
+     */
+    public function redirect($p = array(), $delay = 0)
+    {
+        $location = rcmail::get_instance()->url($p);
+        $this->remote_response("window.setTimeout(\"location.href='{$location}'\", $delay);");
+        exit;
+    }
+    
     
     /**
      * Send an AJAX response to the client.
diff --git a/program/include/rcube_template.php b/program/include/rcube_template.php
index 53808bd..75a9a60 100755
--- a/program/include/rcube_template.php
+++ b/program/include/rcube_template.php
@@ -218,7 +218,7 @@
      * @uses   self::$js_commands
      * @uses   self::$object_handlers
      */
-    public public function reset()
+    public function reset()
     {
         $this->env = array();
         $this->js_env = array();
@@ -229,6 +229,20 @@
 
 
     /**
+     * Redirect to a certain url
+     *
+     * @param mixed Either a string with the action or url parameters as key-value pairs
+     * @see rcmail::url()
+     */
+    public function redirect($p = array())
+    {
+        $location = $this->app->url($p);
+        header('Location: ' . $location);
+        exit;
+    }
+
+
+    /**
      * Send the request output to the client.
      * This will either parse a skin tempalte or send an AJAX response
      *
diff --git a/program/steps/mail/compose.inc b/program/steps/mail/compose.inc
index 0bfcaf2..607cf9b 100644
--- a/program/steps/mail/compose.inc
+++ b/program/steps/mail/compose.inc
@@ -63,7 +63,10 @@
 if (!is_array($_SESSION['compose']) || $_SESSION['compose']['id'] != get_input_value('_id', RCUBE_INPUT_GET))
 {
   rcmail_compose_cleanup();
-  $_SESSION['compose'] = array('id' => uniqid(rand()));
+  $_SESSION['compose'] = array('id' => uniqid(rand()), 'param' => array_map('strip_tags', $_GET));
+  
+  // redirect to a unique URL with all parameters stored in session
+  $OUTPUT->redirect(array('_action' => 'compose', '_id' => $_SESSION['compose']['id']));
 }
 
 // add some labels to client
@@ -74,11 +77,11 @@
 
 
 // get reference message and set compose mode
-if ($msg_uid = get_input_value('_reply_uid', RCUBE_INPUT_GET))
+if ($msg_uid = $_SESSION['compose']['param']['_reply_uid'])
   $compose_mode = RCUBE_COMPOSE_REPLY;
-else if ($msg_uid = get_input_value('_forward_uid', RCUBE_INPUT_GET))
+else if ($msg_uid = $_SESSION['compose']['param']['_forward_uid'])
   $compose_mode = RCUBE_COMPOSE_FORWARD;
-else if ($msg_uid = get_input_value('_draft_uid', RCUBE_INPUT_GET))
+else if ($msg_uid = $_SESSION['compose']['param']['_draft_uid'])
   $compose_mode = RCUBE_COMPOSE_DRAFT;
 
 if (!empty($msg_uid))
@@ -95,7 +98,7 @@
     $_SESSION['compose']['reply_msgid'] = $MESSAGE->headers->messageID;
     $_SESSION['compose']['references']  = trim($MESSAGE->headers->references . " " . $MESSAGE->headers->messageID);
 
-    if (!empty($_GET['_all']))
+    if (!empty($_SESSION['compose']['param']['_all']))
       $MESSAGE->reply_all = 1;
   }
   else if ($compose_mode == RCUBE_COMPOSE_FORWARD)
@@ -131,10 +134,10 @@
       $header = 'to';
       
       // we have a set of recipients stored is session
-      if (($mailto_id = get_input_value('_mailto', RCUBE_INPUT_GET)) && $_SESSION['mailto'][$mailto_id])
+      if (($mailto_id = $_SESSION['compose']['param']['_mailto']) && $_SESSION['mailto'][$mailto_id])
         $fvalue = $_SESSION['mailto'][$mailto_id];
-      else if (!empty($_GET['_to']))
-        $fvalue = get_input_value('_to', RCUBE_INPUT_GET);
+      else if (!empty($_SESSION['compose']['param']['_to']))
+        $fvalue = $_SESSION['compose']['param']['_to'];
         
     case 'cc':
       if (!$fname)
diff --git a/program/steps/mail/sendmail.inc b/program/steps/mail/sendmail.inc
index 1da2fc0..44f2bdf 100644
--- a/program/steps/mail/sendmail.inc
+++ b/program/steps/mail/sendmail.inc
@@ -387,8 +387,8 @@
   if ($olddraftmessageid)
     {
     // delete previous saved draft
-    $a_deleteid = $IMAP->search($CONFIG['drafts_mbox'],'HEADER Message-ID',$olddraftmessageid);
-    $deleted = $IMAP->delete_message($IMAP->get_uid($a_deleteid[0],$CONFIG['drafts_mbox']),$CONFIG['drafts_mbox']);
+    $a_deleteid = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID', $olddraftmessageid);
+    $deleted = $IMAP->delete_message($IMAP->get_uid($a_deleteid[0], $CONFIG['drafts_mbox']), $CONFIG['drafts_mbox']);
 
     // raise error if deletion of old draft failed
     if (!$deleted)
@@ -399,11 +399,17 @@
 
 if ($savedraft)
   {
+  $msgid = strtr($message_id, array('>' => '', '<' => ''));
+  
+  // remember new draft-uid
+  $draftids = $IMAP->search($CONFIG['drafts_mbox'], 'HEADER Message-ID', $msgid);
+  $_SESSION['compose']['param']['_draft_uid'] = $IMAP->get_uid($draftids[0], $CONFIG['drafts_mbox']);
+
   // display success
   $OUTPUT->show_message('messagesaved', 'confirmation');
 
   // update "_draft_saveid" and the "cmp_hash" to prevent "Unsaved changes" warning
-  $OUTPUT->command('set_draft_id', str_replace(array('<','>'), "", $message_id));
+  $OUTPUT->command('set_draft_id', $msgid);
   $OUTPUT->command('compose_field_hash', true);
 
   // start the auto-save timer again

--
Gitblit v1.9.1