********************************************************************************/
require_once dirname(__FILE__) . '/banana.inc.php';
+require_once dirname(__FILE__) . '/tree.inc.php';
-define('BANANA_SPOOL_VERSION', '0.5.12');
+define('BANANA_SPOOL_VERSION', '0.5.14');
/** Class spoolhead
* class used in thread overviews
public $desc;
/** same as desc, but counts only unread posts */
public $descunread;
+ /** last time the number of children has been updated */
+ public $time = 0;
/** storage data */
public $storage = array();
*/
public function __construct($id, array &$message)
{
+ list($name, $from) = BananaMessage::extractMail($message['from']);
$this->id = $id;
$this->msgid = @$message['message-id'];
$this->date = $message['date'];
$this->subject = @$message['subject'];
$this->from = $message['from'];
- $this->color = sprintf('#%06x', abs(crc32($this->from) % 0xffffff));
+ $this->color = sprintf('#%06x', abs(crc32($from) % 0xffffff));
$this->desc = 1;
$this->isread = true;
$this->descunread = 0;
- if (preg_match("/^([^ ]+@[^ ]+) \((.*)\)$/", $this->from, $regs)) {
- $this->name = $regs[2];
- }
- if (preg_match("/^\"?([^<>\"]+)\"? +<(.+@.+)>$/", $this->from, $regs)) {
- $this->name = preg_replace("/^'(.*)'$/", '\1', $regs[1]);
- $this->name = stripslashes($this->name);
- }
- if ($this->name) {
- $this->name = preg_replace("/\\\(\(|\))/","\\1", $this->name);
- } else if (preg_match("/([^< ]+)@([^> ]+)/", $this->from, $regs)) {
- $this->name = $regs[1];
- } else {
- $this->name = 'Anonymous';
+ $this->name = $name;
+ if ($name === $from) {
+ $this->name = 'Anonymous';
}
}
}
public $ids = array();
/** thread starts */
public $roots = array();
- /** thread trees (one tree per root node) */
- public $trees = array();
/** protocole specific data */
public $storage = array();
$spool->markAllAsRead();
}
$spool->updateUnread($since);
- //var_dump($spool->trees);
return $spool;
}
- private static function spoolFilename($group)
+ public static function getPath($file = null)
{
- $file = Banana::$spool_root . '/' . Banana::$protocole->name() . '/';
- if (!is_dir($file)) {
- mkdir($file);
+ $path = Banana::$spool_root . '/' . Banana::$protocole->name() . '/' . Banana::$protocole->filename();
+ if (!is_dir($path)) {
+ if (file_exists($path)) {
+ @unlink($path);
+ }
+ mkdir($path, 0777, true);
}
- return $file . Banana::$protocole->filename();
+ return $path . '/' . $file;
+ }
+
+ private static function spoolFilename()
+ {
+ return BananaSpool::getPath('spool');
}
private static function &readFromFile($group)
{
$spool = null;
- $file = BananaSpool::spoolFilename($group);
+ $file = BananaSpool::spoolFilename();
if (!file_exists($file)) {
return $spool;
}
return $spool;
}
- private function compare(&$a, &$b)
+ private function compare($a, $b)
{
return ($b->date - $a->date);
}
private function saveToFile()
{
- $file = BananaSpool::spoolFilename($this->group);
+ $file = BananaSpool::spoolFilename();
$this->roots = Array();
foreach($this->overview as &$msg) {
array('Date', 'Subject', 'From', 'Message-ID', 'References', 'In-Reply-To'));
// Build all the new Spool Heads
+ $time = time();
foreach ($messages as $id=>&$message) {
if (!isset($this->overview[$id])) {
$this->overview[$id] = new BananaSpoolHead($id, $message);
$head =& $this->overview[$id];
$this->ids[$head->msgid] =& $head;
+ $head->time = $time;
}
}
// Build tree
- $updateTrees = array();
$null = null;
foreach ($messages as $id=>&$message) {
$msg =& $this->overview[$id];
$parent->children[] =& $msg;
while (!is_null($parent)) {
$parent->desc += $msg->desc;
+ $parent->time = $time;
$prev =& $parent;
if ($parent !== $parent->parent) {
$parent =& $parent->parent;
$parent =& $null;
}
}
- $updateTrees[$prev->id] = true;
}
}
- foreach ($updateTrees as $root=>$t) {
- $this->trees[$root] =& $this->buildTree($root);
- }
Banana::$protocole->updateSpool($messages);
return true;
}
}
}
$this->unreadnb += count($newpostsids);
+
+ if (function_exists('hook_listReadMessages')) {
+ $msgs = hook_listReadMessages($this->group);
+ if (!is_array($msgs)) {
+ return;
+ }
+ foreach ($msgs as $msg) {
+ if (!is_numeric($msg)) {
+ if (!isset($this->ids[$msg])) {
+ continue;
+ }
+ $msg = $this->ids[$msg]->id;
+ }
+ $this->markAsRead($msg);
+ }
+ }
}
public function setMode($mode)
return $references;
}
+ /** Get the tree associated to a given id
+ */
+ public function &getTree($id)
+ {
+ return BananaTree::build($id)->show();
+ }
+
/** Mark the given id as read
* @param id MSGNUM of post
*/
public function markAsRead($id)
{
- if (!$this->overview[$id]->isread) {
- $this->overview[$id]->isread = true;
+ $overview =& $this->overview[$id];
+ if (!$overview->isread) {
+ $overview->isread = true;
$this->unreadnb--;
- while (isset($id)) {
- $this->overview[$id]->descunread--;
- $id = $this->overview[$id]->parent;
+ while (!is_null($overview)) {
+ $overview->descunread--;
+ $overview =& $overview->parent;
}
}
}
}
}
unset($this->ids[$overview->msgid]);
- unset($this->trees[$_id]);
$overview = null;
}
// Remove from the message tree
if (!is_null($parent)) {
+ $time = time();
foreach ($parent->children as $key=>&$child) {
if ($child === $overview) {
unset($parent->children[$key]);
}
}
if (sizeof($overview->children)) {
- $parent->children = array_merge($parent->children, $overview->children);
foreach ($overview->children as &$child) {
+ $parent->children[] =& $child;
+ $child->time = $time;
$child->parent =& $parent;
}
}
while (!is_null($parent)) {
$parent->desc--;
+ $parent->time = $time;
$parent =& $parent->parent;
}
}
// Remove all refenrences and assign null to the object
unset($this->ids[$overview->msgid]);
unset($this->overview[$_id]);
- unset($this->trees[$_id]);
+ BananaTree::kill($_id);
foreach ($this->roots as $k=>&$root) {
if ($root === $overview) {
unset($this->roots[$k]);
}
}
- public function formatDate(BananaSpoolHead &$head)
+ public function formatDate(BananaSpoolHead $head)
{
$stamp = $head->date;
$today = intval(time() / (24*3600));
return strftime($format, $stamp);
}
- public function formatSubject(BananaSpoolHead &$head)
+ public function formatSubject(BananaSpoolHead $head)
{
$subject = $popup = $head->subject;
$popup = $subject;
if (empty($subject)) {
$subject = _b_('(pas de sujet)');
}
- if ($head->id != Banana::$artid) {
+ if (mb_strlen($subject) > 100) {
+ $subject = mb_substr($subject, 0, 99) . '…';
+ }
+ if ($head->id !== Banana::$artid) {
$subject = Banana::$page->makeLink(Array('group' => $this->group, 'artid' => $head->id,
'text' => $subject, 'popup' => $popup));
}
return $subject . $link;
}
- public function formatFrom(BananaSpoolHead &$head)
+ public function formatFrom(BananaSpoolHead $head)
{
return BananaMessage::formatFrom($head->from);
}
return Banana::$first ? Banana::$spool_tmax : Banana::$spool_tcontext;
}
-
- private function &_buildTree(BananaSpoolHead &$head) {
- static $t_e, $u_h, $u_ht, $u_vt, $u_l, $u_f, $r_h, $r_ht, $r_vt, $r_l, $r_f;
- if (!isset($spfx_f)) {
- $t_e = Banana::$page->makeImg(Array('img' => 'e', 'alt' => ' ', 'height' => 18, 'width' => 14));
- $u_h = Banana::$page->makeImg(Array('img' => 'h2', 'alt' => '-', 'height' => 18, 'width' => 14));
- $u_ht = Banana::$page->makeImg(Array('img' => 'T2', 'alt' => '+', 'height' => 18, 'width' => 14));
- $u_vt = Banana::$page->makeImg(Array('img' => 't2', 'alt' => '`', 'height' => 18, 'width' => 14));
- $u_l = Banana::$page->makeImg(Array('img' => 'l2', 'alt' => '|', 'height' => 18, 'width' => 14));
- $u_f = Banana::$page->makeImg(Array('img' => 'f2', 'alt' => 't', 'height' => 18, 'width' => 14));
- $r_h = Banana::$page->makeImg(Array('img' => 'h2r', 'alt' => '-', 'height' => 18, 'width' => 14));
- $r_ht = Banana::$page->makeImg(Array('img' => 'T2r', 'alt' => '+', 'height' => 18, 'width' => 14));
- $r_vt = Banana::$page->makeImg(Array('img' => 't2r', 'alt' => '`', 'height' => 18, 'width' => 14));
- $r_l = Banana::$page->makeImg(Array('img' => 'l2r', 'alt' => '|', 'height' => 18, 'width' => 14));
- $r_f = Banana::$page->makeImg(Array('img' => 'f2r', 'alt' => 't', 'height' => 18, 'width' => 14));
- }
- $style = 'background-color:' . $head->color . '; text-decoration: none';
- $text = '<span style="' . $style . '" title="' . banana_entities($head->name . ', ' . $this->formatDate($head))
- . '"><input type="radio" name="banana_tree" '
- . (Banana::$msgshow_javascript ? 'onchange="window.location=\'' .
- banana_entities(Banana::$page->makeURL(array('group' => $this->group, 'artid' => $head->id))) . '\'"'
- : ' disabled="disabled"')
- . ' /></span>';
- $array = array($text);
- foreach ($head->children as $key=>&$msg) {
- $tree =& $this->_buildTree($msg);
- $last = $key == count($head->children) - 1;
- foreach ($tree as $kt=>&$line) {
- if ($kt === 0 && $key === 0 && !$last) {
- $array[0] .= ($msg->isread ? $r_ht : $u_ht) . $line;
- } else if($kt === 0 && $key === 0) {
- $array[0] .= ($msg->isread ? $r_h : $u_h) . $line;
- } else if ($kt === 0 && $last) {
- $array[] = $t_e . ($msg->isread ? $r_vt : $u_vt) . $line;
- } else if ($kt === 0) {
- $array[] = $t_e . ($msg->isread ? $r_f : $u_f) . $line;
- } else if ($last) {
- $array[] = $t_e . $t_e . $line;
- } else {
- $array[] = $t_e . ($msg->isread ? $r_l : $u_l) . $line;
- }
- }
- unset($tree);
- }
- return $array;
- }
-
- /** build the spool tree associated with the given message
- */
- public function &buildTree($id, $force = false) {
- $root =& $this->root($id);
- $id = $root->id;
- if (!$force && isset($this->trees[$id])) {
- return $this->trees[$id];
- } else {
- $tree =& $this->_buildTree($root);
- $tree = '<div class="tree"><div style="height:18px">'
- . implode("</div>\n<div style=\"height:18px\">", $tree)
- . '</div></div>';
- return $tree;
- }
- }
-
- /** computes linear post index
- * @param $_id INTEGER MSGNUM of post
- * @return INTEGER linear index of post
- */
- public function getNdX($_id)
- {
- $ndx = 1;
- $id_cur = $_id;
- while (true) {
- $id_parent = $this->overview[$id_cur]->parent;
- if (is_null($id_parent)) break;
- $pos = array_search($id_cur, $this->overview[$id_parent]->children);
-
- for ($i = 0; $i < $pos ; $i++) {
- $ndx += $this->overview[$this->overview[$id_parent]->children[$i]]->desc;
- }
- $ndx++; //noeud père
-
- $id_cur = $id_parent;
- }
-
- foreach ($this->roots as $i) {
- if ($i==$id_cur) {
- break;
- }
- $ndx += $this->overview[$i]->desc;
- }
- return $ndx;
- }
-
/** Return root message of the given thread
* @param id INTEGER id of a message
*/
/** Look for an unread message in the thread rooted by the message
* @param id INTEGER message number
*/
- private function _nextUnread(BananaSpoolHead &$cur)
+ private function _nextUnread(BananaSpoolHead $cur)
{
if (!$cur->isread) {
return $cur->id;
return null;
}
}
-
// vim:set et sw=4 sts=4 ts=4 enc=utf-8:
?>