1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16:
17: class IMP_Mime_Viewer_Plain extends Horde_Mime_Viewer_Plain
18: {
19: 20: 21: 22: 23:
24: static protected $_cache = array();
25:
26: 27: 28: 29: 30:
31: protected function _render()
32: {
33: $data = $this->_impRender(false);
34: $item = reset($data);
35: Horde::startBuffer();
36: Horde::includeStylesheetFiles();
37: $item['data'] = '<html><head>' . Horde::endBuffer() . '</head><body>' . $item['data'] . '</body></html>';
38: $data[key($data)] = $item;
39: return $data;
40: }
41:
42: 43: 44: 45: 46:
47: protected function _renderInline()
48: {
49: return $this->_impRender(true);
50: }
51:
52: 53: 54: 55: 56: 57: 58:
59: protected function _impRender($inline)
60: {
61: global $conf, $prefs;
62:
63: $mime_id = $this->_mimepart->getMimeId();
64:
65: if (isset(self::$_cache[$mime_id])) {
66: return array($mime_id => null);
67: }
68:
69:
70: $charset = $this->_mimepart->getCharset();
71: $text = trim($this->_mimepart->getContents());
72: if ($text == '') {
73: return array(
74: $mime_id => array(
75: 'data' => '',
76: 'type' => 'text/html; charset=' . $charset
77: )
78: );
79: }
80:
81:
82: if ($inline) {
83: $text = Horde_String::convertCharset($text, $charset, 'UTF-8');
84: $charset = $this->getConfigParam('charset');
85: }
86: $type = 'text/html; charset=' . $charset;
87:
88:
89: if ($this->_mimepart->getContentTypeParameter('format') == 'flowed') {
90: $text = $this->_formatFlowed($text, $this->_mimepart->getContentTypeParameter('delsp'));
91: } else {
92: 93: 94: 95: 96:
97: $text = preg_replace('/(\n+)> ?From(\s+)/', "$1From$2", $text);
98: }
99:
100: $text = IMP::filterText($text);
101:
102:
103: if (IMP::getViewMode() == 'mimp') {
104: $filters = array(
105: 'text2html' => array(
106: 'charset' => $charset,
107: 'parselevel' => Horde_Text_Filter_Text2html::NOHTML_NOBREAK
108: )
109: );
110:
111: $text = $this->_textFilter($text, array_keys($filters), array_values($filters));
112:
113: return array(
114: $mime_id => array(
115: 'data' => $text,
116: 'type' => $type
117: )
118: );
119: }
120:
121:
122: $filters = array(
123: 'text2html' => array(
124: 'charset' => $charset,
125: 'parselevel' => $inline ? Horde_Text_Filter_Text2html::MICRO : Horde_Text_Filter_Text2html::MICRO_LINKURL
126: ),
127: 'tabs2spaces' => array(),
128: );
129:
130:
131: if ($prefs->getValue('highlight_text')) {
132: $show = $prefs->getValue('show_quoteblocks');
133: $hideBlocks = $inline &&
134: (($show == 'hidden') ||
135: (($show == 'thread') && (basename(Horde::selfUrl()) == 'thread.php')));
136: if (!$hideBlocks && in_array($show, array('list', 'listthread'))) {
137: $header = $this->getConfigParam('imp_contents')->getHeader();
138: $imp_ui = new IMP_Ui_Message();
139: $list_info = $imp_ui->getListInformation($header);
140: $hideBlocks = $list_info['exists'];
141: }
142:
143: if ($inline) {
144: $filters['highlightquotes'] = array(
145: 'hideBlocks' => $hideBlocks,
146: 'noJS' => (IMP::getViewMode() == 'dimp')
147: );
148: } else {
149: $filters['Horde_Text_Filter_Highlightquotes'] = array(
150: 'hideBlocks' => $hideBlocks
151: );
152: }
153: }
154:
155:
156: if ($prefs->getValue('highlight_simple_markup')) {
157: $filters['simplemarkup'] = array();
158: }
159:
160:
161: if ($prefs->getValue('dim_signature')) {
162: $filters['dimsignature'] = array();
163: }
164:
165: if ($prefs->getValue('emoticons')) {
166: $filters['emoticons'] = array('entities' => true);
167: }
168:
169:
170: $text = $this->_textFilter($text, array_keys($filters), array_values($filters));
171:
172:
173: $text = str_replace(array(' ', "\n "), array(' ', "\n "), $text);
174: if (!strncmp($text, ' ', 1)) {
175: $text = ' ' . substr($text, 1);
176: }
177:
178: return array(
179: $mime_id => array(
180: 'data' => "<div class=\"fixed leftAlign\">\n" . $text . '</div>',
181: 'type' => $type
182: )
183: );
184: }
185:
186: 187: 188: 189: 190: 191:
192: public function embeddedMimeParts()
193: {
194: return (!empty($GLOBALS['conf']['gnupg']['path']) && $GLOBALS['prefs']->getValue('pgp_scan_body')) || $this->getConfigParam('uudecode');
195: }
196:
197: 198: 199: 200: 201: 202: 203:
204: protected function _getEmbeddedMimeParts()
205: {
206: $ret = null;
207:
208: if (!empty($GLOBALS['conf']['gnupg']['path']) &&
209: $GLOBALS['prefs']->getValue('pgp_scan_body')) {
210: $ret = $this->_parsePGP();
211: }
212:
213: if (is_null($ret) && $this->getConfigParam('uudecode')) {
214: $ret = $this->_parseUUencode();
215: }
216:
217: return $ret;
218: }
219:
220: 221: 222: 223: 224: 225:
226: protected function _parsePGP()
227: {
228:
229: $parts = $GLOBALS['injector']->getInstance('IMP_Crypt_Pgp')->parsePGPData($this->_mimepart->getContents());
230: if (empty($parts) ||
231: ((count($parts) == 1) &&
232: ($parts[0]['type'] == Horde_Crypt_Pgp::ARMOR_TEXT))) {
233: return null;
234: }
235:
236: $new_part = new Horde_Mime_Part();
237: $new_part->setType('multipart/mixed');
238: $charset = $this->_mimepart->getCharset();
239: $mime_id = $this->_mimepart->getMimeId();
240:
241: while (list(,$val) = each($parts)) {
242: switch ($val['type']) {
243: case Horde_Crypt_Pgp::ARMOR_TEXT:
244: $part = new Horde_Mime_Part();
245: $part->setType('text/plain');
246: $part->setCharset($charset);
247: $part->setContents(implode("\n", $val['data']));
248: $new_part->addPart($part);
249: break;
250:
251: case Horde_Crypt_Pgp::ARMOR_PUBLIC_KEY:
252: $part = new Horde_Mime_Part();
253: $part->setType('application/pgp-keys');
254: $part->setContents(implode("\n", $val['data']));
255: $new_part->addPart($part);
256: break;
257:
258: case Horde_Crypt_Pgp::ARMOR_MESSAGE:
259: $part = new Horde_Mime_Part();
260: $part->setType('multipart/encrypted');
261: $part->setMetadata(IMP_Mime_Viewer_Pgp::PGP_ARMOR, true);
262:
263: $part->setContentTypeParameter('protocol', 'application/pgp-encrypted');
264:
265: $part1 = new Horde_Mime_Part();
266: $part1->setType('application/pgp-encrypted');
267: $part1->setContents("Version: 1\n");
268:
269: $part2 = new Horde_Mime_Part();
270: $part2->setType('application/octet-stream');
271: $part2->setContents(implode("\n", $val['data']));
272: $part2->setDisposition('inline');
273:
274: $part->addPart($part1);
275: $part->addPart($part2);
276:
277: $new_part->addPart($part);
278: break;
279:
280: case Horde_Crypt_Pgp::ARMOR_SIGNED_MESSAGE:
281: if (($sig = current($parts)) &&
282: ($sig['type'] == Horde_Crypt_Pgp::ARMOR_SIGNATURE)) {
283: $part = new Horde_Mime_Part();
284: $part->setType('multipart/signed');
285:
286: $part->setContentTypeParameter('protocol', 'application/pgp-signature');
287:
288: $part1 = new Horde_Mime_Part();
289: $part1->setType('text/plain');
290: $part1->setCharset($charset);
291:
292: $part1_data = implode("\n", $val['data']);
293: $part1->setContents(substr($part1_data, strpos($part1_data, "\n\n") + 2));
294:
295: $part2 = new Horde_Mime_Part();
296: $part2->setType('application/pgp-signature');
297: $part2->setContents(implode("\n", $val['data']) . "\n" . implode("\n", $sig['data']));
298:
299:
300:
301:
302:
303: $part2->setMetadata(IMP_Mime_Viewer_Pgp::PGP_SIG, true);
304: $part2->setMetadata(IMP_Mime_Viewer_Pgp::PGP_CHARSET, $charset);
305:
306: $part->addPart($part1);
307: $part->addPart($part2);
308: $new_part->addPart($part);
309:
310: next($parts);
311: }
312: }
313: }
314:
315: self::$_cache[$mime_id] = true;
316:
317: return $new_part;
318: }
319:
320: 321: 322: 323: 324: 325:
326: protected function _parseUUencode()
327: {
328: $text = Horde_String::convertCharset($this->_mimepart->getContents(), $this->_mimepart->getCharset(), 'UTF-8');
329:
330: $files = Horde_Mime::uudecode($text);
331: if (empty($files)) {
332: return null;
333: }
334:
335: $new_part = new Horde_Mime_Part();
336: $new_part->setType('multipart/mixed');
337: $mime_id = $this->_mimepart->getMimeId();
338:
339: $text_part = new Horde_Mime_Part();
340: $text_part->setType('text/plain');
341: $text_part->setCharset($this->getConfigParam('charset'));
342: $text_part->setContents(preg_replace("/begin [0-7]{3} .+\r?\n.+\r?\nend/Us", "\n", $text));
343: $new_part->addPart($text_part);
344:
345: reset($files);
346: while (list(,$file) = each($files)) {
347: $uupart = new Horde_Mime_Part();
348: $uupart->setType('application/octet-stream');
349: $uupart->setContents($file['data']);
350: $uupart->setName(strip_tags($file['name']));
351: $new_part->addPart($uupart);
352: }
353:
354: return $new_part;
355: }
356:
357: 358: 359: 360: 361: 362:
363: public function overLimitText()
364: {
365: $stream = $this->_mimepart->getContents(array('stream' => true));
366: rewind($stream);
367:
368:
369: $filters = array(
370: 'text2html' => array(
371: 'parselevel' => Horde_Text_Filter_Text2html::MICRO
372: ),
373: 'tabs2spaces' => array(),
374: );
375:
376: return '<div class="fixed">' .
377: $this->_textFilter(Horde_String::convertCharset(fread($stream, 1024), $this->_mimepart->getCharset(), 'UTF-8'), array_keys($filters), array_values($filters)) .
378: ' [...]</div>';
379: }
380:
381: }
382: