1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15: class IMP_Minimal_Compose extends IMP_Minimal_Base
16: {
17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33:
34: protected function _init()
35: {
36: global $injector, $notification, $prefs, $registry;
37:
38:
39: $expand = array();
40: $header = array(
41: 'to' => '',
42: 'cc' => '',
43: 'bcc' => ''
44: );
45: $msg = '';
46: $this->title = _("Compose Message");
47:
48:
49: $display_hdrs = array(
50: 'to' => _("To: "),
51: 'cc' => _("Cc: "),
52: 'bcc' => ("Bcc: ")
53: );
54:
55:
56: $identity = $injector->getInstance('IMP_Identity');
57: if (!$prefs->isLocked('default_identity') &&
58: isset($this->vars->identity)) {
59: $identity->setDefault($this->vars->identity);
60: }
61:
62:
63: $drafts = IMP_Mailbox::getPref(IMP_Mailbox::MBOX_DRAFTS);
64: $readonly_drafts = $drafts && $drafts->readonly;
65: $sent_mail = $identity->getValue(IMP_Mailbox::MBOX_SENT);
66: $save_sent_mail = (!$sent_mail || $sent_mail->readonly)
67: ? false
68: : $prefs->getValue('save_sent_mail');
69:
70:
71: $compose_disable = !IMP_Compose::canCompose();
72:
73:
74: $imp_compose = $injector->getInstance('IMP_Factory_Compose')->create($this->vars->composeCache);
75:
76:
77: $attach_upload = $imp_compose->canUploadAttachment();
78:
79: foreach (array_keys($display_hdrs) as $val) {
80: $header[$val] = $this->vars->$val;
81:
82:
83: if ($this->vars->composeCache) {
84: $expanded = array();
85: for ($i = 0; $i < 5; ++$i) {
86: if ($tmp = $this->vars->get($val . '_expand_' . $i)) {
87: $expanded[] = $tmp;
88: }
89: }
90: if (!empty($expanded)) {
91: $header['to'] = strlen($header['to'])
92: ? implode(', ', $expanded) . ', ' . $header['to']
93: : implode(', ', $expanded);
94: }
95: }
96: }
97:
98:
99: if ($attach_upload &&
100: isset($_FILES['upload_1']) &&
101: strlen($_FILES['upload_1']['name'])) {
102: try {
103: $atc_ob = $imp_compose->addAttachmentFromUpload('upload_1');
104: if ($atc_ob[0] instanceof IMP_Compose_Exception) {
105: throw $atc_ob[0];
106: }
107: if ($this->vars->a == _("Expand Names")) {
108: $notification->push(sprintf(_("Added \"%s\" as an attachment."), $atc_ob[0]->getPart()->getName()), 'horde.success');
109: }
110: } catch (IMP_Compose_Exception $e) {
111: $this->vars->a = null;
112: $notification->push($e, 'horde.error');
113: }
114: }
115:
116:
117: switch ($this->vars->a) {
118:
119:
120:
121: case 'd':
122: case 'en':
123: case 't':
124: try {
125: switch ($this->vars->a) {
126: case 'd':
127: $result = $imp_compose->resumeDraft($this->indices, array(
128: 'format' => 'text'
129: ));
130: $this->view->resume = true;
131: break;
132:
133: case 'en':
134: $result = $imp_compose->editAsNew($this->indices, array(
135: 'format' => 'text'
136: ));
137: break;
138:
139: case 't':
140: $result = $imp_compose->useTemplate($this->indices, array(
141: 'format' => 'text'
142: ));
143: break;
144: }
145:
146: $msg = $result['body'];
147: $header = array_merge(
148: $header,
149: $this->_convertToHeader($result)
150: );
151: if (!is_null($result['identity']) &&
152: ($result['identity'] != $identity->getDefault()) &&
153: !$prefs->isLocked('default_identity')) {
154: $identity->setDefault($result['identity']);
155: $sent_mail = $identity->getValue(IMP_Mailbox::MBOX_SENT);
156: }
157: } catch (IMP_Compose_Exception $e) {
158: $notification->push($e);
159: }
160: break;
161:
162: case _("Expand Names"):
163: foreach (array_keys($display_hdrs) as $val) {
164: if (($val == 'to') || ($this->vars->action != 'rc')) {
165: $res = $this->_expandAddresses($header[$val]);
166: if (is_string($res)) {
167: $header[$val] = $res;
168: } else {
169: $header[$val] = $res[0];
170: $expand[$val] = array_slice($res, 1);
171: }
172: }
173: }
174:
175: if (isset($this->vars->action)) {
176: $this->vars->a = $this->vars->action;
177: }
178: break;
179:
180:
181:
182:
183: case 'r':
184: case 'ra':
185: case 'rl':
186: $actions = array(
187: 'r' => IMP_Compose::REPLY_SENDER,
188: 'ra' => IMP_Compose::REPLY_ALL,
189: 'rl' => IMP_Compose::REPLY_LIST
190: );
191:
192: try {
193: $reply_msg = $imp_compose->replyMessage(
194: $actions[$this->vars->a],
195: $this->_getContents(),
196: array(
197: 'format' => 'text',
198: 'to' => $header['to']
199: )
200: );
201: } catch (IMP_Exception $e) {
202: $notification->push($e, 'horde.error');
203: break;
204: }
205:
206: $header = $this->_convertToHeader($reply_msg);
207:
208: $notification->push(_("Reply text will be automatically appended to your outgoing message."), 'horde.message');
209: $this->title = _("Reply");
210: break;
211:
212:
213: case 'f':
214: try {
215: $fwd_msg = $imp_compose->forwardMessage(
216: IMP_Compose::FORWARD_ATTACH,
217: $this->_getContents(),
218: false
219: );
220: } catch (IMP_Exception $e) {
221: $notification->push($e, 'horde.error');
222: break;
223: }
224:
225: $header = $this->_convertToHeader($fwd_msg);
226:
227: $notification->push(_("Forwarded message will be automatically added to your outgoing message."), 'horde.message');
228: $this->title = _("Forward");
229: break;
230:
231:
232: case 'rc':
233: $imp_compose->redirectMessage($this->indices);
234: $this->title = _("Redirect");
235: break;
236:
237: case _("Redirect"):
238: try {
239: $num_msgs = $imp_compose->sendRedirectMessage($header['to']);
240: $imp_compose->destroy('send');
241:
242: $notification->push(ngettext("Message redirected successfully.", "Messages redirected successfully.", count($num_msgs)), 'horde.success');
243: IMP_Minimal_Mailbox::url(array('mailbox' => $this->indices->mailbox))->redirect();
244: } catch (Horde_Exception $e) {
245: $this->vars->a = 'rc';
246: $notification->push($e);
247: }
248: break;
249:
250: case _("Save Draft"):
251: case _("Send"):
252: switch ($this->vars->a) {
253: case _("Save Draft"):
254: if ($readonly_drafts) {
255: break 2;
256: }
257: break;
258:
259: case _("Send"):
260: if ($compose_disable) {
261: break 2;
262: }
263: break;
264: }
265:
266: $message = strval($this->vars->message);
267: $f_to = $header['to'];
268: $old_header = $header;
269: $header = array();
270:
271: switch ($imp_compose->replyType(true)) {
272: case IMP_Compose::REPLY:
273: try {
274: $reply_msg = $imp_compose->replyMessage(IMP_Compose::REPLY_SENDER, $imp_compose->getContentsOb(), array(
275: 'to' => $f_to
276: ));
277: $msg = $reply_msg['body'];
278: } catch (IMP_Exception $e) {
279: $notification->push($e, 'horde.error');
280: $msg = '';
281: }
282: $message .= "\n" . $msg;
283: break;
284:
285: case IMP_Compose::FORWARD:
286: try {
287: $fwd_msg = $imp_compose->forwardMessage(IMP_Compose::FORWARD_ATTACH, $imp_compose->getContentsOb());
288: $msg = $fwd_msg['body'];
289: } catch (IMP_Exception $e) {
290: $notification->push($e, 'horde.error');
291: }
292: $message .= "\n" . $msg;
293: break;
294: }
295:
296: try {
297: $header['from'] = strval($identity->getFromLine(null, $this->vars->from));
298: } catch (Horde_Exception $e) {
299: $header['from'] = '';
300: }
301: $header['replyto'] = $identity->getValue('replyto_addr');
302: $header['subject'] = strval($this->vars->subject);
303:
304: foreach (array_keys($display_hdrs) as $val) {
305: $header[$val] = $old_header[$val];
306: }
307:
308: switch ($this->vars->a) {
309: case _("Save Draft"):
310: try {
311: $notification->push($imp_compose->saveDraft($header, $message), 'horde.success');
312: if ($prefs->getValue('close_draft')) {
313: $imp_compose->destroy('save_draft');
314: IMP_Minimal_Mailbox::url(array('mailbox' => $this->indices->mailbox))->redirect();
315: }
316: } catch (IMP_Compose_Exception $e) {
317: $notification->push($e);
318: }
319: break;
320:
321: case _("Send"):
322: try {
323: $imp_compose->buildAndSendMessage(
324: $message,
325: $header,
326: $identity,
327: array(
328: 'readreceipt' => ($prefs->getValue('request_mdn') == 'always'),
329: 'save_sent' => $save_sent_mail,
330: 'sent_mail' => $sent_mail
331: )
332: );
333: $imp_compose->destroy('send');
334:
335: $notification->push(_("Message sent successfully."), 'horde.success');
336: IMP_Minimal_Mailbox::url(array('mailbox' => $this->indices->mailbox))->redirect();
337: } catch (IMP_Compose_Exception $e) {
338: $notification->push($e);
339:
340:
341: if (!is_null($e->tied_identity)) {
342: $identity->setDefault($e->tied_identity);
343: $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."));
344: }
345: }
346: break;
347: }
348: break;
349:
350: case _("Cancel"):
351: $imp_compose->destroy('cancel');
352: IMP_Minimal_Mailbox::url(array('mailbox' => $this->indices->mailbox))->redirect();
353: exit;
354:
355: case _("Discard Draft"):
356: $imp_compose->destroy('discard');
357: IMP_Minimal_Mailbox::url(array('mailbox' => $this->indices->mailbox))->redirect();
358: exit;
359: }
360:
361:
362: if (empty($msg)) {
363: $msg = strval($this->vars->message);
364: }
365: if (empty($header['subject'])) {
366: $header['subject'] = strval($this->vars->subject);
367: }
368:
369: $this->view->cacheid = $imp_compose->getCacheId();
370: $this->view->hmac = $imp_compose->getHmac();
371: $this->view->menu = $this->getMenu('compose');
372: $this->view->url = self::url();
373: $this->view->user = $registry->getAuth();
374:
375: switch ($this->vars->a) {
376: case 'rc':
377: $this->_pages[] = 'redirect';
378: $this->_pages[] = 'menu';
379: unset($display_hdrs['cc'], $display_hdrs['bcc']);
380: break;
381:
382: default:
383: $this->_pages[] = 'compose';
384: $this->_pages[] = 'menu';
385:
386: $this->view->compose_enable = !$compose_disable;
387: $this->view->msg = $msg;
388: $this->view->save_draft = ($injector->getInstance('IMP_Factory_Imap')->create()->access(IMP_Imap::ACCESS_DRAFTS) && !$readonly_drafts);
389: $this->view->subject = $header['subject'];
390:
391: $select_list = $identity->getSelectList();
392: $default_identity = $identity->getDefault();
393:
394: if ($prefs->isLocked('default_identity')) {
395: $select_list = array(
396: $default_identity => $select_list[$default_identity]
397: );
398: }
399:
400: $tmp = array();
401: foreach ($select_list as $key => $val) {
402: $tmp[] = array(
403: 'key' => $key,
404: 'sel' => ($key == $default_identity),
405: 'val' => $val
406: );
407: }
408: $this->view->identities = $tmp;
409:
410: if ($attach_upload) {
411: $this->view->attach = true;
412: if (count($imp_compose)) {
413: $atc_part = $imp_compose[0]->getPart();
414: $this->view->attach_name = $atc_part->getName();
415: $this->view->attach_size = IMP::sizeFormat($atc_part->getBytes());
416: $this->view->attach_type = $atc_part->getType();
417: }
418: }
419:
420: $this->title = _("Message Composition");
421: }
422:
423: $hdrs = array();
424: foreach ($display_hdrs as $key => $val) {
425: $tmp = array(
426: 'key' => $key,
427: 'label' => $val,
428: 'val' => $header[$key]
429: );
430:
431: if (isset($expand[$key])) {
432: $tmp['matchlabel'] = (count($expand[$key][1]) > 5)
433: ? sprintf(_("Ambiguous matches for \"%s\" (first 5 matches displayed):"), $expand[$key][0])
434: : sprintf(_("Ambiguous matches for \"%s\":"), $expand[$key][0]);
435:
436: $tmp['match'] = array();
437: foreach ($expand[$key][1] as $key2 => $val2) {
438: if ($key2 == 5) {
439: break;
440: }
441: $tmp['match'][] = array(
442: 'id' => $key . '_expand_' . $key2,
443: 'val' => $val2
444: );
445: }
446: }
447:
448: $hdrs[] = $tmp;
449: }
450:
451: $this->view->hdrs = $hdrs;
452: $this->view->title = $this->title;
453: }
454:
455: 456:
457: public static function url(array $opts = array())
458: {
459: return Horde::url('minimal.php')->add('page', 'compose')->unique();
460: }
461:
462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472: 473:
474: protected function _expandAddresses($input)
475: {
476: $addr_list = IMP::parseAddressList($input, array(
477: 'default_domain' => null
478: ));
479:
480: if (!($size = count($addr_list))) {
481: return '';
482: }
483:
484: $search = $addr_list[$size - 1];
485:
486:
487: if (!is_null($search->mailbox) && !is_null($search->host)) {
488: return strval($search);
489: }
490:
491:
492: $imple = new IMP_Ajax_Imple_ContactAutoCompleter();
493: $res = $imple->getAddressList($search->mailbox);
494:
495: switch (count($res)) {
496: case 0:
497: $GLOBALS['notification']->push(sprintf(_("Search for \"%s\" failed: no address found."), $search->mailbox), 'horde.warning');
498: return strval($addr_list);
499: case 1:
500: $addr_list[$size] = $res[0];
501: return strval($addr_list);
502:
503: default:
504: $GLOBALS['notification']->push(_("Ambiguous address found."), 'horde.warning');
505: unset($addr_list[$size]);
506: return array(
507: strval($addr_list),
508: $search->mailbox,
509: $res
510: );
511: }
512: }
513:
514: 515: 516: 517: 518: 519: 520: 521:
522: protected function _getContents()
523: {
524: try {
525: return $GLOBALS['injector']->getInstance('IMP_Factory_Contents')->create($this->indices);
526: } catch (Horde_Exception $e) {}
527:
528: $this->vars->buid = null;
529: $this->vars->type = 'new';
530:
531: throw new IMP_Exception(_("Could not retrieve message data from the mail server."));
532: }
533:
534: 535: 536: 537: 538: 539: 540:
541: protected function ($in)
542: {
543: $out = array();
544:
545: if (isset($in['addr'])) {
546: $out['to'] = strval($in['addr']['to']);
547: $out['cc'] = strval($in['addr']['cc']);
548: $out['bcc'] = strval($in['addr']['bcc']);
549: }
550:
551: if (isset($in['subject'])) {
552: $out['subject'] = $in['subject'];
553: }
554:
555: return $out;
556: }
557:
558: }
559: