* Copyright: See COPYING files that comes with this distribution
********************************************************************************/
-if(!function_exists('file_put_contents')) {
- function file_put_contents($filename, $data)
- {
- $fp = fopen($filename, 'w');
- if(!$fp) {
- trigger_error('file_put_contents cannot write in file '.$filename, E_USER_ERROR);
- return;
- }
- fputs($fp, $data);
- fclose($fp);
- }
-}
+require_once dirname(__FILE__) . '/banana.inc.php';
-function spoolCompare($a,$b) { return ($b->date>=$a->date); }
+define('BANANA_SPOOL_VERSION', '0.3');
/** Class spoolhead
* class used in thread overviews
class BananaSpoolHead
{
/** date (timestamp) */
- var $date;
+ public $date;
/** subject */
- var $subject;
+ public $subject;
/** author */
- var $from;
+ public $from;
/** reference of parent */
- var $parent;
+ public $parent = null;
/** paren is direct */
- var $parent_direct;
+ public $parent_direct;
/** array of children */
- var $children = Array();
+ public $children = Array();
/** true if post is read */
- var $isread;
+ public $isread;
/** number of posts deeper in this branch of tree */
- var $desc;
+ public $desc;
/** same as desc, but counts only unread posts */
- var $descunread;
+ public $descunread;
+
+ /** storage data */
+ public $storage = array();
/** constructor
* @param $_date INTEGER timestamp of post
* @param $_read BOOLEAN true if read
* @param $_descunread INTEGER descunread value (0 for a new post)
*/
-
- function BananaSpoolHead($_date, $_subject, $_from, $_desc=1, $_read=true, $_descunread=0)
+ public function __construct(array &$message)
{
- $this->date = $_date;
- $this->subject = $_subject;
- $this->from = $_from;
- $this->desc = $_desc;
- $this->isread = $_read;
- $this->descunread = $_descunread;
+ $this->date = $message['date'];
+ $this->subject = $message['subject'];
+ $this->from = $message['from'];
+ $this->desc = 1;
+ $this->isread = true;
+ $this->descunread = 0;
}
}
-/** Class spool
- * builds and updates spool
- */
-
-define("BANANA_SPOOL_VERSION", '0.2');
class BananaSpool
{
- var $version;
- /** spool */
- var $overview;
+ private $version;
+ private $mode;
+
/** group name */
- var $group;
+ public $group;
+ /** spool */
+ public $overview;
/** array msgid => msgnum */
- var $ids;
+ public $ids;
/** thread starts */
- var $roots;
- /** test validity */
- var $valid = true;
+ public $roots;
+
/** constructor
* @param $_group STRING group name
* @param $_display INTEGER 1 => all posts, 2 => only threads with new posts
* @param $_since INTEGER time stamp (used for read/unread)
*/
- function BananaSpool($_group, $_display=0, $_since="")
+ protected function __construct($group)
{
- global $banana;
- $this->group = $_group;
- $groupinfo = $banana->nntp->group($_group);
- if (!$groupinfo) {
- $this->valid = false;
- return null;
- }
-
- $this->_readFromFile();
-
- $do_save = false;
- $first = $banana->maxspool ? max($groupinfo[2] - $banana->maxspool, $groupinfo[1]) : $groupinfo[1];
- $last = $groupinfo[2];
+ $this->version = BANANA_SPOOL_VERSION;
+ $this->mode = Banana::SPOOL_ALL;
+ $this->group = $group;
+ }
- if ($this->version == BANANA_SPOOL_VERSION && is_array($this->overview)) {
- $mids = array_keys($this->overview);
- foreach ($mids as $id) {
- if (($first <= $last && ($id < $first || $id > $last))
- || ($first > $last && $id < $first && $id > $last))
- {
- $this->delid($id, false);
- $do_save = true;
- }
- }
- if (!empty($this->overview)) {
- $first = max(array_keys($this->overview))+1;
- }
+ public static function getSpool($group, $since = 0, $clean = false)
+ {
+ if (!is_null(Banana::$spool) && Banana::$spool->group == $group) {
+ $spool =& Banana::$spool;
} else {
- unset($this->overview, $this->ids);
- $this->version = BANANA_SPOOL_VERSION;
+ $spool = BananaSpool::readFromFile($group);
+ }
+ if (is_null($spool)) {
+ $spool = new BananaSpool($group);
}
-
- if ($first<=$last && $groupinfo[0]) {
- $do_save = true;
- $this->_updateSpool("$first-$last");
+ Banana::$spool =& $spool;
+ $spool->build();
+ if ($clean) {
+ $spool->markAllAsRead();
}
+ $spool->updateUnread($since);
+ return $spool;
+ }
- if ($do_save) { $this->_saveToFile(); }
-
- $this->_updateUnread($_since, $_display);
+ private static function spoolFilename($group)
+ {
+ $file = dirname(dirname(__FILE__));
+ $file .= '/spool/' . Banana::$protocole->name() . '/';
+ if (!is_dir($file)) {
+ mkdir($file);
+ }
+ return $file . Banana::$protocole->filename();
}
- function _readFromFile()
+ private static function readFromFile($group)
{
- $file = $this->_spoolfile();
- if (file_exists($file)) {
- $temp = unserialize(file_get_contents($file));
- foreach (get_object_vars($temp) as $key=>$val) {
- $this->$key = $val;
- }
+ $file = BananaSpool::spoolFilename($group);
+ if (!file_exists($file)) {
+ return null;
}
+ $spool = unserialize(file_get_contents($file));
+ if ($spool->version != BANANA_SPOOL_VERSION || $spool->mode != Banana::SPOOL_ALL) {
+ return null;
+ }
+ return $spool;
}
- function _saveToFile()
+ private function compare($a, $b)
{
- $file = $this->_spoolfile();
- uasort($this->overview, "spoolcompare");
+ return ($b->date >= $a->date);
+ }
+
+ private function saveToFile()
+ {
+ $file = BananaSpool::spoolFilename($this->group);
+ uasort($this->overview, array($this, 'compare'));
$this->roots = Array();
foreach($this->overview as $id=>$msg) {
}
}
- file_put_contents($file, serialize($this));
+ if ($this->mode == Banana::SPOOL_ALL) {
+ file_put_contents($file, serialize($this));
+ }
}
- function _spoolfile()
+ private function build()
{
- global $banana;
- $url = parse_url($banana->host);
- $file = $url['host'].'_'.$url['port'].'_'.$this->group;
- return dirname(dirname(__FILE__)).'/spool/'.$file;
+ $threshold = 0;
+
+ // Compute the range of indexes
+ list($msgnum, $first, $last) = Banana::$protocole->getIndexes();
+ if ($last < $first) {
+ $threshold = $firt + $msgnum - $last;
+ $threshold = (int)(log($threshold)/log(2));
+ $threshold = (2 ^ ($threshold + 1)) - 1;
+ }
+ if (Banana::$spool_max && Banana::$spool_max < $msgnum) {
+ $first = $last - Banana::$spool_max;
+ if ($first < 0) {
+ $first += $threshold;
+ }
+ }
+ $clean = $this->clean($first, $last, $msgnum);
+ $update = $this->update($first, $last, $msgnum);
+
+ if ($clean || $update) {
+ $this->saveToFile();
+ }
+ }
+
+ private function clean(&$first, &$last, $msgnum)
+ {
+ $do_save = false;
+ if (is_array($this->overview)) {
+ $mids = array_keys($this->overview);
+ foreach ($mids as $id) {
+ if (($first <= $last && ($id < $first || $id > $last))
+ || ($first > $last && $id < $first && $id > $last)) {
+ $this->delid($id, false);
+ $do_save = true;
+ }
+ }
+ if (!empty($this->overview)) {
+ $first = max(array_keys($this->overview))+1;
+ }
+ }
+ return $do_save;
}
- function _updateSpool($arg)
+ private function update(&$first, &$last, $msgnum)
{
- global $banana;
- $dates = array_map('strtotime', $banana->nntp->xhdr('Date', $arg));
- $subjects = array_map('headerdecode', $banana->nntp->xhdr('Subject', $arg));
- $froms = array_map('headerdecode', $banana->nntp->xhdr('From', $arg));
- $msgids = $banana->nntp->xhdr('Message-ID', $arg);
- $refs = $banana->nntp->xhdr('References', $arg);
-
- if (is_array(@$this->ids)) {
- $this->ids = array_merge($this->ids, array_flip($msgids));
- } else {
- $this->ids = array_flip($msgids);
+ if ($first > $last || !$msgnum) {
+ return false;
}
- foreach ($msgids as $id=>$msgid) {
- $msg = new BananaSpoolHead($dates[$id], $subjects[$id], $froms[$id]);
- $refs[$id] = str_replace('><', '> <', @$refs[$id]);
- $msgrefs = preg_split("/[ \t]/", strtr($refs[$id], $this->ids));
- $parents = preg_grep('/^\d+$/', $msgrefs);
- $msg->parent = array_pop($parents);
- $msg->parent_direct = preg_match('/^\d+$/', array_pop($msgrefs));
+ $messages =& Banana::$protocole->getMessageHeaders($first, $last,
+ array('Date', 'Subject', 'From', 'Message-ID', 'References', 'In-Reply-To'));
+
+ if (!is_array($this->ids)) {
+ $this->ids = array();
+ }
+ foreach ($messages as $id=>&$message) {
+ $this->ids[$message['message-id']] = $id;
+ }
- if (isset($this->overview[$id])) {
- $msg->desc = $this->overview[$id]->desc;
- $msg->children = $this->overview[$id]->children;
+ foreach ($messages as $id=>&$message) {
+ if (!isset($this->overview[$id])) {
+ $this->overview[$id] = new BananaSpoolHead($message);
}
- $this->overview[$id] = $msg;
+ $msg =& $this->overview[$id];
+ $msgrefs = BananaMessage::formatReferences($message);
+ $parents = preg_grep('/^\d+$/', $msgrefs);
+ $msg->parent = array_pop($parents);
+ $msg->parent_direct = preg_match('/^\d+$/', array_pop($msgrefs));
- if ($p = $msg->parent) {
+ if (!is_null($p = $msg->parent)) {
if (empty($this->overview[$p])) {
- $this->overview[$p] = new BananaSpoolHead($dates[$p], $subjects[$p], $froms[$p], 1);
+ $this->overview[$p] = new BananaSpoolHead($messages[$p]);
}
$this->overview[$p]->children[] = $id;
- while ($p) {
+ while (!is_null($p)) {
$this->overview[$p]->desc += $msg->desc;
- $p = $this->overview[$p]->parent;
+ if ($p != $this->overview[$p]->parent) {
+ $p = $this->overview[$p]->parent;
+ } else {
+ $p = null;
+ }
}
}
}
+ Banana::$protocole->updateSpool($messages);
+ return true;
}
- function _updateUnread($since, $mode)
+ private function updateUnread($since)
{
- global $banana;
- if (empty($since)) { return; }
-
- if (is_array($newpostsids = $banana->nntp->newnews($since, $this->group))) {
- if (!is_array($this->ids)) { $this->ids = array(); }
- $newpostsids = array_intersect($newpostsids, array_keys($this->ids));
- foreach ($newpostsids as $mid) {
- $this->overview[$this->ids[$mid]]->isread = false;
- $this->overview[$this->ids[$mid]]->descunread = 1;
- $parentmid = $this->ids[$mid];
- while (isset($parentmid)) {
- $this->overview[$parentmid]->descunread ++;
- $parentmid = $this->overview[$parentmid]->parent;
+ if (empty($since)) {
+ return;
+ }
+
+ $newpostsids = Banana::$protocole->getNewIndexes($since);
+
+ if (empty($newpostsids)) {
+ return;
+ }
+
+ if (!is_array($this->ids)) {
+ $this->ids = array();
+ }
+ $newpostsids = array_intersect($newpostsids, array_keys($this->ids));
+ foreach ($newpostsids as $mid) {
+ $id = $this->ids[$mid];
+ if ($this->overview[$id]->isread) {
+ $this->overview[$id]->isread = false;
+ while (isset($id)) {
+ $this->overview[$id]->descunread ++;
+ $id = $this->overview[$id]->parent;
}
}
+ }
+ }
- if (count($newpostsids)) {
- switch ($mode) {
- case 1:
- foreach ($this->roots as $k=>$i) {
- if ($this->overview[$i]->descunread==0) {
- $this->killdesc($i);
- unset($this->roots[$k]);
- }
- }
- break;
+ public function setMode($mode)
+ {
+ $this->mode = $mode;
+ switch ($mode) {
+ case Banana::SPOOL_UNREAD:
+ foreach ($this->roots as $k=>$i) {
+ if ($this->overview[$i]->descunread == 0) {
+ $this->killdesc($i);
+ unset($this->roots[$k]);
}
}
+ break;
+ }
+ }
+
+ /** 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;
+ while (isset($id)) {
+ $this->overview[$id]->descunread--;
+ $id = $this->overview[$id]->parent;
+ }
+ }
+ }
+
+ /** Mark all unread messages as read
+ */
+ public function markAllAsRead(array &$array = null)
+ {
+ if (is_null($array)) {
+ $array =& $this->roots;
+ }
+ foreach ($array as $id) {
+ if (!$this->overview[$id]->isread) {
+ $this->markAsRead($id);
+ }
+ if ($this->overview[$id]->descunread) {
+ $this->markAllAsRead($this->overview[$id]->children);
+ }
}
}
/** kill post and childrens
* @param $_id MSGNUM of post
*/
-
- function killdesc($_id)
+ private function killdesc($_id)
{
if (sizeof($this->overview[$_id]->children)) {
foreach ($this->overview[$_id]->children as $c) {
/** delete a post from overview
* @param $_id MSGNUM of post
*/
-
- function delid($_id, $write=true)
+ public function delid($_id, $write = true)
{
if (isset($this->overview[$_id])) {
if (sizeof($this->overview[$_id]->parent)) {
unset($this->ids[$msgid]);
}
- if ($write) { $this->_saveToFile(); }
+ if ($write) {
+ $this->saveToFile();
+ }
}
}
+ private function formatDate($stamp)
+ {
+ $today = intval(time() / (24*3600));
+ $dday = intval($stamp / (24*3600));
+
+ if ($today == $dday) {
+ $format = "%H:%M";
+ } elseif ($today == 1 + $dday) {
+ $format = _b_('hier')." %H:%M";
+ } elseif ($today < 7 + $dday) {
+ $format = '%a %H:%M';
+ } else {
+ $format = '%a %e %b';
+ }
+ return utf8_encode(strftime($format, $stamp));
+ }
+
/** displays children tree of a post
* @param $_id INTEGER MSGNUM of post
* @param $_index INTEGER linear number of post in the tree
* @param $_pfx_end STRING prefix used for children of current node
* @param $_head BOOLEAN true if first post in thread
*
- * If you want to analyse subject, you can define the function hook_getSubject(&$subject) which
- * take the subject as a reference parameter, transform this subject to be displaid in the spool
- * view and return a string. This string will be put after the subject.
+ * If you want to analyse subject, you can define the function hook_formatDisplayHeader
*/
-
- function _to_html($_id, $_index, $_first=0, $_last=0, $_ref="", $_pfx_node="", $_pfx_end="", $_head=true)
+ private function _to_html($_id, $_index, $_first=0, $_last=0, $_ref="", $_pfx_node="", $_pfx_end="", $_head=true)
{
- $spfx_f = makeImg('k1.gif', 'o', 21, 9);
- $spfx_n = makeImg('k2.gif', '*', 21, 9);
- $spfx_Tnd = makeImg('T-direct.gif', '+', 21, 12);
- $spfx_Lnd = makeImg('L-direct.gif', '`', 21, 12);
- $spfx_snd = makeImg('s-direct.gif', '-', 21, 5);
- $spfx_T = makeImg('T.gif', '+', 21, 12);
- $spfx_L = makeImg('L.gif', '`', 21, 12);
- $spfx_s = makeImg('s.gif', '-', 21, 5);
- $spfx_e = makeImg('e.gif', ' ', 21, 12);
- $spfx_I = makeImg('I.gif', '|', 21, 12);
-
- if ($_index + $this->overview[$_id]->desc < $_first || $_index > $_last) {
- return;
+ static $spfx_f, $spfx_n, $spfx_Tnd, $spfx_Lnd, $spfx_snd, $spfx_T, $spfx_L, $spfx_s, $spfx_e, $spfx_I;
+ if (!isset($spfx_f)) {
+ $spfx_f = Banana::$page->makeImg(Array('img' => 'k1', 'alt' => 'o', 'height' => 21, 'width' => 9));
+ $spfx_n = Banana::$page->makeImg(Array('img' => 'k2', 'alt' => '*', 'height' => 21, 'width' => 9));
+ $spfx_Tnd = Banana::$page->makeImg(Array('img' => 'T-direct', 'alt' => '+', 'height' => 21, 'width' => 12));
+ $spfx_Lnd = Banana::$page->makeImg(Array('img' => 'L-direct', 'alt' => '`', 'height' => 21, 'width' => 12));
+ $spfx_snd = Banana::$page->makeImg(Array('img' => 's-direct', 'alt' => '-', 'height' => 21, 'width' => 5));
+ $spfx_T = Banana::$page->makeImg(Array('img' => 'T', 'alt' => '+', 'height' => 21, 'width' => 12));
+ $spfx_L = Banana::$page->makeImg(Array('img' => 'L', 'alt' => '`', 'height' => 21, 'width' => 12));
+ $spfx_s = Banana::$page->makeImg(Array('img' => 's', 'alt' => '-', 'height' => 21, 'width' => 5));
+ $spfx_e = Banana::$page->makeImg(Array('img' => 'e', 'alt' => ' ', 'height' => 21, 'width' => 12));
+ $spfx_I = Banana::$page->makeImg(Array('img' => 'I', 'alt' => '|', 'height' => 21, 'width' => 12));
}
- $res = '';
-
- if ($_index>=$_first) {
- $hc = empty($this->overview[$_id]->children);
+ $overview =& $this->overview[$_id];
+ if ($_index + $overview->desc < $_first || $_index > $_last) {
+ return '';
+ }
- $res .= '<tr class="'.($_index%2?'pair':'impair').($this->overview[$_id]->isread?'':' new')."\">\n";
- $res .= "<td class='date'>".fancyDate($this->overview[$_id]->date)." </td>\n";
- $res .= "<td class='subj'>"
- ."<div class='tree'>$_pfx_node".($hc?($_head?$spfx_f:($this->overview[$_id]->parent_direct?$spfx_s:$spfx_snd)):$spfx_n)
- ."</div>";
- $subject = $this->overview[$_id]->subject;
- if (strlen($subject) == 0) {
- $subject = _b_('(pas de sujet)');
+ $res = '';
+ if ($_index >= $_first) {
+ $hc = empty($overview->children);
+
+ $res .= '<tr class="' . ($_index%2 ? 'pair' : 'impair') . ($overview->isread ? '' : ' new') . "\">\n";
+ $res .= '<td class="date">' . $this->formatDate($overview->date) . " </td>\n";
+ $res .= '<td class="subj' . ($_index == $_ref ? ' cur' : '') . '">'
+ . $_pfx_node .($hc ? ($_head ? $spfx_f : ($overview->parent_direct ? $spfx_s : $spfx_snd)) : $spfx_n);
+ $subject = $overview->subject;
+ if (function_exists('hook_formatDisplayHeader')) {
+ list($subject, $link) = hook_formatDisplayHeader('subject', $subject, true);
+ } else {
+ $subject = banana_catchFormats(stripslashes($subject));
+ $link = null;
}
- $link = null;
- if (function_exists('hook_getSubject')) {
- $link = hook_getSubject($subject);
+ if (empty($subject)) {
+ $subject = _b_('(pas de sujet)');
}
- $subject = formatPlainText(htmlentities($subject));
- if ($_index == $_ref) {
- $res .= '<span class="cur">' . $subject . $link . '</span>';
- } else {
- $res .= makeHREF(Array('group' => $this->group,
- 'artid' => $_id),
- $subject,
- $subject)
- . $link;
+ if ($_index != $_ref) {
+ $subject = Banana::$page->makeLink(Array('group' => $this->group, 'artid' => $_id,
+ 'text' => $subject, 'popup' => $subject));
}
- $res .= "</td>\n<td class='from'>".formatFrom($this->overview[$_id]->from)."</td>\n</tr>";
+ $res .= ' ' . $subject . $link;
+ $res .= "</td>\n<td class='from'>" . BananaMessage::formatFrom($overview->from) . "</td>\n</tr>";
- if ($hc) { return $res; }
+ if ($hc) {
+ return $res;
+ }
}
$_index ++;
-
- $children = $this->overview[$_id]->children;
+ $children = $overview->children;
while ($child = array_shift($children)) {
- if ($_index > $_last) { return $res; }
- if ($_index+$this->overview[$child]->desc >= $_first) {
+ $overview =& $this->overview[$child];
+ if ($_index > $_last) {
+ return $res;
+ }
+ if ($_index + $overview->desc >= $_first) {
if (sizeof($children)) {
$res .= $this->_to_html($child, $_index, $_first, $_last, $_ref,
- $_pfx_end.($this->overview[$child]->parent_direct?$spfx_T:$spfx_Tnd),
- $_pfx_end.$spfx_I, false);
+ $_pfx_end . ($overview->parent_direct ? $spfx_T : $spfx_Tnd),
+ $_pfx_end . $spfx_I, false);
} else {
$res .= $this->_to_html($child, $_index, $_first, $_last, $_ref,
- $_pfx_end.($this->overview[$child]->parent_direct?$spfx_L:$spfx_Lnd),
- $_pfx_end.$spfx_e, false);
+ $_pfx_end . ($overview->parent_direct ? $spfx_L : $spfx_Lnd),
+ $_pfx_end . $spfx_e, false);
}
}
- $_index += $this->overview[$child]->desc;
+ $_index += $overview->desc;
}
return $res;
* @param $_last INTEGER MSGNUM of last post
* @param $_ref STRING MSGNUM of current/selectionned post
*/
-
- function to_html($_first=0, $_last=0, $_ref = null)
+ public function toHtml($first = 0, $overview = false)
{
- $res = '<table class="bicol banana_thread" cellpadding="0" cellspacing="0">';
-
- $new = '<div class="banana_action">'
- . makeImgLink(Array('group' => $this->group,
- 'action' => 'new'),
- 'post.gif',
- _b_('Nouveau message'));
- $new .= '</div>';
-
- if (is_null($_ref)) {
- $res .= '<tr><th>' . _b_('Date') . '</th>';
- $res .= '<th>' . $new . _b_('Sujet') . '</th>';
- $res .= '<th>' . _b_('Auteur') . '</th></tr>';
+ $res = '';
+
+ if (!$overview) {
+ $_first = $first;
+ $_last = $first + Banana::$spool_tmax - 1;
+ $_ref = null;
} else {
- $res .= '<tr><th colspan="3">' . _b_('Aperçu de ')
- . makeHREF(Array('group' => $this->group),
- $this->group)
- . '</th></tr>';
+ $_ref = $this->getNdx($first);
+ $_last = $_ref + Banana::$spool_tafter;
+ $_first = $_ref - Banana::$spool_tbefore;
+ if ($_first < 0) {
+ $_last -= $_first;
+ }
}
-
$index = 1;
- if (sizeof($this->overview)) {
- foreach ($this->roots as $id) {
- $res .= $this->_to_html($id, $index, $_first, $_last, $_ref);
- $index += $this->overview[$id]->desc ;
- if ($index > $_last) { break; }
+ foreach ($this->roots as $id) {
+ $res .= $this->_to_html($id, $index, $_first, $_last, $_ref);
+ $index += $this->overview[$id]->desc ;
+ if ($index > $_last) {
+ break;
}
- } else {
- $res .= '<tr><td colspan="3">'._b_('Aucun message dans ce forum').'</td></tr>';
- }
-
- global $banana;
- if (is_object($banana->groups)) {
- $res .= '<tr><td colspan="3" class="subs">'
- . $banana->groups->to_html()
- . '</td></tr>';
}
- return $res .= '</table>';
+ return $res;
}
/** computes linear post index
* @param $_id INTEGER MSGNUM of post
* @return INTEGER linear index of post
*/
-
- function getndx($_id)
+ public function getNdX($_id)
{
$ndx = 1;
$id_cur = $_id;
for ($i = 0; $i < $pos ; $i++) {
$ndx += $this->overview[$this->overview[$id_parent]->children[$i]]->desc;
}
- $ndx++; //noeud père
+ $ndx++; //noeud père
$id_cur = $id_parent;
}
/** Return root message of the given thread
* @param id INTEGER id of a message
*/
- function root($id)
- {
+ public function root($id)
+ {
$id_cur = $id;
while (true) {
$id_parent = $this->overview[$id_cur]->parent;
/** Returns previous thread root index
* @param id INTEGER message number
*/
- function prevThread($id)
+ public function prevThread($id)
{
$root = $this->root($id);
$last = null;
/** Returns next thread root index
* @param id INTEGER message number
*/
- function nextThread($id)
+ public function nextThread($id)
{
$root = $this->root($id);
$ok = false;
/** Return prev post in the thread
* @param id INTEGER message number
*/
- function prevPost($id)
+ public function prevPost($id)
{
$parent = $this->overview[$id]->parent;
if (is_null($parent)) {
/** Return next post in the thread
* @param id INTEGER message number
*/
- function nextPost($id)
+ public function nextPost($id)
{
if (count($this->overview[$id]->children) != 0) {
return $this->overview[$id]->children[0];
/** Look for an unread message in the thread rooted by the message
* @param id INTEGER message number
*/
- function _nextUnread($id)
+ private function _nextUnread($id)
{
if (!$this->overview[$id]->isread) {
return $id;
}
foreach ($this->overview[$id]->children as $child) {
- return $this->_nextUnread($child);
+ $unread = $this->_nextUnread($child);
+ if (!is_null($unread)) {
+ return $unread;
+ }
}
return null;
}
/** Find next unread message
* @param id INTEGER message number
*/
- function nextUnread($id)
+ public function nextUnread($id = null)
{
- // Look in message children
- foreach ($this->overview[$id]->children as $child) {
- $next = $this->_nextUnread($child);
- if (is_null($next)) {
- return $next;
+ if (!is_null($id)) {
+ // Look in message children
+ foreach ($this->overview[$id]->children as $child) {
+ $next = $this->_nextUnread($child);
+ if (!is_null($next)) {
+ return $next;
+ }
}
}
// Look in current thread
$cur = $id;
- while (true) {
- $parent = $this->overview[$cur]->parent;
- $ok = false;
- if (is_null($parent)) {
+ do {
+ $parent = is_null($cur) ? null : $this->overview[$cur]->parent;
+ $ok = is_null($cur) ? true : false;
+ if (!is_null($parent)) {
$array = &$this->overview[$parent]->children;
} else {
$array = &$this->roots;
}
}
$cur = $parent;
- }
+ } while(!is_null($cur));
return null;
}
}
-// vim:set et sw=4 sts=4 ts=4
+// vim:set et sw=4 sts=4 ts=4 enc=utf-8:
?>