Use explicit serialization (revert r291).
[banana.git] / banana / nntp.inc.php
CommitLineData
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
10require_once dirname(__FILE__) . '/banana.inc.php';
11require_once dirname(__FILE__) . '/message.inc.php';
12require_once dirname(__FILE__) . '/nntpcore.inc.php';
13require_once dirname(__FILE__) . '/protocoleinterface.inc.php';
14
15class 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?>