Add chance to switch reply type to single recipient on compose page when using auto...
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 4 Feb 2010 22:12:07 +0000 (15:12 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 4 Feb 2010 23:24:16 +0000 (16:24 -0700)
imp/compose-dimp.php
imp/docs/CHANGES
imp/js/compose-dimp.js
imp/js/fullmessage-dimp.js
imp/lib/Ajax/Application.php
imp/lib/Compose.php
imp/templates/chunks/compose.php

index 4618855..c369d77 100644 (file)
@@ -31,6 +31,7 @@ require_once dirname(__FILE__) . '/lib/Application.php';
 Horde_Registry::appInit('imp');
 
 Horde_Nls::setTimeZone();
+$vars = Horde_Variables::getDefaultVariables();
 
 /* Determine if compose mode is disabled. */
 $compose_disable = !IMP::canCompose();
@@ -38,18 +39,17 @@ $compose_disable = !IMP::canCompose();
 /* The headers of the message. */
 $header = array();
 foreach (array('to', 'cc', 'bcc', 'subject') as $v) {
-    $header[$v] = rawurldecode(Horde_Util::getFormData($v, ''));
+    $header[$v] = rawurldecode($vars->$v);
 }
 
+$fillform_opts = array('noupdate' => 1);
 $get_sig = true;
+$js = array();
 $msg = '';
 
 $identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
-if (!$prefs->isLocked('default_identity')) {
-    $identity_id = Horde_Util::getFormData('identity');
-    if (!is_null($identity_id)) {
-        $identity->setDefault($identity_id);
-    }
+if (!$prefs->isLocked('default_identity') && isset($vars->identity)) {
+    $identity->setDefault($vars->identity);
 }
 
 /* Initialize the IMP_Compose:: object. */
@@ -62,42 +62,44 @@ $imp_ui = new IMP_Ui_Compose();
 $imp_ui->attachAutoCompleter(array('to', 'cc', 'bcc'));
 $imp_ui->attachSpellChecker('dimp');
 
-$type = Horde_Util::getFormData('type');
-$uid = Horde_Util::getFormData('uid');
-$folder = Horde_Util::getFormData('folder');
 $show_editor = false;
 $title = _("New Message");
 
-if (in_array($type, array('reply', 'reply_all', 'reply_auto', 'reply_list', 'forward_attach', 'forward_auto', 'forward_body', 'forward_both', 'resume'))) {
-    if (!$uid || !$folder) {
-        $type = 'new';
+if (in_array($vars->type, array('reply', 'reply_all', 'reply_auto', 'reply_list', 'forward_attach', 'forward_auto', 'forward_body', 'forward_both', 'resume'))) {
+    if (!$vars->uid || !$vars->folder) {
+        $vars->type = 'new';
     }
 
     try {
-        $imp_contents = IMP_Contents::singleton($uid . IMP::IDX_SEP . $folder);
+        $imp_contents = IMP_Contents::singleton($vars->uid . IMP::IDX_SEP . $vars->folder);
     } catch (Horde_Exception $e) {
         $notification->push(_("Requested message not found."), 'horde.error');
-        $uid = $folder = null;
-        $type = 'new';
+        $vars->uid = $vars->folder = null;
+        $vars->type = 'new';
     }
 }
 
-switch ($type) {
+switch ($vars->type) {
 case 'reply':
 case 'reply_all':
 case 'reply_auto':
 case 'reply_list':
-    $reply_msg = $imp_compose->replyMessage($type, $imp_contents, $header['to']);
+    $reply_msg = $imp_compose->replyMessage($vars->type, $imp_contents, $header['to']);
     $msg = $reply_msg['body'];
     $header = $reply_msg['headers'];
     $header['replytype'] = 'reply';
-    $type = $reply_msg['type'];
 
-    if ($type == 'reply') {
+    if (($vars->type == 'reply_auto') && ($reply_msg['type'] == 'reply_all')) {
+        $fillform_opts['reply_auto_all'] = 1;
+    }
+
+    $vars->type = $reply_msg['type'];
+
+    if ($vars->type == 'reply') {
         $title = _("Reply:");
-    } elseif ($type == 'reply_all') {
+    } elseif ($vars->type == 'reply_all') {
         $title = _("Reply to All:");
-    } elseif ($type == 'reply_list') {
+    } elseif ($vars->type == 'reply_list') {
         $title = _("Reply to List:");
     }
     $title .= ' ' . $header['subject'];
@@ -115,7 +117,7 @@ case 'forward_attach':
 case 'forward_auto':
 case 'forward_body':
 case 'forward_both':
-    $fwd_msg = $imp_compose->forwardMessage($type, $imp_contents);
+    $fwd_msg = $imp_compose->forwardMessage($vars->type, $imp_contents);
     $msg = $fwd_msg['body'];
     $header = $fwd_msg['headers'];
     $header['replytype'] = 'forward';
@@ -123,7 +125,7 @@ case 'forward_both':
     if ($fwd_msg['format'] == 'html') {
         $show_editor = true;
     }
-    $type = 'forward';
+    $vars->type = 'forward';
 
     if (!$prefs->isLocked('default_identity') &&
         !is_null($fwd_msg['identity'])) {
@@ -133,7 +135,7 @@ case 'forward_both':
 
 case 'resume':
     try {
-        $result = $imp_compose->resumeDraft($uid . IMP::IDX_SEP . $folder);
+        $result = $imp_compose->resumeDraft($vars->uid . IMP::IDX_SEP . $vars->folder);
 
         if ($result['mode'] == 'html') {
             $show_editor = true;
@@ -172,28 +174,29 @@ $t->set('title', $title);
 
 $compose_result = IMP_Views_Compose::showCompose(array(
     'composeCache' => $imp_compose->getCacheId(),
-    'folder' => $folder,
+    'folder' => $vars->folder,
     'qreply' => false,
-    'uid' => $uid
+    'uid' => $vars->uid
 ));
 
 $t->set('compose_html', $compose_result['html']);
 
 /* Javscript variables to be set immediately. */
 if ($show_editor) {
-    $compose_result['js'][] = 'DIMP.conf_compose.show_editor = 1';
+    $js[] = 'DIMP.conf_compose.show_editor = 1';
 }
-if (Horde_Util::getFormData('popup')) {
-    $compose_result['js'][] = 'DIMP.conf_compose.popup = 1';
+if ($vars->popup) {
+    $js[] = 'DIMP.conf_compose.popup = 1';
 }
-Horde::addInlineScript($compose_result['js']);
+Horde::addInlineScript(array_merge($compose_result['js'], $js));
 
 /* Some actions, like adding forwards, may return error messages so explicitly
  * display those messages now. */
 Horde::addInlineScript(array(IMP_Dimp::notify()), 'dom');
 
 /* Javascript to be run on window load. */
-$compose_result['js_onload'][] = 'DimpCompose.fillForm(' . Horde_Serialize::serialize($msg, Horde_Serialize::JSON) . ', ' . Horde_Serialize::serialize($header, Horde_Serialize::JSON) . ', "' . (($type == 'new' || $type == 'forward') ? 'to' : 'composeMessage') . '", true)';
+$fillform_opts['focus'] = ($vars->type == 'new' || $vars->type == 'forward') ? 'to' : 'composeMessage';
+$compose_result['js_onload'][] = 'DimpCompose.fillForm(' . Horde_Serialize::serialize($msg, Horde_Serialize::JSON) . ',' . Horde_Serialize::serialize($header, Horde_Serialize::JSON) . ',' . Horde_Serialize::serialize($fillform_opts, Horde_Serialize::JSON) . ')';
 Horde::addInlineScript($compose_result['js_onload'], 'load');
 
 $scripts = array(
index afc19ef..386dac6 100644 (file)
@@ -2,6 +2,8 @@
 v5.0-git
 --------
 
+[mms] Add chance to switch reply type to single recipient on compose page when
+      using auto-reply (DIMP).
 [mms] Fix printing multipage HTML messages in Mozilla browsers (Bug #8708).
 [mms] Provide command line script to obtain IMAP caching statistics.
 [mms] Catch flag changes from other IMAP clients when refreshing if CONDSTORE
index c7b2765..0e9cf4b 100644 (file)
@@ -459,18 +459,20 @@ var DimpCompose = {
         }
     },
 
-    fillForm: function(msg, header, focus, noupdate)
+    // opts = focus, noupdate, reply_auto_all
+    fillForm: function(msg, header, opts)
     {
         // On IE, this can get loaded before DOM:loaded. Check for an init
         // value and don't load until it is available.
         if (!this.resizeto) {
-            this.fillForm.bind(this, msg, header, focus, noupdate).defer();
+            this.fillForm.bind(this, msg, header, opts).defer();
             return;
         }
 
         var bcc_add,
             identity = this.getIdentity($F('last_identity')),
             msgval = $('composeMessage');
+        opts = opts || {};
 
         // Set auto-save-drafts now if not already active.
         if (DIMP.conf_compose.auto_save_interval_val &&
@@ -520,19 +522,31 @@ var DimpCompose = {
         }
         $('subject').setValue(header.subject);
 
-        Field.focus(focus || 'to');
+        Field.focus(opts.focus || 'to');
         this.resizeMsgArea();
 
+        if (opts.reply_auto_all) {
+            $('noticerow').show().down('.replyallnotice').show();
+        }
+
         if (DIMP.conf_compose.show_editor) {
             if (!this.editor_on) {
-                this.toggleHtmlEditor(noupdate || false);
+                this.toggleHtmlEditor(opts.noupdate);
             }
-            if (focus == 'composeMessage') {
+            if (opts.focus && (opts.focus == 'composeMessage')) {
                 this.focusEditor();
             }
         }
     },
 
+    replyAutoAllCallback: function(r)
+    {
+        if (r.response.header) {
+            $('to').setValue(r.response.header.to);
+            this.resizeto.resizeNeeded();
+        }
+    },
+
     focusEditor: function()
     {
         try {
@@ -746,6 +760,18 @@ var DimpCompose = {
             case 'save_sent_mail':
                 this.setSaveSentMail($F(elt));
                 break;
+
+            case 'replyallclick':
+                elt.up('LI').fade({
+                    afterFinish: function() {
+                        elt.up('TR').hide();
+                        this.resizeMsgArea();
+                    }.bind(this),
+                    duration: 0.4
+                });
+                DimpCore.doAction('GetReplyData', { headeronly: 1, imp_compose: $F('composeCache'), type: 'reply' }, { callback: this.replyAutoAllCallback.bind(this) });
+                e.stop();
+                return;
             }
 
             elt = elt.up();
index 23b2acd..63b1614 100644 (file)
@@ -52,7 +52,7 @@ var DimpFullmessage = {
 
         $('identity', 'last_identity').invoke('setValue', id);
 
-        DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header);
+        DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header, r.opts);
 
         if (r.fwd_list && r.fwd_list.length) {
             r.fwd_list.each(function(ptr) {
index 8c985ad..d094361 100644 (file)
@@ -18,7 +18,7 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
      * @var array
      */
     protected $_readOnly = array(
-        'GetReplyData', 'Html2Text', 'Text2Html'
+        'Html2Text', 'Text2Html'
     );
 
     /**
@@ -986,6 +986,8 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
      *                               _checkUidvalidity(). Additional variables
      *                               used:
      * <pre>
+     * 'headeronly' - (boolean) Only return header information (DEFAULT:
+     *                false).
      * 'imp_compose' - (string) The IMP_Compose cache identifier.
      * 'type' - (string) See IMP_Compose::replyMessage().
      * 'uid' - (string) Indices of the messages to reply to (IMAP sequence
@@ -1000,27 +1002,39 @@ class IMP_Ajax_Application extends Horde_Ajax_Application_Base
      * 'header' - (array) The headers of the message.
      * 'identity' - (integer) The identity ID to use for this message.
      * 'imp_compose'- (string) The IMP_Compose cache identifier.
+     * 'opts' - (array) Additional options needed for DimpCompose.fillForm().
      * 'ViewPort' - (object) See _viewPortData().
      * </pre>
      */
     public function GetReplyData($vars)
     {
-        $indices = $GLOBALS['imp_imap']->ob()->utils->fromSequenceString($vars->uid);
-        $i = each($indices);
 
         try {
-            $imp_contents = IMP_Contents::singleton(reset($i['value']) . IMP::IDX_SEP . $i['key']);
             $imp_compose = IMP_Compose::singleton($vars->imp_compose);
+            if ($imp_compose->getMetadata('reply_type')) {
+                $idx_string = $imp_compose->getMetadata('uid') . IMP::IDX_SEP . $imp_compose->getMetadata('mailbox');
+            } else {
+                $indices = $GLOBALS['imp_imap']->ob()->utils->fromSequenceString($vars->uid);
+                $i = each($indices);
+                $idx_string = reset($i['value']) . IMP::IDX_SEP . $i['key'];
+            }
+            $imp_contents = IMP_Contents::singleton($idx_string);
             $reply_msg = $imp_compose->replyMessage($vars->type, $imp_contents);
             $header = $reply_msg['headers'];
             $header['replytype'] = 'reply';
 
             $result = new stdClass;
-            $result->imp_compose = $imp_compose->getCacheId();
-            $result->format = $reply_msg['format'];
-            $result->body = $reply_msg['body'];
             $result->header = $header;
-            $result->identity = $reply_msg['identity'];
+            if (!$vars->headeronly) {
+                $result->body = $reply_msg['body'];
+                $result->format = $reply_msg['format'];
+                $result->identity = $reply_msg['identity'];
+                $result->imp_compose = $imp_compose->getCacheId();
+                if (($vars->type == 'reply_auto') &&
+                    ($reply_msg['type'] == 'reply_all')) {
+                    $result->opts = array('reply_auto_all' => 1);
+                }
+            }
         } catch (Horde_Exception $e) {
             $GLOBALS['notification']->push($e, 'horde.error');
             $result = $this->_checkUidvalidity($vars);
index 8daebbe..149d9d9 100644 (file)
@@ -98,13 +98,13 @@ class IMP_Compose
      */
     static public function singleton($cacheid = null)
     {
-        if (!is_null($cacheid) && !isset(self::$_instances[$cacheid])) {
+        if (!empty($cacheid) && !isset(self::$_instances[$cacheid])) {
             $obs = Horde_SessionObjects::singleton();
             self::$_instances[$cacheid] = $obs->query($cacheid);
         }
 
-        if (is_null($cacheid) || empty(self::$_instances[$cacheid])) {
-            $cacheid = is_null($cacheid) ? uniqid(mt_rand()) : $cacheid;
+        if (empty($cacheid) || empty(self::$_instances[$cacheid])) {
+            $cacheid = empty($cacheid) ? uniqid(mt_rand()) : $cacheid;
             self::$_instances[$cacheid] = new self($cacheid);
         }
 
@@ -1261,10 +1261,12 @@ class IMP_Compose
      * <pre>
      * 'body'     - The text of the body part
      * 'encoding' - The guessed charset to use for the reply
-     * 'headers'  - The headers of the message to use for the reply
      * 'format'   - The format of the body message
+     * 'headers'  - The headers of the message to use for the reply
      * 'identity' - The identity to use for the reply based on the original
      *              message's addresses.
+     * 'type'     - The reply type used (either 'reply', 'reply_all', or
+     *              'reply_list').
      * </pre>
      */
     public function replyMessage($type, $contents, $to = null)
@@ -1283,21 +1285,23 @@ class IMP_Compose
         $match_identity = $this->_getMatchingIdentity($h);
         $reply_type = 'reply';
 
-        $this->_metadata['mailbox'] = $contents->getMailbox();
-        $this->_metadata['reply_type'] = 'reply';
-        $this->_metadata['uid'] = $contents->getUid();
-        $this->_modified = true;
+        if (!isset($this->_metadata['reply_type'])) {
+            $this->_metadata['mailbox'] = $contents->getMailbox();
+            $this->_metadata['reply_type'] = 'reply';
+            $this->_metadata['uid'] = $contents->getUid();
+            $this->_modified = true;
 
-        /* Set the message-id related headers. */
-        if (($msg_id = $h->getValue('message-id'))) {
-            $this->_metadata['in_reply_to'] = chop($msg_id);
+            /* Set the message-id related headers. */
+            if (($msg_id = $h->getValue('message-id'))) {
+                $this->_metadata['in_reply_to'] = chop($msg_id);
 
-            if (($refs = $h->getValue('references'))) {
-                $refs .= ' ' . $this->_metadata['in_reply_to'];
-            } else {
-                $refs = $this->_metadata['in_reply_to'];
+                if (($refs = $h->getValue('references'))) {
+                    $refs .= ' ' . $this->_metadata['in_reply_to'];
+                } else {
+                    $refs = $this->_metadata['in_reply_to'];
+                }
+                $this->_metadata['references'] = $refs;
             }
-            $this->_metadata['references'] = $refs;
         }
 
         $subject = $h->getValue('subject');
@@ -1399,6 +1403,9 @@ class IMP_Compose
                 }
             }
 
+            if (!empty($header['to']) || (count($hdr_cc) > 1)) {
+                $reply_type = 'reply_all';
+            }
             $header[empty($header['to']) ? 'to' : 'cc'] = rtrim(implode('', $hdr_cc), ' ,');
 
             /* Build the Bcc: header. */
@@ -1406,8 +1413,6 @@ class IMP_Compose
             if ($type == '*') {
                 $all_headers['reply_all'] = $header;
             }
-
-            $reply_type = 'reply_all';
         }
 
         if ($type == '*') {
index 34cc09c..27c1235 100644 (file)
@@ -122,6 +122,13 @@ $compose_disable = !IMP::canCompose();
      <ul id="attach_list" style="display:none"></ul>
     </td>
    </tr>
+   <tr id="noticerow" style="display:none">
+    <td colspan="2">
+     <ul class="notices">
+      <li class="replyallnotice" style="display:none"><?php echo Horde::img('alerts/message.png', _("Message"), null, $GLOBALS['registry']->getImageDir('horde')) ?> <?php echo sprintf(_("You are currently replying to ALL recipients. To reply only to the original sender, click %s."), '<a href="#" id="replyallclick">' . _("HERE") . '</a>') ?></li>
+     </ul>
+    </td>
+   </tr>
   </table>
  </div>