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