id = $_id; $this->pj = array(); $this->messages = array(); $this->_header(); if ($body = $banana->nntp->body($_id)) { $this->body = join("\n", $body); } else { return ($this = null); } if (isset($this->headers['content-transfer-encoding'])) { if (preg_match("/base64/", $this->headers['content-transfer-encoding'])) { $this->body = base64_decode($this->body); } elseif (preg_match("/quoted-printable/", $this->headers['content-transfer-encoding'])) { $this->body = quoted_printable_decode($this->body); } } if (preg_match("@multipart/([^;]+);@", $this->headers['content-type'], $mpart_type)) { preg_match("/boundary=\"?([^ \"]+)\"?/", $this->headers['content-type'], $mpart_boundary); $this->_split_multipart($mpart_type[1], $mpart_boundary[1]); } else { if (preg_match('!charset=([^;]*)\s*(;|$)!', $this->headers['content-type'], $matches)) { $this->body = iconv($matches[1], 'utf-8', $this->body); } else { $this->body = utf8_encode($this->body); } } } /** split multipart messages * @param $type STRING multipart type description * @param $boundary STRING multipart boundary identification string */ function _split_multipart($type, $boundary) { $parts = preg_split("/\n--$boundary(--|\n)/", $this->body); foreach ($parts as $part) { $part = $this->_get_part($part); $local_header = $part['headers']; $local_body = $part['body']; if (isset($local_header['content-disposition']) && preg_match("/attachment/", $local_header['content-disposition'])) { $this->_add_attachment($part); } else if (isset($local_header['content-type']) && preg_match("@text/([^;]+);@", $local_header['content-type'], $format)) { array_push($this->messages, $part); } } $this->set_body_to_part(0); } /** extract new headers from the part * @param $part STRING part of a multipart message */ function _get_part($part) { global $banana; $lines = split("\n", $part); while (count($lines)) { $line = array_shift($lines); if ($line != "") { list($hdr, $val) = split(":[ \t\r]*", $line, 2); $hdr = strtolower($hdr); if (in_array($hdr, $banana->parse_hdr)) { $local_headers[$hdr] = $val; } } else { break; } } return Array('headers' => $local_headers, 'body' => join("\n", $lines)); } /** add an attachment */ function _add_attachment($part) { $local_header = $part['headers']; $local_body = $part['body']; if (!isset($local_header['content-transfer-encoding'])) { return false; } if (isset($local_header['content-disposition'])) { if (preg_match("/attachment/", $local_header['content-disposition'])) { preg_match("/filename=\"?([^\"]+)\"?/", $local_header['content-disposition'], $filename); $filename = $filename[1]; } } if (!isset($filename)) { $filename = "attachment".count($pj); } if (isset($local_header['content-type'])) { if (preg_match("/^\\s*([^ ;]+);/", $local_header['content-type'], $mimetype)) { $mimetype = $mimetype[1]; } } if (!isset($mimetype)) { return false; } array_push($this->pj, Array('MIME' => $mimetype, 'filename' => $filename, 'encoding' => strtolower($local_header['content-transfer-encoding']), 'data' => $local_body)); return true; } /** return body in plain text (useful for messages without a text/plain part) */ function get_body() { preg_match("@text/([^;]+);@", $this->headers['content-type'], $format); if ($format[1] == 'plain') { return $this->body; } $res = preg_replace("@]>@", "@@@#@", $this->body); $res = trim(html_entity_decode(strip_tags($res))); $res = str_replace("@@@#@", "\n", $res); if (!is_utf8($res)) { $res = utf8_encode($res); } return $res; } /** decode an attachment * @param pjid INT id of the attachment to decode * @param action BOOL action to execute : true=view, false=download */ function get_attachment($pjid, $action = false) { if ($pjid >= count($this->pj)) { return false; } else { $file = $this->pj[$pjid]; header('Content-Type: '.$file['MIME'].'; name="'.$file['filename'].'"'); if (!$action) { header('Content-Disposition: attachment; filename="'.$file['filename'].'"'); } else { header('Content-Disposition: inline; filename="'.$file['filename'].'"'); } if ($file['encoding'] == 'base64') { echo base64_decode($file['data']); } else { header('Content-Transfer-Encoding: '.$file['encoding']); echo $file['data']; } return true; } } /** set body to represent the given part * @param partid INT index of the part in messages */ function set_body_to_part($partid) { global $banana; if (count($this->messages) == 0) { return false; } $local_header = $this->messages[$partid]['headers']; $this->body = $this->messages[$partid]['body']; foreach ($banana->parse_hdr as $hdr) { if (isset($local_header[$hdr])) { $this->headers[$hdr] = $local_header[$hdr]; } } if (preg_match('!charset=([^;]*)\s*(;|$)!', $this->headers['content-type'], $matches)) { $this->body = iconv($matches[1], 'utf-8', $this->body); } else { $this->body = utf8_encode($this->body); } return true; } function _header() { global $banana; $hdrs = $banana->nntp->head($this->id); if (!$hdrs) { $this = null; return false; } // parse headers foreach ($hdrs as $line) { if (preg_match("/^[\t\r ]+/", $line)) { $line = ($hdr=="X-Face"?"":" ").ltrim($line); if (in_array($hdr, $banana->parse_hdr)) { $this->headers[$hdr] .= $line; } } else { list($hdr, $val) = split(":[ \t\r]*", $line, 2); $hdr = strtolower($hdr); if (in_array($hdr, $banana->parse_hdr)) { $this->headers[$hdr] = $val; } } } // decode headers foreach ($banana->hdecode as $hdr) { if (isset($this->headers[$hdr])) { $this->headers[$hdr] = headerDecode($this->headers[$hdr]); } } $this->name = $this->headers['from']; $this->name = preg_replace('/<[^ ]*>/', '', $this->name); $this->name = trim($this->name); } function checkcancel() { if (function_exists('hook_checkcancel')) { return hook_checkcancel($this->headers); } return ($this->headers['from'] == $_SESSION['name']." <".$_SESSION['mail'].">"); } /** convert message to html * @param partid INT id of the multipart message that must be displaid */ function to_html($partid = -1) { global $banana; if (count($this->messages) > 1) { if ($partid != -1) { $this->set_body_to_part($partid); } else { // Select prefered text-format foreach ($banana->body_mime as $mime) { for ($id = 0 ; $id < count($this->messages) ; $id++) { if (preg_match("@$mime@", $this->messages[$id]['headers']['content-type'])) { $partid = $id; $this->set_body_to_part($partid); break; } } if ($partid != -1) { break; } } if ($partid == -1) { $partid = 0; } } } else { $partid = 0; } $res = ''; $res .= ''; foreach ($banana->show_hdr as $hdr) { if (isset($this->headers[$hdr])) { $res2 = formatdisplayheader($hdr, $this->headers[$hdr]); if ($res2) { $res .= '\n"; } } } $res .= ''; preg_match("@text/([^;]+);@", $this->headers['content-type'], $format); $format = $format[1]; $res .= ''; if (count($this->pj) > 0) { $res .= ''; $res .= ''; } $res .= ''; $ndx = $banana->spool->getndx($this->id); $res .= ''; return $res.'
'._b_('En-têtes').'
'.header_translate($hdr)."$res2
'._b_('Corps'); if (count($this->messages) > 1) { for ($i = 0 ; $i < count($this->messages) ; $i++) { if ($i == 0) { $res .= ' : '; } else { $res .= ' . '; } preg_match("@text/([^;]+);@", $this->messages[$i]['headers']['content-type'], $format); $format = textFormat_translate($format[1]); if ($i != $partid) { $res .= ''.$format.''; } else { $res .= $format; } } } $res .= '
'; if ($format == 'html') { $res .= formatbody($this->body, $format); } else { $res .= '
'.formatbody($this->body).'
'; } $res .= '
'._b_('Pièces jointes').'
'; $i = 0; foreach ($this->pj as $file) { $res .= $file['filename'].' ('.$file['MIME'].') : '; $res .= 'télécharger'; $res .= ' . aperçu'; $res .= '
'; $i++; } $res .= '
'._b_('Apercu').'
'.$banana->spool->to_html($ndx-$banana->tbefore, $ndx+$banana->tafter, $ndx).'
'; } } ?>