require_once dirname(__FILE__) . '/banana.inc.php';
-define('BANANA_SPOOL_VERSION', '0.5.1');
+define('BANANA_SPOOL_VERSION', '0.5.7');
/** Class spoolhead
* class used in thread overviews
public $subject;
/** author */
public $from;
+ public $name;
public $color;
/** reference of parent */
public $parent = null;
$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';
+ }
}
}
public $ids;
/** thread starts */
public $roots;
+ /** thread trees (one tree per root node) */
+ public $trees = array();
+
/** protocole specific data */
public $storage = array();
if (!is_array($this->overview)) {
$this->overview = array();
}
+ $updateTrees = array();
foreach ($messages as $id=>&$message) {
if (!isset($this->overview[$id])) {
$this->overview[$id] = new BananaSpoolHead($message);
$this->overview[$p] = new BananaSpoolHead($messages[$p]);
}
$this->overview[$p]->children[] = $id;
-
while (!is_null($p)) {
$this->overview[$p]->desc += $msg->desc;
+ $prev = $p;
if ($p != $this->overview[$p]->parent) {
$p = $this->overview[$p]->parent;
} else {
$p = null;
}
+ if (is_null($p)) {
+ $updateTrees[$prev] = true;
+ }
}
}
}
+ foreach ($updateTrees as $root=>$t) {
+ $this->trees[$root] = $this->buildTree($root, true);
+ }
Banana::$protocole->updateSpool($messages);
return true;
}
}
unset($overview);
unset($this->overview[$_id]);
+ unset($this->trees[$_id]);
$msgid = array_search($_id, $this->ids);
if ($msgid !== false) {
unset($this->ids[$msgid]);
}
}
- private function formatDate($stamp)
+ public function formatDate($stamp)
{
$today = intval(time() / (24*3600));
$dday = intval($stamp / (24*3600));
return strftime($format, $stamp);
}
+ public function formatSubject($id, $subject)
+ {
+ $subject = banana_html_entity_decode($subject);
+ $popup = $subject;
+ if (function_exists('hook_formatDisplayHeader')) {
+ list($subject, $link) = hook_formatDisplayHeader('subject', $subject, true);
+ } else {
+ $subject = banana_catchFormats(banana_entities(stripslashes($subject)));
+ $link = null;
+ }
+ if (empty($subject)) {
+ $subject = _b_('(pas de sujet)');
+ }
+ if ($id != Banana::$artid) {
+ $subject = Banana::$page->makeLink(Array('group' => $this->group, 'artid' => $id,
+ 'text' => $subject, 'popup' => $popup));
+ }
+ return $subject . $link;
+ }
+
+ public function formatFrom($from)
+ {
+ $from = banana_html_entity_decode($from);
+ return BananaMessage::formatFrom($from);
+ }
+
+ public function start()
+ {
+ if (Banana::$first) {
+ return Banana::$first;
+ } else {
+ $first = array_search(Banana::$artid, $this->roots);
+ return max(0, $first - Banana::$spool_tbefore);
+ }
+ }
+
+ public function context()
+ {
+ return Banana::$first ? Banana::$spool_tmax : Banana::$spool_tcontext;
+ }
+
/** displays children tree of a post
* @param $_id INTEGER MSGNUM of post
* @param $_index INTEGER linear number of post in the tree
}
$style = 'background-color:' . $head->color . '; text-decoration: none';
$prof = 1;
- $text = '<span style="' . $style . '" title="' . banana_entities($head->from) . '">' .
+ $text = '<span style="' . $style . '" title="' . banana_entities($head->name . ', ' . $this->formatDate($head->date)) . '">' .
'<input type="radio" name="banana_tree" '. ($id == $current ? 'checked="checked" ' : ' ' ) .
(Banana::$msgshow_javascript ? 'onchange="window.location=\'' .
- Banana::$page->makeURL(array('group' => $this->group, 'artid' => $id)) . '\'"' : ' disabled="disabled"')
+ banana_entities(Banana::$page->makeURL(array('group' => $this->group, 'artid' => $id))) . '\'"'
+ : ' disabled="disabled"')
.' />' .
'</span>';
$array = array($text);
$array[] = $t_e . ($msg->isread ? $r_l : $u_l) . $line;
}
}
+ unset($tree);
if ($tpr > $prof) {
$prof = $tpr + 1;
}
/** build the spool tree associated with the given message
*/
- public function buildTree($id) {
+ public function buildTree($id, $force = false) {
$pos = $id;
$overview =& $this->overview[$id];
while (!is_null($overview->parent)) {
$pos = $overview->parent;
$overview =& $this->overview[$pos];
}
- list($prof, $tree) = $this->_buildTree($pos, $overview, $id);
- return implode("\n", $tree);
+ if (!$force && isset($this->trees[$pos])) {
+ return $this->trees[$pos];
+ } else {
+ list(, $tree) = $this->_buildTree($pos, $overview, $force ? -1 : $id);
+ return '<div style="height:18px">' . implode("</div>\n<div style=\"height:18px\">", $tree) . '</div>';
+ }
}
/** computes linear post index
-<pre class="thread_tree">
-{$spool->buildTree($artid)|smarty:nodefaults}
-</pre>
-
<table class="bicol message">
<tr>
<th colspan="3" class="subject">
{if !$noactions}
<div class="menu">
- {if $spool->nextUnread($artid)}
- {imglink group=$group artid=$spool->nextUnread($artid) img=next_unread alt="Message non-lu suivant"|b accesskey=u}{/if}
- {if $spool->prevPost($artid)}
- {imglink group=$group artid=$spool->prevPost($artid) img=prev alt="Message précédent"|b accesskey=a}{/if}
- {if $spool->nextPost($artid)}
- {imglink group=$group artid=$spool->nextPost($artid) img=next alt="Message suivant"|b accesskey=z}{/if}
- {if $spool->prevThread($artid)}
- {imglink group=$group artid=$spool->prevThread($artid) img=prev_thread alt="Discussion précédente"|b accesskey=q}{/if}
- {if $spool->nextThread($artid)}
- {imglink group=$group artid=$spool->nextThread($artid) img=next_thread alt="Discussion suivante"|b accesskey=s}{/if}
+ {assign var=nextUnread value=$spool->nextUnread($artid)}
+ {assign var=prevPost value=$spool->prevPost($artid)}
+ {assign var=nextPost value=$spool->nextPost($artid)}
+ {assign var=prevThread value=$spool->prevThread($artid)}
+ {assign var=nextThread value=$spool->nextThread($artid)}
+ {if $nextUnread}{imglink group=$group artid=$nextUnread img=next_unread alt="Message non-lu suivant"|b accesskey=u}{/if}
+ {if $prevPost}{imglink group=$group artid=$prevPost img=prev alt="Message précédent"|b accesskey=a}{/if}
+ {if $nextPost}{imglink group=$group artid=$nextPost img=next alt="Message suivant"|b accesskey=z}{/if}
+ {if $prevThread}{imglink group=$group artid=$prevThread img=prev_thread alt="Discussion précédente"|b accesskey=q}{/if}
+ {if $nextThread}{imglink group=$group artid=$nextThread img=next_thread alt="Discussion suivante"|b accesskey=s}{/if}
</div>
<div class="action">
{if $message->canSend()}
{$body|banana_utf8entities|smarty:nodefaults}
</td>
</tr>
+ {if $spool && ($nextPost || $prevPost)}
+ <tr class="pair">
+ <th colspan="3">
+ <strong>{"Naviguer dans la discussion..."|b}</strong>
+ </th>
+ </tr>
+ <tr class="pair">
+ <td colspan="3" class="thread_tree">{$spool->buildTree($artid)|smarty:nodefaults}</td>
+ </tr>
+ {/if}
</table>
{* vim:set et sw=2 sts=2 ts=2 enc=utf-8: *}
{capture name=pages}
{if $withtitle}
<div class="pages">
-{if $spool->overview|@count gt $msgbypage}
-{section name=pages loop=$spool->overview step=$msgbypage}
+{if $spool->roots|@count gt $msgbypage}
+{section name=pages loop=$spool->roots step=$msgbypage}
{if $first ge $smarty.section.pages.index && $first lt $smarty.section.pages.index_next}
<strong>{$smarty.section.pages.iteration}</strong>
{else}
<tr>
{if $withtitle}
<th>
- {if $spool->nextUnread()}
+ {assign var=nextUnread value=$spool->nextUnread()}
+ {if $nextUnread}
<div class="menu">
- {imglink group=$group artid=$spool->nextUnread() img=next_unread alt="Message non-lu suivant"|b accesskey=u}
+ {imglink group=$group artid=$nextUnread img=next_unread alt="Message non-lu suivant"|b accesskey=u}
</div>
{/if}
{"Date"|b}
{"Auteur"|b}
</th>
{else}
- <th colspan="3">
- {"Aperçu de "|b}{link group=$group text=$group}
- </th>
+ <th colspan="3">{"En discussion sur "|b}{link group=$group text=$group}...</th>
{/if}
</tr>
- {if $spool->overview|@count}
- {if $artid}{$spool->toHtml($artid, true)|smarty:nodefaults}{else}{$spool->toHtml($first)|smarty:nodefaults}{/if}
+ {if $spool->roots|@count}
+ {section name=threads loop=$spool->roots step=1 start=$spool->start() max=$spool->context()}
+ {assign var=id value=$spool->roots[$smarty.section.threads.index]}
+ {assign var=overview value=$spool->overview[$id]}
+ {cycle assign=class values="impair,pair"}
+ <tr class="{$class} {if $overview->descunread}new{/if}">
+ <td class="date">{$spool->formatDate($overview->date)}</td>
+ <td class="subj">{$spool->formatSubject($id, $overview->subject)|smarty:nodefaults}</td>
+ <td class="from">{$spool->formatFrom($overview->from)|smarty:nodefaults}</td>
+ </tr>
+ {if !$artid && $spool->nextPost($id)}
+ <tr class="{$class}">
+ <td colspan="3" class="thread_tree">{$spool->buildTree($id)|smarty:nodefaults}</td>
+ </tr>
+ {/if}
+ {/section}
{else}
<tr>
<td colspan="3">