$group = empty($_GET['group']) ? null : strtolower($_GET['group']);
$artid = empty($_GET['artid']) ? null : strtolower($_GET['artid']);
+ $partid = empty($_GET['part']) ? 0 : $_GET['part'];
$banana->state = Array ('group' => $group, 'artid' => $artid);
if (is_null($group)) {
if (isset($_GET['action'])) {
switch ($_GET['action']) {
case 'cancel':
- $res .= $banana->action_showArticle($group, $artid);
+ $res .= $banana->action_showArticle($group, $artid, $partid);
if ($banana->post->checkcancel()) {
$form = '<p class="error">'._b_('Voulez-vous vraiment annuler ce message ?').'</p>'
. "<form action=\"?group=$group&artid=$artid\" method='post'><p>"
return $banana->action_getAttachment($group, $artid, $_GET['pj'], $action);
}
- return $res . $banana->action_showArticle($group, $artid);
+ return $res . $banana->action_showArticle($group, $artid, $partid);
}
}
return $res.$cuts;
}
- function action_showArticle($group, $id)
+ function action_showArticle($group, $id, $part)
{
$this->_newSpool($group, $this->profile['display'], $this->profile['lastnews']);
$this->_newPost($id);
$cuts = displayshortcuts();
$res = '<h1>'._b_('Message').'</h1>'.$cuts;
- $res .= $this->post->to_html();
+ $res .= $this->post->to_html($part);
$this->nntp->quit();
function is_utf8($s) { return iconv('utf-8', 'utf-8', $s) == $s; }
+function textFormat_translate($format)
+{
+ switch (strtolower($format)) {
+ case 'plain': return _b_('Texte brut');
+ case 'richtext': return _b_('Texte enrichi');
+ case 'html': return _b_('HTML');
+ default: return $format;
+ }
+}
+
+/********************************************************************************
+ * HTML STUFF
+ * Taken from php.net
+ */
+
+ /**
+ * @return string
+ * @param string
+ * @desc Strip forbidden tags and delegate tag-source check to removeEvilAttributes()
+ */
+function removeEvilTags($source)
+{
+ $allowedTags = '<h1><b><i><a><ul><li><pre><hr><blockquote><img><br><font><p>';
+ $source = strip_tags($source, $allowedTags);
+ return preg_replace('/<(.*?)>/ie', "'<'.removeEvilAttributes('\\1').'>'", $source);
+}
+
+/**
+ * @return string
+ * @param string
+ * @desc Strip forbidden attributes from a tag
+ */
+function removeEvilAttributes($tagSource)
+{
+ $stripAttrib = 'javascript:|onclick|ondblclick|onmousedown|onmouseup|onmouseover|'.
+ 'onmousemove|onmouseout|onkeypress|onkeydown|onkeyup';
+ return stripslashes(preg_replace("/$stripAttrib/i", '', $tagSource));
+}
+
/********************************************************************************
* HEADER STUFF
*/
return $_prefix.join("\n$_prefix", $result).($_prefix ? '' : $sign);
}
-function formatbody($_text) {
- $res = "\n\n" . to_entities(wrap($_text, ""))."\n\n";
+function formatbody($_text, $format='plain')
+{
+ if ($format == 'html') {
+ $res = '<br/>'.removeEvilTags(html_entity_decode(to_entities($_text))).'<br/>';
+ } else {
+ $res = "\n\n" . to_entities(wrap($_text, ""))."\n\n";
+ }
$res = preg_replace("/(<|>|")/", " \\1 ", $res);
$res = preg_replace('/(["\[])?((https?|ftp|news):\/\/[a-z@0-9.~%$£µ&i#\-+=_\/\?]*)(["\]])?/i', "\\1<a href=\"\\2\">\\2</a>\\4", $res);
$res = preg_replace("/ (<|>|") /", "\\1", $res);
-
+
+ if ($format == 'html') {
+ return $res;
+ }
+
$parts = preg_split("/\n-- ?\n/", $res);
if (count($parts) > 1) {
var $headers;
/** body */
var $body;
+ /** formating */
+ var $messages;
/** attachment */
var $pj;
/** poster name */
function BananaPost($_id)
{
global $banana;
- $this->id = $_id;
- $this->pj = array();
+ $this->id = $_id;
+ $this->pj = array();
+ $this->messages = array();
$this->_header();
if ($body = $banana->nntp->body($_id)) {
*/
function split_multipart($type, $boundary)
{
- global $banana;
-
$parts = preg_split("/\n--$boundary(--|\n)/", $this->body);
foreach ($parts as $part) {
$part = $this->get_part($part);
$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'])) {
- $this->body = $local_body;
- foreach ($banana->parse_hdr as $hdr) {
- if (isset($local_header[$hdr])) {
- $this->headers[$hdr] = $local_header[$hdr];
- }
- }
- }
+ } else if (isset($local_header['content-type']) && preg_match("@text/([^;]+);@", $local_header['content-type'], $format)) {
+ array_push($this->messages, $part);
+ }
+ }
+ if (count($this->messages) > 0) {
+ $this->set_body_to_part(0);
}
}
/** extract new headers from the part
* @param $part STRING part of a multipart message
*/
- function get_part($part) {
+ function get_part($part)
+ {
global $banana;
$lines = split("\n", $part);
break;
}
}
- # echo join("\n", $lines)."<br/>------------------------------------<br/>";
return Array('headers' => $local_headers, 'body' => join("\n", $lines));
}
- function add_attachment($part) {
+ /** add an attachment
+ */
+ function add_attachment($part)
+ {
$local_header = $part['headers'];
$local_body = $part['body'];
if (!isset($local_header['content-transfer-encoding'])) {
- return;
+ return false;
}
if (isset($local_header['content-disposition'])) {
}
}
if (!isset($mimetype)) {
- return;
+ return false;
}
array_push($this->pj, Array('MIME' => $mimetype,
'filename' => $filename,
'encoding' => strtolower($local_header['content-transfer-encoding']),
'data' => $local_body));
+ return true;
}
/** 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) {
+ function get_attachment($pjid, $action = false)
+ {
if ($pjid >= count($this->pj)) {
return false;
} else {
}
}
+ /** 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];
+ }
+ }
+ return true;
+ }
+
function _header()
{
global $banana;
return ($this->headers['from'] == $_SESSION['name']." <".$_SESSION['mail'].">");
}
- function to_html()
+ /** convert message to html
+ * @param partid INT id of the multipart message that must be displaid
+ */
+ function to_html($partid = 0)
{
global $banana;
+ if ($partid != 0) {
+ $this->set_body_to_part($partid);
+ }
+
$res = '<table class="bicol banana_msg" cellpadding="0" cellspacing="0">';
$res .= '<tr><th colspan="2">'._b_('En-têtes').'</th></tr>';
}
}
- $res .= '<tr><th colspan="2">'._b_('Corps').'</th></tr>';
- $res .= '<tr><td colspan="2"><pre>'.formatbody($this->body).'</pre></td></tr>';
+ $res .= '<tr><th colspan="2">'._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 .= '<a href="?group='.$banana->state['group'].'&artid='.$this->id.'&part='.$i.'">'.$format.'</a>';
+ } else {
+ $res .= $format;
+ }
+ }
+ }
+ $res .= '</th></tr>';
+
+ preg_match("@text/([^;]+);@", $this->headers['content-type'], $format);
+ $format = $format[1];
+ $res .= '<tr><td colspan="2">';
+ if ($format == 'html') {
+ $res .= formatbody($this->body, $format);
+ } else {
+ $res .= '<pre>'.formatbody($this->body).'</pre>';
+ }
+ $res .= '</td></tr>';
if (count($this->pj) > 0) {
$res .= '<tr><th colspan="2">'._b_('Pièces jointes').'</th></tr>';