Commit | Line | Data |
---|---|---|
7027794f | 1 | <?php |
2 | /******************************************************************************** | |
3 | * banana/nntp.inc.php : NNTP protocole handler | |
4 | * ------------------------ | |
5 | * | |
6 | * This file is part of the banana distribution | |
7 | * Copyright: See COPYING files that comes with this distribution | |
8 | ********************************************************************************/ | |
9 | ||
10 | require_once dirname(__FILE__) . '/banana.inc.php'; | |
11 | require_once dirname(__FILE__) . '/message.inc.php'; | |
12 | require_once dirname(__FILE__) . '/nntpcore.inc.php'; | |
13 | require_once dirname(__FILE__) . '/protocoleinterface.inc.php'; | |
14 | ||
15 | class BananaNNTP extends BananaNNTPCore implements BananaProtocoleInterface | |
16 | { | |
7027794f | 17 | private $ingroup = null; |
18 | ||
19 | private $mode = null; | |
20 | private $boxes = null; | |
21 | ||
22 | /** Build a protocole handler plugged on the given box | |
23 | */ | |
0e25d15d | 24 | public function __construct() |
7027794f | 25 | { |
e9360b11 | 26 | $url = parse_url(Banana::$nntp_host); |
7027794f | 27 | if ($url['scheme'] == 'nntps' || $url['scheme'] == 'snntp') { |
28 | $url['host'] = 'ssl://' . $url['host']; | |
b0d3d665 FB |
29 | if (!isset($url['port'])) { |
30 | $url['port'] = 563; | |
31 | } | |
32 | } else if (!isset($url['port'])) { | |
7027794f | 33 | $url['port'] = 119; |
34 | } | |
b4d2fbe0 | 35 | parent::__construct($url['host'], $url['port']); |
36 | if (isset($url['user'])) { | |
7027794f | 37 | $this->authinfo($url['user'], $url['pass']); |
b0d3d665 | 38 | } |
7027794f | 39 | } |
40 | ||
41 | /** Return the descript;ion of the current box | |
42 | */ | |
43 | public function getDescription() | |
44 | { | |
0e25d15d | 45 | $descs = $this->xgtitle(Banana::$group); |
46 | if (isset($descs[Banana::$group])) { | |
cd58d954 | 47 | return trim(utf8_encode($descs[Banana::$group])); |
7027794f | 48 | } |
cd58d954 | 49 | return null; |
7027794f | 50 | } |
51 | ||
52 | /** Return the list of the boxes | |
53 | * @param mode Kind of boxes to list | |
54 | * @param since date of last check (for new boxes and new messages) | |
55 | * @return Array(boxname => array(desc => boxdescripton, msgnum => number of message, unread =>number of unread messages) | |
56 | */ | |
57 | public function getBoxList($mode = Banana::BOXES_ALL, $since = 0, $withstats = false) | |
58 | { | |
59 | if (!is_array($this->boxes) || $this->mode != $mode) { | |
60 | $descs = $this->xgtitle(); | |
61 | if ($mode == Banana::BOXES_NEW && $since) { | |
62 | $list = $this->newgroups($since); | |
63 | } else { | |
64 | $list = $this->listGroups(); | |
65 | if ($mode == Banana::BOXES_SUB) { | |
a1023723 | 66 | if (is_array(Banana::$profile['subscribe'])) { |
67 | $sub = array_flip(Banana::$profile['subscribe']); | |
68 | } else { | |
69 | $sub = array(); | |
70 | } | |
7027794f | 71 | $list = array_intersect_key($list, $sub); |
72 | } | |
73 | } | |
74 | $this->boxes = array(); | |
75 | foreach ($list as $group=>&$infos) { | |
76 | if (isset($descs[$group])) { | |
77 | $desc = $descs[$group]; | |
78 | if (!is_utf8($desc)) { | |
79 | $desc = utf8_encode($desc); | |
80 | } | |
0fa5e39a | 81 | $this->boxes[$group] = array('desc' => $desc); |
7027794f | 82 | } else { |
83 | $this->boxes[$group] = array('desc' => null); | |
0fa5e39a | 84 | } |
7027794f | 85 | } |
86 | ksort($this->boxes); | |
87 | } | |
88 | if ($withstats) { | |
89 | foreach ($this->boxes as $group=>&$desc) { | |
90 | list($msgnum, $first, $last, $groupname) = $this->group($group); | |
91 | $this->ingroup = $group; | |
8da34e72 FB |
92 | $new = $this->newnews($group, $since); |
93 | if (!is_array($new)) { | |
94 | $new = 0; | |
95 | } else { | |
2b974d09 FB |
96 | $c = count($new); |
97 | if ($c > 0 && function_exists('hook_listReadMessages')) { | |
98 | $msgs = hook_listReadMessages($group); | |
99 | if (is_array($msgs)) { | |
100 | foreach ($msgs as $msg) { | |
101 | if (is_numeric($msg)) { | |
102 | $c--; | |
103 | } else if (in_array($msg, $new)) { | |
104 | $c--; | |
105 | } | |
106 | } | |
107 | } | |
108 | } | |
109 | $new = $c; | |
8da34e72 | 110 | } |
7027794f | 111 | $desc['msgnum'] = $msgnum; |
112 | $desc['unread'] = $new; | |
113 | } | |
114 | } | |
115 | return $this->boxes; | |
116 | } | |
117 | ||
118 | /** Return a message | |
119 | * @param id Id of the emssage (can be either an Message-id or a message index) | |
7027794f | 120 | * @return A BananaMessage or null if the given id can't be retreived |
121 | */ | |
7a5823f9 | 122 | public function &getMessage($id) |
7027794f | 123 | { |
f06f42dc | 124 | $message = null; |
7a5823f9 | 125 | if (is_numeric($id) && Banana::$group != $this->ingroup) { |
7027794f | 126 | if (is_null(Banana::$spool)) { |
0e25d15d | 127 | $this->group(Banana::$group); |
128 | $this->ingroup = Banana::$group; | |
7027794f | 129 | } else { |
130 | $id = array_search($id, Banana::$spool->ids); | |
131 | } | |
132 | } | |
133 | $data = $this->article($id); | |
134 | if ($data !== false) { | |
f06f42dc | 135 | $message = new BananaMessage($data); |
7027794f | 136 | } |
f06f42dc | 137 | return $message; |
7027794f | 138 | } |
139 | ||
7a5823f9 | 140 | /** Return the sources of the message |
141 | */ | |
142 | public function getMessageSource($id) | |
143 | { | |
144 | if (is_numeric($id) && Banana::$group != $this->ingroup) { | |
145 | if (is_null(Banana::$spool)) { | |
146 | $this->group(Banana::$group); | |
147 | $this->ingroup = Banana::$group; | |
148 | } else { | |
149 | $id = array_search($id, Banana::$spool->ids); | |
150 | } | |
151 | } | |
152 | $data = $this->article($id); | |
153 | if ($data !== false) { | |
154 | return implode("\n", $data); | |
155 | } | |
7d3f4749 | 156 | $data = null; |
157 | return $data; | |
7a5823f9 | 158 | } |
159 | ||
7027794f | 160 | /** Return the indexes of the messages presents in the Box |
161 | * @return Array(number of messages, MSGNUM of the first message, MSGNUM of the last message) | |
162 | */ | |
163 | public function getIndexes() | |
164 | { | |
0e25d15d | 165 | list($msgnum, $first, $last, $groupname) = $this->group(Banana::$group); |
166 | $this->ingroup = Banana::$group; | |
7027794f | 167 | return array($msgnum, $first, $last); |
168 | } | |
169 | ||
170 | /** Return the message headers (in BananaMessage) for messages from firstid to lastid | |
171 | * @return Array(id => array(headername => headervalue)) | |
172 | */ | |
173 | public function &getMessageHeaders($firstid, $lastid, array $msg_headers = array()) | |
174 | { | |
175 | $messages = array(); | |
176 | foreach ($msg_headers as $header) { | |
177 | $headers = $this->xhdr($header, $firstid, $lastid); | |
7027794f | 178 | $header = strtolower($header); |
179 | if ($header == 'date') { | |
180 | $headers = array_map('strtotime', $headers); | |
345c3a85 | 181 | } else { |
182 | array_walk($headers, array('BananaMimePart', 'decodeHeader')); | |
7027794f | 183 | } |
184 | foreach ($headers as $id=>&$value) { | |
185 | if (!isset($messages[$id])) { | |
186 | $messages[$id] = array(); | |
187 | } | |
188 | $messages[$id][$header] =& $value; | |
189 | } | |
190 | } | |
191 | return $messages; | |
192 | } | |
193 | ||
194 | /** Add protocole specific data in the spool | |
195 | */ | |
196 | public function updateSpool(array &$messages) | |
197 | { | |
198 | return true; | |
199 | } | |
200 | ||
201 | /** Return the indexes of the new messages since the give date | |
202 | * @return Array(MSGNUM of new messages) | |
203 | */ | |
204 | public function getNewIndexes($since) | |
205 | { | |
0e25d15d | 206 | return $this->newnews(Banana::$group, $since); |
7027794f | 207 | } |
208 | ||
209 | /** Return true if can post | |
210 | */ | |
211 | public function canSend() | |
212 | { | |
213 | return $this->isValid(); | |
214 | } | |
215 | ||
216 | /** Return true if can cancel | |
217 | */ | |
218 | public function canCancel() | |
219 | { | |
220 | return $this->isValid(); | |
221 | } | |
222 | ||
223 | /** Return the list of requested header for a new post | |
224 | */ | |
225 | public function requestedHeaders() | |
226 | { | |
227 | return Array('From', 'Subject', 'dest' => 'Newsgroups', 'reply' => 'Followup-To', 'Organization'); | |
228 | } | |
229 | ||
230 | /** Send the message | |
231 | */ | |
8a30c7d6 | 232 | public function send(BananaMessage $message) |
7027794f | 233 | { |
234 | $sources = $message->get(true); | |
235 | return $this->post($sources); | |
236 | } | |
237 | ||
238 | /** Cancel the message | |
239 | */ | |
8a30c7d6 | 240 | public function cancel(BananaMessage $message) |
7027794f | 241 | { |
242 | $headers = Array('From' => Banana::$profile['From'], | |
0e25d15d | 243 | 'Newsgroups' => Banana::$group, |
7027794f | 244 | 'Subject' => 'cmsg ' . $message->getHeaderValue('message-id'), |
245 | 'Control' => 'cancel ' . $message->getHeaderValue('message-id')); | |
e9360b11 | 246 | $headers = array_merge($headers, Banana::$msgedit_headers); |
7027794f | 247 | $body = 'Message canceled with Banana'; |
248 | $msg = BananaMessage::newMessage($headers, $body); | |
249 | return $this->send($msg); | |
250 | } | |
251 | ||
252 | /** Return the protocole name | |
253 | */ | |
254 | public function name() | |
255 | { | |
256 | return 'NNTP'; | |
257 | } | |
7027794f | 258 | |
e9360b11 | 259 | /** Return the filename for the spool |
260 | */ | |
261 | public function filename() | |
262 | { | |
263 | $url = parse_url(Banana::$nntp_host); | |
264 | $file = ''; | |
265 | if (isset($url['host'])) { | |
266 | $file .= $url['host'] . '_'; | |
267 | } | |
268 | if (isset($url['port'])) { | |
269 | $file .= $url['port'] . '_'; | |
270 | } | |
271 | $file .= Banana::$group; | |
272 | return $file; | |
273 | } | |
7027794f | 274 | } |
7027794f | 275 | |
a90b6fc9 | 276 | // vim:set et sw=4 sts=4 ts=4 fenc=utf-8: |
7027794f | 277 | ?> |