2 /********************************************************************************
3 * banana/message.inc.php : class for messages
4 * ------------------------
6 * This file is part of the banana distribution
7 * Copyright: See COPYING files that comes with this distribution
8 ********************************************************************************/
10 require_once dirname(__FILE__
) . '/mimepart.inc.php';
11 require_once dirname(__FILE__
) . '/message.func.inc.php';
12 require_once dirname(__FILE__
) . '/banana.inc.php';
14 final class BananaMessage
extends BananaMimePart
16 private $msg_headers = array();
18 public function __construct($data = null
)
20 parent
::__construct($data);
21 if (!is_null($data)) {
22 if (isset($this->headers
['in-reply-to']) && isset($this->headers
['references'])) {
23 unset($this->headers
['in-reply-to']);
25 Banana
::$msgshow_headers = array_intersect(Banana
::$msgshow_headers, array_keys($this->headers
));
26 Banana
::$message =& $this;
30 public function hasHeader($hdr)
32 return isset($this->headers
[$hdr]);
35 static public function newMessage(array $headers, $body, array $file = null
)
37 $msg = new BananaMessage();
38 $msg->msg_headers
= $headers;
39 $msg->makeTextPart($body, 'text/plain', '8bits', 'UTF-8', 'flowed');
40 if (!is_null($file)) {
41 $msg->addAttachment($file);
46 static public function translateHeaderName($hdr)
48 switch (strtolower($hdr)) {
49 case 'from': return _b_('De');
50 case 'subject': return _b_('Sujet');
51 case 'newsgroups': return _b_('Forums');
52 case 'followup-to': return _b_('Suivi à');
53 case 'to': return _b_('À');
54 case 'cc': return _b_('Copie à');
55 case 'bcc': return _b_('Copie cachée à');
56 case 'reply-to': return _b_('Répondre à');
57 case 'date': return _b_('Date');
58 case 'organization': return _b_('Organisation');
60 case 'references': return _b_('Références');
61 case 'x-face': return _b_('Image');
66 public function translateHeaderValue($hdr)
68 if (!isset($this->headers
[$hdr])) {
71 $text = $this->headers
[$hdr];
73 if (function_exists('hook_formatDisplayHeader')
74 && $res = hook_formatDisplayHeader($hdr, $text)) {
79 return BananaMessage
::formatDate($text);
81 case "followup-to": case "newsgroups":
82 $groups = preg_split("/[\t ]*,[\t ]*/", $text);
84 foreach ($groups as $g) {
85 $res .= Banana
::$page->makeLink(Array('group' => $g, 'text' => $g)) . ', ';
87 return substr($res,0, -2);
90 return BananaMessage
::formatFrom($text, $this->headers
['subject']);
92 case "references": case "in-reply-to":
94 $parents = preg_grep('/^\d+$/', $this->getTranslatedReferences());
95 $p = array_pop($parents);
98 while (!is_null($p)) {
99 array_unshift($parents, $p);
100 $p = Banana
::$spool->overview
[$p]->parent
;
103 foreach ($parents as $p) {
104 $rsl .= Banana
::$page->makeLink(Array('group' => Banana
::$spool->group
,
105 'artid' => $p, 'text' => $ndx++
)) . ' ';
110 $text = stripslashes($text);
111 $text = banana_htmlentities($text);
112 return banana_catchFormats($text);
119 public function getSender()
121 $from = $this->headers
['from'];
122 $name = trim(preg_replace('/<[^ ]*>/', '', $from));
129 public function getHeaderValue($hdr)
131 $hdr = strtolower($hdr);
132 if (!isset($this->headers
[$hdr])) {
135 if ($hdr == 'date') {
136 return strtotime($this->headers
['date']);
137 } else if ($hdr == 'references' ||
$hdr == 'reply-to') {
138 return str_replace('><', '> <', $this->headers
[$hdr]);
140 return $this->headers
[$hdr];
144 public function getHeaders()
146 $this->msg_headers
= array_merge($this->msg_headers
, Banana
::$msgedit_headers, Banana
::$profile['headers']);
147 $headers = array_map(array($this, 'encodeHeader'), $this->msg_headers
);
148 return array_merge($headers, parent
::getHeaders());
151 static public function formatFrom($text, $subject = '')
153 # From: mark@cbosgd.ATT.COM
154 # From: <mark@cbosgd.ATT.COM>
155 # From: mark@cbosgd.ATT.COM (Mark Horton)
156 # From: Mark Horton <mark@cbosgd.ATT.COM>
157 $mailto = '<a href="mailto:';
159 $result = banana_htmlentities($text);
161 $subject = '?subject=' . banana_htmlentities(_b_('Re: ') . $subject, ENT_QUOTES
);
163 if (preg_match("/^<?([^< ]+@[^> ]+)>?$/", $text, $regs)) {
164 $result = $mailto . $regs[1] . $subject . '">' . banana_htmlentities($regs[1]) . '</a>';
166 if (preg_match("/^([^ ]+@[^ ]+) \((.*)\)$/", $text, $regs)) {
167 $result = $mailto . $regs[1] . $subject . '">' . banana_htmlentities($regs[2]) . '</a>';
169 if (preg_match("/^\"?([^<>\"]+)\"? +<(.+@.+)>$/", $text, $regs)) {
170 $nom = preg_replace("/^'(.*)'$/", '\1', $regs[1]);
171 $nom = stripslashes($nom);
172 $result = $mailto . $regs[2] . $subject . '">' . banana_htmlentities($nom) . '</a>';
174 return preg_replace("/\\\(\(|\))/","\\1",$result);
177 public function getAuthorName()
179 $text = $this->getHeaderValue('From');
181 if (preg_match("/^([^ ]+@[^ ]+) \((.*)\)$/", $text, $regs)) {
184 if (preg_match("/^\"?([^<>\"]+)\"? +<(.+@.+)>$/", $text, $regs)) {
185 $name = preg_replace("/^'(.*)'$/", '\1', $regs[1]);
186 $name = stripslashes($name);
189 return preg_replace("/\\\(\(|\))/","\\1", $name);
192 if (function_exists('hook_getAuthorName') && $name = hook_getAuthorName($this)) {
196 if (preg_match("/([^< ]+)@([^> ]+)/", $text, $regs)) {
202 static public function formatDate($text)
204 return strftime("%A %d %B %Y, %H:%M (fuseau serveur)", strtotime($text));
207 public function translateHeaders()
210 foreach (array_keys($this->headers
) as $name) {
211 $value = $this->translateHeaderValue($name);
212 if (!is_null($value)) {
213 $result[$this->translateHeaderName($name)] = $value;
219 public function getReferences()
221 $text = $this->headers
['references'];
222 $text = str_replace("><","> <", $text);
223 return preg_split('/\s/', $text);
226 public function getTranslatedReferences()
228 return BananaMessage
::formatReferences($this->headers
);
231 static public function formatReferences(array &$refs)
233 if (isset($refs['references'])) {
234 $text = preg_split('/\s/', str_replace('><', '> <', $refs['references']));
235 $references = array();
236 foreach ($text as $id=>&$value) {
237 if (isset(Banana
::$spool->ids
[$value])) {
238 $references[] = Banana
::$spool->ids
[$value];
242 } elseif (isset($refs['in-reply-to']) && isset(Banana
::$spool->ids
[$refs['in-reply-to']])) {
243 return array(Banana
::$spool->ids
[$refs['in-reply-to']]);
249 public function hasXFace()
251 return Banana
::$msgshow_xface && isset($this->headers
['x-face']);
254 public function getXFace()
256 header('Content-Type: image/gif');
257 $xface = $this->headers
['x-face'];
258 passthru('echo ' . escapeshellarg($xface)
260 . '| convert -transparent white xbm:- gif:-');
264 public function getFormattedBody(&$reqtype = null
)
266 $types = Banana
::$msgshow_mimeparts;
267 if (!is_null($reqtype)) {
268 array_unshift($types, $reqtype);
270 foreach ($types as $type) {
271 @list
($type, $subtype) = explode('/', $type);
272 $parts = $this->getParts($type, $subtype);
276 $reqtype = implode('/', $parts[0]->getType());
277 return $parts[0]->toHtml();
282 public function quote()
284 foreach (Banana
::$msgedit_mimeparts as $type) {
285 @list
($type, $subtype) = explode('/', $type);
286 $parts = $this->getParts($type, $subtype);
290 if ($parts[0] === $this) {
291 return parent
::quote();
293 return $parts[0]->quote();
298 public function canCancel()
300 if (!Banana
::$protocole->canCancel()) {
303 if (function_exists('hook_checkcancel')) {
304 return hook_checkcancel($this->headers
);
306 return Banana
::$profile['headers']['From'] == $this->headers
['from'];
309 public function canSend()
311 return Banana
::$protocole->canSend();
314 public function getSignature()
316 $email = $this->getHeaderValue('from');
317 if (preg_match('/<?([^ <]+@[^ >]+)>?/', $email, $matches)) {
318 $email = $matches[1];
320 $signature = BananaMimePart
::getSignature();
321 if (empty($signature)) {
324 foreach ($signature['identity'] as $ident) {
325 if (strpos($ident, "<$email>") !== false
) {
329 $signature['certified'] = false
;
330 $signature['certification_error'] = 'mauvaise identité';
336 // vim:set et sw=4 sts=4 ts=4 enc=utf-8: