1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28:
29: class IMP_Basic_Compose extends IMP_Basic_Base
30: {
31: 32:
33: protected function _init()
34: {
35: global $browser, $injector, $notification, $page_output, $prefs, $registry, $session;
36:
37:
38: if ($this->vars->actionID == 'mailto_link') {
39: switch ($registry->getView()) {
40: case Horde_Registry::VIEW_DYNAMIC:
41: IMP_Dynamic_Compose::url()->add($_GET)->redirect();
42: exit;
43:
44: case Horde_Registry::VIEW_MINIMAL:
45: IMP_Minimal_Compose::url()->add($_GET)->redirect();
46: exit;
47: }
48: }
49:
50:
51: $header = array();
52: $msg = '';
53:
54: $redirect = $resume = $spellcheck = false;
55: $oldrtemode = $rtemode = null;
56:
57:
58: if ($isPopup = ($prefs->getValue('compose_popup') || $this->vars->popup)) {
59: $page_output->topbar = $page_output->sidebar = false;
60: }
61:
62:
63: $identity = $injector->getInstance('IMP_Identity');
64: if (!$prefs->isLocked('default_identity') &&
65: !is_null($this->vars->identity)) {
66: $identity->setDefault($this->vars->identity);
67: }
68:
69: if ($this->vars->actionID) {
70: switch ($this->vars->actionID) {
71: case 'draft':
72: case 'editasnew':
73: case 'forward_attach':
74: case 'forward_auto':
75: case 'forward_body':
76: case 'forward_both':
77: case 'fwd_digest':
78: case 'mailto':
79: case 'mailto_link':
80: case 'reply':
81: case 'reply_all':
82: case 'reply_auto':
83: case 'reply_list':
84: case 'redirect_compose':
85: case 'template':
86: case 'template_edit':
87: case 'template_new':
88: 89:
90: break;
91:
92: default:
93: try {
94: $session->checkToken($this->vars->compose_requestToken);
95: } catch (Horde_Exception $e) {
96: $notification->push($e);
97: $this->vars->actionID = null;
98: }
99: }
100: }
101:
102:
103: if ($reload = $this->vars->compose_formToken) {
104: try {
105: $session->checkNonce($reload);
106: } catch (Horde_Exception $e) {
107: $notification->push(_("You have already submitted this page."), 'horde.error');
108: $this->vars->actionID = null;
109: }
110: }
111:
112:
113: $compose_disable = !IMP_Compose::canCompose();
114:
115:
116: $draft = IMP_Mailbox::getPref(IMP_Mailbox::MBOX_DRAFTS);
117: $readonly_drafts = $draft && $draft->readonly;
118:
119: $sent_mail = $identity->getValue(IMP_Mailbox::MBOX_SENT);
120: if (!$sent_mail) {
121: $readonly_sentmail = $save_sent_mail = false;
122: } elseif ($sent_mail->readonly) {
123: $readonly_sentmail = true;
124: $save_sent_mail = false;
125: } else {
126: $readonly_sentmail = false;
127: $save_sent_mail = $reload
128: ? (bool)$this->vars->save_sent_mail
129: : true;
130: }
131:
132:
133: $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create($this->vars->composeCache);
134:
135:
136: $imp_imap = $injector->getInstance('IMP_Factory_Imap')->create();
137: $imp_ui = new IMP_Compose_Ui();
138:
139: 140:
141: if ($session->get('imp', 'rteavail')) {
142: if ($prefs->isLocked('compose_html')) {
143: $rtemode = $prefs->getValue('compose_html');
144: } else {
145: $rtemode = $this->vars->rtemode;
146: if (is_null($rtemode)) {
147: $rtemode = $prefs->getValue('compose_html');
148: } else {
149: $rtemode = intval($rtemode);
150: $oldrtemode = intval($this->vars->oldrtemode);
151: }
152: }
153: }
154:
155:
156: $attach_upload = $imp_compose->canUploadAttachment();
157: if ($attach_upload) {
158:
159: $notify = !in_array($this->vars->actionID, array('send_message', 'save_draft'));
160:
161: $deleteList = Horde_Util::getPost('delattachments', array());
162:
163:
164: foreach ($imp_compose as $key => $val) {
165: if (!in_array($key, $deleteList)) {
166: $val->getPart()->setDescription($this->vars->filter('file_description_' . $key));
167: $imp_compose[$key] = $val;
168: }
169: }
170:
171:
172: foreach ($deleteList as $val) {
173: if ($notify) {
174: $notification->push(sprintf(_("Deleted attachment \"%s\"."), $imp_compose[$val]->getPart()->getName(true)), 'horde.success');
175: }
176: unset($imp_compose[$val]);
177: }
178:
179:
180: for ($i = 1, $fcount = count($_FILES); $i <= $fcount; ++$i) {
181: if (isset($_FILES['upload_' . $i]) &&
182: strlen($_FILES['upload_' . $i]['name'])) {
183: try {
184: $atc_ob = $imp_compose->addAttachmentFromUpload('upload_' . $i);
185: if ($atc_ob[0] instanceof IMP_Compose_Exception) {
186: throw $atc_ob[0];
187: }
188: if ($notify) {
189: $notification->push(sprintf(_("Added \"%s\" as an attachment."), $atc_ob[0]->getPart()->getName()), 'horde.success');
190: }
191: } catch (IMP_Compose_Exception $e) {
192:
193: $this->vars->actionID = null;
194: $notification->push($e, 'horde.error');
195: }
196: }
197: }
198: }
199:
200:
201: $priority = $this->vars->get('priority', 'normal');
202:
203:
204: $request_read_receipt = (bool)$this->vars->request_read_receipt;
205:
206:
207: $this->title = _("New Message");
208: switch ($this->vars->actionID) {
209: case 'mailto':
210: try {
211: $contents = $this->_getContents();
212: } catch (IMP_Exception $e) {
213: $notification->push($e, 'horde.error');
214: break;
215: }
216:
217: $imp_headers = $contents->getHeader();
218: $header['to'] = '';
219: if ($this->vars->mailto) {
220: $header['to'] = $imp_headers->getValue('to');
221: }
222: if (empty($header['to'])) {
223: ($header['to'] = strval($imp_headers->getOb('from'))) ||
224: ($header['to'] = strval($imp_headers->getOb('reply-to')));
225: }
226: break;
227:
228: case 'mailto_link':
229: $clink = new IMP_Compose_Link($this->vars);
230: if (isset($clink->args['body'])) {
231: $msg = $clink->args['body'];
232: }
233: foreach (array('to', 'cc', 'bcc', 'subject') as $val) {
234: if (isset($clink->args[$val])) {
235: $header[$val] = $clink->args[$val];
236: }
237: }
238: break;
239:
240: case 'draft':
241: case 'editasnew':
242: case 'template':
243: case 'template_edit':
244: try {
245: switch ($this->vars->actionID) {
246: case 'draft':
247: $result = $imp_compose->resumeDraft($this->indices);
248: $resume = true;
249: break;
250:
251: case 'editasnew':
252: $result = $imp_compose->editAsNew($this->indices);
253: break;
254:
255: case 'template':
256: $result = $imp_compose->useTemplate($this->indices);
257: break;
258:
259: case 'template_edit':
260: $result = $imp_compose->editTemplate($this->indices);
261: $this->vars->template_mode = true;
262: break;
263: }
264:
265: if (!is_null($rtemode)) {
266: $rtemode = ($result['format'] == 'html');
267: }
268: $msg = $result['body'];
269: $header = array_merge(
270: $header,
271: $this->_convertToHeader($result)
272: );
273: if (!is_null($result['identity']) &&
274: ($result['identity'] != $identity->getDefault()) &&
275: !$prefs->isLocked('default_identity')) {
276: $identity->setDefault($result['identity']);
277: $sent_mail = $identity->getValue(IMP_Mailbox::MBOX_SENT);
278: }
279: $priority = $result['priority'];
280: $request_read_receipt = $result['readreceipt'];
281: } catch (IMP_Compose_Exception $e) {
282: $notification->push($e);
283: }
284: break;
285:
286: case 'reply':
287: case 'reply_all':
288: case 'reply_auto':
289: case 'reply_list':
290: try {
291: $contents = $this->_getContents();
292: } catch (IMP_Exception $e) {
293: $notification->push($e, 'horde.error');
294: break;
295: }
296:
297: $reply_map = array(
298: 'reply' => IMP_Compose::REPLY_SENDER,
299: 'reply_all' => IMP_Compose::REPLY_ALL,
300: 'reply_auto' => IMP_Compose::REPLY_AUTO,
301: 'reply_list' => IMP_Compose::REPLY_LIST
302: );
303:
304: $reply_msg = $imp_compose->replyMessage($reply_map[$this->vars->actionID], $contents, array(
305: 'to' => $this->vars->to
306: ));
307: $msg = $reply_msg['body'];
308: $header = $this->_convertToHeader($reply_msg);
309: $format = $reply_msg['format'];
310:
311: switch ($reply_msg['type']) {
312: case IMP_Compose::REPLY_SENDER:
313: $this->vars->actionID = 'reply';
314: $this->title = _("Reply:");
315: break;
316:
317: case IMP_Compose::REPLY_ALL:
318: if ($this->vars->actionID == 'reply_auto') {
319: $recip_list = $imp_compose->recipientList($header);
320: if (!empty($recip_list['list'])) {
321: $replyauto_all = count($recip_list['list']);
322: }
323: }
324:
325: $this->vars->actionID = 'reply_all';
326: $this->title = _("Reply to All:");
327: break;
328:
329: case IMP_Compose::REPLY_LIST:
330: if ($this->vars->actionID == 'reply_auto') {
331: $replyauto_list = true;
332: if (($parse_list = $injector->getInstance('Horde_ListHeaders')->parse('list-id', $contents->getHeader()->getValue('list-id'))) &&
333: !is_null($parse_list->label)) {
334: $replyauto_list_id = $parse_list->label;
335: }
336: }
337:
338: $this->vars->actionID = 'reply_list';
339: $this->title = _("Reply to List:");
340: break;
341: }
342:
343: if (!empty($reply_msg['lang'])) {
344: $reply_lang = array_values($reply_msg['lang']);
345: }
346:
347: $this->title .= ' ' . $header['subject'];
348:
349: if (!is_null($rtemode)) {
350: $rtemode = ($rtemode || ($format == 'html'));
351: }
352: break;
353:
354: case 'replyall_revert':
355: case 'replylist_revert':
356: try {
357: $reply_msg = $imp_compose->replyMessage(
358: IMP_Compose::REPLY_SENDER,
359: $imp_compose->getContentsOb()
360: );
361: $header = $this->_convertToHeader($reply_msg);
362: } catch (IMP_Exception $e) {
363: $notification->push($e, 'horde.error');
364: }
365: break;
366:
367: case 'forward_attach':
368: case 'forward_auto':
369: case 'forward_body':
370: case 'forward_both':
371: $fwd_map = array(
372: 'forward_attach' => IMP_Compose::FORWARD_ATTACH,
373: 'forward_auto' => IMP_Compose::FORWARD_AUTO,
374: 'forward_body' => IMP_Compose::FORWARD_BODY,
375: 'forward_both' => IMP_Compose::FORWARD_BOTH
376: );
377:
378: try {
379: $fwd_msg = $imp_compose->forwardMessage(
380: $fwd_map[$this->vars->actionID],
381: $this->_getContents()
382: );
383: } catch (IMP_Exception $e) {
384: $notification->push($e, 'horde.error');
385: break;
386: }
387:
388: $msg = $fwd_msg['body'];
389: $header = $this->_convertToHeader($fwd_msg);
390: $format = $fwd_msg['format'];
391: $rtemode = ($rtemode || (!is_null($rtemode) && ($format == 'html')));
392: $this->title = $fwd_msg['title'];
393: break;
394:
395: case 'redirect_compose':
396: try {
397: $imp_compose->redirectMessage($this->indices);
398: $redirect = true;
399: $this->title = ngettext("Redirect", "Redirect Messages", count($this->indices));
400: } catch (IMP_Compose_Exception $e) {
401: $notification->push($e, 'horde.error');
402: }
403: break;
404:
405: case 'redirect_send':
406: try {
407: $num_msgs = $imp_compose->sendRedirectMessage($this->vars->to);
408: $imp_compose->destroy('send');
409: if ($isPopup) {
410: if ($prefs->getValue('compose_confirm')) {
411: $notification->push(ngettext("Message redirected successfully.", "Messages redirected successfully", count($num_msgs)), 'horde.success');
412: $this->_popupSuccess();
413: return;
414: }
415: echo Horde::wrapInlineScript(array('window.close();'));
416: } else {
417: $notification->push(ngettext("Message redirected successfully.", "Messages redirected successfully", count($num_msgs)), 'horde.success');
418: $this->_mailboxReturnUrl()->redirect();
419: }
420: exit;
421: } catch (Horde_Exception $e) {
422: $notification->push($e);
423: $this->vars->actionID = 'redirect_compose';
424: }
425: break;
426:
427: case 'auto_save_draft':
428: case 'save_draft':
429: case 'save_template':
430: case 'send_message':
431:
432: if ($compose_disable &&
433: ($this->vars->actionID == 'send_message')) {
434: break;
435: }
436:
437: try {
438: $header['from'] = strval($identity->getFromLine(null, $this->vars->from));
439: } catch (Horde_Exception $e) {
440: $header['from'] = '';
441: $notification->push($e);
442: break;
443: }
444:
445: $header['to'] = $this->vars->to;
446: $header['cc'] = $this->vars->cc;
447: $header['bcc'] = $this->vars->bcc;
448:
449: $header['subject'] = strval($this->vars->subject);
450: $message = strval($this->vars->message);
451:
452:
453: switch ($this->vars->actionID) {
454: case 'auto_save_draft':
455: case 'save_draft':
456: case 'save_template':
457: if (!$readonly_drafts ||
458: ($this->vars->actionID == 'save_template')) {
459: $save_opts = array(
460: 'html' => $rtemode,
461: 'priority' => $priority,
462: 'readreceipt' => $request_read_receipt
463: );
464:
465: try {
466: switch ($this->vars->actionID) {
467: case 'save_template':
468: $result = $imp_compose->saveTemplate($header, $message, $save_opts);
469: break;
470:
471: default:
472: $result = $imp_compose->saveDraft($header, $message, $save_opts);
473: break;
474: }
475:
476:
477: switch ($this->vars->actionID) {
478: case 'save_draft':
479: if ($isPopup) {
480: if ($prefs->getValue('close_draft')) {
481: $imp_compose->destroy('save_draft');
482: echo Horde::wrapInlineScript(array('window.close();'));
483: exit;
484: }
485: $notification->push($result, 'horde.success');
486: } else {
487: $notification->push($result, 'horde.success');
488: if ($prefs->getValue('close_draft')) {
489: $imp_compose->destroy('save_draft');
490: $this->_mailboxReturnUrl()->redirect();
491: }
492: }
493: break;
494:
495: case 'save_template':
496: if ($isPopup) {
497: echo Horde::wrapInlineScript(array('window.close();'));
498: exit;
499: }
500:
501: $notification->push($result, 'horde.success');
502: $this->_mailboxReturnUrl()->redirect();
503: break;
504: }
505: } catch (IMP_Compose_Exception $e) {
506: if ($this->vars->actionID == 'save_draft') {
507: $notification->push($e);
508: }
509: }
510: }
511:
512: if ($this->vars->actionID == 'auto_save_draft') {
513: $r = new stdClass;
514: $r->requestToken = $session->getToken();
515: $r->formToken = $session->getNonce();
516:
517: $response = new Horde_Core_Ajax_Response_HordeCore($r);
518: $response->sendAndExit();
519: }
520: break;
521:
522: default:
523: $header['replyto'] = $identity->getValue('replyto_addr');
524:
525: if ($this->vars->sent_mail) {
526: $sent_mail = IMP_Mailbox::formFrom($this->vars->sent_mail);
527: }
528:
529: try {
530: $imp_compose->buildAndSendMessage(
531: $message,
532: $header,
533: $identity,
534: array(
535: 'encrypt' => $prefs->isLocked('default_encrypt') ? $prefs->getValue('default_encrypt') : $this->vars->encrypt_options,
536: 'html' => $rtemode,
537: 'pgp_attach_pubkey' => $this->vars->pgp_attach_pubkey,
538: 'priority' => $priority,
539: 'save_sent' => $save_sent_mail,
540: 'sent_mail' => $sent_mail,
541: 'signature' => $this->vars->signature,
542: 'strip_attachments' => !$this->vars->save_attachments_select,
543: 'readreceipt' => $request_read_receipt,
544: 'vcard_attach' => $this->vars->vcard ? $identity->getValue('fullname') : null
545: )
546: );
547: $imp_compose->destroy('send');
548:
549: if ($isPopup) {
550: if ($prefs->getValue('compose_confirm')) {
551: $notification->push(_("Message sent successfully."), 'horde.success');
552: $this->_popupSuccess();
553: return;
554: }
555: echo Horde::wrapInlineScript(array('window.close();'));
556: } else {
557: $notification->push(_("Message sent successfully."), 'horde.success');
558: $this->_mailboxReturnUrl()->redirect();
559: }
560: exit;
561: } catch (IMP_Compose_Exception $e) {
562: $code = $e->getCode();
563: $notification->push($e->getMessage(), strpos($code, 'horde.') === 0 ? $code : 'horde.error');
564:
565:
566: if (!is_null($e->tied_identity)) {
567: $identity->setDefault($e->tied_identity);
568: $notification->push(_("Your identity has been switched to the identity associated with the current recipient address. The identity will not be checked again during this compose action."));
569: }
570:
571: switch ($e->encrypt) {
572: case 'pgp_symmetric_passphrase_dialog':
573: $imp_ui->passphraseDialog('pgp_symm', $imp_compose->getCacheId());
574: break;
575:
576: case 'pgp_passphrase_dialog':
577: $imp_ui->passphraseDialog('pgp');
578: break;
579:
580: case 'smime_passphrase_dialog':
581: $imp_ui->passphraseDialog('smime');
582: break;
583: }
584: }
585: break;
586: }
587: break;
588:
589: case 'fwd_digest':
590: if (count($this->indices)) {
591: try {
592: $res = $imp_compose->forwardMultipleMessages($this->indices);
593: $header['subject'] = $res['subject'];
594: $fwd_msg = array('type' => IMP_Compose::FORWARD_ATTACH);
595: } catch (IMP_Compose_Exception $e) {
596: $notification->push($e, 'horde.error');
597: }
598: }
599: break;
600:
601: case 'cancel_compose':
602: case 'discard_compose':
603: $imp_compose->destroy($this->vars->actionID == 'cancel_compose' ? 'cancel' : 'discard');
604: if ($isPopup) {
605: echo Horde::wrapInlineScript(array('window.close();'));
606: } else {
607: $this->_mailboxReturnUrl()->redirect();
608: }
609: exit;
610:
611: case 'template_new':
612: $this->vars->template_mode = true;
613: break;
614: }
615:
616:
617: $composeCacheID = filter_var($imp_compose->getCacheId(), FILTER_SANITIZE_STRING);
618:
619: $page_output->addScriptPackage('IMP_Script_Package_ContactAutocomplete');
620: if (!$redirect) {
621: $spellcheck = $imp_ui->attachSpellChecker();
622: $page_output->addScriptFile('ieescguard.js', 'horde');
623: }
624:
625: $max_attach = $imp_compose->additionalAttachmentsAllowed();
626:
627: 628: 629:
630: if ($isPopup) {
631: if ($resume || count($imp_compose)) {
632: $cancel_url = self::url()->setRaw(true)->add(array(
633: 'actionID' => 'cancel_compose',
634: 'compose_requestToken' => $session->getToken(),
635: 'composeCache' => $composeCacheID,
636: 'popup' => 1
637: ));
638: $discard_url = clone $cancel_url;
639: $discard_url->add('actionID', 'discard_compose');
640: } else {
641: $cancel_url = $discard_url = '';
642: }
643: } elseif ($resume || count($imp_compose)) {
644: $cancel_url = $this->_mailboxReturnUrl(self::url()->setRaw(true))->setRaw(true)->add(array(
645: 'actionID' => 'cancel_compose',
646: 'compose_requestToken' => $session->getToken(),
647: 'composeCache' => $composeCacheID
648: ));
649: $discard_url = clone $cancel_url;
650: $discard_url->add('actionID', 'discard_compose');
651: } else {
652: $cancel_url = $discard_url = $this->_mailboxReturnUrl(false)->setRaw(true);
653: }
654:
655:
656: if (!strlen($msg)) {
657: $msg = $this->vars->get('message', strval($this->vars->body));
658: if ($browser->hasQuirk('double_linebreak_textarea')) {
659: $msg = preg_replace('/(\r?\n){3}/', '$1', $msg);
660: }
661: $msg = "\n" . $msg;
662: }
663: if (isset($this->vars->signature)) {
664: $signature = $this->vars->signature;
665: if ($browser->hasQuirk('double_linebreak_textarea')) {
666: $signature = preg_replace('/(\r?\n){3}/', '$1', $signature);
667: }
668: $signatureChanged = $signature != $identity->getSignature($oldrtemode ? 'html' : 'text');
669: } else {
670: $signatureChanged = false;
671: }
672:
673:
674: if (!is_null($oldrtemode) && ($oldrtemode != $rtemode)) {
675: $msg = $imp_ui->convertComposeText($msg, $rtemode ? 'html' : 'text');
676: if ($signatureChanged) {
677: $signature = $imp_ui->convertComposeText($signature, $rtemode ? 'html' : 'text');
678: }
679: }
680:
681: 682:
683: if (!$reload && !$resume) {
684: $header['bcc'] = strval($identity->getBccAddresses());
685: }
686:
687: foreach (array('to', 'cc', 'bcc') as $val) {
688: if (!isset($header[$val])) {
689: $header[$val] = $this->vars->$val;
690: }
691: }
692:
693: if (!isset($header['subject'])) {
694: $header['subject'] = $this->vars->subject;
695: }
696:
697: 698:
699: $encrypt_options = $prefs->isLocked('default_encrypt')
700: ? $prefs->getValue('default_encrypt')
701: : $this->vars->encrypt_options;
702: if ($prefs->getValue('use_pgp') &&
703: !$prefs->isLocked('default_encrypt') &&
704: $prefs->getValue('pgp_reply_pubkey')) {
705: $default_encrypt = $prefs->getValue('default_encrypt');
706: if (!$reload &&
707: in_array($default_encrypt, array(IMP_Crypt_Pgp::ENCRYPT, IMP_Crypt_Pgp::SIGNENC))) {
708: $addrs = $imp_compose->recipientList($header);
709: if (!empty($addrs['list'])) {
710: $imp_pgp = $injector->getInstance('IMP_Crypt_Pgp');
711: try {
712: foreach ($addrs['list'] as $val) {
713: $imp_pgp->getPublicKey(strval($val));
714: }
715: } catch (Horde_Exception $e) {
716: $notification->push(_("PGP encryption cannot be used by default as public keys cannot be found for all recipients."), 'horde.warning');
717: $encrypt_options = ($default_encrypt == IMP_Crypt_Pgp::ENCRYPT) ? IMP::ENCRYPT_NONE : IMP_Crypt_Pgp::SIGN;
718: }
719: }
720: }
721: }
722:
723:
724: $js_vars = array(
725: 'ImpComposeBase.editor_on' => $rtemode,
726: 'ImpCompose.auto_save' => intval($prefs->getValue('auto_save_drafts')),
727: 'ImpCompose.cancel_url' => strval($cancel_url),
728: 'ImpCompose.cursor_pos' => ($rtemode ? null : $prefs->getValue('compose_cursor')),
729: 'ImpCompose.discard_url' => strval($discard_url),
730: 'ImpCompose.max_attachments' => (($max_attach === true) ? null : $max_attach),
731: 'ImpCompose.popup' => intval($isPopup),
732: 'ImpCompose.redirect' => intval($redirect),
733: 'ImpCompose.reloaded' => intval($reload),
734: 'ImpCompose.sm_check' => intval(!$prefs->isLocked(IMP_Mailbox::MBOX_SENT)),
735: 'ImpCompose.spellcheck' => intval($spellcheck && $prefs->getValue('compose_spellcheck')),
736: 'ImpCompose.text' => array(
737: 'cancel' => _("Cancelling this message will permanently discard its contents.") . "\n" . _("Are you sure you want to do this?"),
738: 'change_identity' => _("You have edited your signature. Change the identity and lose your changes?"),
739: 'discard' => _("Doing so will discard this message permanently."),
740: 'file' => _("File"),
741: 'nosubject' => _("The message does not have a Subject entered.") . "\n" . _("Send message without a Subject?"),
742: 'recipient' => _("You must specify a recipient.")
743: )
744: );
745:
746:
747: $view = $injector->createInstance('Horde_View');
748: $view->addHelper('FormTag');
749: $view->addHelper('Horde_Core_View_Helper_Accesskey');
750: $view->addHelper('Horde_Core_View_Helper_Help');
751: $view->addHelper('Horde_Core_View_Helper_Image');
752: $view->addHelper('Horde_Core_View_Helper_Label');
753: $view->addHelper('Tag');
754:
755: $view->allow_compose = !$compose_disable;
756: $view->post_action = self::url();
757:
758: $blank_url = new Horde_Url('#');
759:
760: if ($redirect) {
761:
762: $view->cacheid = $composeCacheID;
763: $view->title = $this->title;
764: $view->token = $session->getToken();
765:
766: if ($registry->hasMethod('contacts/search')) {
767: $view->abook = $blank_url->copy()->link(array(
768: 'class' => 'widget',
769: 'id' => 'redirect_abook',
770: 'title' => _("Address Book")
771: ));
772: $js_vars['ImpCompose.redirect_contacts'] = strval(IMP_Basic_Contacts::url()->add(array('to_only' => 1))->setRaw(true));
773: }
774:
775: $view->input_value = $header['to'];
776:
777: $this->output = $view->render('basic/compose/redirect');
778: } else {
779:
780: $view->file_upload = $attach_upload;
781:
782: $hidden = array(
783: 'actionID' => '',
784: 'attachmentAction' => '',
785: 'compose_formToken' => $session->getNonce(),
786: 'compose_requestToken' => $session->getToken(),
787: 'composeCache' => $composeCacheID,
788: 'composeHmac' => $imp_compose->getHmac(),
789: 'oldrtemode' => $rtemode,
790: 'rtemode' => $rtemode,
791: 'user' => $registry->getAuth()
792: );
793:
794: if ($attach_upload) {
795: $hidden['MAX_FILE_SIZE'] = $session->get('imp', 'file_upload');
796: }
797: foreach (array('page', 'start', 'popup', 'template_mode') as $val) {
798: $hidden[$val] = $this->vars->$val;
799: }
800:
801: $view->hidden = $hidden;
802: $view->tabindex = 1;
803: $view->title = $this->title;
804:
805: if (!$this->vars->template_mode) {
806: $view->send_msg = true;
807: $view->save_draft = ($imp_imap->access(IMP_Imap::ACCESS_DRAFTS) && !$readonly_drafts);
808: }
809:
810: $view->resume = $resume;
811:
812: $view->di_locked = $prefs->isLocked('default_identity');
813: if ($view->di_locked) {
814: $view->fromaddr_locked = $prefs->isLocked('from_addr');
815: try {
816: $view->from = $identity->getFromLine(null, $this->vars->from);
817: } catch (Horde_Exception $e) {}
818: } else {
819: $select_list = $identity->getSelectList();
820: $view->last_identity = $identity->getDefault();
821:
822: if (count($select_list) > 1) {
823: $view->count_select_list = true;
824: $t_select_list = array();
825: foreach ($select_list as $key => $select) {
826: $t_select_list[] = array(
827: 'label' => $select,
828: 'selected' => ($key == $identity->getDefault()),
829: 'value' => $key
830: );
831: }
832: $view->select_list = $t_select_list;
833: } else {
834: $view->identity_default = $identity->getDefault();
835: $view->identity_text = $select_list[0];
836: }
837: }
838: $view->signature = $identity->hasSignature(true);
839:
840: $addr_array = array(
841: 'to' => _("_To"),
842: 'cc' => _("_Cc"),
843: 'bcc' => _("_Bcc")
844: );
845:
846: $address_array = array();
847: foreach ($addr_array as $val => $label) {
848: $address_array[] = array(
849: 'id' => $val,
850: 'label' => $label,
851: 'val' => $header[$val]
852: );
853: }
854: $view->addr = $address_array;
855:
856: $view->subject = $header['subject'];
857:
858: if ($prefs->getValue('set_priority')) {
859: $view->set_priority = true;
860:
861: $priorities = array(
862: 'high' => _("High"),
863: 'normal' => _("Normal"),
864: 'low' => _("Low")
865: );
866:
867: $priority_option = array();
868: foreach ($priorities as $key => $val) {
869: $priority_option[] = array(
870: 'label' => $val,
871: 'selected' => ($priority == $key),
872: 'val' => $key
873: );
874: }
875: $view->pri_opt = $priority_option;
876: }
877:
878: $compose_options = array();
879:
880: if ($registry->hasMethod('contacts/search')) {
881: $compose_options[] = array(
882: 'url' => $blank_url->copy()->link(array(
883: 'class' => 'widget',
884: 'id' => 'addressbook_popup'
885: )),
886: 'img' => Horde_Themes_Image::tag('addressbook_browse.png'),
887: 'label' => _("Address Book")
888: );
889: $js_vars['ImpCompose.contacts_url'] = strval(IMP_Basic_Contacts::url()->setRaw(true));
890: }
891: if ($spellcheck) {
892: $compose_options[] = array(
893: 'url' => $blank_url->copy()->link(array(
894: 'class' => 'widget',
895: 'id' => 'spellcheck'
896: )),
897: 'img' => '',
898: 'label' => ''
899: );
900: }
901: if ($attach_upload) {
902: $url = new Horde_Url('#attachments');
903: $compose_options[] = array(
904: 'url' => $url->link(array('class' => 'widget')),
905: 'img' => Horde_Themes_Image::tag('attachment.png'),
906: 'label' => _("Attachments")
907: );
908: }
909: $view->compose_options = $compose_options;
910:
911: if ($imp_imap->access(IMP_Imap::ACCESS_FOLDERS) &&
912: !$prefs->isLocked('save_sent_mail')) {
913: $view->ssm = true;
914: if ($readonly_sentmail) {
915: $notification->push(sprintf(_("Cannot save sent-mail message to \"%s\" as that mailbox is read-only.", $sent_mail->display), 'horde.warning'));
916: }
917: $view->ssm_selected = $reload
918: ? $save_sent_mail
919: : ($sent_mail && $identity->saveSentmail());
920: if ($this->vars->sent_mail) {
921: $sent_mail = IMP_Mailbox::formFrom($this->vars->sent_mail);
922: }
923: if (!$prefs->isLocked(IMP_Mailbox::MBOX_SENT)) {
924: $iterator = new IMP_Ftree_IteratorFilter(
925: $injector->getInstance('IMP_Ftree')
926: );
927: $iterator->add($iterator::NONIMAP);
928: $iterator->mboxes = array('INBOX');
929:
930: $ssm_options = array(
931: 'abbrev' => false,
932: 'basename' => true,
933: 'iterator' => $iterator,
934: 'selected' => $sent_mail
935: );
936:
937: 938:
939: if ($sent_mail) {
940: $sent_mail->create();
941: }
942:
943: $view->ssm_mboxes = new IMP_Ftree_Select($ssm_options);
944: } else {
945: if ($sent_mail) {
946: $sent_mail = '"' . $sent_mail->display_html . '"';
947: }
948: $view->ssm_mbox = $sent_mail;
949: }
950: }
951:
952: $view->rrr_selected = $prefs->isLocked('request_mdn')
953: ? null
954: : (($prefs->getValue('request_mdn') == 'always') || $request_read_receipt);
955:
956: if (!is_null($rtemode) && !$prefs->isLocked('compose_html')) {
957: $view->compose_html = true;
958: $view->html_switch = $blank_url->copy()->link(array(
959: 'id' => 'rte_toggle',
960: 'title' => _("Switch Composition Method")
961: ));
962: $view->rtemode = $rtemode;
963: }
964:
965: if (isset($replyauto_all)) {
966: $view->replyauto_all = $replyauto_all;
967: } elseif (isset($replyauto_list)) {
968: $view->replyauto_list = true;
969: if (isset($replyauto_list_id)) {
970: $view->replyauto_list_id = $replyauto_list_id;
971: }
972: }
973:
974: if (isset($reply_lang)) {
975: $view->reply_lang = implode(',', $reply_lang);
976: }
977:
978: $view->message = $msg;
979: if ($signatureChanged) {
980: $view->signatureContent = $signature;
981: }
982:
983: if ($prefs->getValue('use_pgp') || $prefs->getValue('use_smime')) {
984: if ($prefs->isLocked('default_encrypt')) {
985: $view->use_encrypt = false;
986: } else {
987: $view->use_encrypt = true;
988: $view->encrypt_options = $imp_ui->encryptList($encrypt_options);
989: }
990:
991: if ($prefs->getValue('use_pgp') && $prefs->getValue('pgp_public_key')) {
992: $view->pgp_options = true;
993: $view->pgp_attach_pubkey = $reload
994: ? $this->vars->pgp_attach_pubkey
995: : $prefs->getValue('pgp_attach_pubkey');
996: }
997: }
998:
999: if ($registry->hasMethod('contacts/ownVCard')) {
1000: $view->vcard = true;
1001: $view->attach_vcard = $this->vars->vcard;
1002: }
1003:
1004: if ($attach_upload) {
1005: $view->attach_size = IMP::numberFormat($imp_compose->maxAttachmentSize(), 0);
1006: $view->maxattachmentnumber = !$max_attach;
1007:
1008: $save_attach = $prefs->getValue('save_attachments');
1009:
1010: if ($view->ssm && !$prefs->isLocked('save_attachments')) {
1011: $view->show_link_save_attach = true;
1012: $view->attach_options = array(array(
1013: 'label' => _("Save attachments with message in sent-mail mailbox?"),
1014: 'name' => 'save_attachments_select',
1015: 'val' => ($reload ? $this->vars->save_attachments_select : ($save_attach == 'always'))
1016: ));
1017: }
1018:
1019: if (count($imp_compose)) {
1020: $view->numberattach = true;
1021:
1022: $atc = array();
1023: $v = $injector->getInstance('IMP_Factory_MimeViewer');
1024: foreach ($imp_compose as $data) {
1025: $mime = $data->getPart();
1026: $type = $mime->getType();
1027:
1028: $entry = array(
1029: 'name' => $mime->getName(true),
1030: 'icon' => $v->getIcon($type),
1031: 'number' => $data->id,
1032: 'type' => $type,
1033: 'size' => $mime->getSize(),
1034: 'description' => $mime->getDescription(true)
1035: );
1036:
1037: if (!(isset($fwd_msg) &&
1038: ($fwd_msg['type'] != IMP_Compose::FORWARD_BODY)) &&
1039: ($type != 'application/octet-stream')) {
1040: $entry['name'] = $data->viewUrl()->link(array(
1041: 'class' => 'link',
1042: 'target' => 'compose_preview_window',
1043: 'title' => _("Preview")
1044: )) . htmlspecialchars($entry['name']) . '</a>';
1045: }
1046:
1047: $atc[] = $entry;
1048: }
1049: $view->atc = $atc;
1050: }
1051: }
1052:
1053: $this->output = $view->render('basic/compose/compose');
1054: }
1055:
1056: $page_output->addScriptPackage('IMP_Script_Package_ComposeBase');
1057: $page_output->addScriptFile('compose.js');
1058: $page_output->addScriptFile('editor.js');
1059: $page_output->addScriptFile('imp.js');
1060: $page_output->addInlineJsVars($js_vars);
1061: if (!$redirect) {
1062: $imp_ui->addIdentityJs();
1063: }
1064:
1065: if ($rtemode && !$redirect) {
1066: $page_output->addScriptPackage('IMP_Script_Package_Editor');
1067: }
1068: }
1069:
1070: 1071: 1072: 1073:
1074: public static function url(array $opts = array())
1075: {
1076: return Horde::url('basic.php', !empty($opts['full']))->add('page', 'compose')->unique();
1077: }
1078:
1079: 1080: 1081: 1082: 1083: 1084:
1085: protected function _getContents()
1086: {
1087: $ob = null;
1088:
1089: if (count($this->indices)) {
1090: try {
1091: $ob = $GLOBALS['injector']->getInstance('IMP_Factory_Contents')->create($this->indices);
1092: } catch (Horde_Exception $e) {}
1093: }
1094:
1095: if (!is_null($ob)) {
1096: return $ob;
1097: }
1098:
1099: $this->vars->buid = null;
1100: $this->vars->type = 'new';
1101: throw new IMP_Exception(_("Could not retrieve message data from the mail server."));
1102: }
1103:
1104: 1105: 1106: 1107: 1108: 1109: 1110:
1111: protected function _mailboxReturnUrl($url = null)
1112: {
1113: $url = $this->indices->mailbox->url('mailbox');
1114:
1115: foreach (array('start', 'page') as $key) {
1116: if (isset($vars->$key)) {
1117: $url->add($key, $vars->$key);
1118: }
1119: }
1120:
1121: return $url;
1122: }
1123:
1124: 1125: 1126:
1127: protected function ()
1128: {
1129: global $page_output;
1130:
1131: $page_output->topbar = $page_output->sidebar = false;
1132: $page_output->addInlineScript(array(
1133: '$("close_success").observe("click", function() { window.close(); })'
1134: ), true);
1135:
1136: $this->title =_("Message Successfully Sent");
1137:
1138: $view = new Horde_View(array(
1139: 'templatePath' => IMP_TEMPLATES . '/basic/compose'
1140: ));
1141:
1142: $view->close = Horde::widget(array(
1143: 'id' => 'close_success',
1144: 'url' => new Horde_Url('#'),
1145: 'title' => _("Close this window")
1146: ));
1147: $view->new = Horde::widget(array(
1148: 'url' => self::url(),
1149: 'title' => _("New Message")
1150: ));
1151:
1152: $this->output = $view->render('success');
1153: }
1154:
1155: 1156: 1157: 1158: 1159: 1160: 1161:
1162: protected function ($in)
1163: {
1164: $out = array();
1165:
1166: if (isset($in['addr'])) {
1167: $out['to'] = strval($in['addr']['to']);
1168: $out['cc'] = strval($in['addr']['cc']);
1169: $out['bcc'] = strval($in['addr']['bcc']);
1170: }
1171:
1172: if (isset($in['subject'])) {
1173: $out['subject'] = $in['subject'];
1174: }
1175:
1176: return $out;
1177: }
1178:
1179: }
1180: