/** * Helper function to parse a parameters-like tokenized array. * * @param mixed $data Message data. Either a Horde_Imap_Client_Tokenize * object or null. * @param string $type The header name. * * @return array The parameter array. */ protected function _parseStructureParams($data, $type) { $params = array(); if (is_null($data)) { return $params; } while (($name = $data->next()) !== false) { $params[strtolower($name)] = $data->next(); } $ret = Horde_Mime::decodeParam($type, $params); return $ret['params']; }
/** * Helper function to parse a parameters-like tokenized array. * * @param array $data The tokenized data. * @param string $type The header name. * * @return array The parameter array. */ protected function _parseStructureParams($data, $type) { $params = array(); if (is_array($data)) { for ($i = 0, $cnt = count($data); $i < $cnt; ++$i) { $params[Horde_String::lower($data[$i])] = $data[++$i]; } } $ret = Horde_Mime::decodeParam($type, $params); return $ret['params']; }
/** * Builds a Horde_Mime_Headers object from header text. * This function can be called statically: * $headers = Horde_Mime_Headers::parseHeaders(). * * @param string $text A text string containing the headers. * * @return Horde_Mime_Headers A new Horde_Mime_Headers object. */ public static function parseHeaders($text) { $currheader = $currtext = null; $mime = self::mimeParamFields(); $to_process = array(); foreach (explode("\n", $text) as $val) { $val = rtrim($val); if (empty($val)) { break; } if ($val[0] == ' ' || $val[0] == "\t") { $currtext .= ' ' . ltrim($val); } else { if (!is_null($currheader)) { $to_process[] = array($currheader, $currtext); } $pos = strpos($val, ':'); $currheader = substr($val, 0, $pos); $currtext = ltrim(substr($val, $pos + 1)); } } if (!is_null($currheader)) { $to_process[] = array($currheader, $currtext); } $headers = new Horde_Mime_Headers(); reset($to_process); while (list(, $val) = each($to_process)) { /* Ignore empty headers. */ if (!strlen($val[1])) { continue; } if (in_array(Horde_String::lower($val[0]), $mime)) { $res = Horde_Mime::decodeParam($val[0], $val[1]); $headers->addHeader($val[0], $res['val'], array('params' => $res['params'], 'sanity_check' => true)); } else { $headers->addHeader($val[0], $val[1], array('sanity_check' => true)); } } return $headers; }
/** * Parse the output from imap_fetchstructure() into a MIME Part object. * * @param object $data Data from imap_fetchstructure(). * * @return Horde_Mime_Part A MIME Part object. */ protected function _parseStructure($data) { $ob = new Horde_Mime_Part(); $ob->setType(Horde_String::lower($data->type) . '/' . Horde_String::lower($data->subType)); // Optional for multipart-parts, required for all others if (isset($data->parameters)) { $params = array(); foreach ($data->parameters as $key => $value) { $params[Horde_String::lower($key)] = $value; } $params = Horde_Mime::decodeParam('content-type', $params); foreach ($params['params'] as $key => $value) { $ob->setContentTypeParameter($key, $value); } } // Optional entries. 'location' and 'language' not supported if (isset($data->disposition)) { $ob->setDisposition($data->disposition); if (isset($data->dparameters)) { $dparams = array(); foreach ($data->dparameters as $key => $value) { $dparams[Horde_String::lower($key)] = $value; } $dparams = Horde_Mime::decodeParam('content-disposition', $dparams); foreach ($dparams['params'] as $key => $value) { $ob->setDispositionParameter($key, $value); } } } if ($ob->getPrimaryType() == 'multipart') { // multipart/* specific entries foreach ($data->subParts as $val) { $ob->addPart($this->_parseStructure($val)); } } else { // Required options if (isset($data->partID)) { $ob->setContentId($data->partID); } $ob->setTransferEncoding(Horde_String::lower($data->encoding)); $ob->setBytes($data->bytes); if ($ob->getType() == 'message/rfc822') { $ob->addPart($this->_parseStructure(reset($data->subParts))); } } return $ob; }
/** */ 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']); }
/** * Adds an attachment to the outgoing compose message. * * @param string $atc_file Temporary file containing attachment contents. * @param integer $bytes Size of data, in bytes. * @param string $filename Filename of data. * @param string $type MIME type of data. * * @return IMP_Compose_Attachment Attachment object. * @throws IMP_Compose_Exception */ protected function _addAttachment($atc_file, $bytes, $filename, $type) { global $conf, $injector; $atc = new Horde_Mime_Part(); $atc->setBytes($bytes); /* Try to determine the MIME type from 1) the extension and * then 2) analysis of the file (if available). */ if (strlen($filename)) { $atc->setName($filename); if ($type == 'application/octet-stream') { $type = Horde_Mime_Magic::filenameToMIME($filename, false); } } $atc->setType($type); if ($atc->getType() == 'application/octet-stream' || $atc->getPrimaryType() == 'text') { $analyze = Horde_Mime_Magic::analyzeFile($atc_file, empty($conf['mime']['magic_db']) ? null : $conf['mime']['magic_db'], array('nostrip' => true)); if ($analyze) { $analyze = Horde_Mime::decodeParam('Content-Type', $analyze); $atc->setType($analyze['val']); $atc->setCharset(isset($analyze['params']['charset']) ? $analyze['params']['charset'] : 'UTF-8'); } else { $atc->setCharset('UTF-8'); } } else { $atc->setHeaderCharset('UTF-8'); } $atc_ob = new IMP_Compose_Attachment($this, $atc, $atc_file); /* Check for attachment size limitations. */ $size_limit = null; if ($atc_ob->linked) { if (!empty($conf['compose']['link_attach_size_limit'])) { $linked = true; $size_limit = 'link_attach_size_limit'; } } elseif (!empty($conf['compose']['attach_size_limit'])) { $linked = false; $size_limit = 'attach_size_limit'; } if (!is_null($size_limit)) { $total_size = $conf['compose'][$size_limit] - $bytes; foreach ($this as $val) { if ($val->linked == $linked) { $total_size -= $val->getPart()->getBytes(); } } if ($total_size < 0) { throw new IMP_Compose_Exception(strlen($filename) ? sprintf(_("Attached file \"%s\" exceeds the attachment size limits. File NOT attached."), $filename) : _("Attached file exceeds the attachment size limits. File NOT attached.")); } } try { $injector->getInstance('Horde_Core_Hooks')->callHook('compose_attachment', 'imp', array($atc_ob)); } catch (Horde_Exception_HookNotSet $e) { } $this->_atc[$atc_ob->id] = $atc_ob; $this->changed = 'changed'; return $atc_ob; }
/** * Builds a Horde_Mime_Headers object from header text. * * @param mixed $text A text string (or, as of 2.3.0, a Horde_Stream * object or stream resource) containing the headers. * * @return Horde_Mime_Headers A new Horde_Mime_Headers object. */ public static function parseHeaders($text) { $currheader = $currtext = null; $mime = self::mimeParamFields(); $to_process = array(); if ($text instanceof Horde_Stream) { $stream = $text; $stream->rewind(); } else { $stream = new Horde_Stream_Temp(); $stream->add($text, true); } while (!$stream->eof()) { if (!($val = rtrim($stream->getToChar("\n", false), "\r"))) { break; } if ($val[0] == ' ' || $val[0] == "\t") { $currtext .= ' ' . ltrim($val); } else { if (!is_null($currheader)) { $to_process[] = array($currheader, rtrim($currtext)); } $pos = strpos($val, ':'); $currheader = substr($val, 0, $pos); $currtext = ltrim(substr($val, $pos + 1)); } } if (!is_null($currheader)) { $to_process[] = array($currheader, $currtext); } $headers = new Horde_Mime_Headers(); reset($to_process); while (list(, $val) = each($to_process)) { /* Ignore empty headers. */ if (!strlen($val[1])) { continue; } if (in_array(Horde_String::lower($val[0]), $mime)) { $res = Horde_Mime::decodeParam($val[0], $val[1]); $headers->addHeader($val[0], $res['val'], array('params' => $res['params'], 'sanity_check' => true)); } else { $headers->addHeader($val[0], $val[1], array('sanity_check' => true)); } } return $headers; }
/** * Parse the output from imap_fetchstructure() into a MIME Part object. * * @param object $data Data from imap_fetchstructure(). * * @return Horde_Mime_Part A MIME Part object. */ protected function _parseStructure($data) { $ob = new Horde_Mime_Part(); $ob->setType($this->_mimeTypes[$data->type] . '/' . ($data->ifsubtype ? strtolower($data->subtype) : Horde_Mime_Part::UNKNOWN)); // Optional for multipart-parts, required for all others if ($data->ifparameters) { $params = array(); foreach ($data->parameters as $val) { $params[$val->attribute] = $val->value; } $params = Horde_Mime::decodeParam('content-type', $params); foreach ($params['params'] as $key => $val) { $ob->setContentTypeParameter($key, $val); } } // Optional entries. 'location' and 'language' not supported if ($data->ifdisposition) { $ob->setDisposition($data->disposition); if ($data->ifdparameters) { $dparams = array(); foreach ($data->dparameters as $val) { $dparams[$val->attribute] = $val->value; } $dparams = Horde_Mime::decodeParam('content-disposition', $dparams); foreach ($dparams['params'] as $key => $val) { $ob->setDispositionParameter($key, $val); } } } if ($ob->getPrimaryType() == 'multipart') { // multipart/* specific entries foreach ($data->parts as $val) { $ob->addPart($this->_parseStructure($val)); } } else { // Required options if ($data->ifid) { $ob->setContentId($data->id); } if ($data->ifdescription) { $ob->setDescription(Horde_Mime::decode($data->description)); } $ob->setTransferEncoding($this->_mimeEncodings[$data->encoding]); $ob->setBytes($data->bytes); if ($ob->getType() == 'message/rfc822') { $ob->addPart($this->_parseStructure(reset($data->parts))); } } return $ob; }