Fixes deprecated features in PHP 5.3.x.
[banana.git] / banana / mbox.inc.php
index 52b9e7a..f48c877 100644 (file)
@@ -14,28 +14,29 @@ require_once dirname(__FILE__) . '/message.inc.php';
 class BananaMBox implements BananaProtocoleInterface
 {
     private $debug      = false;
-    
+    private $bt         = array();
+
     private $_lasterrno = 0;
     private $_lasterror = null;
-    
+
     public function __construct()
     {
         $this->debug = Banana::$debug_mbox;
     }
-    
+
     public function isValid()
     {
         return true;
         //!Banana::$group || $this->file;
     }
-    
+
     /** Indicate last error n°
      */
     public function lastErrNo()
     {
         return $this->_lasterrno;;
     }
-    
+
     /** Indicate last error text
      */
     public function lastError()
@@ -65,22 +66,13 @@ class BananaMBox implements BananaProtocoleInterface
     {
         $message = null;
         if (!is_numeric($id)) {
-            if (!Banana::$spool) { 
+            if (!Banana::$spool) {
                 return $message;
             }
-            $id = Banana::$spool->ids[$id];
+            $id = Banana::$spool->ids[$id]->id;
         }
         $options = array ('-m ' . $id);
-        if (Banana::$spool->overview) {
-            if (Banana::$spool->overview[$id]) {
-               $options[] = '-p ' . $id . ':' . Banana::$spool->overview[$id]->storage['offset'];
-            } else {
-                $key       = max(array_keys(Banana::$spool->overview));
-                if ($key < $id) {
-                    $options[] = '-p ' . $key . ':' . Banana::$spool->overview[$key]->storage['offset'];
-                }
-            }
-        }
+        $this->getMBoxPosition($options, $id);
         return $this->callHelper('-b', $options);
     }
 
@@ -93,30 +85,32 @@ class BananaMBox implements BananaProtocoleInterface
         $messages =& $this->getRawMessage($id);
         if ($messages) {
             $messages = new BananaMessage($messages);
+        } else {
+            $messages = null;
         }
-        return $messages;    
+        return $messages;
     }
 
     /** Return the sources of the given message
      */
     public function getMessageSource($id)
-    { 
+    {
         $message =& $this->getRawMessage($id);
         if ($message) {
-            $message = implode("\n", $message); 
+            $message = implode("\n", $message);
         }
         return $message;
-    }   
+    }
 
     /** Compute the number of messages of the box
      */
     private function getCount()
     {
         $options = array();
-        if (Banana::$spool->overview) {
-            $key       = max(array_keys(Banana::$spool->overview));
-            $options[] = '-p ' . $key . ':' . Banana::$spool->overview[$key]->storage['offset'];
+        if (@filesize($this->getFileName()) == @Banana::$spool->storage['size']) {
+            return max(array_keys(Banana::$spool->overview)) + 1;
         }
+        $this->getMBoxPosition($options);
         $val =& $this->callHelper('-c', $options);
         if (!$val) {
             return 0;
@@ -141,54 +135,39 @@ class BananaMBox implements BananaProtocoleInterface
         $headers = null;
         $options = array();
         $options[] = "-m $firstid:$lastid";
-        if (Banana::$spool->overview) {
-            if (isset(Banana::$spool->overview[$firstid])) {
-               $options[] = '-p ' . $firstid . ':' . Banana::$spool->overview[$firstid]->storage['offset'];
-            } else {
-                $key       = max(array_keys(Banana::$spool->overview));
-                if ($key < $firstid) {
-                    $options[] = '-p ' . $key . ':' . Banana::$spool->overview[$key]->storage['offset'];
-                }
-            }
-        }
+        $this->getMboxPosition($options, $firstid);
         $lines =& $this->callHelper('-d', $options, $msg_headers);
         if (!$lines) {
             return $headers;
         }
         $headers = array();
-        while ($lines) {
-            $id = array_shift($lines);
-            if ($id === '') {
-                continue;
-            }
-            $offset = array_shift($lines);
-            if ($offset === '') {
-                continue;
-            }
-            $id     = intval($id);
-            $headers[$id] = array('beginning' => intval($offset));
-            while (true) {
-                $hname = array_shift($lines);
-                if ($hname === '') {
-                    break;
-                }
-                $hval  = array_shift($lines);
-                if ($hval === '') {
-                    break;
-                }
-                if ($hname == 'date') {
-                    $headers[$id][$hname] = @strtotime($hval);
-                } else {
-                    $headers[$id][$hname] = $hval;
+        $in_message = false;
+        $get_pos    = true;
+        $hname      = null;
+        foreach ($lines as $key=>&$line) {
+            if (!$in_message) {
+                if (!empty($line)) {
+                    $id = intval($line);
+                    $in_message = true;
+                    $get_pos    = true;
                 }
+            } elseif ($get_pos) {
+                $headers[$id] = array('beginning' => intval($line));
+                $get_pos = false;
+            } elseif (empty($line) && empty($hname)) {
+                $in_message = false;
+            } elseif (empty($hname)) {
+                $hname = $line;
+            } elseif ($hname == 'date') {
+                $headers[$id][$hname] = @strtotime($line);
+                $hname = null;
+            } else {
+                BananaMimePart::decodeHeader($line, $hname);
+                $headers[$id][$hname] = $line;
+                $hname = null;
             }
-            if (!isset($headers[$id]['date'])) {
-                print_r($id);
-                print_r($offset);
-                print_r($headers[$id]);
-            }
+            unset($lines[$key]);
         }
-        array_walk_recursive($headers, array('BananaMimePart', 'decodeHeader'));
         return $headers;
     }
 
@@ -201,6 +180,7 @@ class BananaMBox implements BananaProtocoleInterface
                 Banana::$spool->overview[$id]->storage['offset'] = $data['beginning'];
             }
         }
+        Banana::$spool->storage['size'] = @filesize($this->getFileName());
     }
 
     /** Return the indexes of the new messages since the give date
@@ -213,7 +193,7 @@ class BananaMBox implements BananaProtocoleInterface
             return array();
         }
         if (is_null($this->new_messages)) {
-            $this->getCount(); 
+            $this->getCount();
         }
         return range($this->count - $this->new_messages, $this->count - 1);
     }
@@ -246,7 +226,7 @@ class BananaMBox implements BananaProtocoleInterface
     /** Send a message
      * @return true if it was successfull
      */
-    public function send(BananaMessage &$message)
+    public function send(BananaMessage $message)
     {
         $headers = $message->getHeaders();
         $to      = $headers['To'];
@@ -257,7 +237,7 @@ class BananaMBox implements BananaProtocoleInterface
         foreach ($headers as $key=>$value) {
             if (!empty($value)) {
                 $hdrs .= "$key: $value\r\n";
-            }    
+            }
         }
         $body = $message->get(false);
         return mail($to, $subject, $body, $hdrs);
@@ -266,7 +246,7 @@ class BananaMBox implements BananaProtocoleInterface
     /** Cancel a message
      * @return true if it was successfull
      */
-    public function cancel(BananaMessage &$message)
+    public function cancel(BananaMessage $message)
     {
         return false;
     }
@@ -290,6 +270,17 @@ class BananaMBox implements BananaProtocoleInterface
         return $file . $mail;
     }
 
+    /** Return the execution backtrace
+     */
+    public function backtrace()
+    {
+        if ($this->debug) {
+            return $this->bt;
+        } else {
+            return null;
+        }
+    }
+
 #######
 # Filesystem functions
 #######
@@ -307,19 +298,36 @@ class BananaMBox implements BananaProtocoleInterface
 # MBox parser
 #######
 
+    /** Add the '-p' optioin for callHelper
+     */
+    private function getMBoxPosition(array &$options, $id = null)
+    {
+        if (Banana::$spool && Banana::$spool->overview) {
+            if (!is_null($id) && isset(Banana::$spool->overview[$id])) {
+                $key = $id;
+            } else {
+                $key = max(array_keys(Banana::$spool->overview));
+                if (!is_null($id) && $key >= $id) {
+                    return;
+                }
+            }
+            if (isset(Banana::$spool->overview[$key]->storage['offset'])) {
+                $options[] = '-p ' . $key . ':' . Banana::$spool->overview[$key]->storage['offset'];
+            }
+        }
+    }
+
     private function &callHelper($action, array $options = array(), array $headers = array())
     {
         $action .= ' -f ' . $this->getFileName();
         $cmd = Banana::$mbox_helper . " $action " . implode(' ', $options) . ' ' . implode(' ', $headers);
         if ($this->debug) {
-            echo $cmd . '<br />';
             $start = microtime(true);
         }
         exec($cmd, $out, $return);
         if ($this->debug) {
-            echo '&nbsp;&nbsp;Execution : ' . (microtime(true) - $start) . 's<br />';
-            echo "&nbsp;&nbsp;Retour : $return<br />";
-            echo '&nbsp;&nbsp;Sortie : ' . count($out) . ' ligne(s)<br />';
+            $this->bt[] = array('action' => $cmd, 'time' => (microtime(true) - $start),
+                                'code' => $return, 'response' => count($out), 'error' => $return ? "Helper failed" : null);
         }
         if ($return != 0) {
             $this->_lasterrorno = 1;