Add documentation in page.inc.php
[banana.git] / banana / message.inc.php
CommitLineData
7027794f 1<?php
2/********************************************************************************
3* banana/message.inc.php : class for messages
4* ------------------------
5*
6* This file is part of the banana distribution
7* Copyright: See COPYING files that comes with this distribution
8********************************************************************************/
9
10require_once dirname(__FILE__) . '/mimepart.inc.php';
11require_once dirname(__FILE__) . '/message.func.inc.php';
12require_once dirname(__FILE__) . '/banana.inc.php';
13
14final class BananaMessage extends BananaMimePart
15{
16 private $msg_headers = array();
17
18 public function __construct($data = null)
19 {
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']);
24 }
25 Banana::$show_hdr = array_intersect(Banana::$show_hdr, array_keys($this->headers));
26 Banana::$message =& $this;
27 }
28 }
29
30 public function hasHeader($hdr)
31 {
32 return isset($this->headers[$hdr]);
33 }
34
35 static public function newMessage(array $headers, $body, array $file = null)
36 {
37 $msg = new BananaMessage();
38 $msg->msg_headers = $headers;
39 $msg->makeTextPart($body, 'text/plain', '8bits', 'UTF-8', 'fixed');
40 if (!is_null($file)) {
41 $msg->addAttachment($file);
42 }
43 return $msg;
44 }
45
46 static public function translateHeaderName($hdr)
47 {
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');
59 case 'in-reply-to':
60 case 'references': return _b_('Références');
61 case 'x-face': return _b_('Image');
62 }
63 return $hdr;
64 }
65
66 public function translateHeaderValue($hdr)
67 {
68 if (!isset($this->headers[$hdr])) {
69 return null;
70 }
71 $text = $this->headers[$hdr];
72
73 if (function_exists('hook_formatDisplayHeader')
74 && $res = hook_formatDisplayHeader($hdr, $text)) {
75 return $res;
76 }
77 switch ($hdr) {
78 case "date":
79 return BananaMessage::formatDate($text);
80
81 case "followup-to": case "newsgroups":
82 $groups = preg_split("/[\t ]*,[\t ]*/", $text);
83 $res = '';
84 foreach ($groups as $g) {
85 $res .= Banana::$page->makeLink(Array('group' => $g, 'text' => $g)) . ', ';
86 }
87 return substr($res,0, -2);
88
89 case "from":
90 return BananaMessage::formatFrom($text);
91
92 case "references": case "in-reply-to":
93 $rsl = "";
94 $parents = preg_grep('/^\d+$/', $this->getTranslatedReferences());
95 $p = array_pop($parents);
96
97 $parents = array();
98 while (!is_null($p)) {
99 array_unshift($parents, $p);
100 $p = Banana::$spool->overview[$p]->parent;
101 }
102 $ndx = 1;
103 foreach ($parents as $p) {
104 $rsl .= Banana::$page->makeLink(Array('group' => Banana::$spool->group,
105 'artid' => $p, 'text' => $ndx++)) . ' ';
106 }
107 return $rsl;
108
109 case "subject":
110 $link = null;
111 $text = stripslashes($text);
112 if (function_exists('hook_getSubject')) {
113 $link = hook_getSubject($text);
114 }
115 return banana_catchFormats($text) . $link;
116
117 default:
118 return $text;
119 }
120 }
121
122 public function getSender()
123 {
124 $from = $this->headers['from'];
125 $name = trim(preg_replace('/<[^ ]*>/', '', $from));
126 if (empty($name)) {
127 return $from;
128 }
129 return $name;
130 }
131
132 public function getHeaderValue($hdr)
133 {
134 $hdr = strtolower($hdr);
135 if (!isset($this->headers[$hdr])) {
136 return null;
137 }
138 if ($hdr == 'date') {
139 return strtotime($this->headers['date']);
140 } else {
141 return $this->headers[$hdr];
142 }
143 }
144
145 public function getHeaders()
146 {
147 $this->msg_headers = array_merge($this->msg_headers, Banana::$custom_hdr, Banana::$profile['custom_hdr']);
148 $headers = array_map(array($this, 'encodeHeader'), $this->msg_headers);
149 return array_merge($headers, parent::getHeaders());
150 }
151
152 static public function formatFrom($text)
153 {
154# From: mark@cbosgd.ATT.COM
155# From: <mark@cbosgd.ATT.COM>
156# From: mark@cbosgd.ATT.COM (Mark Horton)
157# From: Mark Horton <mark@cbosgd.ATT.COM>
158 $mailto = '<a href="mailto:';
159
160 $result = banana_htmlentities($text);
161 if (preg_match("/^([^ ]+@[^ ]+)$/", $text, $regs)) {
162 $result = $mailto . $regs[1] . '">' . banana_htmlentities($regs[1]) . '</a>';
163 }
164 if (preg_match("/^<(.+@.+)>$/", $text, $regs)) {
165 $result = $mailto . $regs[1] . '">' . banana_htmlentities($regs[1]) . '</a>';
166 }
167 if (preg_match("/^([^ ]+@[^ ]+) \((.*)\)$/", $text, $regs)) {
168 $result = $mailto . $regs[1] . '">' . banana_htmlentities($regs[2]) . '</a>';
169 }
170 if (preg_match("/^\"?([^<>\"]+)\"? +<(.+@.+)>$/", $text, $regs)) {
171 $nom = preg_replace("/^'(.*)'$/", '\1', $regs[1]);
172 $nom = stripslashes($nom);
173 $result = $mailto . $regs[2] . '">' . banana_htmlentities($nom) . '</a>';
174 }
175 return preg_replace("/\\\(\(|\))/","\\1",$result);
176 }
177
178 static public function formatDate($text)
179 {
180 return utf8_encode(strftime("%A %d %B %Y, %H:%M (fuseau serveur)", strtotime($text)));
181 }
182
183 public function translateHeaders()
184 {
185 $result = array();
186 foreach (array_keys($this->headers) as $name) {
187 $value = $this->translateHeaderValue($name);
188 if (!is_null($value)) {
189 $result[$this->translateHeaderName($name)] = $value;
190 }
191 }
192 return $result;
193 }
194
195 public function getReferences()
196 {
197 $text = $this->headers['references'];
198 $text = str_replace("><","> <", $text);
199 return preg_split('/\s/', $text);
200 }
201
202 public function getTranslatedReferences()
203 {
204 return BananaMessage::formatReferences($this->headers);
205 }
206
207 static public function formatReferences(array &$refs)
208 {
209 if (isset($refs['references'])) {
210 $text = str_replace('><', '> <', $refs['references']);
211 return preg_split('/\s/', strtr($text, Banana::$spool->ids));
212 } elseif (isset($refs['in-reply-to'])) {
213 return array(Banana::$spool->ids[$refs['in-reply-to']]);
214 } else {
215 return array();
216 }
217 }
218
219 public function hasXFace()
220 {
221 return Banana::$formatxface && isset($this->headers['x-face']);
222 }
223
224 public function getXFace()
225 {
226 header('Content-Type: image/gif');
227 $xface = $this->headers['x-face'];
228 passthru('echo ' . escapeshellarg($xface)
229 . '| uncompface -X '
230 . '| convert -transparent white xbm:- gif:-');
231 exit;
232 }
233
234 public function getFormattedBody($type = null)
235 {
236 $types = Banana::$body_mime;
237 if (!is_null($type)) {
238 array_unshift($types, $type);
239 }
240 foreach ($types as $type) {
241 @list($type, $subtype) = explode('/', $type);
242 $parts = $this->getParts($type, $subtype);
243 if (empty($parts)) {
244 continue;
245 }
246 foreach ($parts as &$part) {
247 list($type, $subtype) = $part->getType();
248 switch ($subtype) {
249 case 'html': return banana_formatHtml($part);
250 case 'enriched': case 'richtext': return banana_formatRichText($part);
251 default: return banana_formatPlainText($part);
252 }
253 }
254 }
255 return null;
256 }
257
258 public function quote()
259 {
260 $part = $this->toPlainText();
261 if (is_null($part)) {
262 return banana_quoteHtml($this->toHtml());
263 }
264 return banana_quotePlainText($part);
265 }
266
267 public function canCancel()
268 {
269 if (!Banana::$protocole->canCancel()) {
270 return false;
271 }
272 if (function_exists('hook_checkcancel')) {
273 return hook_checkcancel($this->headers);
274 }
275 return Banana::$profile['name'] == $this->headers['from'];
276 }
277
278 public function canSend()
279 {
280 return Banana::$protocole->canSend();
281 }
282}
283
284// vim:set et sw=4 sts=4 ts=4:
285?>