2 /********************************************************************************
3 * banana/protocoleinterface.inc.php : interface for box access
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__
) . '/banana.inc.php';
11 require_once dirname(__FILE__
) . '/protocoleinterface.inc.php';
12 require_once dirname(__FILE__
) . '/message.inc.php';
14 class BananaMBox
implements BananaProtocoleInterface
16 private $debug = false
;
18 private $_lasterrno = 0;
19 private $_lasterror = null
;
21 public function __construct()
23 $this->debug
= Banana
::$debug_mbox;
26 public function isValid()
29 //!Banana::$group || $this->file;
32 /** Indicate last error n°
34 public function lastErrNo()
36 return $this->_lasterrno
;;
39 /** Indicate last error text
41 public function lastError()
43 return $this->_lasterror
;
46 /** Return the description of the current box
48 public function getDescription()
53 /** Return the list of the boxes
54 * @param mode Kind of boxes to list
55 * @param since date of last check (for new boxes and new messages)
56 * @param withstats Indicated whether msgnum and unread must be set in the result
57 * @return Array(boxname => array(desc => boxdescripton, msgnum => number of message, unread =>number of unread messages)
59 public function getBoxList($mode = Banana
::BOXES_ALL
, $since = 0, $withstats = false
)
61 return array(Banana
::$group => array('desc' => '', 'msgnum' => 0, 'unread' => 0));
64 private function &getRawMessage($id)
67 if (!is_numeric($id)) {
68 if (!Banana
::$spool) {
71 $id = Banana
::$spool->ids
[$id];
73 $options = array ('-m ' . $id);
74 if (Banana
::$spool->overview
) {
75 if (Banana
::$spool->overview
[$id]) {
76 $options[] = '-p ' . $id . ':' . Banana
::$spool->overview
[$id]->storage
['offset'];
78 $key = max(array_keys(Banana
::$spool->overview
));
80 $options[] = '-p ' . $key . ':' . Banana
::$spool->overview
[$key]->storage
['offset'];
84 return $this->callHelper('-b', $options);
88 * @param id Id of the emssage (can be either an Message-id or a message index)
89 * @return A BananaMessage or null if the given id can't be retreived
91 public function &getMessage($id)
93 $messages =& $this->getRawMessage($id);
95 $messages = new BananaMessage($messages);
100 /** Return the sources of the given message
102 public function getMessageSource($id)
104 $message =& $this->getRawMessage($id);
106 $message = implode("\n", $message);
111 /** Compute the number of messages of the box
113 private function getCount()
116 if (Banana
::$spool->overview
) {
117 $key = max(array_keys(Banana
::$spool->overview
));
118 $options[] = '-p ' . $key . ':' . Banana
::$spool->overview
[$key]->storage
['offset'];
120 $val =& $this->callHelper('-c', $options);
124 return intval(trim($val[0]));
127 /** Return the indexes of the messages presents in the Box
128 * @return Array(number of messages, MSGNUM of the first message, MSGNUM of the last message)
130 public function getIndexes()
132 $count = $this->getCount();
133 return array($count, 0, $count - 1);
136 /** Return the message headers (in BananaMessage) for messages from firstid to lastid
137 * @return Array(id => array(headername => headervalue))
139 public function &getMessageHeaders($firstid, $lastid, array $msg_headers = array())
143 $options[] = "-m $firstid:$lastid";
144 if (Banana
::$spool->overview
) {
145 if (isset(Banana
::$spool->overview
[$firstid])) {
146 $options[] = '-p ' . $firstid . ':' . Banana
::$spool->overview
[$firstid]->storage
['offset'];
148 $key = max(array_keys(Banana
::$spool->overview
));
149 if ($key < $firstid) {
150 $options[] = '-p ' . $key . ':' . Banana
::$spool->overview
[$key]->storage
['offset'];
154 $lines =& $this->callHelper('-d', $options, $msg_headers);
160 $id = array_shift($lines);
164 $offset = array_shift($lines);
165 if ($offset === '') {
169 $headers[$id] = array('beginning' => intval($offset));
171 $hname = array_shift($lines);
175 $hval = array_shift($lines);
179 if ($hname == 'date') {
180 $headers[$id][$hname] = @strtotime
($hval);
182 $headers[$id][$hname] = $hval;
185 if (!isset($headers[$id]['date'])) {
188 print_r($headers[$id]);
191 array_walk_recursive($headers, array('BananaMimePart', 'decodeHeader'));
195 /** Add storage data in spool overview
197 public function updateSpool(array &$messages)
199 foreach ($messages as $id=>&$data) {
200 if (isset(Banana
::$spool->overview
[$id])) {
201 Banana
::$spool->overview
[$id]->storage
['offset'] = $data['beginning'];
206 /** Return the indexes of the new messages since the give date
207 * @return Array(MSGNUM of new messages)
209 public function getNewIndexes($since)
212 if (is_null($this->file
)) {
215 if (is_null($this->new_messages
)) {
218 return range($this->count
- $this->new_messages
, $this->count
- 1);
221 /** Return wether or not the protocole can be used to add new messages
223 public function canSend()
228 /** Return false because we can't cancel a mail
230 public function canCancel()
235 /** Return the list of requested headers
236 * @return Array('header1', 'header2', ...) with the key 'dest' for the destination header
237 * and 'reply' for the reply header, eg:
238 * * for a mail: Array('From', 'Subject', 'dest' => 'To', 'Cc', 'Bcc', 'reply' => 'Reply-To')
239 * * for a post: Array('From', 'Subject', 'dest' => 'Newsgroups', 'reply' => 'Followup-To')
241 public function requestedHeaders()
243 return Array('From', 'Subject', 'dest' => 'To', 'Cc', 'Bcc', 'reply' => 'Reply-To');
247 * @return true if it was successfull
249 public function send(BananaMessage
&$message)
251 $headers = $message->getHeaders();
252 $to = $headers['To'];
253 $subject = $headers['Subject'];
254 unset($headers['To']);
255 unset($headers['Subject']);
257 foreach ($headers as $key=>$value) {
258 if (!empty($value)) {
259 $hdrs .= "$key: $value\r\n";
262 $body = $message->get(false
);
263 return mail($to, $subject, $body, $hdrs);
267 * @return true if it was successfull
269 public function cancel(BananaMessage
&$message)
274 /** Return the protocole name
276 public function name()
281 /** Return the spool filename
283 public function filename()
285 @list
($mail, $domain) = explode('@', Banana
::$group);
287 if (isset($domain)) {
288 $file = $domain . '_';
290 return $file . $mail;
294 # Filesystem functions
297 protected function getFileName()
299 if (is_null(Banana
::$group)) {
302 @list
($mail, $domain) = explode('@', Banana
::$group);
303 return Banana
::$mbox_path . '/' . $mail;
310 private function &callHelper($action, array $options = array(), array $headers = array())
312 $action .= ' -f ' . $this->getFileName();
313 $cmd = Banana
::$mbox_helper . " $action " . implode(' ', $options) . ' ' . implode(' ', $headers);
315 echo $cmd . '<br />';
316 $start = microtime(true
);
318 exec($cmd, $out, $return);
320 echo ' Execution : ' . (microtime(true
) - $start) . 's<br />';
321 echo " Retour : $return<br />";
322 echo ' Sortie : ' . count($out) . ' ligne(s)<br />';
325 $this->_lasterrorno
= 1;
326 $this->_lasterrorcode
= "Helper failed";
333 // vim:set et sw=4 sts=4 ts=4 enc=utf-8: