Overview

Packages

  • IMP
  • None

Classes

  • IMP
  • IMP_Ajax_Application
  • IMP_Ajax_Imple_ContactAutoCompleter
  • IMP_Ajax_Imple_PassphraseDialog
  • IMP_Ajax_Queue
  • IMP_Api
  • IMP_Auth
  • IMP_Block_Newmail
  • IMP_Block_Summary
  • IMP_Compose
  • IMP_Compose_Exception
  • IMP_Compose_Stationery
  • IMP_Contents
  • IMP_Crypt_Pgp
  • IMP_Crypt_Smime
  • IMP_Dimp
  • IMP_Exception
  • IMP_Factory_AuthImap
  • IMP_Factory_Compose
  • IMP_Factory_Contents
  • IMP_Factory_Flags
  • IMP_Factory_Identity
  • IMP_Factory_Imap
  • IMP_Factory_Imaptree
  • IMP_Factory_Mail
  • IMP_Factory_Mailbox
  • IMP_Factory_MailboxList
  • IMP_Factory_MimeViewer
  • IMP_Factory_Pgp
  • IMP_Factory_Quota
  • IMP_Factory_Search
  • IMP_Factory_Sentmail
  • IMP_Factory_Smime
  • IMP_Filter
  • IMP_Flag_Base
  • IMP_Flag_Imap
  • IMP_Flag_Imap_Answered
  • IMP_Flag_Imap_Deleted
  • IMP_Flag_Imap_Draft
  • IMP_Flag_Imap_Flagged
  • IMP_Flag_Imap_Forwarded
  • IMP_Flag_Imap_Junk
  • IMP_Flag_Imap_NotJunk
  • IMP_Flag_Imap_Seen
  • IMP_Flag_System_Attachment
  • IMP_Flag_System_Encrypted
  • IMP_Flag_System_HighPriority
  • IMP_Flag_System_List
  • IMP_Flag_System_LowPriority
  • IMP_Flag_System_Match_Address
  • IMP_Flag_System_Match_Flag
  • IMP_Flag_System_Match_Header
  • IMP_Flag_System_Personal
  • IMP_Flag_System_Signed
  • IMP_Flag_System_Unseen
  • IMP_Flag_User
  • IMP_Flags
  • IMP_Imap
  • IMP_Imap_Acl
  • IMP_Imap_Exception
  • IMP_Imap_PermanentFlags
  • IMP_Imap_Thread
  • IMP_Imap_Tree
  • IMP_Indices
  • IMP_Indices_Form
  • IMP_LoginTasks_SystemTask_GarbageCollection
  • IMP_LoginTasks_SystemTask_Upgrade
  • IMP_LoginTasks_SystemTask_UpgradeAuth
  • IMP_LoginTasks_Task_Autocreate
  • IMP_LoginTasks_Task_DeleteAttachmentsMonthly
  • IMP_LoginTasks_Task_DeleteSentmailMonthly
  • IMP_LoginTasks_Task_FilterOnLogin
  • IMP_LoginTasks_Task_PurgeSentmail
  • IMP_LoginTasks_Task_PurgeSpam
  • IMP_LoginTasks_Task_PurgeTrash
  • IMP_LoginTasks_Task_RecoverDraft
  • IMP_LoginTasks_Task_RenameSentmailMonthly
  • IMP_Mailbox
  • IMP_Mailbox_List
  • IMP_Mailbox_List_Track
  • IMP_Maillog
  • IMP_Menu_Dimp
  • IMP_Message
  • IMP_Mime_Status
  • IMP_Mime_Viewer_Alternative
  • IMP_Mime_Viewer_Appledouble
  • IMP_Mime_Viewer_Audio
  • IMP_Mime_Viewer_Enriched
  • IMP_Mime_Viewer_Externalbody
  • IMP_Mime_Viewer_Html
  • IMP_Mime_Viewer_Images
  • IMP_Mime_Viewer_Itip
  • IMP_Mime_Viewer_Mdn
  • IMP_Mime_Viewer_Partial
  • IMP_Mime_Viewer_Pdf
  • IMP_Mime_Viewer_Pgp
  • IMP_Mime_Viewer_Plain
  • IMP_Mime_Viewer_Related
  • IMP_Mime_Viewer_Rfc822
  • IMP_Mime_Viewer_Smil
  • IMP_Mime_Viewer_Smime
  • IMP_Mime_Viewer_Status
  • IMP_Mime_Viewer_Vcard
  • IMP_Mime_Viewer_Video
  • IMP_Mime_Viewer_Zip
  • IMP_Notification_Event_Status
  • IMP_Notification_Handler_Decorator_ImapAlerts
  • IMP_Notification_Handler_Decorator_NewmailNotify
  • IMP_Notification_Listener_AjaxStatus
  • Imp_Prefs_Identity
  • IMP_Prefs_Ui
  • IMP_Quota
  • IMP_Quota_Base
  • IMP_Quota_Command
  • IMP_Quota_Hook
  • IMP_Quota_Imap
  • IMP_Quota_Maildir
  • IMP_Quota_Mdaemon
  • IMP_Quota_Mercury32
  • IMP_Quota_Null
  • IMP_Quota_Sql
  • IMP_Search
  • IMP_Search_Element
  • IMP_Search_Element_Attachment
  • IMP_Search_Element_Autogenerated
  • IMP_Search_Element_Bulk
  • IMP_Search_Element_Contacts
  • IMP_Search_Element_Date
  • IMP_Search_Element_Flag
  • IMP_Search_Element_Header
  • IMP_Search_Element_Mailinglist
  • IMP_Search_Element_Or
  • IMP_Search_Element_Personal
  • IMP_Search_Element_Recipient
  • IMP_Search_Element_Size
  • IMP_Search_Element_Text
  • IMP_Search_Element_Within
  • IMP_Search_Filter
  • IMP_Search_Filter_Attachment
  • IMP_Search_Filter_Autogenerated
  • IMP_Search_Filter_Builtin
  • IMP_Search_Filter_Bulk
  • IMP_Search_Filter_Contacts
  • IMP_Search_Filter_Mailinglist
  • IMP_Search_Filter_Personal
  • IMP_Search_Query
  • IMP_Search_Vfolder
  • IMP_Search_Vfolder_Builtin
  • IMP_Search_Vfolder_Vinbox
  • IMP_Search_Vfolder_Vtrash
  • IMP_Sentmail
  • IMP_Sentmail_Base
  • IMP_Sentmail_Null
  • IMP_Sentmail_Sql
  • IMP_Spam
  • IMP_Test
  • IMP_Tree_Flist
  • IMP_Tree_Jquerymobile
  • IMP_Tree_Simplehtml
  • IMP_Ui_Compose
  • IMP_Ui_Editor
  • IMP_Ui_Folder
  • IMP_Ui_Headers
  • IMP_Ui_Imageview
  • IMP_Ui_Mailbox
  • IMP_Ui_Message
  • IMP_Ui_Mimp
  • IMP_Ui_Search
  • IMP_Views_Compose
  • IMP_Views_ListMessages
  • IMP_Views_ShowMessage
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: /**
  3:  * The IMP_Ui_Message:: class is designed to provide a place to store common
  4:  * code shared among IMP's various UI views for the message page.
  5:  *
  6:  * Copyright 2006-2012 Horde LLC (http://www.horde.org/)
  7:  *
  8:  * See the enclosed file COPYING for license information (GPL). If you
  9:  * did not receive this file, see http://www.horde.org/licenses/gpl.
 10:  *
 11:  * @author   Michael Slusarz <slusarz@horde.org>
 12:  * @category Horde
 13:  * @license  http://www.horde.org/licenses/gpl GPL
 14:  * @package  IMP
 15:  */
 16: class IMP_Ui_Message
 17: {
 18:     /**
 19:      * Return a list of "basic" headers w/gettext translations.
 20:      *
 21:      * @return array  Header name -> gettext translation mapping.
 22:      */
 23:     public function basicHeaders()
 24:     {
 25:         return array(
 26:             'date'      =>  _("Date"),
 27:             'from'      =>  _("From"),
 28:             'to'        =>  _("To"),
 29:             'cc'        =>  _("Cc"),
 30:             'bcc'       =>  _("Bcc"),
 31:             'reply-to'  =>  _("Reply-To"),
 32:             'subject'   =>  _("Subject")
 33:         );
 34:     }
 35: 
 36:     /**
 37:      * Get the list of user-defined headers to display.
 38:      *
 39:      * @return array  The list of user-defined headers.
 40:      */
 41:     public function getUserHeaders()
 42:     {
 43:         $user_hdrs = $GLOBALS['prefs']->getValue('mail_hdr');
 44: 
 45:         /* Split the list of headers by new lines and sort the list of headers
 46:          * to make sure there are no duplicates. */
 47:         if (is_array($user_hdrs)) {
 48:             $user_hdrs = implode("\n", $user_hdrs);
 49:         }
 50:         $user_hdrs = trim($user_hdrs);
 51:         if (empty($user_hdrs)) {
 52:             return array();
 53:         }
 54: 
 55:         $user_hdrs = array_filter(array_keys(array_flip(array_map('trim', preg_split("/[\n\r]+/", str_replace(':', '', $user_hdrs))))));
 56:         natcasesort($user_hdrs);
 57: 
 58:         return $user_hdrs;
 59:     }
 60: 
 61:     /**
 62:      * Check if we need to send a MDN, and send if needed.
 63:      *
 64:      * @param IMP_Mailbox $mailbox         The mailbox of the message.
 65:      * @param integer $uid                 The UID of the message.
 66:      * @param Horde_Mime_Headers $headers  The headers of the message.
 67:      * @param boolean $confirmed           Has the MDN request been confirmed?
 68:      *
 69:      * @return boolean  True if the MDN request needs to be confirmed.
 70:      */
 71:     public function MDNCheck(IMP_Mailbox $mailbox, $uid, $headers,
 72:                              $confirmed = false)
 73:     {
 74:         $imp_imap = $GLOBALS['injector']->getInstance('IMP_Factory_Imap')->create();
 75:         $pref_val = $GLOBALS['prefs']->getValue('send_mdn');
 76: 
 77:         if (!$pref_val || $mailbox->readonly) {
 78:             return false;
 79:         }
 80: 
 81:         /* Check to see if an MDN has been requested. */
 82:         $mdn = new Horde_Mime_Mdn($headers);
 83:         $return_addr = $mdn->getMdnReturnAddr();
 84:         if (!$return_addr) {
 85:             return false;
 86:         }
 87: 
 88:         $msg_id = $headers->getValue('message-id');
 89:         $mdn_flag = $mdn_sent = false;
 90: 
 91:         /* See if we have already processed this message. */
 92:         /* 1st test: MDNSent keyword (RFC 3503 [3.1]). */
 93:         if ($mailbox->permflags->allowed('$mdnsent')) {
 94:             $mdn_flag = true;
 95: 
 96:             $query = new Horde_Imap_Client_Fetch_Query();
 97:             $query->flags();
 98: 
 99:             try {
100:                 $res = $imp_imap->fetch($mailbox, $query, array(
101:                     'ids' => $imp_imap->getIdsOb($uid)
102:                 ));
103:                 $mdn_sent = in_array('$mdnsent', $res[$uid]->getFlags());
104:             } catch (IMP_Imap_Exception $e) {}
105:         } else {
106:             /* 2nd test: Use Maillog as a fallback. */
107:             $mdn_sent = IMP_Maillog::sentMDN($msg_id, 'displayed');
108:         }
109: 
110:         if ($mdn_sent) {
111:             return false;
112:         }
113: 
114:         /* See if we need to query the user. */
115:         if (!$confirmed &&
116:             ((intval($pref_val) == 1) ||
117:              $mdn->userConfirmationNeeded())) {
118:             try {
119:                 if (Horde::callHook('mdn_check', array($headers), 'imp')) {
120:                     return true;
121:                 }
122:             } catch (Horde_Exception_HookNotSet $e) {
123:                 return true;
124:             }
125:         }
126: 
127:         /* Send out the MDN now. */
128:         try {
129:             $mdn->generate(
130:                 false,
131:                 $confirmed,
132:                 'displayed',
133:                 $GLOBALS['conf']['server']['name'],
134:                 $GLOBALS['injector']->getInstance('IMP_Mail'),
135:                 array(
136:                     'charset' => 'UTF-8',
137:                     'from_addr' => $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create()->getDefaultFromAddress()
138:                 )
139:             );
140:             IMP_Maillog::log(IMP_Maillog::MDN, $msg_id, 'displayed');
141:             $success = true;
142: 
143:             if ($mdn_flag) {
144:                 $GLOBALS['injector']->getInstance('IMP_Message')->flag(array(Horde_Imap_Client::FLAG_MDNSENT), $mailbox->getIndicesOb($uid), true);
145:             }
146:         } catch (Exception $e) {
147:             $success = false;
148:         }
149: 
150:         $GLOBALS['injector']->getInstance('IMP_Sentmail')->log(IMP_Sentmail::MDN, '', $return_addr, $success);
151: 
152:         return false;
153:     }
154: 
155:     /**
156:      * Adds the local time string to the date header.
157:      *
158:      * @param Horde_Imap_Client_DateTime $date  The date object.
159:      *
160:      * @return string  The local formatted time string.
161:      */
162:     public function getLocalTime(Horde_Imap_Client_DateTime $date)
163:     {
164:         $time_str = strftime($GLOBALS['prefs']->getValue('time_format'), strval($date));
165:         $tz = strftime('%Z');
166: 
167:         if ((date('Y') != $date->format('Y')) ||
168:             (date('M') != $date->format('M')) ||
169:             (date('d') != $date->format('d'))) {
170:             /* Not today, use the date. */
171:             $date_str = strftime($GLOBALS['prefs']->getValue('date_format'), strval($date));
172:             return sprintf('%s (%s %s)', $date_str, $time_str, $tz);
173:         }
174: 
175:         /* Else, it's today, use the time only. */
176:         return sprintf(_("Today, %s %s"), $time_str, $tz);
177:     }
178: 
179:     /**
180:      * Parses all of the available mailing list headers.
181:      *
182:      * @param Horde_Mime_Headers $headers  A Horde_Mime_Headers object.
183:      *
184:      * @return array  Keys are the list header names, values are the
185:      *                parsed list header values.
186:      */
187:     public function parseAllListHeaders($headers)
188:     {
189:         $ret = array();
190: 
191:         foreach (array_keys($headers->listHeaders()) as $val) {
192:             if (($data = $headers->getValue($val))) {
193:                 $ret[$val] = $this->parseListHeaders($data);
194:             }
195:         }
196: 
197:         return $ret;
198:     }
199: 
200:     /**
201:      * Parse the information in mailing list headers.
202:      *
203:      * @param string $data  The header text to process.
204:      * @param array $opts   Additional options:
205:      * <pre>
206:      * 'email' - (boolean) Only return e-mail values.
207:      *           DEFAULT: false
208:      * 'raw' - (boolean) Should the raw URL be returned instead of linking
209:      *                   the header value?
210:      *                   DEFAULT: false
211:      * </pre>
212:      *
213:      * @return string  The header value.
214:      */
215:     public function parseListHeaders($data, $opts = array())
216:     {
217:         $output = '';
218: 
219:         /* Split the incoming data by the ',' character. */
220:         foreach (explode(',', $data) as $orig_entry) {
221:             $entry = Horde_Mime_Address::trimAddress($orig_entry);
222: 
223:             /* Get the data inside of the brackets. If there is no brackets,
224:              * then return the raw text. */
225:             if (trim($orig_entry) == $entry) {
226:                 return $entry;
227:             }
228: 
229:             /* Remove all whitespace from between brackets (RFC 2369 [2]). */
230:             $match = preg_replace("/\s+/", '', $entry);
231: 
232:             /* Determine if there are any comments. */
233:             preg_match("/(\(.+\))/", $entry, $comments);
234: 
235:             /* RFC 2369 [2] states that we should only show the *FIRST* URL
236:              * that appears in a header that we can adequately handle. */
237:             if (stristr($match, 'mailto:') !== false) {
238:                 $match = substr($match, strpos($match, ':') + 1);
239:                 if (!empty($opts['raw'])) {
240:                     return $match;
241:                 }
242:                 $output = Horde::link(IMP::composeLink($match)) . $match . '</a>';
243:                 if (!empty($comments[1])) {
244:                     $output .= '&nbsp;' . $comments[1];
245:                 }
246: 
247:                 return $output;
248:             } elseif ($url = $GLOBALS['injector']->getInstance('Horde_Core_Factory_TextFilter')->filter($match, 'linkurls')) {
249:                 if (!empty($opts['email'])) {
250:                     continue;
251:                 }
252: 
253:                 if (!empty($opts['raw'])) {
254:                     return $match;
255:                 }
256: 
257:                 $output = $url;
258:                 if (!empty($comments[1])) {
259:                     $output .= '&nbsp;' . $comments[1];
260:                 }
261: 
262:                 return $output;
263:             } else {
264:                 /* Use this entry unless we can find a better one. */
265:                 $output = $match;
266:             }
267:         }
268: 
269:         return $output;
270:     }
271: 
272:     /**
273:      * Returns e-mail information for a mailing list.
274:      *
275:      * @param Horde_Mime_Headers $headers  A Horde_Mime_Headers object.
276:      *
277:      * @return array  An array with 2 elements: 'exists' and 'reply_list'.
278:      */
279:     public function getListInformation($headers)
280:     {
281:         $ret = array('exists' => false, 'reply_list' => null);
282: 
283:         if ($headers->listHeadersExist()) {
284:             $ret['exists'] = true;
285: 
286:             /* See if the List-Post header provides an e-mail address for the
287:              * list. */
288:             if (($val = $headers->getValue('list-post')) &&
289:                 ($val != 'NO')) {
290:                 $ret['reply_list'] = $this->parseListHeaders($val, array('email' => true, 'raw' => true));
291:             }
292:         }
293: 
294:         return $ret;
295:     }
296: 
297:     /**
298:      * Builds a string containing a list of addresses.
299:      *
300:      * @param array $addrlist    The list of addresses from
301:      *                           Horde_Mime_Address::parseAddressList().
302:      * @param Horde_Url $addURL  The self URL.
303:      * @param boolean $link      Link each address to the compose screen?
304:      *
305:      * @return string  String containing the formatted address list.
306:      */
307:     public function buildAddressLinks($addrlist, $addURL = null, $link = true)
308:     {
309:         global $prefs, $registry;
310: 
311:         /* Make sure this is a valid object address field. */
312:         if (empty($addrlist) || !is_array($addrlist)) {
313:             return null;
314:         }
315: 
316:         $add_link = null;
317:         $addr_array = array();
318:         $mimp_view = IMP::getViewMode() == 'mimp';
319: 
320:         /* Set up the add address icon link if contact manager is
321:          * available. */
322:         if (!is_null($addURL) && $link && $prefs->getValue('add_source')) {
323:             try {
324:                 $add_link = $registry->hasMethod('contacts/import')
325:                     ? $addURL->copy()->add('actionID', 'add_address')
326:                     : null;
327:             } catch (Horde_Exception $e) {}
328:         }
329: 
330:         foreach (Horde_Mime_Address::getAddressesFromObject($addrlist, array('charset' => 'UTF-8')) as $ob) {
331:             if (isset($ob['groupname'])) {
332:                 $group_array = array();
333:                 foreach ($ob['addresses'] as $ad) {
334:                     if (empty($ad['address']) || empty($ad['inner'])) {
335:                         continue;
336:                     }
337: 
338:                     $ret = $mimp_view
339:                         ? $ad['display']
340:                         : htmlspecialchars($ad['display']);
341: 
342:                     if ($link) {
343:                         $ret = Horde::link(IMP::composeLink(array('to' => $ad['address'])), sprintf(_("New Message to %s"), $ad['inner'])) . htmlspecialchars($ad['display']) . '</a>';
344:                     }
345: 
346:                     /* Append the add address icon to every address if contact
347:                      * manager is available. */
348:                     if ($add_link) {
349:                         $curr_link = $add_link->copy()->add(array('name' => $ad['personal'], 'address' => $ad['inner']));
350:                         $ret .= Horde::link($curr_link, sprintf(_("Add %s to my Address Book"), $ad['inner'])) .
351:                             '<span class="iconImg addrbookaddImg"></span></a>';
352:                     }
353: 
354:                     $group_array[] = $ret;
355:                 }
356: 
357:                 if (!$mimp_view) {
358:                     $ob['groupname'] = htmlspecialchars($ob['groupname']);
359:                 }
360: 
361:                 $addr_array[] = $ob['groupname'] . ':' . (count($group_array) ? ' ' . implode(', ', $group_array) : '');
362:             } elseif (!empty($ob['address']) && !empty($ob['inner'])) {
363:                 $ret = $mimp_view
364:                     ? $ob['display']
365:                     : htmlspecialchars($ob['display']);
366: 
367:                 /* If this is an incomplete e-mail address, don't link to
368:                  * anything. */
369:                 if (stristr($ob['host'], 'UNKNOWN') === false) {
370:                     if ($link) {
371:                         $ret = Horde::link(IMP::composeLink(array('to' => $ob['address'])), sprintf(_("New Message to %s"), $ob['inner'])) . htmlspecialchars($ob['display']) . '</a>';
372:                     }
373: 
374:                     /* Append the add address icon to every address if contact
375:                      * manager is available. */
376:                     if ($add_link) {
377:                         $curr_link = $add_link->copy()->add(array('name' => $ob['personal'], 'address' => $ob['inner']));
378:                         $ret .= Horde::link($curr_link, sprintf(_("Add %s to my Address Book"), $ob['inner'])) .
379:                             '<span class="iconImg addrbookaddImg"></span></a>';
380:                     }
381:                 }
382: 
383:                 $addr_array[] = $ret;
384:             }
385:         }
386: 
387:         if (IMP::getViewMode() == 'mimp') {
388:             return implode(', ', $addr_array);
389:         }
390: 
391:         /* If left with an empty address list ($ret), inform the user that the
392:          * recipient list is purposely "undisclosed". */
393:         if (empty($addr_array)) {
394:             $ret = _("Undisclosed Recipients");
395:         } else {
396:             /* Build the address line. */
397:             $addr_count = count($addr_array);
398:             $ret = '<span class="nowrap">' . implode(',</span> <span class="nowrap">', $addr_array) . '</span>';
399:             if ($link && $addr_count > 15) {
400:                 $ret = '<span>' .
401:                     '<span onclick="[ this, this.next(), this.next(1) ].invoke(\'toggle\')" class="widget largeaddrlist">' . sprintf(_("[Show Addresses - %d recipients]"), $addr_count) . '</span>' .
402:                     '<span onclick="[ this, this.previous(), this.next() ].invoke(\'toggle\')" class="widget largeaddrlist" style="display:none">' . _("[Hide Addresses]") . '</span>' .
403:                     '<span style="display:none">' .
404:                     $ret . '</span></span>';
405:             }
406:         }
407: 
408:         return $ret;
409:     }
410: 
411:     /**
412:      * Get the display subject (filtered, formatted, and linked).
413:      *
414:      * @param string $subject  The subject text.
415:      *
416:      * @return string  The display subject string.
417:      */
418:     public function getDisplaySubject($subject)
419:     {
420:         return $GLOBALS['injector']->getInstance('Horde_Core_Factory_TextFilter')->filter(preg_replace("/\b\s+\b/", ' ', IMP::filterText($subject)), 'text2html', array(
421:             'parselevel' => Horde_Text_Filter_Text2html::MICRO
422:         ));
423:     }
424: 
425:     /**
426:      * Increment mailbox index after deleting a message?
427:      *
428:      * @return boolean  If true, increments index.
429:      */
430:     public function moveAfterAction()
431:     {
432:         return (!IMP::$mailbox->hideDeletedMsgs() &&
433:                 !$GLOBALS['prefs']->getValue('use_trash'));
434:     }
435: 
436: }
437: 
API documentation generated by ApiGen