[mms] Properly redirect messages pursuant to RFC 5322 [3.6.6].
[mms] Add redirect message capability to DIMP.
}
/**
- * Generate the 'Resent' headers (conforms to guidelines in
- * RFC 2822 [3.6.6]).
- *
- * @param string $from The address to use for 'Resent-From'.
- * @param string $to The address to use for 'Resent-To'.
- */
- public function addResentHeaders($from, $to)
- {
- /* We don't set Resent-Sender, Resent-Cc, or Resent-Bcc. */
- $this->addHeader('Resent-Date', date('r'));
- $this->addHeader('Resent-From', $from);
- $this->addHeader('Resent-To', $to);
- $this->addHeader('Resent-Message-ID', Horde_Mime::generateMessageId());
- }
-
- /**
* Generate the user agent description header.
*/
public function addUserAgentHeader()
$fillform_opts = array('noupdate' => 1);
$get_sig = true;
-$js = array();
$msg = '';
+$js = array();
+if ($vars->popup) {
+ $js[] = 'DIMP.conf_compose.popup = 1';
+}
+
$identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
if (!$prefs->isLocked('default_identity') && isset($vars->identity)) {
$identity->setDefault($vars->identity);
/* Init IMP_Ui_Compose:: object. */
$imp_ui = new IMP_Ui_Compose();
-/* Attach spellchecker & auto completer. */
-$imp_ui->attachAutoCompleter(array('to', 'cc', 'bcc'));
-$imp_ui->attachSpellChecker();
-
$show_editor = false;
$title = _("New Message");
-if (in_array($vars->type, array('reply', 'reply_all', 'reply_auto', 'reply_list', 'forward_attach', 'forward_auto', 'forward_body', 'forward_both', 'resume'))) {
+if (in_array($vars->type, array('reply', 'reply_all', 'reply_auto', 'reply_list', 'forward_attach', 'forward_auto', 'forward_body', 'forward_both', 'forward_redirect', 'resume'))) {
if (!$vars->uid || !$vars->folder) {
$vars->type = 'new';
}
}
break;
+case 'forward_redirect':
+ $imp_compose->redirectMessage($imp_contents);
+ $get_sig = false;
+ $title = _("Redirect");
+ $vars->type = 'redirect';
+ break;
+
case 'resume':
try {
$result = $imp_compose->resumeDraft($vars->uid . IMP::IDX_SEP . $vars->folder);
break;
}
-$sig = $identity->getSignature();
-if ($get_sig && !empty($sig)) {
- if ($show_editor) {
- $sig = '<p><!--begin_signature-->' . $imp_compose->text2html(trim($sig)) . '<!--end_signature--></p>';
+/* Attach spellchecker & auto completer. */
+if ($vars->type == 'redirect') {
+ $imp_ui->attachAutoCompleter(array('redirect_to'));
+} else {
+ $imp_ui->attachAutoCompleter(array('to', 'cc', 'bcc', 'redirect_to'));
+ $imp_ui->attachSpellChecker();
+
+ $sig = $identity->getSignature();
+ if ($get_sig && !empty($sig)) {
+ if ($show_editor) {
+ $sig = '<p><!--begin_signature-->' . $imp_compose->text2html(trim($sig)) . '<!--end_signature--></p>';
+ }
+
+ $msg = ($identity->getValue('sig_first'))
+ ? "\n" . $sig . $msg
+ : $msg . "\n" . $sig;
}
- $msg = ($identity->getValue('sig_first'))
- ? "\n" . $sig . $msg
- : $msg . "\n" . $sig;
+ if ($show_editor) {
+ $js[] = 'DIMP.conf_compose.show_editor = 1';
+ }
}
$t = $injector->createInstance('Horde_Template');
$compose_result = IMP_Views_Compose::showCompose(array(
'composeCache' => $imp_compose->getCacheId(),
- 'folder' => $vars->folder,
- 'qreply' => false,
- 'uid' => $vars->uid
+ 'redirect' => ($vars->type == 'redirect')
));
$t->set('compose_html', $compose_result['html']);
-/* Javscript variables to be set immediately. */
-if ($show_editor) {
- $js[] = 'DIMP.conf_compose.show_editor = 1';
-}
-if ($vars->popup) {
- $js[] = 'DIMP.conf_compose.popup = 1';
-}
Horde::addInlineScript(array_merge($compose_result['js'], $js));
-/* Javascript to be run on window load. */
-$fillform_opts['focus'] = ($vars->type == 'new' || $vars->type == 'forward') ? 'to' : 'composeMessage';
-$compose_result['jsonload'][] = 'DimpCompose.fillForm(' . Horde_Serialize::serialize($msg, Horde_Serialize::JSON) . ',' . Horde_Serialize::serialize($header, Horde_Serialize::JSON) . ',' . Horde_Serialize::serialize($fillform_opts, Horde_Serialize::JSON) . ')';
+$fillform_opts['focus'] = in_array($vars->type, array('forward', 'new', 'redirect')) ? 'to' : 'composeMessage';
+if ($vars->type != 'redirect') {
+ $compose_result['jsonload'][] = '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['jsonload'], 'load');
$scripts = array(
);
IMP::status();
-IMP_Dimp::header(_("Message Composition"), $scripts);
+IMP_Dimp::header($title, $scripts);
echo $t->fetch(IMP_TEMPLATES . '/dimp/compose/compose.html');
Horde::includeScriptFiles();
Horde::outputInlineScript();
$expand = array();
$header = array('to' => '', 'cc' => '', 'bcc' => '');
$msg = '';
+$title = _("Compose Message");
/* Get the list of headers to display. */
$display_hdrs = array('to' => _("To: "));
$header = $reply_msg['headers'];
$notification->push(_("Reply text will be automatically appended to your outgoing message."), 'horde.message');
+ $title = _("Reply");
break;
// 'f' = forward
$header = $fwd_msg['headers'];
$notification->push(_("Forwarded message will be automatically added to your outgoing message."), 'horde.message');
+ $title = _("Forward");
break;
-case _("Redirect"):
- if (!($imp_contents = $imp_ui->getIMPContents($imp_compose->getMetadata('uid'), $imp_compose->getMetadata('mailbox')))) {
+// 'rc' = redirect compose
+case 'rc':
+ $title = _("Redirect");
+ if (!($imp_contents = $imp_ui->getIMPContents($imp_mbox['uid'], $imp_mbox['thismailbox']))) {
+ // TODO: Error message
break;
}
+ $imp_compose->redirectMessage($imp_contents);
+ break;
- $f_to = $imp_ui->getAddressList($header['to']);
-
+case _("Redirect"):
try {
- $imp_ui->redirectMessage($f_to, $imp_compose, $imp_contents);
+ $imp_compose->sendRedirectMessage($imp_ui->getAddressList($header['to']));
+ $imp_compose->destroy('send');
+
if ($prefs->getValue('compose_confirm')) {
$notification->push(_("Message redirected successfully."), 'horde.success');
}
$t->set('url', Horde::applicationUrl('compose-mimp.php'));
if ($vars->a == 'rc') {
+ $t->set('redirect', true);
unset($display_hdrs['cc'], $display_hdrs['bcc']);
- $title = _("Redirect");
} else {
$t->set('compose_enable', !$compose_disable);
$t->set('msg', htmlspecialchars($msg));
break;
case 'redirect_compose':
- $title = _("Redirect this message");
- break;
-
-case 'redirect_send':
if (!($imp_contents = $imp_ui->getIMPContents($uid, $thismailbox))) {
break;
}
+ $imp_compose->redirectMessage($imp_contents);
+ $title = _("Redirect");
+ break;
- $f_to = $imp_ui->getAddressList($vars->to);
-
+case 'redirect_send':
try {
- $imp_ui->redirectMessage($f_to, $imp_compose, $imp_contents);
+ $imp_compose->sendRedirectMessage($imp_ui->getAddressList($vars->to));
+
$imp_compose->destroy('send');
if ($isPopup) {
if ($prefs->getValue('compose_confirm')) {
if ($redirect) {
/* Prepare the redirect template. */
- $t->set('mailbox', htmlspecialchars($thismailbox));
- $t->set('uid', htmlspecialchars($uid));
+ $t->set('cacheid', $composeCacheID);
$t->set('status', Horde_Util::bufferOutput(array('IMP', 'status')));
$t->set('title', htmlspecialchars($title));
$t->set('token', Horde::getRequestToken('imp.compose'));
v5.0-git
--------
+[mms] Properly redirect messages pursuant to RFC 5322 [3.6.6].
+[mms] Add redirect message capability to DIMP.
[mms] Add ability to add attachments to composed messages for advanced mobile
browsers - disabled by default (MIMP).
[mms] Add checkbox interface to mailbox page for advanced mobile browsers -
case 'ctx_forward_attach':
case 'ctx_forward_body':
case 'ctx_forward_both':
+ case 'ctx_forward_redirect':
this.composeMailbox(id.substring(4));
break;
this._addMouseEvents({ id: 'folderopts', type: 'folderopts' }, $('folderopts').down(1));
DM.addSubMenu('ctx_message_reply', 'ctx_reply');
- if ($('ctx_forward')) {
- DM.addSubMenu('ctx_message_forward', 'ctx_forward');
- }
+ DM.addSubMenu('ctx_message_forward', 'ctx_forward');
[ 'ctx_message_', 'oa_' ].each(function(i) {
if ($(i + 'setflag')) {
DM.addSubMenu(i + 'setflag', 'ctx_flag');
this._addMouseEvents({ id: 'button_reply', type: 'reply' }, $('button_reply'));
DM.disable('button_reply_img', true, true);
- if ($('ctx_forward')) {
- this._addMouseEvents({ id: 'button_forward', type: 'forward' }, $('button_forward'));
- DM.disable('button_forward_img', true, true);
- }
+ this._addMouseEvents({ id: 'button_forward', type: 'forward' }, $('button_forward'));
+ DM.disable('button_forward_img', true, true);
}
new Drop('dropbase', this._folderDropConfig);
uniqueSubmit: function(action)
{
- var c = $('compose');
+ var c = (action == 'redirectMessage')
+ ? $('redirect')
+ : $('compose');
if (DIMP.SpellChecker &&
DIMP.SpellChecker.isActive()) {
// Can't disable until we send the message - or else nothing
// will get POST'ed.
- if (action == 'sendMessage' || action == 'saveDraft') {
+ if (action != 'autoSaveDraft') {
this.setDisabled(true);
}
}
}
return this.closeCompose();
+ case 'redirectMessage':
+ if (this.is_popup && DIMP.baseWindow.DimpBase) {
+ if (d.log) {
+ DIMP.baseWindow.DimpBase.updateMsgLog(d.log, { uid: d.uid, mailbox: d.mbox });
+ }
+
+ if (!DIMP.conf_compose.qreply) {
+ DIMP.baseWindow.DimpCore.showNotifications(r.msgs);
+ r.msgs = [];
+ }
+ }
+ return this.closeCompose();
+
case 'addAttachment':
this.uploading = false;
if (d.success) {
}
this.setDisabled(false);
- $('compose').setStyle({ cursor: null });
+
+ $((d.action == 'redirectMessage') ? 'redirect' : 'compose').setStyle({ cursor: null });
},
setDisabled: function(disable)
{
this.disabled = disable;
- DimpCore.loadingImg('sendingImg', 'composeMessageParent', disable);
- DimpCore.toggleButtons($('compose').select('DIV.dimpActions A'), disable);
- [ $('compose') ].invoke(disable ? 'disable' : 'enable');
- if (DIMP.SpellChecker) {
- DIMP.SpellChecker.disable(disable);
- }
- if (IMP_Compose_Base.editor_on) {
- this.RTELoading(disable ? 'show' : 'hide', true);
+
+ if ($('redirect').visible()) {
+ DimpCore.loadingImg('sendingImg', 'redirect', disable);
+ DimpCore.toggleButtons($('redirect').select('DIV.dimpActions A'), disable);
+ } else {
+ DimpCore.loadingImg('sendingImg', 'composeMessageParent', disable);
+ DimpCore.toggleButtons($('compose').select('DIV.dimpActions A'), disable);
+ [ $('compose') ].invoke(disable ? 'disable' : 'enable');
+ if (DIMP.SpellChecker) {
+ DIMP.SpellChecker.disable(disable);
+ }
+ if (IMP_Compose_Base.editor_on) {
+ this.RTELoading(disable ? 'show' : 'hide', true);
+ }
}
},
if (DIMP.conf_compose.auto_save_interval_val &&
!this.auto_save_interval) {
this.auto_save_interval = new PeriodicalExecuter(function() {
- var curr_hash = MD5.hash($('to', 'cc', 'bcc', 'subject').invoke('getValue').join('\0') + (IMP_Compose_Base.editor_on ? this.rte.getData() : $F('composeMessage')));
- if (this.last_msg && curr_hash != this.last_msg) {
- this.uniqueSubmit('autoSaveDraft');
+ if ($('compose').visible()) {
+ var curr_hash = MD5.hash($('to', 'cc', 'bcc', 'subject').invoke('getValue').join('\0') + (IMP_Compose_Base.editor_on ? this.rte.getData() : $F('composeMessage')));
+ if (this.last_msg && curr_hash != this.last_msg) {
+ this.uniqueSubmit('autoSaveDraft');
+ }
+ this.last_msg = curr_hash;
}
- this.last_msg = curr_hash;
}.bind(this), DIMP.conf_compose.auto_save_interval_val * 60);
/* Immediately execute to get MD5 hash of empty message. */
this.auto_save_interval.execute();
},
/* Open the addressbook window. */
- openAddressbook: function()
+ openAddressbook: function(params)
{
- window.open(DIMP.conf_compose.URI_ABOOK, 'contacts', 'toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=550,height=300,left=100,top=100');
+ var uri = DIMP.conf_compose.URI_ABOOK;
+
+ if (params) {
+ uri = DimpCore.addURLParam(uri, params);
+ }
+
+ window.open(uri, 'contacts', 'toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=550,height=300,left=100,top=100');
},
/* Click observe handler. */
break;
case 'draft_button':
+ if (!this.disabled) {
+ this.uniqueSubmit('saveDraft');
+ }
+ break;
+
case 'send_button':
if (!this.disabled) {
- this.uniqueSubmit(id == 'send_button' ? 'sendMessage' : 'saveDraft');
+ this.uniqueSubmit('sendMessage');
+ }
+ break;
+
+ case 'send_button_redirect':
+ if (!this.disabled) {
+ this.uniqueSubmit('redirectMessage');
}
break;
}
break;
+ case 'redirect_sendto':
+ if (orig.match('TD.label SPAN')) {
+ this.openAddressbook({
+ formfield: 'redirect_to',
+ formname: 'redirect',
+ to_only: 1
+ });
+ }
+ break;
+
case 'sendcc':
case 'sendbcc':
case 'sendto':
this.is_popup = (DIMP.baseWindow && DIMP.baseWindow.DimpBase);
+ /* Initialize redirect elements (always needed). */
+ $('redirect').observe('submit', Event.stop);
+ new TextareaResize('redirect_to');
+ if (DIMP.conf_compose.URI_ABOOK) {
+ $('redirect_sendto').down('TD.label SPAN').addClassName('composeAddrbook');
+ }
+
+ /* Nothing more to do if this is strictly a redirect window. */
+ if (DIMP.conf_compose.redirect) {
+ $('dimpLoading').hide();
+ $('redirect', 'pageContainer').invoke('show');
+ return;
+ }
+
/* Attach event handlers. */
document.observe('change', this.changeHandler.bindAsEventListener(this));
Event.observe(window, 'resize', this.resizeMsgArea.bind(this));
document.observe('SpellChecker:before', this._onSpellCheckBefore.bind(this));
}
- // Automatically resize address fields.
- new TextareaResize('to');
- new TextareaResize('cc');
- new TextareaResize('bcc');
-
- /* Add addressbook link formatting. */
- if (DIMP.conf_compose.URI_ABOOK) {
- $('sendto', 'sendcc', 'sendbcc').each(function(a) {
- a.down('TD.label SPAN').addClassName('composeAddrbook');
- });
- }
-
/* Create folderlist. */
if (DIMP.conf_compose.flist) {
this.knl_sm = new KeyNavList('save_sent_mail', {
$('priority_label').insert({ after: new Element('SPAN', { className: 'popdownImg' }).observe('click', function(e) { if (!this.disabled) { this.knl_p.show(); this.knl_p.ignoreClick(e); e.stop(); } }.bindAsEventListener(this)) });
}
+ // Automatically resize compose address fields.
+ new TextareaResize('to');
+ new TextareaResize('cc');
+ new TextareaResize('bcc');
+
+ /* Add addressbook link formatting. */
+ if (DIMP.conf_compose.URI_ABOOK) {
+ $('sendto', 'sendcc', 'sendbcc', 'redirect_sendto').each(function(a) {
+ a.down('TD.label SPAN').addClassName('composeAddrbook');
+ });
+ }
+
$('dimpLoading').hide();
$('pageContainer').show();
var func, ob = {};
ob[this.mailbox] = [ this.uid ];
- $('msgData').hide();
- $('qreply').show();
-
switch (type) {
case 'reply':
case 'reply_all':
case 'reply_auto':
case 'reply_list':
+ $('compose').show();
+ $('redirect').hide();
func = 'getReplyData';
break;
case 'forward_attach':
case 'forward_body':
case 'forward_both':
+ $('compose').show();
+ $('redirect').hide();
func = 'getForwardData';
break;
+
+ case 'forward_redirect':
+ $('compose').hide();
+ $('redirect').show();
+ func = 'getRedirectData';
+ break;
}
+ $('msgData').hide();
+ $('qreply').show();
+
DimpCore.doAction(func,
{ imp_compose: $F('composeCache'),
type: type },
return;
}
- var i,
- r = result.response,
- id = (r.identity === null) ? $F('identity') : r.identity;
+ var i, id,
+ r = result.response;
- if (!r.opts) {
- r.opts = {};
- }
- r.opts.noupdate = true;
- r.opts.show_editor = (r.format == 'html');
+ if (r.type == 'forward_redirect') {
+ $('redirect_composeCache').setValue(r.imp_compose);
+ } else {
+ if (!r.opts) {
+ r.opts = {};
+ }
+ r.opts.noupdate = true;
+ r.opts.show_editor = (r.format == 'html');
- i = IMP_Compose_Base.getIdentity(id, r.opts.show_editor);
+ id = (r.identity === null) ? $F('identity') : r.identity;
+ i = IMP_Compose_Base.getIdentity(id, r.opts.show_editor);
- $('identity', 'last_identity').invoke('setValue', id);
+ $('identity', 'last_identity').invoke('setValue', id);
- DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header, r.opts);
+ DimpCompose.fillForm((i.id[2]) ? ("\n" + i.sig + r.body) : (r.body + "\n" + i.sig), r.header, r.opts);
- if (r.imp_compose) {
- $('composeCache').setValue(r.imp_compose);
+ if (r.imp_compose) {
+ $('composeCache').setValue(r.imp_compose);
+ }
}
},
case 'ctx_forward_attach':
case 'ctx_forward_body':
case 'ctx_forward_both':
+ case 'ctx_forward_redirect':
this.quickreply(id.substring(4));
break;
tmp = $('reply_link', 'forward_link').compact().invoke('up', 'SPAN').concat([ $('ctx_contacts_new') ]).compact().invoke('remove');
} else {
this.addPopdown('reply_link', 'replypopdown');
- if ($('ctx_forwardpopdown')) {
- this.addPopdown('forward_link', 'forwardpopdown');
- }
+ this.addPopdown('forward_link', 'forwardpopdown');
}
/* Set up address linking. */
public function getForwardData()
{
try {
- $imp_compose = IMP_Compose::singleton($this->_vars->imp_compose);
- if (!($imp_contents = $imp_compose->getContentsOb())) {
- $indices = $GLOBALS['imp_imap']->ob()->utils->fromSequenceString($this->_vars->uid);
- $i = each($indices);
- $imp_contents = IMP_Contents::singleton(reset($i['value']) . IMP::IDX_SEP . $i['key']);
- }
+ list($imp_compose, $imp_contents) = $this->_initCompose();
$fwd_msg = $imp_compose->forwardMessage($this->_vars->type, $imp_contents);
* '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().
+ * 'type' - (string) The input 'type' value.
* 'ViewPort' - (object) See _viewPortData().
* </pre>
*/
public function getReplyData()
{
try {
- $imp_compose = IMP_Compose::singleton($this->_vars->imp_compose);
- if (!($imp_contents = $imp_compose->getContentsOb())) {
- $indices = $GLOBALS['imp_imap']->ob()->utils->fromSequenceString($this->_vars->uid);
- $i = each($indices);
- $imp_contents = IMP_Contents::singleton(reset($i['value']) . IMP::IDX_SEP . $i['key']);
- }
+ list($imp_compose, $imp_contents) = $this->_initCompose();
$reply_msg = $imp_compose->replyMessage($this->_vars->type, $imp_contents);
$reply_msg['headers']['replytype'] = 'reply';
* cache id. */
$result = new stdClass;
$result->header = $reply_msg['headers'];
+ $result->type = $this->_vars->type;
if (!$this->_vars->headeronly) {
$result->body = $reply_msg['body'];
$result->format = $reply_msg['format'];
}
/**
+ * AJAX action: Get compose redirect data.
+ *
+ * Variables used:
+ * <pre>
+ * 'uid' - (string) Index of the message to redirect (IMAP sequence
+ * string).
+ * </pre>
+ *
+ * @return mixed False on failure, or an object with the following
+ * entries:
+ * <pre>
+ * 'imp_compose' - (string) The IMP_Compose cache identifier.
+ * 'type' - (string) The input 'type' value.
+ * </pre>
+ */
+ public function getRedirectData()
+ {
+ list($imp_compose, $imp_contents) = $this->_initCompose();
+
+ $imp_compose->redirectMessage($imp_contents);
+
+ $ob = new stdClass;
+ $ob->imp_compose = $imp_compose->getCacheId();
+ $ob->type = $this->_vars->type;
+
+ return $ob;
+ }
+
+ /**
* AJAX action: Cancel compose.
*
* Variables used:
}
/**
+ * Redirect the message.
+ *
+ * Variables used:
+ * <pre>
+ * 'redirect_composeCache' - (string) The IMP_Compose cache identifier.
+ * 'redirect_to' - (string) The address(es) to redirect to.
+ * </pre>
+ *
+ * @return object An object with the following entries:
+ * <pre>
+ * 'log' - (array) TODO
+ * 'mbox' - (array) TODO
+ * 'success' - (integer) 1 on success, 0 on failure.
+ * 'uid' - (integer) TODO
+ * </pre>
+ */
+ public function redirectMessage()
+ {
+ $result = new stdClass;
+ $result->action = $this->_action;
+ $result->success = 1;
+
+ try {
+ $imp_compose = IMP_Compose::singleton($this->_vars->redirect_composeCache);
+ $imp_compose->sendRedirectMessage($this->_vars->redirect_to);
+
+ $result->mbox = $imp_compose->getMetadata('mailbox');
+ $result->uid = $imp_compose->getMetadata('uid');
+
+ $contents = $imp_compose->getContentsOb();
+ $headers = $contents->getHeaderOb();
+
+ if ($GLOBALS['prefs']->getValue('compose_confirm')) {
+ $subject = $headers->getValue('subject');
+ $GLOBALS['notification']->push(empty($subject) ? _("Message redirected successfully.") : sprintf(_("Message \"%s\" redirected successfully."), Horde_String::truncate($subject)), 'horde.success');
+ }
+
+ if (!empty($GLOBALS['conf']['maillog']['use_maillog']) &&
+ ($tmp = IMP_Dimp::getMsgLogInfo($headers->getValue('message-id')))) {
+ $result->log = $tmp;
+ }
+ } catch (Horde_Exception $e) {
+ $GLOBALS['notification']->push($e);
+ $result->success = 0;
+ }
+
+ return $result;
+ }
+
+ /**
* Setup environment for dimp compose actions.
*
* Variables used:
}
/**
+ * TODO
+ */
+ protected function _initCompose()
+ {
+ $imp_compose = IMP_Compose::singleton($this->_vars->imp_compose);
+ if (!($imp_contents = $imp_compose->getContentsOb())) {
+ $indices = $GLOBALS['imp_imap']->ob()->utils->fromSequenceString($this->_vars->uid);
+ $i = each($indices);
+ $imp_contents = IMP_Contents::singleton(reset($i['value']) . IMP::IDX_SEP . $i['key']);
+ }
+
+ return array($imp_compose, $imp_contents);
+ }
+
+ /**
* Save a draft composed message.
*
* See the list of variables needed for _dimpComposeSetup(). Additional
* 'view' - (string) The current ViewPort view (mailbox).
* </pre>
*
- * @param boolean $rw Open mailbox as READ+WRITE?
+ * @param boolean $rw Open mailbox as READ+WRITE?
*
* @return boolean True if the server state differs from the browser
* state.
$email = $this->_prepSendMessage($email, $headers, $message);
$mail_driver = $this->getMailDriver();
- $mailer = Mail::factory($mail_driver['driver'], $mail_driver['params']);
- if ($mailer instanceof PEAR_Error) {
- throw new IMP_Compose_Exception($mailer);
+ try {
+ $mailer = Horde_Mime_Mail::getMailOb($mail_driver['driver'], $mail_driver['params']);
+ } catch (Horde_Mime_Exception $e) {
+ throw new IMP_Compose_Exception($e);
}
try {
$params['password'] = $GLOBALS['imp_imap']->ob()->getParam('password');
}
- return array('driver' => $GLOBALS['conf']['mailer']['type'], 'params' => $params);
+ return array(
+ 'driver' => $GLOBALS['conf']['mailer']['type'],
+ 'params' => $params
+ );
}
/**
}
/**
+ * Prepare a redirect message.
+ *
+ * @param IMP_Contents $contents An IMP_Contents object.
+ */
+ public function redirectMessage($contents)
+ {
+ $this->_metadata['mailbox'] = $contents->getMailbox();
+ $this->_metadata['reply_type'] = 'redirect';
+ $this->_metadata['uid'] = $contents->getUid();
+ $this->_modified = true;
+ }
+
+ /**
+ * Send a redirect (a/k/a resent) message. See RFC 5322 [3.6.6].
+ *
+ * @param string $to The addresses to redirect to.
+ *
+ * @throws IMP_Compose_Exception
+ */
+ public function sendRedirectMessage($to)
+ {
+ $recip = $this->recipientList(array('to' => $to));
+ $recipients = implode(', ', $recip['list']);
+
+ $identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
+ $from_addr = $identity->getFromAddress();
+
+ $contents = $this->getContentsOb();
+ $headers = $contents->getHeaderOb();
+
+ /* Generate the 'Resent' headers (RFC 5322 [3.6.6]). These headers are
+ * prepended to the message. */
+ $resent_headers = new Horde_Mime_Headers();
+ $resent_headers->addHeader('Resent-Date', date('r'));
+ $resent_headers->addHeader('Resent-From', $from_addr);
+ $resent_headers->addHeader('Resent-To', $recip['header']['to']);
+ $resent_headers->addHeader('Resent-Message-ID', Horde_Mime::generateMessageId());
+
+ $header_text = trim($resent_headers->toString(array('encode' => Horde_Nls::getCharset()))) . "\n" . trim($contents->getHeaderOb(false));
+
+ $mail_driver = $this->getMailDriver();
+ try {
+ $mailer = Horde_Mime_Mail::getMailOb($mail_driver['driver'], $mail_driver['params'], array('raw' => array('from' => $headers->getValue('from'), 'headertext' => $header_text)));
+ } catch (Horde_Mime_Exception $e) {
+ throw new IMP_Compose_Exception($e);
+ }
+
+ $to = $this->_prepSendMessage($recipients);
+
+ try {
+ Horde_Mime_Mail::sendPearMail($mailer, $to, $headers->toArray(array('charset' => Horde_Nls::getCharset())), $contents->getBody());
+ } catch (Horde_Mime_Exception $e) {
+ throw new IMP_Compose_Exception($e);
+ }
+
+ Horde::logMessage(sprintf("%s Redirected message sent to %s from %s", $_SERVER['REMOTE_ADDR'], $recipients, Horde_Auth::getAuth()), 'INFO');
+
+ /* Store history information. */
+ if (!empty($GLOBALS['conf']['maillog']['use_maillog'])) {
+ IMP_Maillog::log('redirect', $headers->getValue('message-id'), $recipients);
+ }
+
+ if ($GLOBALS['conf']['sentmail']['driver'] != 'none') {
+ $GLOBALS['injector']->getInstance('IMP_Sentmail')>log('redirect', $headers->getValue('message-id'), $recipients);
+ }
+ }
+
+ /**
* Get "tieto" identity information.
*
* @param Horde_Mime_Headers $h The headers object for the message.
$msgAddresses[] = $h->getValue($val);
}
- $user_identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
- return $user_identity->getMatchingIdentity($msgAddresses);
+ return Horde_Prefs_Identity::singleton(array('imp', 'imp'))->getMatchingIdentity($msgAddresses);
}
/**
/**
* Returns the header object.
*
- * @return Horde_Mime_Headers The Horde_Mime_Headers object.
+ * @param boolean $parse Parse the headers into a headers object?
+ *
+ * @return Horde_Mime_Headers|string Either a Horde_Mime_Headers object
+ * (if $parse is true) or the header
+ * text (if $parse is false).
*/
- public function getHeaderOb()
+ public function getHeaderOb($parse = true)
{
if (is_null($this->_message)) {
return $this->_message->getMIMEHeaders();
try {
$res = $GLOBALS['imp_imap']->ob()->fetch($this->_mailbox, array(
- Horde_Imap_Client::FETCH_HEADERTEXT => array(array('parse' => true, 'peek' => true))
+ Horde_Imap_Client::FETCH_HEADERTEXT => array(array('parse' => $parse, 'peek' => true))
), array('ids' => array($this->_uid)));
return $res[$this->_uid]['headertext'][0];
} catch (Horde_Imap_Client_Exception $e) {
- return new Horde_Mime_Headers();
+ return $parse
+ ? new Horde_Mime_Headers()
+ : '';
}
}
* bodypart from the server.
* DEFAULT: All data is retrieved.
* 'nocontents' - (boolean) If true, don't add the contents to the part
- * DEFAULT: Contents are added to the part
+ * DEFAULT: Contents are added to the part
* </pre>
*
* @return Horde_Mime_Part The raw MIME part asked for (reference).
}
/**
- * Redirect a message.
- *
- * @param string $to The To address.
- * @param IMP_Compose $imp_compose An IMP_Compose object.
- * @param IMP_Contents $imp_contents An IMP_Contents object.
- *
- * @throws Horde_Exception
- */
- public function redirectMessage($to, $imp_compose, $contents)
- {
- try {
- $recip = $imp_compose->recipientList(array('to' => $to));
- } catch (IMP_Compose_Exception $e) {
- throw new Horde_Exception_Prior($recip);
- }
- $recipients = implode(', ', $recip['list']);
-
- $identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
- $from_addr = $identity->getFromAddress();
-
- $headers = $contents->getHeaderOb();
- $headers->addResentHeaders($from_addr, $recip['header']['to']);
-
- $mime_message = $contents->getMIMEMessage();
-
- /* We need to set the Return-Path header to the current user - see
- RFC 2821 [4.4]. */
- $headers->removeHeader('return-path');
- $headers->addHeader('Return-Path', $from_addr);
-
- /* Store history information. */
- if (!empty($GLOBALS['conf']['maillog']['use_maillog'])) {
- IMP_Maillog::log('redirect', $headers->getValue('message-id'), $recipients);
- }
-
- try {
- $imp_compose->sendMessage($recipients, $headers, $mime_message);
- } catch (IMP_Compose_Exception $e) {
- throw new Horde_Exception_Prior($e);
- }
-
- $entry = sprintf("%s Redirected message sent to %s from %s",
- $_SERVER['REMOTE_ADDR'], $recipients, Horde_Auth::getAuth());
- Horde::logMessage($entry, 'INFO');
-
- $GLOBALS['injector']->getInstance('IMP_Sentmail')>log('redirect', $headers->getValue('message-id'), $recipients);
- }
-
- /**
* Attach the auto-completer to the current compose form.
*
* @param array $fields The list of DOM IDs to attach the autocompleter
*
* @param array $args Configuration parameters:
* <pre>
- * 'composeCache' - The cache ID of the IMP_Compose object.
- * 'qreply' - Is this a quickreply view?
+ * 'composeCache' - (string) The cache ID of the IMP_Compose object.
+ * 'redirect' - (string) Display the redirect interface?
+ * 'qreply' - (boolean) Is this a quickreply view?
* </pre>
*
* @return array Array with the following keys:
{
$result = array(
'html' => '',
- 'jsappend' => '',
+ 'js' => array(),
'jsonload' => array()
);
- /* Load Identity. */
- $identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
- $selected_identity = $identity->getDefault();
+ $compose_html = $redirect = $rte = false;
- /* Generate identities list. */
- $imp_ui = new IMP_Ui_Compose();
- $result['js'] = array($imp_ui->identityJs());
-
- $composeCache = null;
- if (!empty($args['composeCache'])) {
+ if (empty($args['composeCache'])) {
+ $composeCache = null;
+ } else {
$imp_compose = IMP_Compose::singleton($args['composeCache']);
$composeCache = $args['composeCache'];
+ }
+
+ if (empty($args['redirect'])) {
+ /* Load Identity. */
+ $identity = Horde_Prefs_Identity::singleton(array('imp', 'imp'));
+ $selected_identity = $identity->getDefault();
- if ($imp_compose->numberOfAttachments()) {
+ /* Generate identities list. */
+ $imp_ui = $GLOBALS['injector']->getInstance('IMP_Ui_Compose');
+ $result['js'][] = $imp_ui->identityJs();
+
+ if ($composeCache &&
+ $imp_compose->numberOfAttachments()) {
foreach ($imp_compose->getAttachments() as $num => $atc) {
$mime = $atc['part'];
$result['jsonload'][] = 'DimpCompose.addAttach(' . $num . ', \'' . addslashes($mime->getName(true)) . '\', \'' . addslashes($mime->getType()) . '\', \'' . addslashes($mime->getSize()) . "')";
}
}
- }
- if (!empty($args['qreply'])) {
- $result['js'][] = 'DIMP.conf_compose.qreply = 1';
- }
+ if (!empty($args['qreply'])) {
+ $result['js'][] = 'DIMP.conf_compose.qreply = 1';
+ }
- $compose_html = $rte = false;
- if ($_SESSION['imp']['rteavail']) {
- $compose_html = $GLOBALS['prefs']->getValue('compose_html');
- $rte = true;
+ if ($_SESSION['imp']['rteavail']) {
+ $compose_html = $GLOBALS['prefs']->getValue('compose_html');
+ $rte = true;
- $imp_ui->initRTE(!$compose_html);
- }
+ $imp_ui->initRTE(!$compose_html);
+ }
- /* Create list for sent-mail selection. */
- if (!empty($GLOBALS['conf']['user']['select_sentmail_folder']) &&
- !$GLOBALS['prefs']->isLocked('sent_mail_folder')) {
- $imp_folder = $GLOBALS['injector']->getInstance('IMP_Folder');
+ /* Create list for sent-mail selection. */
+ if (!empty($GLOBALS['conf']['user']['select_sentmail_folder']) &&
+ !$GLOBALS['prefs']->isLocked('sent_mail_folder')) {
+ $imp_folder = $GLOBALS['injector']->getInstance('IMP_Folder');
- /* Check to make sure the sent-mail folders are created - they
- * need to exist to show up in drop-down list. */
- foreach (array_keys($identity->getAllSignatures()) as $ident) {
- $val = $identity->getValue('sent_mail_folder', $ident);
- if (!$imp_folder->exists($val)) {
- $imp_folder->create($val, true);
+ /* Check to make sure the sent-mail folders are created - they
+ * need to exist to show up in drop-down list. */
+ foreach (array_keys($identity->getAllSignatures()) as $ident) {
+ $val = $identity->getValue('sent_mail_folder', $ident);
+ if (!$imp_folder->exists($val)) {
+ $imp_folder->create($val, true);
+ }
}
- }
- $flist = array();
- foreach ($imp_folder->flist() as $val) {
- $tmp = array('l' => $val['abbrev'], 'v' => $val['val']);
- $tmp2 = IMP::displayFolder($val['val']);
- if ($val['val'] != $tmp2) {
- $tmp['f'] = $tmp2;
+ $flist = array();
+ foreach ($imp_folder->flist() as $val) {
+ $tmp = array('l' => $val['abbrev'], 'v' => $val['val']);
+ $tmp2 = IMP::displayFolder($val['val']);
+ if ($val['val'] != $tmp2) {
+ $tmp['f'] = $tmp2;
+ }
+ $flist[] = $tmp;
}
- $flist[] = $tmp;
+ $result['js'][] = 'DIMP.conf_compose.flist = ' . Horde_Serialize::serialize($flist, Horde_Serialize::JSON);
}
- $result['js'][] = 'DIMP.conf_compose.flist = ' . Horde_Serialize::serialize($flist, Horde_Serialize::JSON);
+ } else {
+ $result['js'][] = 'DIMP.conf_compose.redirect = 1';
+ $redirect = true;
}
// Buffer output so that we can return a string from this function
/* Attach spellchecker & auto completer. */
$imp_ui = new IMP_Ui_Compose();
- $imp_ui->attachAutoCompleter(array('to', 'cc', 'bcc'));
+ $imp_ui->attachAutoCompleter(array('to', 'cc', 'bcc', 'redirect_to'));
$imp_ui->attachSpellChecker();
$js_out = array_merge($js_out, $compose_result['js']);
$compose_disable = !IMP::canCompose();
?>
+<?php if (!$redirect): ?>
<form id="compose" name="compose" enctype="multipart/form-data" action="<?php echo Horde::getServiceLink('ajax', 'imp') ?>addAttachment" method="post" target="submit_frame">
<?php echo Horde_Util::formInput() ?>
<input type="hidden" id="last_identity" name="last_identity" value="<?php echo (int)$selected_identity ?>" />
</div>
</div>
</form>
+<?php endif; // !$redirect ?>
+
+<?php if (!$compose_disable): ?>
+<form id="redirect" name="redirect" style="display:none">
+ <input type="hidden" id="redirect_composeCache" name="redirect_composeCache" value="<?php echo $composeCache ?>" />
+<?php echo Horde_Util::formInput() ?>
+ <div class="msgwrite">
+ <div class="dimpActions dimpActionsCompose">
+ <div><?php echo IMP_Dimp::actionButton(array('icon' => 'Forward', 'id' => 'send_button_redirect', 'title' => _("Redirect"))); ?></div>
+ </div>
+ <table>
+ <tr id="redirect_sendto">
+ <td class="label"><span><?php echo _("To: ") ?></span></td>
+ <td>
+ <span id="redirect_to_loading_img" class="loadingImg" style="display:none"></span>
+ <textarea id="redirect_to" name="redirect_to" rows="1" cols="75"></textarea>
+ </td>
+ </tr>
+ </table>
+ </div>
+</form>
+<?php endif; ?>
<span id="sendingImg" class="loadingImg" style="display:none"></span>
<?php endif; ?>
</div>
-<?php if (!$prefs->isLocked('forward_default')): ?>
<div class="context" id="ctx_forwardpopdown" style="display:none;">
+<?php if (!$prefs->isLocked('forward_default')): ?>
<a id="ctx_forward_attach"><span class="contextImg"></span><?php echo _("As Attachment") ?></a>
<a id="ctx_forward_body"><span class="contextImg"></span><?php echo _("In Body Text") ?></a>
<a id="ctx_forward_both"><span class="contextImg"></span><?php echo _("Attachment and Body Text") ?></a>
-</div>
+ <div class="sep"></div>
<?php endif; ?>
+ <a id="ctx_forward_redirect"><span class="contextImg"></span><?php echo _("Redirect") ?></a>
+</div>
<?php endif; ?>
<div class="context" id="ctx_contacts" style="display:none">
<a id="ctx_reply_reply_list"><span class="contextImg"></span><?php echo _("To List") ?></a>
</div>
-<?php if (!$prefs->isLocked('forward_default')): ?>
<div class="context" id="ctx_forward" style="display:none;">
+<?php if (!$prefs->isLocked('forward_default')): ?>
<a id="ctx_forward_attach"><span class="contextImg"></span><?php echo _("As Attachment") ?></a>
<a id="ctx_forward_body"><span class="contextImg"></span><?php echo _("In Body Text") ?></a>
<a id="ctx_forward_both"><span class="contextImg"></span><?php echo _("Attachment and Body Text") ?></a>
-</div>
+ <div class="sep"></div>
<?php endif; ?>
+ <a id="ctx_forward_redirect"><span class="contextImg"></span><?php echo _("Redirect") ?></a>
+</div>
<div class="context" id="ctx_otheractions" style="display:none">
<a id="oa_preview_hide"><span class="contextImg"></span><?php echo _("Hide Preview") ?></a>
<form method="post" action="<tag:post_action />" id="redirect" name="redirect">
-<input type="hidden" name="thismailbox" value="<tag:mailbox />" />
-<input type="hidden" name="uid" value="<tag:uid />" />
+<input type="hidden" name="composeCache" value="<tag:cacheid />" />
<input type="hidden" id="actionID" name="actionID" value="redirect_send" />
<input type="hidden" name="compose_requestToken" value="<tag:token />" />
#ctx_reply_reply span.contextImg, #ctx_reply_reply_all span.contextImg, #ctx_reply_reply_list span.contextImg {
background-image: url("../graphics/replyall.png");
}
-#ctx_message_forward span.contextImg, #ctx_forward_attach span.contextImg, #ctx_forward_body span.contextImg, #ctx_forward_both span.contextImg {
+#ctx_message_forward span.contextImg, #ctx_forward_attach span.contextImg, #ctx_forward_body span.contextImg, #ctx_forward_both span.contextImg, #ctx_forward_redirect span.contextImg {
background-image: url("../graphics/forward.png");
}
#ctx_folder_empty span.contextImg, #ctx_message_deleted span.contextImg, #oa_purge_deleted span.contextImg {
#ctx_reply_reply span.contextImg, #ctx_reply_reply_all span.contextImg, #ctx_reply_reply_list span.contextImg {
background-image: url("../graphics/replyall.png");
}
-#ctx_message_forward span.contextImg, #ctx_forward_attach span.contextImg, #ctx_forward_body span.contextImg, #ctx_forward_both span.contextImg {
+#ctx_message_forward span.contextImg, #ctx_forward_attach span.contextImg, #ctx_forward_body span.contextImg, #ctx_forward_both span.contextImg, #ctx_forward_redirect span.contextImg {
background-image: url("../graphics/forward.png");
}
#ctx_folder_empty span.contextImg, #ctx_message_deleted span.contextImg, #oa_purge_deleted span.contextImg {