Tree is full featured now.
[banana.git] / banana / tree.inc.php
CommitLineData
d3b026ab 1<?php
2/********************************************************************************
3* include/tree.inc.php : thread tree
4* -----------------------
5*
6* This file is part of the banana distribution
7* Copyright: See COPYING files that comes with this distribution
8********************************************************************************/
9
10
e3bc13e0 11define('BANANA_TREE_VERSION', '0.1.2');
d3b026ab 12
13/**
14 * Class representing a thread tree
15 */
16class BananaTree
17{
18 /** Tree cache
19 */
20 static private $cache = array();
21
22 /** Tree format
23 */
24 public $version;
25
26 /** Last update timestamp
27 */
28 public $time = 0;
29
30 /** Data
31 */
e3bc13e0 32 public $data = array();
33
34 /** Data caching
35 */
36 private $urls = array();
37 private $title = array();
38
39 private $displaid = null;
d3b026ab 40
41 /** Construct a new tree from a given root
42 */
43 public function __construct(BananaSpoolHead &$root)
44 {
45 if (empty($root->children)) {
46 $this->data = null;
47 } else {
e3bc13e0 48 $this->data =& $this->builder($root);
d3b026ab 49 }
50 $this->time = time();
51 $this->version = BANANA_TREE_VERSION;
52 $this->saveToFile($root->id);
53 }
54
55 private function &builder(BananaSpoolHead &$head)
56 {
e3bc13e0 57 $array = array(array($head->id));
58 $this->urls[$head->id] = banana_entities(Banana::$page->makeURL(array('group' => Banana::$group,
59 'artid' => $head->id)));
60 $this->title[$head->id] = banana_entities($head->name . ', ' . Banana::$spool->formatDate($head));
d3b026ab 61 foreach ($head->children as $key=>&$msg) {
62 $tree =& $this->builder($msg);
63 $last = $key == count($head->children) - 1;
64 foreach ($tree as $kt=>&$line) {
65 if ($kt === 0 && $key === 0 && !$last) {
ee4eff66 66 $array[0] = array_merge($array[0], array(array('+', $msg->id)), $line);
d3b026ab 67 } else if($kt === 0 && $key === 0) {
ee4eff66 68 $array[0] = array_merge($array[0], array(array('-', $msg->id)), $line);
d3b026ab 69 } else if ($kt === 0 && $last) {
ee4eff66 70 $array[] = array_merge(array(' ', array('`', $msg->id)), $line);
d3b026ab 71 } else if ($kt === 0) {
ee4eff66 72 $array[] = array_merge(array(' ', array('t', $msg->id)), $line);
d3b026ab 73 } else if ($last) {
e3bc13e0 74 $array[] = array_merge(array(' ', ' '), $line);
d3b026ab 75 } else {
ee4eff66 76 $array[] = array_merge(array(' ', array('|', $head->children[$key+1]->id)), $line);
d3b026ab 77 }
78 }
79 unset($tree);
80 }
81 return $array;
82 }
83
84 /** Save the content of the tree into a file
85 */
86 private function saveToFile($id)
87 {
88 file_put_contents(BananaTree::filename($id), serialize($this));
89 }
90
1d521296 91 /** Return html to display the tree
92 */
93 public function &show()
94 {
e3bc13e0 95 if (!is_null($this->displaid)) {
96 return $this->displaid;
97 }
98 static $t_e, $u_h, $u_ht, $u_vt, $u_l, $u_f, $r_h, $r_ht, $r_vt, $r_l, $r_f;
99 if (!isset($t_e)) {
100 $t_e = Banana::$page->makeImg(Array('img' => 'e', 'alt' => ' ', 'height' => 18, 'width' => 14));
101 $u_h = Banana::$page->makeImg(Array('img' => 'h2', 'alt' => '-', 'height' => 18, 'width' => 14));
102 $u_ht = Banana::$page->makeImg(Array('img' => 'T2', 'alt' => '+', 'height' => 18, 'width' => 14));
103 $u_vt = Banana::$page->makeImg(Array('img' => 't2', 'alt' => '`', 'height' => 18, 'width' => 14));
104 $u_l = Banana::$page->makeImg(Array('img' => 'l2', 'alt' => '|', 'height' => 18, 'width' => 14));
105 $u_f = Banana::$page->makeImg(Array('img' => 'f2', 'alt' => 't', 'height' => 18, 'width' => 14));
106 $r_h = Banana::$page->makeImg(Array('img' => 'h2r', 'alt' => '-', 'height' => 18, 'width' => 14));
107 $r_ht = Banana::$page->makeImg(Array('img' => 'T2r', 'alt' => '+', 'height' => 18, 'width' => 14));
108 $r_vt = Banana::$page->makeImg(Array('img' => 't2r', 'alt' => '`', 'height' => 18, 'width' => 14));
109 $r_l = Banana::$page->makeImg(Array('img' => 'l2r', 'alt' => '|', 'height' => 18, 'width' => 14));
110 $r_f = Banana::$page->makeImg(Array('img' => 'f2r', 'alt' => 't', 'height' => 18, 'width' => 14));
111 }
112 $text = '<div class="tree">';
113 foreach ($this->data as &$line) {
114 $text .= '<div style="height: 18px">';
115 foreach ($line as &$item) {
ee4eff66 116 if ($item == ' ') {
117 $text .= $t_e;
118 } else if (is_array($item)) {
119 $head =& Banana::$spool->overview[$item[1]];
120 switch ($item[0]) {
121 case '+': $text .= $head->isread ? $r_ht : $u_ht; break;
122 case '-': $text .= $head->isread ? $r_h : $u_h; break;
123 case '|': $text .= $head->isread ? $r_l : $u_l; break;
124 case '`': $text .= $head->isread ? $r_vt : $u_vt; break;
125 case 't': $text .= $head->isread ? $r_f : $u_f; break;
126 }
127 } else {
e3bc13e0 128 $head =& Banana::$spool->overview[$item];
129 $text .= '<span style="background-color:' . $head->color . '; text-decoration: none"'
130 . ' title="' . $this->title[$item] . '">'
131 . '<input type="radio" name="banana_tree" value="' . $head->id . '"';
132 if (Banana::$msgshow_javascript) {
133 $text .= ' onchange="window.location=\'' . $this->urls[$item] . '\'"';
134 } else {
135 $text .= ' disabled="disabled"';
136 }
137 if (Banana::$artid == $item) {
138 $text .= ' checked="checked"';
139 }
140 $text .= '/></span>';
141 }
142 }
143 $text .= "</div>\n";
144 }
145 $text .= '</div>';
146 $this->displaid =& $text;
147 return $text;
1d521296 148 }
149
d3b026ab 150 /** Get filename
151 */
152 static private function filename($id)
153 {
154 return BananaSpool::getPath('tree_' . $id);
155 }
156
157 /** Read a tree from a file
158 */
159 static private function &readFromFile($id)
160 {
161 $tree = null;
162 $file = BananaTree::filename($id);
163 if (!file_exists($file)) {
164 return $tree;
165 }
166 $tree = unserialize(file_get_contents($file));
167 if ($tree->version != BANANA_TREE_VERSION) {
168 $tree = null;
169 }
170 return $tree;
171 }
172
173 /** Build a tree for the given id
174 */
175 static public function &build($id)
176 {
177 $root =& Banana::$spool->root($id);
178 if (!isset(BananaTree::$cache[$root->id])) {
179 $tree =& BananaTree::readFromFile($root->id);
180 if (is_null($tree) || $tree->time < $root->time) {
181 $tree = new BananaTree($root);
182 }
183 BananaTree::$cache[$root->id] =& $tree;
184 }
185 return BananaTree::$cache[$root->id];
186 }
187
188 /** Kill the file associated to the given id
189 */
190 static public function kill($id)
191 {
192 @unlink(BananaTree::filename($id));
193 }
194}
195// vim:set et sw=4 sts=4 ts=4 enc=utf-8:
196?>