/** * @see showInlineImage */ protected function _showInlineImage(IMP_Contents $contents) { global $injector, $prefs; if ($this->alwaysShow || !$prefs->getValue('image_replacement')) { return true; } if (!$contents || !($tmp = $contents->getHeader()->getHeader('from')) || !($from = $tmp->getAddressList(true))) { return false; } $res = $injector->getInstance('IMP_Contacts')->searchEmail($from->first()->bare_address, array('email_exact' => true)); if (count($res)) { /* Don't allow personal addresses by default - this is the only * e-mail address a Spam sender for sure knows you will recognize * so it is too much of a loophole. */ $res->setIteratorFilter(0, $injector->getInstance('IMP_Identity')->getAllFromAddresses()); foreach ($from as $val) { if ($res->contains($val)) { return true; } } } /* Check safe address list. */ $safeAddrs = $injector->getInstance('IMP_Prefs_Special_ImageReplacement')->safeAddrList(); foreach ($from as $val) { if ($safeAddrs->contains($val)) { return true; } } return false; }
/** * @see showInlineImage */ protected function _showInlineImage(IMP_Contents $contents) { global $injector, $prefs, $registry; if ($this->alwaysShow || !$prefs->getValue('image_replacement')) { return true; } if (!$contents || !($from = $contents->getHeader()->getOb('from'))) { return false; } if ($registry->hasMethod('contacts/search')) { $sparams = $injector->getInstance('IMP_Contacts')->getAddressbookSearchParams(); try { $res = $registry->call('contacts/search', array($from->bare_addresses, array('customStrict' => array('email'), 'fields' => array_fill_keys($sparams['sources'], array('email')), 'returnFields' => array('email'), 'rfc822Return' => true, 'sources' => $sparams['sources']))); // Don't allow personal addresses by default - this is the // only e-mail address a Spam sender for sure knows you will // recognize so it is too much of a loophole. $res->setIteratorFilter(0, $injector->getInstance('IMP_Identity')->getAllFromAddresses()); foreach ($from as $val) { if ($res->contains($val)) { return true; } } } catch (Horde_Exception $e) { // Ignore errors from the search - default to not showing // images. Horde::log($e, 'INFO'); } } /* Check safe address list. */ $safeAddrs = $injector->getInstance('IMP_Prefs_Special_ImageReplacement')->safeAddrList(); foreach ($from as $val) { if ($safeAddrs->contains($val)) { return true; } } return false; }
/** * Loads the MIME headers object internally. */ protected function _loadHeaders() { return $this->_peek ? $this->contents->getHeader() : $this->contents->getHeaderAndMarkAsSeen(); }
/** * Returns the forward text for a message. * * @param IMP_Contents $contents An IMP_Contents object. * @param array $opts Additional options: * - format: (string) Force to this format. * DEFAULT: Auto-determine. * * @return array An array with the following keys: * - body: (string) The text of the body part. * - charset: (string) The guessed charset to use for the forward. * - format: (string) The format of the body message ('html', 'text'). */ public function forwardMessageText($contents, array $opts = array()) { $h = $contents->getHeader(); $from = strval($h['from']); $msg_pre = "\n----- " . ($from ? sprintf(_("Forwarded message from %s"), $from) : _("Forwarded message")) . " -----\n" . $this->_getMsgHeaders($h) . "\n"; $msg_post = "\n\n----- " . _("End forwarded message") . " -----\n"; list($compose_html, $force_html) = $this->_msgTextFormat($opts, 'forward_format'); $msg_text = $this->_getMessageText($contents, array('html' => $compose_html)); if (!empty($msg_text) && ($msg_text['mode'] == 'html' || $force_html)) { $msg = $this->text2html($msg_pre) . ($msg_text['mode'] == 'text' ? $this->text2html($msg_text['text']) : $msg_text['text']) . $this->text2html($msg_post); $format = 'html'; } else { $msg = $msg_pre . $msg_text['text'] . $msg_post; $format = 'text'; } // Bug #10148: Message text might be us-ascii, but forward headers may // contain 8-bit characters. if ($msg_text['charset'] == 'us-ascii' && (Horde_Mime::is8bit($msg_pre) || Horde_Mime::is8bit($msg_post))) { $msg_text['charset'] = 'UTF-8'; } return array('body' => $msg, 'charset' => $msg_text['charset'], 'format' => $format); }
/** */ public function printAttach($id) { global $injector, $page_output, $prefs, $registry; if (is_null($id) || !($render = $this->_contents->renderMIMEPart($id, IMP_Contents::RENDER_FULL))) { return array(); } $part = reset($render); /* Directly render part if this is not an HTML part or it is empty. */ if (stripos($part['type'], 'text/html') !== 0 || !strlen($part['data'])) { return $part; } $imp_ui_mbox = new IMP_Mailbox_Ui(); $basic_headers = $injector->getInstance('IMP_Message_Ui')->basicHeaders(); unset($basic_headers['bcc'], $basic_headers['reply-to']); $headerob = $this->_contents->getHeader(); $d_param = Horde_Mime::decodeParam('content-type', $part['type']); $headers = array(); foreach ($basic_headers as $key => $val) { if ($hdr_val = $headerob->getValue($key)) { /* Format date string. */ if ($key == 'date') { $date_ob = new IMP_Message_Date($hdr_val); $hdr_val = $date_ob->format($date_ob::DATE_FORCE); } $headers[] = array('header' => $val, 'value' => $hdr_val); } } if ($prefs->getValue('add_printedby')) { $user_identity = $injector->getInstance('IMP_Identity'); $headers[] = array('header' => _("Printed By"), 'value' => $user_identity->getFullname() ?: $registry->getAuth()); } $view = new Horde_View(array('templatePath' => IMP_TEMPLATES . '/print')); $view->addHelper('Text'); $view->headers = $headers; $header_dom = new Horde_Domhtml(Horde_String::convertCharset($view->render('headers'), 'UTF-8', $d_param['params']['charset']), $d_param['params']['charset']); $elt = $header_dom->dom->getElementById('headerblock'); $elt->removeAttribute('id'); if ($elt->hasAttribute('class')) { $selectors = array('body'); foreach (explode(' ', $elt->getAttribute('class')) as $val) { if (strlen($val = trim($val))) { $selectors[] = '.' . $val; } } /* Cache CSS. */ $cache_list = array(); $cache_ob = $injector->getInstance('Horde_Cache'); $css_list = $page_output->css->getStylesheets(); foreach ($css_list as $val) { $cache_list[] = $val['fs']; $cache_list[] = filemtime($val['fs']); } $cache_id = 'imp_printcss_' . hash(PHP_MINOR_VERSION >= 4 ? 'fnv132' : 'sha1', implode('|', $cache_list)); if (($style = $cache_ob->get($cache_id, 0)) === false) { try { $css_parser = new Horde_Css_Parser($page_output->css->loadCssFiles($page_output->css->getStylesheets())); $style = ''; foreach ($css_parser->doc->getContents() as $val) { if ($val instanceof Sabberworm\CSS\RuleSet\DeclarationBlock && array_intersect($selectors, array_map('strval', $val->getSelectors()))) { $style .= implode('', array_map('strval', $val->getRules())); } } $cache_ob->set($cache_id, $style, 86400); } catch (Exception $e) { // Ignore CSS if it can't be parsed. } } if (strlen($style)) { $elt->setAttribute('style', ($elt->hasAttribute('style') ? rtrim($elt->getAttribute('style'), ' ;') . ';' : '') . $style); } } $elt->removeAttribute('class'); /* Need to wrap headers in another DIV. */ $newdiv = new DOMDocument(); $div = $newdiv->createElement('div'); $div->appendChild($newdiv->importNode($elt, true)); $pstring = Horde_Mime::decodeParam('content-type', $part['type']); $doc = new Horde_Domhtml($part['data'], $pstring['params']['charset']); $bodyelt = $doc->dom->getElementsByTagName('body')->item(0); $bodyelt->insertBefore($doc->dom->importNode($div, true), $bodyelt->firstChild); /* Make the title the e-mail subject. */ $headelt = $doc->getHead(); foreach ($headelt->getElementsByTagName('title') as $node) { $headelt->removeChild($node); } $headelt->appendChild($doc->dom->createElement('title', htmlspecialchars($imp_ui_mbox->getSubject($headerob->getValue('subject'))))); return array('data' => $doc->returnHtml(), 'name' => $part['name'], 'type' => $part['type']); }
/** * Create the object used to display the message. * * @param array $args Configuration parameters: * - headers: (array) The headers desired in the returned headers array * (only used with non-preview view). * - preview: (boolean) Is this the preview view? * * @return array Array with the following keys: * - atc_download: The download all link * - atc_label: The label to use for Attachments * - atc_list: The list (HTML code) of attachments * - bcc (FULL): The Bcc addresses * - cc: The CC addresses * - fulldate (FULL): The full canonical date. * - from: The From addresses * - headers (FULL): An array of headers (not including basic headers) * - js: Javascript code to run on display * - list_info (FULL): List information. * - localdate (PREVIEW): The date formatted to the user's timezone * - md: Metadata * - msgtext: The text of the message * - onepart: True if message only contains one part. * - replyTo (FULL): The Reply-to addresses * - save_as: The save link * - subject: The subject * - subjectlink: The subject with linked URLs/email addresses (defaults * to 'subject') * - title (FULL): The title of the page * - to: The To addresses * * @throws IMP_Exception */ public function showMessage($args) { global $injector, $page_output, $prefs, $registry, $session; $preview = !empty($args['preview']); $result = array(); $mime_headers = $this->_peek ? $this->_contents->getHeader() : $this->_contents->getHeaderAndMarkAsSeen(); $headers = array(); $imp_ui = $injector->getInstance('IMP_Message_Ui'); /* Develop the list of Headers to display now. Deal with the 'basic' * header information first since there are various manipulations * done to them. */ $basic_headers = $imp_ui->basicHeaders(); if (empty($args['headers'])) { $args['headers'] = array('from', 'date', 'to', 'cc', 'bcc'); } $headers_list = array_intersect_key($basic_headers, array_flip($args['headers'])); /* Build From/To/Cc/Bcc/Reply-To links. */ foreach (array('from', 'to', 'cc', 'bcc', 'reply-to') as $val) { if (isset($headers_list[$val]) && (!$preview || $val != 'reply-to')) { if ($tmp = $this->getAddressHeader($val)) { $result[$val] = $tmp; } if ($preview) { unset($headers_list[$val]); } } } /* Build the rest of the headers. */ foreach ($headers_list as $head => $str) { if ($val = $mime_headers->getValue($head)) { if ($head == 'date') { /* Add local time to date header. */ $date_ob = new IMP_Message_Date($this->_envelope->date); $val = htmlspecialchars($date_ob->format($date_ob::DATE_LOCAL)); if ($preview) { $result['localdate'] = $val; } else { $result['fulldate'] = $date_ob->format($date_ob::DATE_FORCE); } } elseif (!$preview) { $val = htmlspecialchars($val); } if (!$preview) { $headers[$head] = array('id' => Horde_String::ucfirst($head), 'name' => $str, 'value' => $val); } } } if (empty($result['reply-to']) || $result['from']['addr'][0]->b == $result['reply-to']['addr'][0]->b) { unset($result['reply-to'], $headers['reply-to']); } /* JS requires camelized name for reply-to. */ if (!$preview && isset($headers['reply-to'])) { $result['replyTo'] = $result['reply-to']; $headers['reply-to']['id'] = 'ReplyTo'; unset($result['reply-to']); } /* Maillog information. */ $ajax_queue = $injector->getInstance('IMP_Ajax_Queue'); $ajax_queue->maillog($this->_indices); if (!$preview) { /* Display the user-specified headers for the current identity. */ $user_hdrs = $imp_ui->getUserHeaders(); foreach ($user_hdrs as $user_hdr) { $user_val = $mime_headers->getValue($user_hdr); if (!empty($user_val)) { if (!is_array($user_val)) { $user_val = array($user_val); } foreach ($user_val as $val) { $headers[] = array('name' => $user_hdr, 'value' => htmlspecialchars($val)); } } } $result['headers'] = array_values($headers); } /* Process the subject. */ $subject = $mime_headers->getValue('subject'); if ($subject) { $text_filter = $injector->getInstance('Horde_Core_Factory_TextFilter'); $filtered_subject = preg_replace("/\\b\\s+\\b/", ' ', IMP::filterText($subject)); $result['subject'] = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::NOHTML)); $subjectlink = $text_filter->filter($filtered_subject, 'text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); if ($subjectlink != $result['subject']) { $result['subjectlink'] = $subjectlink; } if (!$preview) { $result['title'] = $subject; } } else { $result['subject'] = _("[No Subject]"); if (!$preview) { $result['title'] = _("[No Subject]"); } } // Create message text and attachment list. $result['msgtext'] = ''; $show_parts = $prefs->getValue('parts_display'); switch ($registry->getView()) { case $registry::VIEW_SMARTMOBILE: $contents_mask = 0; break; default: $contents_mask = IMP_Contents::SUMMARY_BYTES | IMP_Contents::SUMMARY_SIZE | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_DESCRIP_LINK | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_DOWNLOAD_ZIP | IMP_Contents::SUMMARY_PRINT_STUB; break; } $part_info = $part_info_display = array('icon', 'description', 'size', 'download', 'download_zip'); $part_info_display[] = 'print'; list($mbox, $uid) = $this->_indices->getSingle(); /* Do MDN processing now. */ switch ($registry->getView()) { case $registry::VIEW_DYNAMIC: if ($imp_ui->MDNCheck(new IMP_Indices($mbox, $uid), $mime_headers)) { $status = new IMP_Mime_Status(array(_("The sender of this message is requesting notification from you when you have read this message."), sprintf(_("Click %s to send the notification message."), Horde::link('#', '', '', '', '', '', '', array('id' => 'send_mdn_link')) . _("HERE") . '</a>'))); $status->domid('sendMdnMessage'); $result['msgtext'] .= strval($status); } } /* Build body text. This needs to be done before we build the * attachment list. */ $session->close(); $inlineout = $this->_contents->getInlineOutput(array('mask' => $contents_mask, 'part_info_display' => $part_info_display, 'show_parts' => $show_parts)); $session->start(); $result['md'] = $inlineout['metadata']; $result['msgtext'] .= $inlineout['msgtext']; if ($inlineout['one_part']) { $result['onepart'] = true; } if (count($inlineout['atc_parts']) || $show_parts == 'all' && count($inlineout['display_ids']) > 2) { $result['atc_label'] = $show_parts == 'all' ? _("Parts") : sprintf(ngettext("%d Attachment", "%d Attachments", count($inlineout['atc_parts'])), count($inlineout['atc_parts'])); if (count($inlineout['atc_parts']) > 2) { $result['atc_download'] = Horde::link($this->_contents->urlView($this->_contents->getMIMEMessage(), 'download_all')) . '[' . _("Save All") . ']</a>'; } } /* Show attachment information in headers? */ if (!empty($inlineout['atc_parts'])) { $partlist = array(); if ($show_parts == 'all') { array_unshift($part_info, 'id'); } foreach ($inlineout['atc_parts'] as $id) { $contents_mask |= IMP_Contents::SUMMARY_DESCRIP | IMP_Contents::SUMMARY_DOWNLOAD | IMP_Contents::SUMMARY_ICON | IMP_Contents::SUMMARY_SIZE; $part_info[] = 'description_raw'; $part_info[] = 'download_url'; $summary = $this->_contents->getSummary($id, $contents_mask); $tmp = array(); foreach ($part_info as $val) { if (isset($summary[$val])) { $tmp[$val] = $summary[$val] instanceof Horde_Url ? strval($summary[$val]->setRaw(true)) : $summary[$val]; } } $partlist[] = array_filter($tmp); } $result['atc_list'] = $partlist; } $result['save_as'] = IMP_Contents_View::downloadUrl(htmlspecialchars_decode($result['subject']), array_merge(array('actionID' => 'save_message'), $mbox->urlParams($uid))); if ($preview) { /* Need to grab cached inline scripts. */ Horde::startBuffer(); $page_output->outputInlineScript(true); if ($js_inline = Horde::endBuffer()) { $result['js'] = array($js_inline); } $result['save_as'] = strval($result['save_as']->setRaw(true)); } else { $list_info = $imp_ui->getListInformation($mime_headers); if (!empty($list_info['exists'])) { $result['list_info'] = $list_info; } } /* Add changed flag information. */ if (!$this->_peek && $mbox->is_imap) { $status = $mbox->imp_imap->status($mbox, Horde_Imap_Client::STATUS_PERMFLAGS); if (in_array(Horde_Imap_Client::FLAG_SEEN, $status['permflags'])) { $ajax_queue->flag(array(Horde_Imap_Client::FLAG_SEEN), true, $this->_indices); } } return array_filter($result); }